8
|
1 /*--------------------------------------------------------------------------
|
|
2 NETREK II -- Paradise
|
|
3
|
|
4 Permission to use, copy, modify, and distribute this software and its
|
|
5 documentation, or any derivative works thereof, for any NON-COMMERCIAL
|
|
6 purpose and without fee is hereby granted, provided that this copyright
|
|
7 notice appear in all copies. No representations are made about the
|
|
8 suitability of this software for any purpose. This software is provided
|
|
9 "as is" without express or implied warranty.
|
|
10
|
|
11 Xtrek Copyright 1986 Chris Guthrie
|
|
12 Netrek (Xtrek II) Copyright 1989 Kevin P. Smith
|
|
13 Scott Silvey
|
|
14 Paradise II (Netrek II) Copyright 1993 Larry Denys
|
|
15 Kurt Olsen
|
|
16 Brandon Gillespie
|
|
17 --------------------------------------------------------------------------*/
|
|
18
|
|
19 #include "config.h"
|
|
20
|
|
21 #include <stdio.h>
|
|
22 #include <malloc.h>
|
|
23 #include <sys/types.h>
|
|
24 #include <sys/stat.h>
|
|
25 #include <errno.h>
|
|
26 #include "defs.h"
|
|
27 #include "data.h"
|
|
28 #include "struct.h"
|
|
29 #include "shmem.h"
|
|
30 #include "path.h"
|
|
31
|
|
32 #ifdef sparc
|
|
33 extern char *sys_errlist[];
|
|
34 #define strerror(EN) sys_errlist[(EN)]
|
|
35 #endif
|
|
36
|
|
37 #define LINESPERPAGE 38
|
|
38
|
|
39 struct statentry *database;
|
|
40 struct statentry **playertab;
|
|
41 int topn, motd = 0;
|
|
42
|
|
43 void header();
|
|
44
|
|
45 void
|
|
46 printUsage(me)
|
|
47 char *me;
|
|
48 {
|
|
49 int x;
|
|
50 char message[][255] = {
|
|
51 "\nHonor Roll of players in the current database.\n",
|
|
52 "\n\t'%s n [options]'\n\n",
|
|
53 "Where n is the number of scores to print (top n)\n",
|
|
54 "\nOptions:\n",
|
|
55 "\t-f file Use \"file\" as player file (default: $NETREKDIR/etc/db.players)\n",
|
|
56 "\t-m Format output for use in server MOTD\n\n",
|
|
57 ""
|
|
58 };
|
|
59
|
|
60 fprintf(stderr, "--- Netrek II (Paradise), %s ---\n", PARAVERS);
|
|
61 for (x = 0; *message[x] != '\0'; x++)
|
|
62 fprintf(stderr, message[x], me);
|
|
63
|
|
64 exit(1);
|
|
65 }
|
|
66
|
|
67 int
|
|
68 cmp_func(a, b)
|
|
69 struct statentry **a, **b;
|
|
70 {
|
|
71 float di_diff = (*a)->stats.st_di - (*b)->stats.st_di;
|
|
72 int rk_diff = (*a)->stats.st_rank - (*b)->stats.st_rank;
|
|
73
|
|
74 /* rank takes precedent over DI */
|
|
75 if (rk_diff < 0)
|
|
76 return 1;
|
|
77 else if (rk_diff > 0)
|
|
78 return -1;
|
|
79
|
|
80 if (di_diff < 0)
|
|
81 return 1;
|
|
82 else if (di_diff > 0)
|
|
83 return -1;
|
|
84
|
|
85 return strcmp((*a)->name, (*b)->name);
|
|
86 }
|
|
87
|
|
88 #if 0
|
|
89 static char *rankh[] = {
|
|
90 "Recruits:",
|
|
91 "Specialists:",
|
|
92 "Cadets:",
|
|
93 "Midshipmen:",
|
|
94 "Ensigns, Junior Grade:",
|
|
95 "Ensigns:",
|
|
96 "Lieutenants, Junior Grade:",
|
|
97 "Lieutenants:",
|
|
98 "Lieutenant Commanders:",
|
|
99 "Commanders:",
|
|
100 "Captains:",
|
|
101 "Fleet Captains:",
|
|
102 "Commodores:",
|
|
103 "Moffs:",
|
|
104 "Grand Moffs:",
|
|
105 "Rear Admirals:",
|
|
106 "Admirals:",
|
|
107 "Grand Admirals:",
|
|
108 };
|
|
109 #endif
|
|
110
|
|
111 int
|
|
112 main(argc, argv)
|
|
113 int argc;
|
|
114 char *argv[];
|
|
115 {
|
|
116 int i, nplayers, j, count = 0;
|
|
117 FILE *fp;
|
|
118 struct stat fstats;
|
|
119 char *fn;
|
|
120 struct stats *s;
|
|
121
|
|
122 if (argc < 2)
|
|
123 printUsage(argv[0]);
|
|
124
|
|
125 if (!(topn = atoi(argv[1])))
|
|
126 printUsage(argv[0]);
|
|
127
|
|
128 fn = build_path(PLAYERFILE);
|
|
129
|
|
130 for (i = 2; i < argc; i++)
|
|
131 {
|
|
132 if (!strcmp(argv[i], "-f"))
|
|
133 {
|
|
134 if (i + 1 == argc)
|
|
135 printUsage(argv[0]);
|
|
136 fn = argv[++i];
|
|
137 }
|
|
138 else if (!strcmp(argv[i], "-m"))
|
|
139 {
|
|
140 motd = 1;
|
|
141 }
|
|
142 }
|
|
143
|
|
144 if (!(fp = fopen(fn, "r")))
|
|
145 {
|
|
146 fprintf(stderr, "Couldn't open file %s: %s\n", fn, strerror(errno));
|
|
147 exit(1);
|
|
148 }
|
|
149
|
|
150 if (fstat(fileno(fp), &fstats) < 0)
|
|
151 {
|
|
152 fprintf(stderr, "Couldn't fstat file %s: %s\n", fn, strerror(errno));
|
|
153 exit(1);
|
|
154 }
|
|
155
|
|
156 nplayers = fstats.st_size / sizeof(*database);
|
|
157 database = malloc(sizeof(*database) * nplayers);
|
|
158
|
|
159 i = fread(database, sizeof(*database), nplayers, fp);
|
|
160 if (i != nplayers)
|
|
161 {
|
|
162 fprintf(stderr, "failed to read all player records from file %s (%d of %d)\n", fn, i, nplayers);
|
|
163 nplayers = i;
|
|
164 }
|
|
165
|
|
166 fclose(fp);
|
|
167
|
|
168 if (topn < 0 || topn > nplayers)
|
|
169 topn = nplayers;
|
|
170
|
|
171 /* Make an array of pointers to the database. */
|
|
172 playertab = malloc(sizeof(playertab) * nplayers);
|
|
173
|
|
174 for (i = 0; i < nplayers; i++)
|
|
175 playertab[i] = &(database[i]);
|
|
176
|
|
177 /* sort the pointers */
|
|
178 qsort(playertab, nplayers, sizeof(playertab), cmp_func);
|
|
179
|
|
180 header();
|
|
181 count = 1;
|
|
182
|
|
183 j = 18;
|
|
184 for (i = 0; i < topn; i++)
|
|
185 {
|
|
186 s = &(playertab[i]->stats);
|
|
187 if (j > s->st_rank)
|
|
188 {
|
|
189 j = s->st_rank;
|
|
190 if (motd)
|
|
191 {
|
|
192 count += 2;
|
|
193 if (count >= LINESPERPAGE)
|
|
194 {
|
|
195 header();
|
|
196 count = 3;
|
|
197 }
|
|
198 }
|
|
199 printf("\n%s\n", ranks[j].name);
|
|
200 }
|
|
201 if (motd && (++count > LINESPERPAGE))
|
|
202 {
|
|
203 header();
|
|
204 printf("\n");
|
|
205 count = 3;
|
|
206 }
|
|
207 printf("%4d. %15s %8.2f %6d %6d %6d %4d %5d %5d %7.2f\n", i + 1,
|
|
208 playertab[i]->name, s->st_di, s->st_tkills, s->st_tlosses,
|
|
209 s->st_tarmsbomb, s->st_tresbomb, s->st_tplanets,
|
|
210 s->st_tdooshes, (float) (s->st_tticks / 36000.0));
|
|
211 }
|
|
212 exit(1);
|
|
213 }
|
|
214
|
|
215 void
|
|
216 header()
|
|
217 {
|
|
218 if (motd)
|
|
219 printf("\t@@b\n");
|
|
220 printf("TOP %-4d Name DI Wins Losses Armies Rsrcs Plnts Dshs Hours\n", topn);
|
|
221 printf("-------------------------------------------------------------------------------");
|
|
222 }
|