Mercurial > hg > early-roguelike
view rogue5/scedit.c @ 173:78fa1d0e5d25
srogue: open the score and log files when the program starts.
Super-Rogue can now use the same privilege-dropping scheme as the other
games.
author | John "Elwin" Edwards |
---|---|
date | Sat, 01 Aug 2015 15:12:11 -0400 |
parents | f502bf60e6e4 |
children | 3d4252fa2ed3 |
line wrap: on
line source
/* * score editor * * @(#)score.c 4.6 (Berkeley) 02/05/99 * * Rogue: Exploring the Dungeons of Doom * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ # include <curses.h> # include <stdio.h> # include <signal.h> # include <ctype.h> #ifndef TRUE # define TRUE 1 #endif # define FALSE 0 # define RN (((seed = seed*11109+13849) >> 16) & 0xffff) # define MAXSTR 80 # include "score.h" SCORE top_ten[10]; char buf[BUFSIZ], *reason[] = { "killed", "quit", "A total winner", "killed with amulet", }; int seed; FILE *inf; struct passwd *getpwnam(); int do_comm(); int pr_score(SCORE *, int); int main(int ac, char *av[]) { char *scorefile; FILE *outf; if (ac == 1) scorefile = "rogue54.scr"; else scorefile = av[1]; seed = md_getpid(); if ((inf = fopen(scorefile, "r+")) < 0) { perror(scorefile); exit(1); } s_encread((char *) top_ten, sizeof top_ten, inf); while (do_comm()) continue; exit(0); } /* * do_comm: * Get and execute a command */ int do_comm(void) { char *sp; SCORE *scp; struct passwd *pp; static FILE *outf = NULL; static int written = TRUE; printf("\nCommand: "); while (isspace(buf[0] = getchar()) || buf[0] == '\n') continue; (void) fget(s&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()) { void (*fp)(int); fp = signal(SIGINT, SIG_IGN); 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; uid_t id = 0; int i; SCORE new; printf("Name: "); (void) 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 Id: "); (void) fgets(buf, BUFSIZ, stdin); buf[strlen(buf) - 1] = '\0'; id = atoi(buf); } while (id == -1); new.sc_uid = id; 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. */ pr_score(SCORE *scp, int num) { 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(scp->sc_monster, TRUE)); printf(" (%s)", md_getrealname(scp->sc_uid)); putchar('\n'); } return scp->sc_score; } /* * insert_score: * Insert a score into the top ten list */ insert_score(SCORE *new) { SCORE *scp, *sc2; int flags, amount; uid_t uid; 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? "); (void) 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; }