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
|
|
26 #include "struct.h"
|
|
27 #include "data.h"
|
|
28
|
|
29 int nplayers;
|
|
30 struct statentry *database;
|
|
31
|
|
32 struct highscore
|
|
33 {
|
|
34 char name[32];
|
|
35 int advance, newrank;
|
|
36 float didiff;
|
|
37 };
|
|
38
|
|
39 struct highscore *scores;
|
|
40 int scoresize, nscores;
|
|
41
|
|
42 int
|
|
43 cmp_score(a, b)
|
|
44 struct highscore *a, *b;
|
|
45 {
|
|
46 float diff = a->newrank - b->newrank;
|
|
47
|
|
48 if (diff < 0)
|
|
49 return 1;
|
|
50 else if (diff > 0)
|
|
51 return -1;
|
|
52
|
|
53 diff = a->advance - b->advance;
|
|
54
|
|
55 if (diff < 0)
|
|
56 return 1;
|
|
57 else if (diff > 0)
|
|
58 return -1;
|
|
59
|
|
60 diff = a->didiff - b->didiff;
|
|
61
|
|
62 if (diff < 0)
|
|
63 return 1;
|
|
64 else if (diff > 0)
|
|
65 return -1;
|
|
66 else
|
|
67 return 0;
|
|
68 }
|
|
69
|
|
70 struct statentry zeroplayer;
|
|
71
|
|
72 int
|
|
73 main(argc, argv)
|
|
74 int argc;
|
|
75 char **argv;
|
|
76 {
|
|
77 struct stat fstats;
|
|
78 FILE *fp;
|
|
79 int i;
|
|
80 int threshold;
|
|
81 struct statentry currplayer;
|
|
82
|
|
83 if (argc != 4)
|
|
84 {
|
|
85 int x;
|
|
86 char message[][255] = {
|
|
87 "\n\t'%s n oldfile newfile'\n",
|
|
88 "\nLists all players who have been promoted more than n ranks.\n",
|
|
89 ""
|
|
90 };
|
|
91
|
|
92 fprintf(stderr, "-- Netrek II (Paradise), %s --\n", PARAVERS);
|
|
93 for (i = 0; *message[i] != '\0'; i++)
|
|
94 fprintf(stderr, message[i], argv[0]);
|
|
95
|
|
96 exit(1);
|
|
97 }
|
|
98
|
|
99 threshold = atoi(argv[1]);
|
|
100
|
|
101
|
|
102 fp = fopen(argv[2], "r");
|
|
103 if (fp == 0)
|
|
104 {
|
|
105 fprintf(stderr, "Couldn't open file %s for read", argv[1]);
|
|
106 perror("");
|
|
107 exit(1);
|
|
108 }
|
|
109
|
|
110 if (fstat(fileno(fp), &fstats) < 0)
|
|
111 {
|
|
112 fprintf(stderr, "Couldn't fstat file %s", argv[1]);
|
|
113 perror("");
|
|
114 exit(1);
|
|
115 }
|
|
116
|
|
117 nplayers = fstats.st_size / sizeof(*database);
|
|
118 database = (struct statentry *) malloc(sizeof(*database) * nplayers);
|
|
119
|
|
120 i = fread(database, sizeof(*database), nplayers, fp);
|
|
121
|
|
122 if (i == 0)
|
|
123 {
|
|
124 fprintf(stderr, "failed to read any player records from file %s\n", argv[1]);
|
|
125 exit(1);
|
|
126 }
|
|
127 if (i != nplayers)
|
|
128 {
|
|
129 fprintf(stderr, "failed to read all player records from file %s (%d of %d)\n", argv[1], i, nplayers);
|
|
130 nplayers = i;
|
|
131 }
|
|
132
|
|
133 fclose(fp);
|
|
134
|
|
135 fp = fopen(argv[3], "r");
|
|
136 if (fp == 0)
|
|
137 {
|
|
138 fprintf(stderr, "Couldn't open file %s for read", argv[2]);
|
|
139 perror("");
|
|
140 exit(1);
|
|
141 }
|
|
142
|
|
143
|
|
144 scores = (struct highscore *) malloc(sizeof(*scores) * (scoresize = 256));
|
|
145 nscores = 0;
|
|
146
|
|
147 while (1)
|
|
148 {
|
|
149 int delta;
|
|
150 int dt;
|
|
151 struct statentry *prevplayer;
|
|
152 struct highscore *currscore;
|
|
153
|
|
154 i = fread(&currplayer, sizeof(currplayer), 1, fp);
|
|
155 if (i < 0)
|
|
156 {
|
|
157 fprintf(stderr, "error reading player record, aborting loop\n");
|
|
158 perror("");
|
|
159 }
|
|
160 if (i <= 0)
|
|
161 break;
|
|
162
|
|
163 for (i = 0; i < nplayers; i++)
|
|
164 {
|
|
165 if (0 == strcmp(database[i].name, currplayer.name))
|
|
166 break;
|
|
167 }
|
|
168 if (i < nplayers)
|
|
169 prevplayer = &database[i];
|
|
170 else
|
|
171 prevplayer = &zeroplayer;
|
|
172
|
|
173 if (currplayer.stats.st_rank - prevplayer->stats.st_rank <= threshold)
|
|
174 continue; /* didn't advance enough */
|
|
175
|
|
176 if (nscores >= scoresize)
|
|
177 {
|
|
178 scores = (struct highscore *) realloc(scores, sizeof(*scores) * (scoresize *= 2));
|
|
179 }
|
|
180 currscore = &scores[nscores++];
|
|
181 strcpy(currscore->name, currplayer.name);
|
|
182 currscore->newrank = currplayer.stats.st_rank;
|
|
183 currscore->advance = currplayer.stats.st_rank - prevplayer->stats.st_rank;
|
|
184 currscore->didiff = currplayer.stats.st_di - prevplayer->stats.st_di;
|
|
185 }
|
|
186
|
|
187
|
|
188 #define offset(field) ( (int)&(((struct highscore*)0)->field) )
|
|
189
|
|
190 qsort(scores, nscores, sizeof(*scores), cmp_score);
|
|
191
|
|
192 printf("Congratulations to the following warriors:\n");
|
|
193 for (i = 0; i < nscores; i++)
|
|
194 {
|
|
195 struct highscore *curr = &scores[i];
|
|
196 int j;
|
|
197
|
|
198 printf("%s ", curr->name);
|
|
199 for (j = strlen(curr->name); j < 18; j++)
|
|
200 putchar(0x1f);
|
|
201 printf(" promoted from %s to %s", ranks[curr->newrank - curr->advance].name,
|
|
202 ranks[curr->newrank].name);
|
|
203 if (curr->advance > 1)
|
|
204 {
|
|
205 printf(" (%d ranks)", curr->advance);
|
|
206 }
|
|
207 printf("\n");
|
|
208 }
|
|
209 printf("(Your new insignia will be provided as soon as we get\n\
|
|
210 enough scrap plastic donations.)");
|
|
211
|
|
212 exit(0);
|
|
213 }
|