Rogue Score File Manipulators

utzoo!decvax!harpo!seismo!rocheste!avie utzoo!decvax!harpo!seismo!rocheste!avie
Wed Nov 10 16:05:12 AEST 1982


Following are some programs to manipulate the rogue score files.  Many of
you already have an eariler version of these programs, which worked only
on rogue 3.6 score files.  These programs have been upgraded by both myself
and others to work on other versions as well.  Following are the enhancements
made by Stephen Gildea (miterl!gildea).  The enclosed files are:

	Makefile rscore.h rread.c redit.c

The makefile will do it all for you (although you may with to edit rscore.h
to define your installations score file name).

	Good luck
	Avadis Tevanian, Jr.
	(rochester!avie)

*Note:	To actually make changes to the score file, you must have write
	access to it!


-------------------------start of makefile----------------------------------
all: rread3.6 redit3.6 rread5.2 redit5.2

rread3.6: rread.c
	cc rread.c -DVERS3.6 -o rread3.6

redit3.6: redit.c
	cc redit.c -DVERS3.6 -o redit3.6

rread5.2: rread.c
	cc rread.c -DVERS5.2 -o rread5.2

redit5.2: redit.c
	cc redit.c -DVERS5.2 -o redit5.2
-------------------------end of makefile-----------------------------------
-------------------------start-of-rscore.h---------------------------------

/*
 *	File:	rscore.h
 *	Author:	Stephen Gildea
 *
 *	Useful stuff for reading rogue score files.
 *
 *      Define exactly one of the following flags at compile time:
 *	VERS3.6 for version 3.6 (has "arrow" bug)
 *      VERS5.2 for version of 5.2 with negative-gold bug
 *      VERS5R  for another version of 5.2
 */

#ifdef VERS3.6

#define SCOREFILE "/usr/games/lib/rogue_roll"

#define SCOREOFS		0
#define NAMEOFS			1
#define COMPLOFS		21
#define LEVELOFS		22
#define UIDOFS			23
#define MONSTOFS		24
#define NAMELEN			20

int encstr[] = {
	0xdaa3a9ec,
	0xc17c8141,
	0xa98870d1,
	0xf5af22d7,
	0x3325e174,
	0x7e605eb9,
	0xe17b7a83,
	0xe10c3b7d,
	0x9c659299,
	0x00d15de9,	/* notice that the last byte is 0 */
	0 };

#endif
#ifdef VERS5.2

#define SCOREFILE "/usr/games/lib/rogue_score"

#define SCOREOFS		0
#define COMPLOFS		1
#define LEVELOFS		2
#define MONSTOFS		3
#define UIDOFS			4
#define NAMEOFS			5
#define NAMELEN			20


int encstr[] = {
	0x7c8141da,
	0xd2a342c1,
	0x94e98870,
	0x54f68f22,
	0xe1607e89,
	0x2ab93325,
	0x7b8b7ea1,
	0xcd3be17d,
	0x8b5fda0c,
	0xe99d65d1,
	0 };

#endif
#ifdef VERS5R

#define SCOREFILE "/usr/games/lib/rogue_honors"

#define NAMEOFS			0
#define NAMELEN			20
#define COMPLOFS		20
#define UIDOFS			21
#define MONSTOFS		22
#define SCOREOFS		22
#define LEVELOFS		23

#define SHORTSCORE	/* means that score is upper half of word */

int encstr[] = {
	0x5fd16789,
	0xd462a92d,
	0xb3ad3b9f,
	0xd722678c,
	0xaa2c2e94,
	0x3db5397c,
	0x3be32bef,
	0x60e15dc9,
	0x299908a9,
	0xa9d559b6,
	0 };

#endif

struct {
	char letter;
	char *name;
} table[] = {
	'A', "a giant ant",
	'B', "a bat",
	'C', "a centaur",
	'D', "a dragon",
	'E', "a floating eye",
	'F', "a violet fungi",
	'G', "a gnome",
	'H', "a hobgoblin",
	'I', "an invisible stalker",
	'J', "a jackal",
	'K', "a kobold",
	'L', "a leprechaun",
	'M', "a mimic",
	'N', "a nymph",
	'O', "an orc",
	'P', "a purple worm",
	'Q', "a quasit",
	'R', "a rust monster",
	'S', "a snake",
	'T', "a troll",
	'U', "an umber hulk",
	'V', "a vampire",
	'W', "a wraith",
	'X', "a xorn",
	'Y', "a yeti",
	'Z', "a zombie",
	'a', "an arrow",
	'b', "a bolt",
	'd', "a dart",
	's', "starvation",
	'\0',"God"
};
--------------------------end-of-rscore.h----------------------------------
-------------------------start-of-rread.c----------------------------------

/*
 *	File:	rread.c
 *      By:	Stephen Gildea		(MIT-ERL)
 *	3.6 version by:
 *		Avadis Tevanian, Jr.    (University of Rochester)
 *	Date:	27 Oct 1982
 *
 *	This program reads the rogue score file and decrypts it.
 *      A compile-time flag must be specified to tell which version
 *      of rogue to work for.  See file rscore.h for a list.
 */

