1 /* 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)score.c 8.1 (Berkeley) 5/31/93 34 * $FreeBSD: src/games/robots/score.c,v 1.5 1999/11/30 03:49:20 billf Exp $ 35 * $DragonFly: src/games/robots/score.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ 36 */ 37 38 # include "robots.h" 39 # include <sys/types.h> 40 # include <pwd.h> 41 # include "pathnames.h" 42 43 typedef struct { 44 int s_uid; 45 int s_score; 46 char s_name[MAXNAME]; 47 } SCORE; 48 49 typedef struct passwd PASSWD; 50 51 char *Scorefile = _PATH_SCORE; 52 53 int Max_per_uid = MAX_PER_UID; 54 55 static SCORE Top[MAXSCORES]; 56 57 /* 58 * score: 59 * Post the player's score, if reasonable, and then print out the 60 * top list. 61 */ 62 score() 63 { 64 int inf; 65 SCORE *scp; 66 int uid; 67 bool done_show = FALSE; 68 static int numscores, max_uid; 69 70 Newscore = FALSE; 71 if ((inf = open(Scorefile, 2)) < 0) { 72 perror(Scorefile); 73 return; 74 } 75 76 if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid) 77 read(inf, Top, sizeof Top); 78 else { 79 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 80 scp->s_score = -1; 81 max_uid = Max_per_uid; 82 } 83 84 uid = getuid(); 85 if (Top[MAXSCORES-1].s_score <= Score) { 86 numscores = 0; 87 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 88 if (scp->s_score < 0 || 89 (scp->s_uid == uid && ++numscores == max_uid)) { 90 if (scp->s_score > Score) 91 break; 92 scp->s_score = Score; 93 scp->s_uid = uid; 94 set_name(scp); 95 Newscore = TRUE; 96 break; 97 } 98 if (scp == &Top[MAXSCORES]) { 99 Top[MAXSCORES-1].s_score = Score; 100 Top[MAXSCORES-1].s_uid = uid; 101 set_name(&Top[MAXSCORES-1]); 102 Newscore = TRUE; 103 } 104 if (Newscore) 105 qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc); 106 } 107 108 if (!Newscore) { 109 Full_clear = FALSE; 110 close(inf); 111 return; 112 } 113 else 114 Full_clear = TRUE; 115 116 for (scp = Top; scp < &Top[MAXSCORES]; scp++) { 117 if (scp->s_score < 0) 118 break; 119 move((scp - Top) + 1, 15); 120 if (!done_show && scp->s_uid == uid && scp->s_score == Score) 121 standout(); 122 printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name); 123 if (!done_show && scp->s_uid == uid && scp->s_score == Score) { 124 standend(); 125 done_show = TRUE; 126 } 127 } 128 Num_scores = scp - Top; 129 refresh(); 130 131 if (Newscore) { 132 lseek(inf, 0L, 0); 133 write(inf, &max_uid, sizeof max_uid); 134 write(inf, Top, sizeof Top); 135 } 136 close(inf); 137 } 138 139 set_name(scp) 140 SCORE *scp; 141 { 142 PASSWD *pp; 143 144 if ((pp = getpwuid(scp->s_uid)) == NULL) 145 pp->pw_name = "???"; 146 strncpy(scp->s_name, pp->pw_name, MAXNAME); 147 } 148 149 /* 150 * cmp_sc: 151 * Compare two scores. 152 */ 153 cmp_sc(s1, s2) 154 SCORE *s1, *s2; 155 { 156 return s2->s_score - s1->s_score; 157 } 158 159 /* 160 * show_score: 161 * Show the score list for the '-s' option. 162 */ 163 show_score() 164 { 165 SCORE *scp; 166 int inf; 167 static int max_score; 168 169 if ((inf = open(Scorefile, 0)) < 0) { 170 perror(Scorefile); 171 return; 172 } 173 174 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 175 scp->s_score = -1; 176 177 read(inf, &max_score, sizeof max_score); 178 read(inf, Top, sizeof Top); 179 close(inf); 180 inf = 1; 181 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 182 if (scp->s_score >= 0) 183 printf("%d\t%d\t%.*s\n", inf++, scp->s_score, 184 (int)sizeof(scp->s_name), scp->s_name); 185 } 186