Home | History | Annotate | Line # | Download | only in robots
score.c revision 1.6
      1 /*	$NetBSD: score.c,v 1.6 1999/05/15 23:56:36 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1980, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #include <sys/cdefs.h>
     37 #ifndef lint
     38 #if 0
     39 static char sccsid[] = "@(#)score.c	8.1 (Berkeley) 5/31/93";
     40 #else
     41 __RCSID("$NetBSD: score.c,v 1.6 1999/05/15 23:56:36 christos Exp $");
     42 #endif
     43 #endif /* not lint */
     44 
     45 # include	"robots.h"
     46 # include	"pathnames.h"
     47 
     48 char	*Scorefile = _PATH_SCORE;
     49 
     50 int	Max_per_uid = MAX_PER_UID;
     51 
     52 static SCORE	Top[MAXSCORES];
     53 
     54 static u_int32_t	numscores, max_uid;
     55 
     56 /*
     57  * read_score:
     58  *	Read the score file in MI format
     59  */
     60 static void
     61 read_score(inf)
     62 	int inf;
     63 {
     64 	SCORE	*scp;
     65 
     66 	if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid) {
     67 		max_uid = ntohl(max_uid);
     68 
     69 		read(inf, Top, sizeof Top);
     70 		for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
     71 			 scp->s_uid = ntohl(scp->s_uid);
     72 			 scp->s_score = ntohl(scp->s_score);
     73 			 scp->s_auto = ntohl(scp->s_auto);
     74 			 scp->s_level = ntohl(scp->s_level);
     75 		}
     76 	}
     77 	else {
     78 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
     79 			scp->s_score = 0;
     80 		max_uid = Max_per_uid;
     81 	}
     82 }
     83 
     84 /*
     85  * write_score:
     86  *	Write the score file in MI format
     87  */
     88 static void
     89 write_score(inf)
     90 	int inf;
     91 {
     92 	SCORE	*scp;
     93 
     94 	lseek(inf, 0L, 0);
     95 
     96 	max_uid = htonl(max_uid);
     97 	write(inf, &max_uid, sizeof max_uid);
     98 
     99 	for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
    100 		 scp->s_uid = htonl(scp->s_uid);
    101 		 scp->s_score = htonl(scp->s_score);
    102 		 scp->s_auto = htonl(scp->s_auto);
    103 		 scp->s_level = htonl(scp->s_level);
    104 	}
    105 
    106 	write(inf, Top, sizeof Top);
    107 }
    108 
    109 
    110 /*
    111  * score:
    112  *	Post the player's score, if reasonable, and then print out the
    113  *	top list.
    114  */
    115 void
    116 score()
    117 {
    118 	int			inf;
    119 	SCORE			*scp;
    120 	int			uid;
    121 	bool			done_show = FALSE;
    122 
    123 	Newscore = FALSE;
    124 	if ((inf = open(Scorefile, O_RDWR)) < 0) {
    125 		warn("opening `%s'", Scorefile);
    126 		return;
    127 	}
    128 
    129 	read_score(inf);
    130 
    131 	uid = getuid();
    132 	if (Top[MAXSCORES-1].s_score <= Score) {
    133 		numscores = 0;
    134 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
    135 			if (scp->s_score < 0 ||
    136 			    (scp->s_uid == uid && ++numscores == max_uid)) {
    137 				if (scp->s_score > Score)
    138 					break;
    139 				scp->s_score = Score;
    140 				scp->s_uid = uid;
    141 				scp->s_auto = Auto_bot;
    142 				scp->s_level = Level;
    143 				set_name(scp);
    144 				Newscore = TRUE;
    145 				break;
    146 			}
    147 		if (scp == &Top[MAXSCORES]) {
    148 			Top[MAXSCORES-1].s_score = Score;
    149 			Top[MAXSCORES-1].s_uid = uid;
    150 			Top[MAXSCORES-1].s_auto = Auto_bot;
    151 			Top[MAXSCORES-1].s_level = Level;
    152 			set_name(&Top[MAXSCORES-1]);
    153 			Newscore = TRUE;
    154 		}
    155 		if (Newscore)
    156 			qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
    157 	}
    158 
    159 	if (!Newscore) {
    160 		Full_clear = FALSE;
    161 		close(inf);
    162 		return;
    163 	}
    164 	else
    165 		Full_clear = TRUE;
    166 
    167 	move(1, 15);
    168 	printw("%5.5s %5.5s %-9.9s %-8.8s %5.5s", "Rank", "Score", "User",
    169 	    " ", "Level");
    170 
    171 	for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
    172 		if (scp->s_score == 0)
    173 			break;
    174 		move((scp - Top) + 2, 15);
    175 		if (!done_show && scp->s_uid == uid && scp->s_score == Score)
    176 			standout();
    177 		printw("%5.5d %5.5d %-8.8s %-9.9s %5.5d",
    178 		    (scp - Top) + 1, scp->s_score, scp->s_name,
    179 		    Auto_bot ? "(autobot)" : "", scp->s_level);
    180 		if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
    181 			standend();
    182 			done_show = TRUE;
    183 		}
    184 	}
    185 	Num_scores = scp - Top;
    186 	refresh();
    187 
    188 	if (Newscore) {
    189 		write_score(inf);
    190 	}
    191 	close(inf);
    192 }
    193 
    194 void
    195 set_name(scp)
    196 	SCORE	*scp;
    197 {
    198 	PASSWD	*pp;
    199 
    200 	if ((pp = getpwuid(scp->s_uid)) == NULL)
    201 		pp->pw_name = "???";
    202 	strncpy(scp->s_name, pp->pw_name, MAXNAME);
    203 }
    204 
    205 /*
    206  * cmp_sc:
    207  *	Compare two scores.
    208  */
    209 int
    210 cmp_sc(s1, s2)
    211 	const void *s1, *s2;
    212 {
    213 	return ((SCORE *)s2)->s_score - ((SCORE *)s1)->s_score;
    214 }
    215 
    216 /*
    217  * show_score:
    218  *	Show the score list for the '-s' option.
    219  */
    220 void
    221 show_score()
    222 {
    223 	SCORE		*scp;
    224 	int		inf;
    225 
    226 	if ((inf = open(Scorefile, O_RDONLY)) < 0) {
    227 		warn("opening `%s'", Scorefile);
    228 		return;
    229 	}
    230 
    231 	read_score(inf);
    232 	close(inf);
    233 	inf = 1;
    234 	printf("%5.5s %5.5s %-9.9s %-8.8s %5.5s\n", "Rank", "Score", "User",
    235 	    " ", "Level");
    236 	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
    237 		if (scp->s_score > 0)
    238 			printf("%5.5d %5.5d %-8.8s %-9.9s %5.5d\n",
    239 			    inf++, scp->s_score, scp->s_name,
    240 			    scp->s_auto ? "(autobot)" :  "", scp->s_level);
    241 }
    242