#include <stdio.h>
#include "rscore.h"

FILE *fopen(),*scorefile;

main ()
{
	unsigned buffer[250],score;
	int leng,entl;
	char *s1;
	int i,j;

	scorefile = fopen(SCOREFILE,"r");
	leng = read(fileno(scorefile),buffer,1000);
	fclose(scorefile);

	/*   decrypt file   */
	s1 = (char *)encstr;
	for (i = 0; i < leng; i++) {
		*((char *)buffer+i) ^= *s1;
		s1++;
		if (*s1 == '\0') s1 = (char *)encstr;
	}
	

	printf("Rank    Score    Name\n");
	entl=leng/sizeof(0)/10;
	for (i = 0; i < 10; i++)
	{
		score=buffer[i*entl+SCOREOFS];
#ifdef SHORTSCORE
		score >>= 16;
#endif
		if (score == 0) break;
		printf("%-8d",i+1);	/* rank  */
		printf("%-8u ",score);	/* score */
		printf("%s: ",(char *)(buffer+i*entl+NAMEOFS));
		switch (buffer[i*entl+COMPLOFS]) {
		case 2:	printf("A total winner");
			break;
		case 1: printf("quit"); break;
		case 0: printf("killed"); break;
		}
		printf(" on level %u",buffer[i*entl+LEVELOFS]);
		if (buffer[i*entl+COMPLOFS] == 0) {
		    for(j=0; table[j].letter != '\0'; j++)
		       if (table[j].letter == (buffer[i*entl+MONSTOFS] & 0377))
				break;
		    printf(" by %s",
				table[j].name);
		}
		printf(".\n");
	}
}
--------------------------end-of-rread.c-----------------------------------
-------------------------start-of-redit.c----------------------------------
/*
 *	File:	redit.c
 *	By:	Stephen Gildea (MIT)
 *	Date:	28 Oct 1982
 *
 *	This program reads the rogue score file and decrypts it, then
 *	allows the user to modify it.  Modifications can only be saved
 *	by root.
 *	This program is an enhancement of rogueedit by Avadis Tevanian, Jr.
 *	    (University of Rochester)
 *	A compile-time option must be specified to tell which version
 *	of rogue to work for.  See file rscore.h for a list.
 */

#include <stdio.h>
#include <pwd.h>
#include <ctype.h>
#include "rscore.h"

#define TRUE 1
#define FALSE 0

FILE *fopen(),*scorefile;
unsigned buffer[250];
char ebuffer[1000];	/* buffer has decoded result of
						ebuffer. */
int leng, entl;

struct passwd *getpwnam(), *getpwuid();

main ()
{
	int i,c,n;

	encread ();
	while (c = getcommand()) {
		switch (c) {
		case 'D':
			printf("Entry to delete: ");
			while(TRUE) {
				scanf("%d",&n);
				if (n < 1 || n > 10)
					printf("Between 1 and 10 please: ");
					else break;
			}
			DeleteEntry(n);
			getchar();
			break;
		case 'I':
			printf("Entry to insert before: ");
			while(TRUE) {
				scanf("%d",&n);
				if (n < 1 || n > 10)
					printf("Between 1 and 10 please: ");
					else break;
			}
			InsertEntry(n);
			getchar ();
			break;
		case 'C':
			printf("Entry to change: ");
			while(TRUE) {
				scanf("%d",&n);
				if (n < 1 || n > 10)
					printf("Between 1 and 10 please: ");
					else break;
			}
			ChangeEntry(n);
			getchar ();
			break;
		case 'W':
			encwrite();
			break;
		case 'R':
			encread();
			break;
		case 'S':
			printf("Rank Score    Name\n");
			for (i = 0; i < 10; i++)
				printrank(i);
			break;
		case 'Q':
			printf("Good-bye...\n");
			exit(0);
			break;
		}
	}
}

encread ()
{
	scorefile = fopen(SCOREFILE,"r");
	if (scorefile != NULL) {
		leng=read(fileno(scorefile),ebuffer,1000);
		fclose(scorefile);
		entl=leng/sizeof(0)/10;
	} else printf("rogueedit: cannot open %s for reading.\n",SCOREFILE);
	code(buffer,ebuffer);

}

encwrite ()
{

	code(ebuffer,buffer);
	scorefile = fopen(SCOREFILE,"w");
	if (scorefile != NULL) {
		write(fileno(scorefile),ebuffer,leng);
		fclose(scorefile);
	} else printf("rogueedit: cannot open %s for writing.\n",SCOREFILE);
}

code(tobuf,frombuf)	/* encode or decode score file string */
char *tobuf, *frombuf;
{
	int i;
	char *s1;

	s1 = (char *) encstr;
	for (i = 0; i < leng; i++)
	{
		tobuf[i] = frombuf[i] ^ *s1;
		s1++;
		if (*s1 == '\0') s1 = (char *) encstr;
	}
}

