]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/scores.c
s/ be be / be /
[bsdgames-darwin.git] / larn / scores.c
1 /* $NetBSD: scores.c,v 1.21 2012/06/19 05:30:44 dholland Exp $ */
2
3 /*
4 * scores.c Larn is copyrighted 1986 by Noah Morgan.
5 *
6 * Functions in this file are:
7 *
8 * readboard() Function to read in the scoreboard into a static buffer
9 * writeboard() Function to write the scoreboard from readboard()'s buffer
10 * makeboard() Function to create a new scoreboard (wipe out old one)
11 * hashewon() Function to return 1 if player has won a game before, else 0
12 * long paytaxes(x) Function to pay taxes if any are due winshou()
13 * ubroutine to print out the winning scoreboard shou(x)
14 * ubroutine to print out the non-winners scoreboard showscores()
15 * unction to show the scoreboard on the terminal showallscores()
16 * Function to show scores and the iven lists that go with them sortboard()
17 * unction to sort the scoreboard newscore(score, whoo, whyded, winner)
18 * Function to add entry to scoreboard new1sub(score,i,whoo,taxes)
19 * Subroutine to put player into a new2sub(score,i,whoo,whyded)
20 * Subroutine to put player into a died(x) Subroutine to record who
21 * played larn, and what the score was diedsub(x) Subroutine to print out a
22 * line showing player when he is killed diedlog() Subroutine to read a
23 * log file and print it out in ascii format getplid(name)
24 * on to get players id # from id file
25 *
26 */
27 #include <sys/cdefs.h>
28 #ifndef lint
29 __RCSID("$NetBSD: scores.c,v 1.21 2012/06/19 05:30:44 dholland Exp $");
30 #endif /* not lint */
31 #include <sys/types.h>
32 #include <sys/times.h>
33 #include <sys/stat.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include "header.h"
39 #include "extern.h"
40
41 struct scofmt { /* This is the structure for the scoreboard */
42 long score; /* the score of the player */
43 long suid; /* the user id number of the player */
44 short what; /* the number of the monster that killed
45 * player */
46 short level; /* the level player was on when he died */
47 short hardlev;/* the level of difficulty player played at */
48 short order; /* the relative ordering place of this entry */
49 char who[40];/* the name of the character */
50 char sciv[26][2]; /* this is the inventory list of the
51 * character */
52 };
53 struct wscofmt { /* This is the structure for the winning
54 * scoreboard */
55 long score; /* the score of the player */
56 long timeused; /* the time used in mobuls to win the
57 * game */
58 long taxes; /* taxes he owes to LRS */
59 long suid; /* the user id number of the player */
60 short hardlev;/* the level of difficulty player played at */
61 short order; /* the relative ordering place of this entry */
62 char who[40];/* the name of the character */
63 };
64
65 struct log_fmt { /* 102 bytes struct for the log file */
66 long score; /* the players score */
67 int32_t diedtime; /* time when game was over */
68 short cavelev;/* level in caves */
69 short diff; /* difficulty player played at */
70 #ifdef EXTRA
71 long elapsedtime; /* real time of game in seconds */
72 long bytout; /* bytes input and output */
73 long bytin;
74 long moves; /* number of moves made by player */
75 short ac; /* armor class of player */
76 short hp, hpmax; /* players hitpoints */
77 short cputime;/* CPU time needed in seconds */
78 short killed, spused; /* monsters killed and spells cast */
79 short usage; /* usage of the CPU in % */
80 short lev; /* player level */
81 #endif
82 char who[12];/* player name */
83 char what[46]; /* what happened to player */
84 };
85
86 static struct scofmt sco[SCORESIZE]; /* the structure for the scoreboard */
87 static struct wscofmt winr[SCORESIZE]; /* struct for the winning scoreboard */
88 static struct log_fmt logg; /* structure for the log file */
89 static const char *whydead[] = {
90 "quit", "suspended", "self - annihilated", "shot by an arrow",
91 "hit by a dart", "fell into a pit", "fell into a bottomless pit",
92 "a winner", "trapped in solid rock", "killed by a missing save file",
93 "killed by an old save file", "caught by the greedy cheater checker trap",
94 "killed by a protected save file", "killed his family and committed suicide",
95 "erased by a wayward finger", "fell through a bottomless trap door",
96 "fell through a trap door", "drank some poisonous water",
97 "fried by an electric shock", "slipped on a volcano shaft",
98 "killed by a stupid act of frustration", "attacked by a revolting demon",
99 "hit by his own magic", "demolished by an unseen attacker",
100 "fell into the dreadful sleep", "killed by an exploding chest",
101 /* 26 */ "killed by a missing maze data file", "annihilated in a sphere",
102 "died a post mortem death", "wasted by a malloc() failure"
103 };
104
105 static int readboard(void);
106 static int writeboard(void);
107 static int winshou(void);
108 static int shou(int);
109 static int sortboard(void);
110 static void newscore(long, char *, int, int);
111 static void new1sub(long, int, char *, long);
112 static void new2sub(long, int, char *, int);
113 static void diedsub(int);
114
115 /*
116 * readboard() Function to read in the scoreboard into a static buffer
117 *
118 * returns -1 if unable to read in the scoreboard, returns 0 if all is OK
119 */
120 static int
121 readboard(void)
122 {
123 int i;
124
125 if (gid != egid)
126 setegid(egid);
127 i = lopen(scorefile);
128 if (gid != egid)
129 setegid(gid);
130 if (i < 0) {
131 lprcat("Can't read scoreboard\n");
132 lflush();
133 return (-1);
134 }
135 lrfill((char *) sco, sizeof(sco));
136 lrfill((char *) winr, sizeof(winr));
137 lrclose();
138 lcreat((char *) 0);
139 return (0);
140 }
141
142 /*
143 * writeboard() Function to write the scoreboard from readboard()'s buffer
144 *
145 * returns -1 if unable to write the scoreboard, returns 0 if all is OK
146 */
147 static int
148 writeboard(void)
149 {
150 int i;
151
152 set_score_output();
153 if (gid != egid)
154 setegid(egid);
155 i = lcreat(scorefile);
156 if (gid != egid)
157 setegid(gid);
158 if (i < 0) {
159 lprcat("Can't write scoreboard\n");
160 lflush();
161 return (-1);
162 }
163 lwrite((char *) sco, sizeof(sco));
164 lwrite((char *) winr, sizeof(winr));
165 lwclose();
166 lcreat((char *) 0);
167 return (0);
168 }
169
170 /*
171 * makeboard() Function to create a new scoreboard (wipe out old one)
172 *
173 * returns -1 if unable to write the scoreboard, returns 0 if all is OK
174 */
175 int
176 makeboard(void)
177 {
178 int i;
179 set_score_output();
180 for (i = 0; i < SCORESIZE; i++) {
181 winr[i].taxes = winr[i].score = sco[i].score = 0;
182 winr[i].order = sco[i].order = i;
183 }
184 if (writeboard())
185 return (-1);
186 if (gid != egid)
187 setegid(egid);
188 chmod(scorefile, 0660);
189 if (gid != egid)
190 setegid(gid);
191 return (0);
192 }
193
194 /*
195 * hashewon() Function to return 1 if player has won a game before, else 0
196 *
197 * This function also sets c[HARDGAME] to appropriate value -- 0 if not a
198 * winner, otherwise the next level of difficulty listed in the winners
199 * scoreboard. This function also sets outstanding_taxes to the value in
200 * the winners scoreboard.
201 */
202 int
203 hashewon(void)
204 {
205 int i;
206 c[HARDGAME] = 0;
207 if (readboard() < 0)
208 return (0); /* can't find scoreboard */
209 for (i = 0; i < SCORESIZE; i++) /* search through winners scoreboard */
210 if (winr[i].suid == userid)
211 if (winr[i].score > 0) {
212 c[HARDGAME] = winr[i].hardlev + 1;
213 outstanding_taxes = winr[i].taxes;
214 return (1);
215 }
216 return (0);
217 }
218
219 /*
220 * long paytaxes(x) Function to pay taxes if any are due
221 *
222 * Enter with the amount (in gp) to pay on the taxes.
223 * Returns amount actually paid.
224 */
225 long
226 paytaxes(long x)
227 {
228 int i;
229 long amt;
230 if (x < 0)
231 return (0L);
232 if (readboard() < 0)
233 return (0L);
234 for (i = 0; i < SCORESIZE; i++)
235 if (winr[i].suid == userid) /* look for players winning
236 * entry */
237 if (winr[i].score > 0) { /* search for a winning
238 * entry for the player */
239 amt = winr[i].taxes;
240 if (x < amt)
241 amt = x; /* don't overpay taxes
242 * (Ughhhhh) */
243 winr[i].taxes -= amt;
244 outstanding_taxes -= amt;
245 set_score_output();
246 if (writeboard() < 0)
247 return (0);
248 return (amt);
249 }
250 return (0L); /* couldn't find user on winning scoreboard */
251 }
252
253 /*
254 * winshou() Subroutine to print out the winning scoreboard
255 *
256 * Returns the number of players on scoreboard that were shown
257 */
258 static int
259 winshou(void)
260 {
261 struct wscofmt *p;
262 int i, j, count;
263 for (count = j = i = 0; i < SCORESIZE; i++) /* is there anyone on
264 * the scoreboard? */
265 if (winr[i].score != 0) {
266 j++;
267 break;
268 }
269 if (j) {
270 lprcat("\n Score Difficulty Time Needed Larn Winners List\n");
271
272 for (i = 0; i < SCORESIZE; i++) /* this loop is needed to
273 * print out the */
274 for (j = 0; j < SCORESIZE; j++) { /* winners in order */
275 p = &winr[j]; /* pointer to the scoreboard
276 * entry */
277 if (p->order == i) {
278 if (p->score) {
279 count++;
280 lprintf("%10ld %2ld %5ld Mobuls %s \n",
281 (long) p->score, (long) p->hardlev, (long) p->timeused, p->who);
282 }
283 break;
284 }
285 }
286 }
287 return (count); /* return number of people on scoreboard */
288 }
289
290 /*
291 * shou(x) Subroutine to print out the non-winners scoreboard
292 * int x;
293 *
294 * Enter with 0 to list the scores, enter with 1 to list inventories too
295 * Returns the number of players on scoreboard that were shown
296 */
297 static int
298 shou(int x)
299 {
300 int i, j, n, k;
301 int count;
302 for (count = j = i = 0; i < SCORESIZE; i++) /* is the scoreboard
303 * empty? */
304 if (sco[i].score != 0) {
305 j++;
306 break;
307 }
308 if (j) {
309 lprcat("\n Score Difficulty Larn Visitor Log\n");
310 for (i = 0; i < SCORESIZE; i++) /* be sure to print them out
311 * in order */
312 for (j = 0; j < SCORESIZE; j++)
313 if (sco[j].order == i) {
314 if (sco[j].score) {
315 count++;
316 lprintf("%10ld %2ld %s ",
317 (long) sco[j].score, (long) sco[j].hardlev, sco[j].who);
318 if (sco[j].what < 256)
319 lprintf("killed by a %s", monster[sco[j].what].name);
320 else
321 lprintf("%s", whydead[sco[j].what - 256]);
322 if (x != 263)
323 lprintf(" on %s", levelname[sco[j].level]);
324 if (x) {
325 for (n = 0; n < 26; n++) {
326 iven[n] = sco[j].sciv[n][0];
327 ivenarg[n] = sco[j].sciv[n][1];
328 }
329 for (k = 1; k < 99; k++)
330 for (n = 0; n < 26; n++)
331 if (k == iven[n]) {
332 srcount = 0;
333 show3(n);
334 }
335 lprcat("\n\n");
336 } else
337 lprc('\n');
338 }
339 j = SCORESIZE;
340 }
341 }
342 return (count); /* return the number of players just shown */
343 }
344
345 /*
346 * showscores() Function to show the scoreboard on the terminal
347 *
348 * Returns nothing of value
349 */
350 static char esb[] = "The scoreboard is empty.\n";
351 void
352 showscores(void)
353 {
354 int i, j;
355 lflush();
356 lcreat((char *) 0);
357 if (readboard() < 0)
358 return;
359 i = winshou();
360 j = shou(0);
361 if (i + j == 0)
362 lprcat(esb);
363 else
364 lprc('\n');
365 lflush();
366 }
367
368 /*
369 * showallscores() Function to show scores and the iven lists that go with them
370 *
371 * Returns nothing of value
372 */
373 void
374 showallscores(void)
375 {
376 int i, j;
377 lflush();
378 lcreat((char *) 0);
379 if (readboard() < 0)
380 return;
381 c[WEAR] = c[WIELD] = c[SHIELD] = -1; /* not wielding or wearing
382 * anything */
383 for (i = 0; i < MAXPOTION; i++)
384 potionname[i] = potionhide[i];
385 for (i = 0; i < MAXSCROLL; i++)
386 scrollname[i] = scrollhide[i];
387 i = winshou();
388 j = shou(1);
389 if (i + j == 0)
390 lprcat(esb);
391 else
392 lprc('\n');
393 lflush();
394 }
395
396 /*
397 * sortboard() Function to sort the scoreboard
398 *
399 * Returns 0 if no sorting done, else returns 1
400 */
401 static int
402 sortboard(void)
403 {
404 int i, j = 0, pos;
405 long jdat;
406 for (i = 0; i < SCORESIZE; i++)
407 sco[i].order = winr[i].order = -1;
408 pos = 0;
409 while (pos < SCORESIZE) {
410 jdat = 0;
411 for (i = 0; i < SCORESIZE; i++)
412 if ((sco[i].order < 0) && (sco[i].score >= jdat)) {
413 j = i;
414 jdat = sco[i].score;
415 }
416 sco[j].order = pos++;
417 }
418 pos = 0;
419 while (pos < SCORESIZE) {
420 jdat = 0;
421 for (i = 0; i < SCORESIZE; i++)
422 if ((winr[i].order < 0) && (winr[i].score >= jdat)) {
423 j = i;
424 jdat = winr[i].score;
425 }
426 winr[j].order = pos++;
427 }
428 return (1);
429 }
430
431 /*
432 * newscore(score, whoo, whyded, winner) Function to add entry to scoreboard
433 * int score, winner, whyded;
434 * char *whoo;
435 *
436 * Enter with the total score in gp in score, players name in whoo,
437 * died() reason # in whyded, and TRUE/FALSE in winner if a winner
438 * ex. newscore(1000, "player 1", 32, 0);
439 */
440 static void
441 newscore(long score, char *whoo, int whyded, int winner)
442 {
443 int i;
444 long taxes;
445 if (readboard() < 0)
446 return; /* do the scoreboard */
447 /* if a winner then delete all non-winning scores */
448 if (cheat)
449 winner = 0; /* if he cheated, don't let him win */
450 if (winner) {
451 for (i = 0; i < SCORESIZE; i++)
452 if (sco[i].suid == userid)
453 sco[i].score = 0;
454 taxes = score * TAXRATE;
455 score += 100000 * c[HARDGAME]; /* bonus for winning */
456 /*
457 * if he has a slot on the winning scoreboard update it if
458 * greater score
459 */
460 for (i = 0; i < SCORESIZE; i++)
461 if (winr[i].suid == userid) {
462 new1sub(score, i, whoo, taxes);
463 return;
464 }
465 /*
466 * he had no entry. look for last entry and see if he has a
467 * greater score
468 */
469 for (i = 0; i < SCORESIZE; i++)
470 if (winr[i].order == SCORESIZE - 1) {
471 new1sub(score, i, whoo, taxes);
472 return;
473 }
474 } else if (!cheat) { /* for not winning scoreboard */
475 /*
476 * if he has a slot on the scoreboard update it if greater
477 * score
478 */
479 for (i = 0; i < SCORESIZE; i++)
480 if (sco[i].suid == userid) {
481 new2sub(score, i, whoo, whyded);
482 return;
483 }
484 /*
485 * he had no entry. look for last entry and see if he has a
486 * greater score
487 */
488 for (i = 0; i < SCORESIZE; i++)
489 if (sco[i].order == SCORESIZE - 1) {
490 new2sub(score, i, whoo, whyded);
491 return;
492 }
493 }
494 }
495
496 /*
497 * new1sub(score,i,whoo,taxes) Subroutine to put player into a
498 * int score,i,whyded,taxes; winning scoreboard entry if his score
499 * char *whoo; is high enough
500 *
501 * Enter with the total score in gp in score, players name in whoo,
502 * died() reason # in whyded, and TRUE/FALSE in winner if a winner
503 * slot in scoreboard in i, and the tax bill in taxes.
504 * Returns nothing of value
505 */
506 static void
507 new1sub(long score, int i, char *whoo, long taxes)
508 {
509 struct wscofmt *p;
510 p = &winr[i];
511 p->taxes += taxes;
512 if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) {
513 strcpy(p->who, whoo);
514 p->score = score;
515 p->hardlev = c[HARDGAME];
516 p->suid = userid;
517 p->timeused = gltime / 100;
518 }
519 }
520
521 /*
522 * new2sub(score,i,whoo,whyded) Subroutine to put player into a
523 * int score,i,whyded,taxes; non-winning scoreboard entry if his
524 * char *whoo; score is high enough
525 *
526 * Enter with the total score in gp in score, players name in whoo,
527 * died() reason # in whyded, and slot in scoreboard in i.
528 * Returns nothing of value
529 */
530 static void
531 new2sub(long score, int i, char *whoo, int whyded)
532 {
533 int j;
534 struct scofmt *p;
535 p = &sco[i];
536 if ((score >= p->score) || (c[HARDGAME] > p->hardlev)) {
537 strcpy(p->who, whoo);
538 p->score = score;
539 p->what = whyded;
540 p->hardlev = c[HARDGAME];
541 p->suid = userid;
542 p->level = level;
543 for (j = 0; j < 26; j++) {
544 p->sciv[j][0] = iven[j];
545 p->sciv[j][1] = ivenarg[j];
546 }
547 }
548 }
549
550 /*
551 * died(x) Subroutine to record who played larn, and what the score was
552 * int x;
553 *
554 * if x < 0 then don't show scores
555 * died() never returns! (unless c[LIFEPROT] and a reincarnatable death!)
556 *
557 * < 256 killed by the monster number
558 * 256 quit
559 * 257 suspended
560 * 258 self - annihilated
561 * 259 shot by an arrow
562 * 260 hit by a dart
563 * 261 fell into a pit
564 * 262 fell into a bottomless pit
565 * 263 a winner
566 * 264 trapped in solid rock
567 * 265 killed by a missing save file
568 * 266 killed by an old save file
569 * 267 caught by the greedy cheater checker trap
570 * 268 killed by a protected save file
571 * 269 killed his family and killed himself
572 * 270 erased by a wayward finger
573 * 271 fell through a bottomless trap door
574 * 272 fell through a trap door
575 * 273 drank some poisonous water
576 * 274 fried by an electric shock
577 * 275 slipped on a volcano shaft
578 * 276 killed by a stupid act of frustration
579 * 277 attacked by a revolting demon
580 * 278 hit by his own magic
581 * 279 demolished by an unseen attacker
582 * 280 fell into the dreadful sleep
583 * 281 killed by an exploding chest
584 * 282 killed by a missing maze data file
585 * 283 killed by a sphere of annihilation
586 * 284 died a post mortem death
587 * 285 malloc() failure
588 * 300 quick quit -- don't put on scoreboard
589 */
590
591 static int scorerror;
592 void
593 died(int x)
594 {
595 int f, win;
596 char ch;
597 const char *mod;
598 time_t zzz;
599 if (c[LIFEPROT] > 0) { /* if life protection */
600 switch ((x > 0) ? x : -x) {
601 case 256:
602 case 257:
603 case 262:
604 case 263:
605 case 265:
606 case 266:
607 case 267:
608 case 268:
609 case 269:
610 case 271:
611 case 282:
612 case 284:
613 case 285:
614 case 300:
615 goto invalid; /* can't be saved */
616 };
617 --c[LIFEPROT];
618 c[HP] = 1;
619 --c[CONSTITUTION];
620 cursors();
621 lprcat("\nYou feel wiiieeeeerrrrrd all over! ");
622 beep();
623 lflush();
624 sleep(4);
625 return; /* only case where died() returns */
626 }
627 invalid:
628 clearvt100();
629 lflush();
630 f = 0;
631 if (ckpflag)
632 unlink(ckpfile);/* remove checkpoint file if used */
633 if (x < 0) {
634 f++;
635 x = -x;
636 } /* if we are not to display the scores */
637 if ((x == 300) || (x == 257))
638 exit(0); /* for quick exit or saved game */
639 if (x == 263)
640 win = 1;
641 else
642 win = 0;
643 c[GOLD] += c[BANKACCOUNT];
644 c[BANKACCOUNT] = 0;
645 /* now enter the player at the end of the scoreboard */
646 newscore(c[GOLD], logname, x, win);
647 diedsub(x); /* print out the score line */
648 lflush();
649
650 set_score_output();
651 if ((wizard == 0) && (c[GOLD] > 0)) { /* wizards can't score */
652 #ifndef NOLOG
653 if (gid != egid)
654 setegid(egid);
655 if (lappend(logfile) < 0) { /* append to file */
656 if (lcreat(logfile) < 0) { /* and can't create new
657 * log file */
658 lcreat((char *) 0);
659 lprcat("\nCan't open record file: I can't post your score.\n");
660 sncbr();
661 resetscroll();
662 lflush();
663 exit(0);
664 }
665 if (gid != egid)
666 setegid(egid);
667 chmod(logfile, 0660);
668 if (gid != egid)
669 setegid(gid);
670 }
671 if (gid != egid)
672 setegid(gid);
673 strcpy(logg.who, loginname);
674 logg.score = c[GOLD];
675 logg.diff = c[HARDGAME];
676 if (x < 256) {
677 ch = *monster[x].name;
678 if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
679 mod = "an";
680 else
681 mod = "a";
682 snprintf(logg.what, sizeof(logg.what),
683 "killed by %s %s", mod, monster[x].name);
684 } else
685 snprintf(logg.what, sizeof(logg.what),
686 "%s", whydead[x - 256]);
687 logg.cavelev = level;
688 time(&zzz); /* get CPU time -- write out score info */
689 logg.diedtime = zzz;
690 #ifdef EXTRA
691 times(&cputime);/* get CPU time -- write out score info */
692 logg.cputime = i = (cputime.tms_utime + cputime.tms_stime) / 60 + c[CPUTIME];
693 logg.lev = c[LEVEL];
694 logg.ac = c[AC];
695 logg.hpmax = c[HPMAX];
696 logg.hp = c[HP];
697 logg.elapsedtime = (zzz - initialtime + 59) / 60;
698 logg.usage = (10000 * i) / (zzz - initialtime);
699 logg.bytin = c[BYTESIN];
700 logg.bytout = c[BYTESOUT];
701 logg.moves = c[MOVESMADE];
702 logg.spused = c[SPELLSCAST];
703 logg.killed = c[MONSTKILLED];
704 #endif
705 lwrite((char *) &logg, sizeof(struct log_fmt));
706 lwclose();
707 #endif /* NOLOG */
708
709 /*
710 * now for the scoreboard maintenance -- not for a suspended
711 * game
712 */
713 if (x != 257) {
714 if (sortboard()) {
715 set_score_output();
716 scorerror = writeboard();
717 }
718 }
719 }
720 if ((x == 256) || (x == 257) || (f != 0))
721 exit(0);
722 if (scorerror == 0)
723 showscores(); /* if we updated the scoreboard */
724 if (x == 263)
725 mailbill();
726 exit(0);
727 }
728
729 /*
730 * diedsub(x) Subroutine to print out the line showing the player when he is killed
731 * int x;
732 */
733 static void
734 diedsub(int x)
735 {
736 char ch;
737 const char *mod;
738
739 lprintf("Score: %ld, Diff: %ld, %s ", (long) c[GOLD], (long) c[HARDGAME], logname);
740 if (x < 256) {
741 ch = *monster[x].name;
742 if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
743 mod = "an";
744 else
745 mod = "a";
746 lprintf("killed by %s %s", mod, monster[x].name);
747 } else
748 lprintf("%s", whydead[x - 256]);
749 if (x != 263)
750 lprintf(" on %s\n", levelname[level]);
751 else
752 lprc('\n');
753 }
754
755 /*
756 * diedlog() Subroutine to read a log file and print it out in ascii format
757 */
758 void
759 diedlog(void)
760 {
761 int n;
762 char *p;
763 static char q[] = "?";
764 struct stat stbuf;
765 time_t t;
766
767 lcreat((char *) 0);
768 if (lopen(logfile) < 0) {
769 lprintf("Can't locate log file <%s>\n", logfile);
770 return;
771 }
772 if (fstat(io_infd, &stbuf) < 0) {
773 lprintf("Can't stat log file <%s>\n", logfile);
774 return;
775 }
776 for (n = stbuf.st_size / sizeof(struct log_fmt); n > 0; --n) {
777 lrfill((char *) &logg, sizeof(struct log_fmt));
778 t = logg.diedtime;
779 if ((p = ctime(&t)) == NULL)
780 p = q;
781 else {
782 p[16] = '\n';
783 p[17] = 0;
784 }
785 lprintf("Score: %ld, Diff: %ld, %s %s on %ld at %s", (long) (logg.score), (long) (logg.diff), logg.who, logg.what, (long) (logg.cavelev), p + 4);
786 #ifdef EXTRA
787 if (logg.moves <= 0)
788 logg.moves = 1;
789 lprintf(" Experience Level: %ld, AC: %ld, HP: %ld/%ld, Elapsed Time: %ld minutes\n", (long) (logg.lev), (long) (logg.ac), (long) (logg.hp), (long) (logg.hpmax), (long) (logg.elapsedtime));
790 lprintf(" CPU time used: %ld seconds, Machine usage: %ld.%02ld%%\n", (long) (logg.cputime), (long) (logg.usage / 100), (long) (logg.usage % 100));
791 lprintf(" BYTES in: %ld, out: %ld, moves: %ld, deaths: %ld, spells cast: %ld\n", (long) (logg.bytin), (long) (logg.bytout), (long) (logg.moves), (long) (logg.killed), (long) (logg.spused));
792 lprintf(" out bytes per move: %ld, time per move: %ld ms\n", (long) (logg.bytout / logg.moves), (long) ((logg.cputime * 1000) / logg.moves));
793 #endif
794 }
795 lflush();
796 lrclose();
797 return;
798 }
799
800 #ifndef UIDSCORE
801 /*
802 * getplid(name) Function to get players id # from id file
803 *
804 * Enter with the name of the players character in name.
805 * Returns the id # of the players character, or -1 if failure.
806 * This routine will try to find the name in the id file, if its not there,
807 * it will try to make a new entry in the file. Only returns -1 if can't
808 * find him in the file, and can't make a new entry in the file.
809 * Format of playerids file:
810 * Id # in ascii \n character name \n
811 */
812 static int havepid = -1; /* playerid # if previously done */
813 int
814 getplid(nam)
815 char *nam;
816 {
817 int fd7, high = 999, no;
818 char *p, *p2;
819 char name[80];
820 if (havepid != -1)
821 return (havepid); /* already did it */
822 lflush(); /* flush any pending I/O */
823 snprintf(name, sizeof(name), "%s\n", nam);/* append a \n to name */
824 if (lopen(playerids) < 0) { /* no file, make it */
825 if ((fd7 = creat(playerids, 0664)) < 0)
826 return (-1); /* can't make it */
827 close(fd7);
828 goto addone; /* now append new playerid record to file */
829 }
830 for (;;) { /* now search for the name in the player id
831 * file */
832 p = lgetl();
833 if (p == NULL)
834 break; /* EOF? */
835 no = atoi(p); /* the id # */
836 p2 = lgetl();
837 if (p2 == NULL)
838 break; /* EOF? */
839 if (no > high)
840 high = no; /* accumulate highest id # */
841 if (strcmp(p2, name) == 0) { /* we found him */
842 return (no); /* his id number */
843 }
844 }
845 lrclose();
846 /* if we get here, we didn't find him in the file -- put him there */
847 addone:
848 if (lappend(playerids) < 0)
849 return (-1); /* can't open file for append */
850 lprintf("%ld\n%s", (long) ++high, name); /* new id # and name */
851 lwclose();
852 lcreat((char *) 0); /* re-open terminal channel */
853 return (high);
854 }
855 #endif /* UIDSCORE */