mirror of https://github.com/nealey/rogue
299 lines
5.3 KiB
C
299 lines
5.3 KiB
C
/*
|
|
* score editor
|
|
*
|
|
* @(#)netwait.c 4.6 (Berkeley) 02/05/99
|
|
*/
|
|
|
|
# include <stdio.h>
|
|
# include <pwd.h>
|
|
# include <signal.h>
|
|
# include <ctype.h>
|
|
# include <unctrl.h>
|
|
|
|
# define TRUE 1
|
|
# define FALSE 0
|
|
# define bool char
|
|
# define RN (((Seed = Seed*11109+13849) >> 16) & 0xffff)
|
|
|
|
# define MAXSTR 80
|
|
|
|
# include "netwait.h"
|
|
|
|
SCORE Top_ten[10];
|
|
|
|
char frob,
|
|
Buf[BUFSIZ],
|
|
*Reason[] = {
|
|
"killed",
|
|
"quit",
|
|
"A total winner",
|
|
"killed with Amulet",
|
|
};
|
|
|
|
int Seed,
|
|
Inf;
|
|
|
|
struct passwd *getpwnam();
|
|
|
|
int
|
|
main(ac, av)
|
|
int ac;
|
|
char **av;
|
|
{
|
|
char *scorefile;
|
|
FILE *outf;
|
|
|
|
if (ac == 1)
|
|
scorefile = SCOREFILE;
|
|
else
|
|
scorefile = av[1];
|
|
Seed = getpid();
|
|
|
|
if ((Inf = open(scorefile, 2)) < 0) {
|
|
perror(scorefile);
|
|
exit(1);
|
|
}
|
|
frob = 0;
|
|
s_encread((char *) Top_ten, sizeof Top_ten, Inf);
|
|
|
|
while (do_comm())
|
|
continue;
|
|
|
|
exit(0);
|
|
}
|
|
|
|
/*
|
|
* do_comm:
|
|
* Get and execute a command
|
|
*/
|
|
bool
|
|
do_comm(void)
|
|
{
|
|
char *sp;
|
|
SCORE *scp;
|
|
struct passwd *pp;
|
|
static FILE *outf = NULL;
|
|
static bool written = TRUE;
|
|
|
|
printf("\nCommand: ");
|
|
while (isspace(Buf[0] = getchar()) || Buf[0] == '\n')
|
|
continue;
|
|
fgets(&Buf[1], BUFSIZ, stdin);
|
|
Buf[strlen(Buf) - 1] = '\0';
|
|
switch (Buf[0]) {
|
|
case 'w':
|
|
if (strncmp(Buf, "write", strlen(Buf)))
|
|
goto def;
|
|
lseek(Inf, 0L, 0);
|
|
if (outf == NULL && (outf = fdopen(Inf, "w")) == NULL) {
|
|
perror("fdopen");
|
|
exit(1);
|
|
}
|
|
fseek(outf, 0L, 0);
|
|
if (s_lock_sc())
|
|
{
|
|
int (*fp)();
|
|
|
|
fp = signal(SIGINT, SIG_IGN);
|
|
frob = 0;
|
|
s_encwrite((char *) Top_ten, sizeof Top_ten, outf);
|
|
s_unlock_sc();
|
|
signal(SIGINT, fp);
|
|
written = TRUE;
|
|
}
|
|
break;
|
|
|
|
case 'a':
|
|
if (strncmp(Buf, "add", strlen(Buf)))
|
|
goto def;
|
|
add_score();
|
|
written = FALSE;
|
|
break;
|
|
|
|
case 'd':
|
|
if (strncmp(Buf, "delete", strlen(Buf)))
|
|
goto def;
|
|
del_score();
|
|
written = FALSE;
|
|
break;
|
|
|
|
case 'p':
|
|
if (strncmp(Buf, "print", strlen(Buf)))
|
|
goto def;
|
|
printf("\nTop Ten Rogueists:\nRank\tScore\tName\n");
|
|
for (scp = Top_ten; scp < &Top_ten[10]; scp++)
|
|
if (!pr_score(scp, TRUE))
|
|
break;
|
|
break;
|
|
|
|
case 'q':
|
|
if (strncmp(Buf, "quit", strlen(Buf)))
|
|
goto def;
|
|
if (!written) {
|
|
printf("No write\n");
|
|
written = TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
break;
|
|
|
|
default:
|
|
def:
|
|
printf("Unkown command: \"%s\"\n", Buf);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* add_score:
|
|
* Add a score to the score file
|
|
*/
|
|
void
|
|
add_score(void)
|
|
{
|
|
SCORE *scp;
|
|
struct passwd *pp;
|
|
int i;
|
|
static SCORE new;
|
|
|
|
printf("Name: ");
|
|
fgets(new.sc_name, MAXSTR, stdin);
|
|
new.sc_name[strlen(new.sc_name) - 1] = '\0';
|
|
do {
|
|
printf("Reason: ");
|
|
if ((new.sc_flags = getchar()) < '0' || new.sc_flags > '2') {
|
|
for (i = 0; i < 3; i++)
|
|
printf("%d: %s\n", i, Reason[i]);
|
|
ungetc(new.sc_flags, stdin);
|
|
}
|
|
while (getchar() != '\n')
|
|
continue;
|
|
} while (new.sc_flags < '0' || new.sc_flags > '2');
|
|
new.sc_flags -= '0';
|
|
do {
|
|
printf("User: ");
|
|
fgets(Buf, BUFSIZ, stdin);
|
|
Buf[strlen(Buf) - 1] = '\0';
|
|
if ((pp = getpwnam(Buf)) == NULL)
|
|
printf("who (%s)?\n", Buf);
|
|
} while (pp == NULL);
|
|
new.sc_uid = pp->pw_uid;
|
|
do {
|
|
printf("Monster: ");
|
|
if (!isalpha(new.sc_monster = getchar())) {
|
|
printf("type A-Za-z [%s]\n", unctrl(new.sc_monster));
|
|
ungetc(new.sc_monster, stdin);
|
|
}
|
|
while (getchar() != '\n')
|
|
continue;
|
|
} while (!isalpha(new.sc_monster));
|
|
printf("Score: ");
|
|
scanf("%d", &new.sc_score);
|
|
printf("Level: ");
|
|
scanf("%d", &new.sc_level);
|
|
while (getchar() != '\n')
|
|
continue;
|
|
pr_score(&new, FALSE);
|
|
printf("Really add it? ");
|
|
if (getchar() != 'y')
|
|
return;
|
|
while (getchar() != '\n')
|
|
continue;
|
|
insert_score(&new);
|
|
}
|
|
|
|
/*
|
|
* pr_score:
|
|
* Print out a score entry. Return FALSE if last entry.
|
|
*/
|
|
void
|
|
pr_score(SCORE *scp, bool num)
|
|
{
|
|
struct passwd *pp;
|
|
|
|
if (scp->sc_score) {
|
|
if (num)
|
|
printf("%d", scp - Top_ten + 1);
|
|
printf("\t%d\t%s: %s on level %d", scp->sc_score, scp->sc_name,
|
|
Reason[scp->sc_flags], scp->sc_level);
|
|
if (scp->sc_flags == 0)
|
|
printf(" by %s", s_killname((char) scp->sc_monster, TRUE));
|
|
if ((pp = getpwuid(scp->sc_uid)) == NULL)
|
|
printf(" (%d)", scp->sc_uid);
|
|
else
|
|
printf(" (%s)", pp->pw_name);
|
|
putchar('\n');
|
|
}
|
|
return scp->sc_score;
|
|
}
|
|
|
|
/*
|
|
* insert_score:
|
|
* Insert a score into the top ten list
|
|
*/
|
|
void
|
|
insert_score(SCORE *new)
|
|
{
|
|
SCORE *scp, *sc2;
|
|
int flags, uid, amount;
|
|
|
|
flags = new->sc_flags;
|
|
uid = new->sc_uid;
|
|
amount = new->sc_score;
|
|
|
|
for (scp = Top_ten; scp < &Top_ten[10]; scp++)
|
|
if (amount > scp->sc_score)
|
|
break;
|
|
else if (flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
|
|
scp = &Top_ten[10];
|
|
if (scp < &Top_ten[10]) {
|
|
if (flags != 2)
|
|
for (sc2 = scp; sc2 < &Top_ten[10]; sc2++) {
|
|
if (sc2->sc_uid == uid && sc2->sc_flags != 2)
|
|
break;
|
|
}
|
|
else
|
|
sc2 = &Top_ten[9];
|
|
while (sc2 > scp) {
|
|
*sc2 = sc2[-1];
|
|
sc2--;
|
|
}
|
|
*scp = *new;
|
|
sc2 = scp;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* del_score:
|
|
* Delete a score from the score list.
|
|
*/
|
|
void
|
|
del_score(void)
|
|
{
|
|
SCORE *scp;
|
|
int i;
|
|
int num;
|
|
|
|
for (;;) {
|
|
printf("Which score? ");
|
|
fgets(Buf, BUFSIZ, stdin);
|
|
if (Buf[0] == '\n')
|
|
return;
|
|
sscanf(Buf, "%d", &num);
|
|
if (num < 1 || num > 10)
|
|
printf("range is 1-10\n");
|
|
else
|
|
break;
|
|
}
|
|
num--;
|
|
for (scp = &Top_ten[num]; scp < &Top_ten[9]; scp++)
|
|
*scp = scp[1];
|
|
Top_ten[9].sc_score = 0;
|
|
for (i = 0; i < MAXSTR; i++)
|
|
Top_ten[9].sc_name[i] = RN;
|
|
Top_ten[9].sc_flags = RN;
|
|
Top_ten[9].sc_level = RN;
|
|
Top_ten[9].sc_monster = RN;
|
|
Top_ten[9].sc_uid = RN;
|
|
}
|