getcommand ()
{	int c,i;

	while (TRUE) {

		printf("rogueedit> ");
		c = getchar();

		if (c != '\n')
			while ((i = getchar()) != EOF)
				if (i == '\n') break;
		if (islower(c)) c=toupper(c);
		switch (c) {
		case 'I':
		case 'D':
		case 'C':
		case 'R':
		case 'W':
		case 'S':
		case 'Q':
		return(c);
		default:
			printf("Legal commands are:\n");
			printf("I(nsert), D(elete), C(hange), R(ead file), ");
			printf("W(rite file), S(how scores), Q(uit).\n");
		}
	}
}

getline (s)
char *s;
{
	while ((*s = getchar()) != EOF)
		if (*s == '\n') {
			*s = '\0';
			return;
		} else s++;
}

CopyEntry (i,j)		/* entry i <= entry j. */
int i,j;
{	unsigned *s1,*s2;
	int k;

	s1 = buffer+(i-1)*entl; s2 = buffer + (j-1)*entl;

	for (k = 0; k < entl; k++)
		*s1++ = *s2++;
}

DeleteEntry (i)
int i;
{	int j;
	int *s1;

	for (j = i; j < 10; j++)
		CopyEntry(j,j+1);
	ZeroEntry(10);
}

ZeroEntry(i)
int i;
{
	int j;
	unsigned *s1;

	s1 = buffer+(i-1)*entl;
	for (j = 0; j < entl; j++)
		*(s1+j) = 0;
}

InsertEntry (i)
int i;
{	int j;
	unsigned *i1;
	char *s1,who[80];
	char *lengok();
	int complete;
	struct passwd *pw;

	for (j = 9; j >= i; j--)
		CopyEntry(j+1,j);
	ZeroEntry(i);

	i1 = (buffer+(i-1)*entl);
	printf("Enter the new score: ");
	scanf("%d",&j);
#ifdef SHORTSCORE
	j = j << 16 | *(i1+SCOREOFS) & 0xffff;
#endif
	*(i1+SCOREOFS) = j;
	printf("Name: ");
	getchar();
	getline(buffer+(i-1)*entl+NAMEOFS);
	printf("Level: ");
	scanf("%d",&j);
	*(i1+LEVELOFS) = j;
	complete = FALSE;
	while (!complete) {
		printf("Enter completion code (0 = killed, 1 = quit, 2 = ");
		printf("total winner): ");
		scanf("%d",&j);
		*(i1+COMPLOFS) = j;
		switch (j) {
		case 2:
		case 1:
			complete = TRUE;
			break;
		case 0:
			do {
				printf("Enter monster [A-Z,a(arrow),");
				printf("b(olt),d(art),s(tarve)]: ");
				getchar(); /* get old CR */
				scanf("%c",&j);
			} while (j < 'A' || j > 'z');
			*(i1+MONSTOFS) = *(i1+MONSTOFS) & ~0xffff | j;
				/* monster in lower half of word */
			complete = TRUE;
			break;
		}
	}
	do {
		printf("Who really did this: ");
		scanf("%s",who);
		pw = getpwnam(who);
		if (pw == 0) printf("No such user.\n");
			else break;
	} while (TRUE);
	*(i1+UIDOFS) = pw->pw_uid;
	if (*(s1=lengok(i1)) == '\0') *++s1='*';  /* flag entry as fake */
}

ChangeEntry (i)
int i;
{
	DeleteEntry(i);
	InsertEntry(i);
}

printrank (i)
int i;
{
	unsigned uid,j;
	char getmod();
	struct passwd *pw;

	j = *(buffer+i*entl+SCOREOFS);
#ifdef SHORTSCORE
	j >>= 16;
#endif
	if (j == 0) return;
	printf("%c",getmod(buffer+i*entl));	/* print mod flag */
	printf("%-3d ",i+1);			/* print rank     */
	printf("%-8u ",j);			/* print score    */
	printf("%s",buffer+i*entl+NAMEOFS);
	uid = *(buffer+i*entl+UIDOFS);
	pw=getpwuid(uid);
	if (pw != 0) printf("(%s): ",pw->pw_name);
		else printf("(%u): ",uid);
	switch (*(buffer+i*entl+COMPLOFS)) {
		case 2:	printf("A total winner");
			break;
		case 1: printf("quit"); break;
		case 0: printf("killed"); break;
	}
	printf(" on level %u",*(buffer+i*entl+LEVELOFS));
	if (*(buffer+i*entl+COMPLOFS) == 0) {
		int m;
		m = *(buffer+i*entl+MONSTOFS) & 0377;
		for (j=0; table[j].letter != '\0'; j++)
			if (table[j].letter == m) 
				break;
		printf(" by %s",table[j].name);
		if (table[j].letter == '\0') 
			printf("(%c)",m);
	}
	printf(".\n");
}

char
getmod(buf)
char *buf;
{
	char *s1,*lengok();
	
	if (*(s1=lengok(buf)) != '\0') return(' ');
	return(*++s1 == '\0' ? ' ' : '*');
}

putmod(buf)
char *buf;
{
	char *s1,*lengok();

	if (*(s1=lengok(buf)) == '\0') *++s1 = '*';
}

char *
lengok(buf)
char *buf;
{
	return(buf+4*(NAMEOFS+NAMELEN)-2);
}

--------------------------end-of-redit.c-----------------------------------






More information about the Comp.sources.unix mailing list