ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/hiscore.C
(Generate patch)

Comparing deliantra/server/server/hiscore.C (file contents):
Revision 1.6 by root, Tue Sep 12 18:17:34 2006 UTC vs.
Revision 1.18 by pippijn, Mon Jan 15 21:06:20 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game for X-windows
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail at crossfire-devel@real-time.com 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 23 */
23 24
24#include <global.h> 25#include <global.h>
25#ifndef __CEXTRACT__
26# include <sproto.h> 26#include <sproto.h>
27#endif
28 27
29/* 28/*
30 * The score structure is used when treating new high-scores 29 * The score structure is used when treating new high-scores
31 */ 30 */
32
33typedef struct scr 31typedef struct scr
34{ 32{
35 char name[BIG_NAME]; /* name */ 33 char name[64]; // name */
36 char title[BIG_NAME]; /* Title */ 34 char title[64]; // Title */
37 char killer[BIG_NAME]; /* name (+ title) or "quit" */ 35 char killer[64]; // name (+ title) or "quit" */
38 sint64 exp; /* Experience */ 36 sint64 exp; // Experience */
39 char maplevel[BIG_NAME]; /* Killed on what level */ 37 char maplevel[128]; // Killed on what level */
40 int maxhp, maxsp, maxgrace; /* Max hp, sp, grace when killed */ 38 int maxhp, maxsp, maxgrace; // Max hp, sp, grace when killed */
41 int position; /* Position in the highscore list */ 39 int position; // Position in the highscore list */
42} score; 40} score;
43 41
44/* 42/*
45 * spool works mostly like strtok(char *, ":"), but it can also 43 * spool works mostly like strtok(char *, ":"), but it can also
46 * log a specified error message if something goes wrong. 44 * log a specified error message if something goes wrong.
82 */ 80 */
83 81
84static void 82static void
85copy_score (score *sc1, score *sc2) 83copy_score (score *sc1, score *sc2)
86{ 84{
87 strncpy (sc2->name, sc1->name, BIG_NAME); 85 assign (sc2->name , sc1->name);
88 sc2->name[BIG_NAME - 1] = '\0'; 86 assign (sc2->title , sc1->title);
89 strncpy (sc2->title, sc1->title, BIG_NAME);
90 sc2->title[BIG_NAME - 1] = '\0';
91 strncpy (sc2->killer, sc1->killer, BIG_NAME); 87 assign (sc2->killer , sc1->killer);
92 sc2->killer[BIG_NAME - 1] = '\0'; 88 assign (sc2->maplevel, sc1->maplevel);
93 sc2->exp = sc1->exp; 89 sc2->exp = sc1->exp;
94 strcpy (sc2->maplevel, sc1->maplevel);
95 sc2->maxhp = sc1->maxhp; 90 sc2->maxhp = sc1->maxhp;
96 sc2->maxsp = sc1->maxsp; 91 sc2->maxsp = sc1->maxsp;
97 sc2->maxgrace = sc1->maxgrace; 92 sc2->maxgrace = sc1->maxgrace;
98} 93}
99 94
105static char * 100static char *
106put_score (score *sc) 101put_score (score *sc)
107{ 102{
108 static char buf[MAX_BUF]; 103 static char buf[MAX_BUF];
109 104
110 sprintf (buf, "%s:%s:%lld:%s:%s:%d:%d:%d", sc->name, sc->title, (long long) sc->exp, sc->killer, sc->maplevel, 105 sprintf (buf, "%s:%s:%" PRId64 ":%s:%s:%d:%d:%d",
106 sc->name, sc->title, (sint64)sc->exp, sc->killer,
111 sc->maxhp, sc->maxsp, sc->maxgrace); 107 sc->maplevel, sc->maxhp, sc->maxsp, sc->maxgrace);
112 return buf; 108 return buf;
113} 109}
114 110
115/* 111/*
116 * The oposite of put_score, get_score reads from the given buffer into 112 * The oposite of put_score, get_score reads from the given buffer into
125 121
126 if ((cp = strchr (bp, '\n')) != NULL) 122 if ((cp = strchr (bp, '\n')) != NULL)
127 *cp = '\0'; 123 *cp = '\0';
128 124
129 if ((cp = spool (bp, "name")) == NULL) 125 if ((cp = spool (bp, "name")) == NULL)
130 return NULL; 126 return 0;
131 strncpy (sc.name, cp, BIG_NAME);
132 sc.name[BIG_NAME - 1] = '\0';
133 127
128 assign (sc.name, cp);
129
134 if ((cp = spool (NULL, "title")) == NULL) 130 if ((cp = spool (0, "title")) == NULL)
135 return NULL; 131 return 0;
136 strncpy (sc.title, cp, BIG_NAME);
137 sc.title[BIG_NAME - 1] = '\0';
138 132
133 assign (sc.title, cp);
134
139 if ((cp = spool (NULL, "score")) == NULL) 135 if ((cp = spool (0, "score")) == NULL)
140 return NULL; 136 return 0;
141 long long exp;
142 137
143 sscanf (cp, "%lld", &exp); 138 sscanf (cp, "%" SCNd64, &sc.exp);
144 sc.exp = exp;
145 139
146 if ((cp = spool (NULL, "killer")) == NULL) 140 if ((cp = spool (0, "killer")) == NULL)
147 return NULL; 141 return 0;
148 strncpy (sc.killer, cp, BIG_NAME);
149 sc.killer[BIG_NAME - 1] = '\0';
150 142
143 assign (sc.killer, cp);
144
151 if ((cp = spool (NULL, "map")) == NULL) 145 if ((cp = spool (0, "map")) == NULL)
152 return NULL; 146 return 0;
153 strncpy (sc.maplevel, cp, BIG_NAME);
154 sc.maplevel[BIG_NAME - 1] = '\0';
155 147
148 assign (sc.maplevel, cp);
149
156 if ((cp = spool (NULL, "maxhp")) == NULL) 150 if ((cp = spool (0, "maxhp")) == NULL)
157 return NULL; 151 return 0;
152
158 sscanf (cp, "%d", &sc.maxhp); 153 sscanf (cp, "%d", &sc.maxhp);
159 154
160 if ((cp = spool (NULL, "maxsp")) == NULL) 155 if ((cp = spool (0, "maxsp")) == NULL)
161 return NULL; 156 return 0;
157
162 sscanf (cp, "%d", &sc.maxsp); 158 sscanf (cp, "%d", &sc.maxsp);
163 159
164 if ((cp = spool (NULL, "maxgrace")) == NULL) 160 if ((cp = spool (0, "maxgrace")) == NULL)
165 return NULL; 161 return 0;
162
166 sscanf (cp, "%d", &sc.maxgrace); 163 sscanf (cp, "%d", &sc.maxgrace);
167 return &sc; 164 return &sc;
168} 165}
169 166
170static char * 167static char *
269 score *old_score; 266 score *old_score;
270 267
271 if (op->stats.exp == 0) 268 if (op->stats.exp == 0)
272 return; 269 return;
273 270
274 if (!op->contr->name_changed)
275 {
276 if (op->stats.exp > 0)
277 {
278 new_draw_info (NDI_UNIQUE, 0, op, "As you haven't changed your name, you won't");
279 new_draw_info (NDI_UNIQUE, 0, op, "get into the high-score list.");
280 }
281 return;
282 }
283 if (QUERY_FLAG (op, FLAG_WAS_WIZ))
284 {
285 new_draw_info (NDI_UNIQUE, 0, op, "Since you have been in wizard mode,");
286 new_draw_info (NDI_UNIQUE, 0, op, "you can't enter the high-score list.");
287 return;
288 }
289 if (op->contr->explore)
290 {
291 new_draw_info (NDI_UNIQUE, 0, op, "Since you were in explore mode,");
292 new_draw_info (NDI_UNIQUE, 0, op, "you can't enter the high-score list.");
293 return;
294 }
295 strncpy (new_score.name, op->name, BIG_NAME); 271 assign (new_score.name, op->name);
296 new_score.name[BIG_NAME - 1] = '\0'; 272 assign (new_score.title, op->title.length () ? &op->title : op->contr->title);
297 strncpy (new_score.title, op->contr->own_title, BIG_NAME); 273 assign (new_score.killer, op->contr->killer[0] ? op->contr->killer : "a dungeon collapse");
298 if (new_score.title[0] == '\0') 274 assign (new_score.maplevel, op->map ? op->map->name ? &op->map->name : &op->map->path : "");
299 strncpy (new_score.title, op->contr->title, BIG_NAME); 275
300 new_score.title[BIG_NAME - 1] = '\0';
301 strncpy (new_score.killer, op->contr->killer, BIG_NAME);
302 if (new_score.killer[0] == '\0')
303 strcpy (new_score.killer, "a dungeon collapse");
304 new_score.killer[BIG_NAME - 1] = '\0';
305 new_score.exp = op->stats.exp; 276 new_score.exp = op->stats.exp;
306 if (op->map == NULL)
307 *new_score.maplevel = '\0';
308 else
309 {
310 strncpy (new_score.maplevel, op->map->name ? op->map->name : op->map->path, BIG_NAME - 1);
311 new_score.maplevel[BIG_NAME - 1] = '\0';
312 }
313 new_score.maxhp = (int) op->stats.maxhp; 277 new_score.maxhp = op->stats.maxhp;
314 new_score.maxsp = (int) op->stats.maxsp; 278 new_score.maxsp = op->stats.maxsp;
315 new_score.maxgrace = (int) op->stats.maxgrace; 279 new_score.maxgrace = op->stats.maxgrace;
280
316 if ((old_score = add_score (&new_score)) == NULL) 281 if ((old_score = add_score (&new_score)) == NULL)
317 { 282 {
318 new_draw_info (NDI_UNIQUE, 0, op, "Error in the highscore list."); 283 new_draw_info (NDI_UNIQUE, 0, op, "Error in the highscore list.");
319 return; 284 return;
320 } 285 }
286
321 if (new_score.position == -1) 287 if (new_score.position == -1)
322 { 288 {
323 new_score.position = HIGHSCORE_LENGTH + 1; /* Not strictly correct... */ 289 new_score.position = HIGHSCORE_LENGTH + 1; /* Not strictly correct... */
324 if (!strcmp (old_score->name, new_score.name)) 290 if (!strcmp (old_score->name, new_score.name))
325 new_draw_info (NDI_UNIQUE, 0, op, "You didn't beat your last highscore:"); 291 new_draw_info (NDI_UNIQUE, 0, op, "You didn't beat your last highscore:");
327 new_draw_info (NDI_UNIQUE, 0, op, "You didn't enter the highscore list:"); 293 new_draw_info (NDI_UNIQUE, 0, op, "You didn't enter the highscore list:");
328 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (old_score)); 294 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (old_score));
329 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (&new_score)); 295 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (&new_score));
330 return; 296 return;
331 } 297 }
298
332 if (old_score->exp >= new_score.exp) 299 if (old_score->exp >= new_score.exp)
333 new_draw_info (NDI_UNIQUE, 0, op, "You didn't beat your last score:"); 300 new_draw_info (NDI_UNIQUE, 0, op, "You didn't beat your last score:");
334 else 301 else
335 new_draw_info (NDI_UNIQUE, 0, op, "You beat your last score:"); 302 new_draw_info (NDI_UNIQUE, 0, op, "You beat your last score:");
336 303
337 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (old_score)); 304 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (old_score));
338 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (&new_score)); 305 new_draw_info (NDI_UNIQUE, 0, op, draw_one_high_score (&new_score));
339} 306}
340
341
342 307
343/* displays the high score file. object is the calling object 308/* displays the high score file. object is the calling object
344 * (null if being called via command line.) max is the maximum 309 * (null if being called via command line.) max is the maximum
345 * number of scores to display. match, if set, is the name or class 310 * number of scores to display. match, if set, is the name or class
346 * to match to. 311 * to match to.
391 } 356 }
392 /* Replaced what seemed to an overly complicated word wrap method 357 /* Replaced what seemed to an overly complicated word wrap method
393 * still word wraps, but assumes at most 2 lines of data. 358 * still word wraps, but assumes at most 2 lines of data.
394 * mw - 2-12-97 359 * mw - 2-12-97
395 */ 360 */
396 strncpy (buf, scorebuf, MAX_BUF); 361 assign (buf, scorebuf);
397 buf[MAX_BUF - 1] = '\0'; 362
398 cp = buf; 363 cp = buf;
399 while (strlen (cp) > maxchar) 364 while (strlen (cp) > maxchar)
400 { 365 {
401 bp = cp + maxchar - 1; 366 bp = cp + maxchar - 1;
402 while (*bp != ' ' && bp > cp) 367 while (*bp != ' ' && bp > cp)
403 bp--; 368 bp--;
404 *bp = '\0'; 369 *bp = '\0';
370
405 if (op == NULL) 371 if (op == NULL)
406 {
407 LOG (llevDebug, "%s\n", cp); 372 LOG (llevDebug, "%s\n", cp);
408 }
409 else 373 else
410 {
411 new_draw_info (NDI_UNIQUE, 0, op, cp); 374 new_draw_info (NDI_UNIQUE, 0, op, cp);
412 } 375
413 sprintf (buf, " %s", bp + 1); 376 sprintf (buf, " %s", bp + 1);
414 cp = buf; 377 cp = buf;
415 i++; 378 i++;
416 } 379 }
380
417 if (op == NULL) 381 if (op == NULL)
418 LOG (llevDebug, "%s\n", buf); 382 LOG (llevDebug, "%s\n", buf);
419 else 383 else
420 new_draw_info (NDI_UNIQUE, 0, op, buf); 384 new_draw_info (NDI_UNIQUE, 0, op, buf);
421 } 385 }
386
422 close_and_delete (fp, comp); 387 close_and_delete (fp, comp);
423} 388}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines