1 /*
2 * cfg_game.c - storing and loading game setups
3 *
4 * $Id: cfg_game.c,v 1.25 2006/02/24 21:29:16 fzago Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "xblast.h"
25
26 /*
27 * local variables
28 */
29 static DBRoot *dbLocal;
30 static DBRoot *dbRemote;
31
32 static CFGGame defaultGame = {
33 {
34 0, /* ifreclives */
35 1, /* number of lives */
36 9, /* number of victories */
37 20, /* frames per seconed */
38 XBTrue, /* select all levels */
39 XBTrue, /* random level order */
40 XBTrue, /* random player positions */
41 0, /* level order */
42 8, /* info wait time */
43 XBFalse, /* record demo file */
44 XBTM_None, /* no team game */
45 XBTrue, /* XBCC not rated */
46 XBFalse, /* bot */
47 XBFalse, /* beep */
48 XBFalse, /* Music */
49 2, /* number of rec lives (of valid if 1. XBTrue) */
50 1, /* mask bytes for dgram */
51 },
52 {
53 0, /* num of players */
54 {ATOM_INVALID,}, /* player name atom */
55 {XBPC_None,}, /* player control */
56 {XBPH_None,}, /* player host */
57 {XBPT_Invalid,}, /* player team */
58 {COLOR_INVALID,}, /* player team color */
59 {0,}, /* player PID */
60 {0,}, /* player id */
61 },
62 {
63 "localhost", /* hostname */
64 16168, /* tcp-port */
65 XBFalse, /* fixed udp-port */
66 XBTrue, /* browse LAN */
67 XBTrue, /* allow NAT for clients */
68 XBTrue, /* connect to central */
69 XBFalse, /* beep if new client */
70 0, /* Music */
71 "unnamed", /* name of the game */
72 },
73 {
74 6, /* max hosts */
75 6, /* max players */
76 6, /* num local players */
77 1, /* max mask bytes */
78 {0, 0, 0}, /* version */
79 },
80 };
81
82 /* conversion table for player control (alphanumeric sort by key) */
83 static DBToInt convControlTable[XBPC_NUM + 1] = {
84 {"Joystick1", XBPC_Joystick1,},
85 {"Joystick2", XBPC_Joystick2,},
86 {"Joystick3", XBPC_Joystick3,},
87 {"Joystick4", XBPC_Joystick4,},
88 {"LeftKeyboard", XBPC_LeftKeyboard,},
89 {"None", XBPC_None,},
90 {"RightKeyboard", XBPC_RightKeyboard,},
91 /* terminator */
92 {NULL, XBPC_NUM},
93 };
94
95 /* conversion table for player hosts (alphanumeric sort by key) */
96 static DBToInt convHostTable[XBPH_NUM + 1] = {
97 {"Central", XBPH_Central,},
98 {"Client1", XBPH_Client1,},
99 {"Client2", XBPH_Client2,},
100 {"Client3", XBPH_Client3,},
101 {"Client4", XBPH_Client4,},
102 {"Client5", XBPH_Client5,},
103 #ifdef SMPF
104 {"Client6", XBPH_Client6,},
105 {"Client7", XBPH_Client7,},
106 {"Client8", XBPH_Client8,},
107 {"Client9", XBPH_Client9,},
108 {"Client10", XBPH_Client10,},
109 {"Client11", XBPH_Client11,},
110 {"Client12", XBPH_Client12,},
111 {"Client13", XBPH_Client13,},
112 {"Client14", XBPH_Client14,},
113 {"Client15", XBPH_Client15,},
114 #endif
115 {"Demo", XBPH_Demo,},
116 {"Local", XBPH_Local,},
117 {"None", XBPH_None,},
118 {"Server", XBPH_Server,},
119 /* terminator */
120 {NULL, XBPH_NUM},
121 };
122
123 /* conversion table for player teams (alphanumeric sort by key) */
124 static DBToInt convTeamTable[XBPT_NUM + 1] = {
125 {"Blue", XBPT_Blue,},
126 {"Green", XBPT_Green,},
127 {"None", XBPT_None,},
128 {"Red", XBPT_Red,},
129 /* terminator */
130 {NULL, XBPT_NUM,},
131 };
132
133 /* conversion table for player teams (alphanumeric sort by key) */
134 static DBToInt convTeamModeTable[XBTM_NUM + 1] = {
135 {"Hunt", XBTM_Hunt,},
136 {"None", XBTM_None,},
137 {"Team", XBTM_Team,},
138 /* terminator */
139 {NULL, XBTM_NUM,},
140 };
141
142 /*
143 * convert type to database
144 */
145 static DBRoot *
GetDB(CFGType cfgType)146 GetDB (CFGType cfgType)
147 {
148 switch (cfgType) {
149 case CT_Local:
150 return dbLocal;
151 case CT_Remote:
152 return dbRemote;
153 /* case CT_Demo: return dbDemo; */
154 default:
155 return NULL;
156 }
157 } /* GetDB */
158
159 /*
160 *
161 */
162 static void
StoreAnyGameSetup(DBRoot * db,XBAtom atom,const CFGGameSetup * game)163 StoreAnyGameSetup (DBRoot * db, XBAtom atom, const CFGGameSetup * game)
164 {
165 DBSection *section;
166 const char *key;
167
168 /* sanity check */
169 assert (db != NULL);
170 assert (ATOM_INVALID != atom);
171 assert (NULL != game);
172 /* create new game section */
173 section = DB_CreateSection (db, atom);
174 assert (NULL != section);
175 /* other stats */
176 DB_CreateEntryInt (section, atomLives, game->numLives);
177 DB_CreateEntryInt (section, atomRecLives, game->recLives);
178 DB_CreateEntryBool (section, atomIfRecLives, game->ifRecLives);
179 DB_CreateEntryInt (section, atomWins, game->numWins);
180 DB_CreateEntryInt (section, atomFrameRate, game->frameRate);
181 DB_CreateEntryBool (section, atomAllLevels, game->allLevels);
182 DB_CreateEntryBool (section, atomRandomLevels, game->randomLevels);
183 DB_CreateEntryBool (section, atomRandomPlayers, game->randomPlayers);
184 DB_CreateEntryBool (section, atomRecordDemo, game->recordDemo);
185 DB_CreateEntryBool (section, atomRatedGame, game->rated);
186 DB_CreateEntryBool (section, atomBot, game->bot);
187 DB_CreateEntryBool (section, atomBeep, game->beep);
188 DB_CreateEntryInt (section, atomMusic, game->Music);
189 DB_CreateEntryInt (section, atomInfoTime, game->infoTime); // LRF
190 DB_CreateEntryInt (section, atomLevelOrder, game->levelOrder);
191 DB_CreateEntryInt (section, atomMaskBytes, game->maskBytes);
192 /* team mode */
193 if (NULL != (key = DB_IntToString (convTeamModeTable, (int)game->teamMode))) {
194 DB_CreateEntryString (section, atomTeamMode, key);
195 }
196 else {
197 DB_DeleteEntry (section, atomTeamMode);
198 }
199 } /* StoreAnyGameSetup */
200
201 /*
202 *
203 */
204 void
StoreGameSetup(CFGType cfgType,XBAtom atom,const CFGGameSetup * game)205 StoreGameSetup (CFGType cfgType, XBAtom atom, const CFGGameSetup * game)
206 {
207 StoreAnyGameSetup (GetDB (cfgType), atom, game);
208 } /* StoreLocalGameSetup */
209
210 /*
211 * store GamePlayers data from struct to any database
212 */
213 static void
StoreAnyGamePlayers(DBRoot * db,XBAtom atom,const CFGGamePlayers * game)214 StoreAnyGamePlayers (DBRoot * db, XBAtom atom, const CFGGamePlayers * game)
215 {
216 int i;
217 DBSection *section;
218 const char *keyControl;
219 const char *keyHost;
220 const char *keyTeam;
221
222 /* sanity check */
223 assert (db != NULL);
224 assert (ATOM_INVALID != atom);
225 assert (NULL != game);
226 /* create new game section */
227 section = DB_CreateSection (db, atom);
228 assert (NULL != section);
229 /* number of players */
230 DB_CreateEntryInt (section, atomNumPlayers, game->num);
231 /* players */
232 for (i = 0; i < game->num; i++) {
233 keyControl = DB_IntToString (convControlTable, (int)game->control[i]);
234 keyHost = DB_IntToString (convHostTable, (int)game->host[i]);
235 keyTeam = DB_IntToString (convTeamTable, (int)game->team[i]);
236 if (NULL != keyHost && NULL != keyControl && NULL != keyTeam) {
237 DB_CreateEntryString (section, atomArrayPlayer0[i], GUI_AtomToString (game->player[i]));
238 DB_CreateEntryString (section, atomArrayControl0[i], keyControl);
239 DB_CreateEntryString (section, atomArrayHost0[i], keyHost);
240 DB_CreateEntryString (section, atomArrayTeam0[i], keyTeam);
241 }
242 else {
243 DB_DeleteEntry (section, atomArrayPlayer0[i]);
244 DB_DeleteEntry (section, atomArrayControl0[i]);
245 DB_DeleteEntry (section, atomArrayHost0[i]);
246 DB_DeleteEntry (section, atomArrayTeam0[i]);
247 }
248 }
249 for (; i < MAX_PLAYER; i++) {
250 DB_DeleteEntry (section, atomArrayPlayer0[i]);
251 DB_DeleteEntry (section, atomArrayControl0[i]);
252 DB_DeleteEntry (section, atomArrayHost0[i]);
253 DB_DeleteEntry (section, atomArrayTeam0[i]);
254 }
255 } /* StoreAnyGamePlayers */
256
257 /*
258 * copy GamePlayers data from struct to a config database
259 */
260 void
StoreGamePlayers(CFGType cfgType,XBAtom atom,const CFGGamePlayers * game)261 StoreGamePlayers (CFGType cfgType, XBAtom atom, const CFGGamePlayers * game)
262 {
263 StoreAnyGamePlayers (GetDB (cfgType), atom, game);
264 } /* StoreGamePlayers */
265
266 /*
267 *
268 */
269 static void
StoreAnyGameHost(DBRoot * db,XBAtom atom,const CFGGameHost * host)270 StoreAnyGameHost (DBRoot * db, XBAtom atom, const CFGGameHost * host)
271 {
272 DBSection *section;
273 /* sanity check */
274 assert (db != NULL);
275 assert (ATOM_INVALID != atom);
276 assert (NULL != host);
277 /* create new game section */
278 section = DB_CreateSection (db, atom);
279 assert (NULL != section);
280 /* other stats */
281 if (NULL != host->name) {
282 DB_CreateEntryString (section, atomHost, host->name);
283 }
284 else {
285 DB_DeleteEntry (section, atomHost);
286 }
287 DB_CreateEntryInt (section, atomPort, host->port);
288 DB_CreateEntryBool (section, atomFixedUdpPort, host->fixedUdpPort);
289 DB_CreateEntryBool (section, atomBrowseLan, host->browseLan);
290 DB_CreateEntryBool (section, atomAllowNat, host->allowNat);
291 DB_CreateEntryBool (section, atomCentral, host->central);
292 DB_CreateEntryBool (section, atomBeep, host->beep);
293 if (NULL != host->game) {
294 DB_CreateEntryString (section, atomGame, host->game);
295 }
296 else {
297 DB_DeleteEntry (section, atomGame);
298 }
299 } /* StoreGameHost */
300
301 /*
302 *
303 */
304 void
StoreGameHost(CFGType cfgType,XBAtom atom,const CFGGameHost * host)305 StoreGameHost (CFGType cfgType, XBAtom atom, const CFGGameHost * host)
306 {
307 StoreAnyGameHost (GetDB (cfgType), atom, host);
308 } /* StoreGameHost */
309
310 /*
311 * store version data in any database
312 */
313 static void
StoreAnyGameVersion(DBRoot * db,XBAtom atom,const XBVersion * ver)314 StoreAnyGameVersion (DBRoot * db, XBAtom atom, const XBVersion * ver)
315 {
316 DBSection *section;
317 /* sanity check */
318 assert (db != NULL);
319 assert (ATOM_INVALID != atom);
320 assert (NULL != ver);
321 /* create new game section */
322 section = DB_CreateSection (db, atom);
323 assert (NULL != section);
324 /* store version data */
325 DB_CreateEntryInt (section, atomVersionMajor, (int)ver->major);
326 DB_CreateEntryInt (section, atomVersionMinor, (int)ver->minor);
327 DB_CreateEntryInt (section, atomVersionPatch, (int)ver->patch);
328 } /* StoreAnyGameVersion */
329
330 /*
331 * copy version data database directory
332 */
333 void
StoreGameVersion(CFGType cfgType,XBAtom atom,const XBVersion * ver)334 StoreGameVersion (CFGType cfgType, XBAtom atom, const XBVersion * ver)
335 {
336 StoreAnyGameVersion (GetDB (cfgType), atom, ver);
337 } /* StoreGameVersion */
338
339 /*
340 * store constants in any database
341 */
342 static void
StoreAnyGameConst(DBRoot * db,XBAtom atom,const CFGGameConst * con)343 StoreAnyGameConst (DBRoot * db, XBAtom atom, const CFGGameConst * con)
344 {
345 DBSection *section;
346 /* sanity check */
347 assert (db != NULL);
348 assert (ATOM_INVALID != atom);
349 assert (NULL != con);
350 /* create new game section */
351 section = DB_CreateSection (db, atom);
352 assert (NULL != section);
353 /* store version data */
354 DB_CreateEntryInt (section, atomMaxHosts, con->maxhosts);
355 DB_CreateEntryInt (section, atomMaxPlayers, con->maxplayers);
356 DB_CreateEntryInt (section, atomMaxLocals, con->maxlocals);
357 DB_CreateEntryInt (section, atomMaxMaskBytes, con->maxbytes);
358 DB_CreateEntryInt (section, atomVersionMajor, (int)con->version.major);
359 DB_CreateEntryInt (section, atomVersionMinor, (int)con->version.minor);
360 DB_CreateEntryInt (section, atomVersionPatch, (int)con->version.patch);
361 } /* StoreAnyGameConst */
362
363 /*
364 * store constants in config database
365 */
366 void
StoreGameConst(CFGType cfgType,XBAtom atom,const CFGGameConst * con)367 StoreGameConst (CFGType cfgType, XBAtom atom, const CFGGameConst * con)
368 {
369 StoreAnyGameConst (GetDB (cfgType), atom, con);
370 } /* StoreGameConst */
371
372 /*
373 * store local constants in config database
374 */
375 void
StoreGameConstLocal(CFGType cfgType,XBAtom atom)376 StoreGameConstLocal (CFGType cfgType, XBAtom atom)
377 {
378 CFGGameConst con;
379 con.maxhosts = MAX_HOSTS;
380 con.maxplayers = MAX_PLAYER;
381 con.maxlocals = NUM_LOCAL_PLAYER;
382 con.maxbytes = MAX_MASK_BYTES;
383 memcpy (&con.version, &Ver_Local, sizeof (XBVersion));
384 StoreAnyGameConst (GetDB (cfgType), atom, &con);
385 } /* StoreGameConstLocal */
386
387 /*
388 * retrieve game setup from any database
389 */
390 static XBBool
RetrieveAnyGameSetup(const DBRoot * db,XBAtom atom,CFGGameSetup * game)391 RetrieveAnyGameSetup (const DBRoot * db, XBAtom atom, CFGGameSetup * game)
392 {
393 const DBSection *section;
394
395 assert (NULL != db);
396 assert (NULL != game);
397 /* set defaults */
398 memcpy (game, &defaultGame.setup, sizeof (CFGGameSetup));
399 /* find according db section */
400 section = DB_GetSection (db, atom);
401 if (NULL == section) {
402 return XBFalse;
403 }
404 /* copy values */
405 (void)DB_GetEntryInt (section, atomLives, &game->numLives);
406 (void)DB_GetEntryInt (section, atomRecLives, &game->recLives);
407 (void)DB_GetEntryBool (section, atomIfRecLives, &game->ifRecLives);
408 (void)DB_GetEntryInt (section, atomWins, &game->numWins);
409 (void)DB_GetEntryInt (section, atomFrameRate, &game->frameRate);
410 (void)DB_GetEntryBool (section, atomAllLevels, &game->allLevels);
411 (void)DB_GetEntryBool (section, atomRandomLevels, &game->randomLevels);
412 (void)DB_GetEntryBool (section, atomRandomPlayers, &game->randomPlayers);
413 (void)DB_GetEntryBool (section, atomRecordDemo, &game->recordDemo);
414 (void)DB_GetEntryBool (section, atomRatedGame, &game->rated);
415 (void)DB_GetEntryInt (section, atomInfoTime, &game->infoTime); // LRF
416 (void)DB_GetEntryInt (section, atomLevelOrder, &game->levelOrder);
417 (void)DB_GetEntryBool (section, atomBot, &game->bot);
418 (void)DB_GetEntryBool (section, atomBeep, &game->beep);
419 (void)DB_GetEntryInt (section, atomMusic, (int *)&game->Music);
420 (void)DB_GetEntryInt (section, atomMaskBytes, &game->maskBytes);
421 /* team mode */
422 if (DCR_Okay !=
423 DB_ConvertEntryInt (section, atomTeamMode, (int *)&game->teamMode, convTeamModeTable)) {
424 game->teamMode = XBTM_None;
425 }
426 /* that's all */
427 return XBTrue;
428 } /* RetrieveGameConfig */
429
430 /*
431 * retrieve game setup from config database
432 */
433 XBBool
RetrieveGameSetup(CFGType cfgType,XBAtom atom,CFGGameSetup * game)434 RetrieveGameSetup (CFGType cfgType, XBAtom atom, CFGGameSetup * game)
435 {
436 return RetrieveAnyGameSetup (GetDB (cfgType), atom, game);
437 } /* RetrieveGameSetup */
438
439 /*
440 * fill default player data, call only once when accessing game players
441 */
442 static void
DefaultPlayerData(void)443 DefaultPlayerData (void)
444 {
445 static int init = 0;
446 int p;
447 if (init == 0) {
448 for (p = 1; p < MAX_PLAYER; p++) {
449 defaultGame.players.player[p] = defaultGame.players.player[0];
450 defaultGame.players.control[p] = defaultGame.players.control[0];
451 defaultGame.players.host[p] = defaultGame.players.host[0];
452 defaultGame.players.team[p] = defaultGame.players.team[0];
453 defaultGame.players.PID[p] = defaultGame.players.PID[0];
454 defaultGame.players.playerID[p] = defaultGame.players.playerID[0];
455 }
456 init = 1;
457 }
458 } /* DefaultPlayerData */
459
460 /*
461 * copy GamePlayers data from any database to struct
462 */
463 static XBBool
RetrieveAnyGamePlayers(const DBRoot * db,XBAtom atom,CFGGamePlayers * game)464 RetrieveAnyGamePlayers (const DBRoot * db, XBAtom atom, CFGGamePlayers * game)
465 {
466 int i;
467 const DBSection *section;
468 const char *s;
469 assert (NULL != db);
470 assert (NULL != game);
471 /* set defaults */
472 DefaultPlayerData ();
473 memcpy (game, &defaultGame.players, sizeof (CFGGamePlayers));
474 /* find according db section */
475 section = DB_GetSection (db, atom);
476 if (NULL == section) {
477 return XBFalse;
478 }
479 /* get num players */
480 if (!DB_GetEntryInt (section, atomNumPlayers, &game->num)) {
481 game->num = 0;
482 }
483 /* check player max */
484 if (game->num > MAX_PLAYER) {
485 return XBFalse;
486 }
487 /* get players */
488 for (i = 0; i < game->num; i++) {
489 if (DB_GetEntryString (section, atomArrayPlayer0[i], &s)) {
490 game->player[i] = GUI_StringToAtom (s);
491 }
492 else {
493 game->player[i] = ATOM_INVALID;
494 }
495 if (DCR_Okay !=
496 DB_ConvertEntryInt (section, atomArrayControl0[i], (int *)&game->control[i],
497 convControlTable)) {
498 game->control[i] = XBPC_None;
499 }
500 if (DCR_Okay !=
501 DB_ConvertEntryInt (section, atomArrayHost0[i], (int *)&game->host[i], convHostTable)) {
502 game->host[i] = XBPH_None;
503 }
504 if (DCR_Okay !=
505 DB_ConvertEntryInt (section, atomArrayTeam0[i], (int *)&game->team[i], convTeamTable)) {
506 game->team[i] = XBPT_Invalid;
507 }
508 switch (game->team[i]) {
509 case XBPT_Red:
510 game->teamColor[i] = COLOR_RED;
511 break;
512 case XBPT_Green:
513 game->teamColor[i] = COLOR_GREEN;
514 break;
515 case XBPT_Blue:
516 game->teamColor[i] = COLOR_BLUE;
517 break;
518 default:
519 game->teamColor[i] = COLOR_INVALID;
520 break;
521 }
522 }
523 return XBTrue;
524 } /* RetrieveGamePlayers */
525
526 /*
527 * get local player selection
528 */
529 XBBool
RetrieveGamePlayers(CFGType cfgType,XBAtom atom,CFGGamePlayers * game)530 RetrieveGamePlayers (CFGType cfgType, XBAtom atom, CFGGamePlayers * game)
531 {
532 return RetrieveAnyGamePlayers (GetDB (cfgType), atom, game);
533 } /* RetrieveGamePlayers */
534
535 /*
536 *
537 */
538 static XBBool
RetrieveAnyGameHost(const DBRoot * db,XBAtom atom,CFGGameHost * game)539 RetrieveAnyGameHost (const DBRoot * db, XBAtom atom, CFGGameHost * game)
540 {
541 const DBSection *section;
542 const char *s;
543
544 assert (NULL != db);
545 assert (NULL != game);
546 /* find according db section */
547 section = DB_GetSection (db, atom);
548 if (NULL == section) {
549 return XBFalse;
550 }
551 /* get host data */
552 memcpy (game, &defaultGame.host, sizeof (CFGGameHost));
553 if (DB_GetEntryString (section, atomHost, &s)) {
554 game->name = s;
555 }
556 (void)DB_GetEntryInt (section, atomPort, &game->port);
557 (void)DB_GetEntryBool (section, atomFixedUdpPort, &game->fixedUdpPort);
558 (void)DB_GetEntryBool (section, atomBrowseLan, &game->browseLan);
559 (void)DB_GetEntryBool (section, atomAllowNat, &game->allowNat);
560 (void)DB_GetEntryBool (section, atomCentral, &game->central);
561 (void)DB_GetEntryString (section, atomGame, &game->game);
562 (void)DB_GetEntryBool (section, atomBeep, &game->beep);
563 return XBTrue;
564 } /* RetrieveGameHost */
565
566 /*
567 *
568 */
569 XBBool
RetrieveGameHost(CFGType cfgType,XBAtom atom,CFGGameHost * game)570 RetrieveGameHost (CFGType cfgType, XBAtom atom, CFGGameHost * game)
571 {
572 return RetrieveAnyGameHost (GetDB (cfgType), atom, game);
573 } /* RetrieveGameHost */
574
575 /*
576 * get version data from any database
577 */
578 static XBBool
RetrieveAnyGameVersion(const DBRoot * db,XBAtom atom,XBVersion * ver)579 RetrieveAnyGameVersion (const DBRoot * db, XBAtom atom, XBVersion * ver)
580 {
581 const DBSection *section;
582 int maj, min, pat;
583 assert (NULL != ver);
584 /* find according db section */
585 section = DB_GetSection (db, atom);
586 if (NULL == section) {
587 return XBFalse;
588 }
589 Version_Clear (ver);
590 /* now extract version data */
591 if (!DB_GetEntryInt (section, atomVersionMajor, &maj)) {
592 return XBFalse;
593 }
594 if (!DB_GetEntryInt (section, atomVersionMinor, &min)) {
595 return XBFalse;
596 }
597 if (!DB_GetEntryInt (section, atomVersionPatch, &pat)) {
598 return XBFalse;
599 }
600 ver->major = maj & 0xFF;
601 ver->minor = min & 0xFF;
602 ver->patch = pat & 0xFF;
603 return XBTrue;
604 } /* RetrieveAnyGameVersion */
605
606 /*
607 * get version data from config database
608 */
609 XBBool
RetrieveGameVersion(CFGType cfgType,XBAtom atom,XBVersion * ver)610 RetrieveGameVersion (CFGType cfgType, XBAtom atom, XBVersion * ver)
611 {
612 return RetrieveAnyGameVersion (GetDB (cfgType), atom, ver);
613 } /* RetrieveGameVersion */
614
615 /*
616 * get game constants any database
617 */
618 static XBBool
RetrieveAnyGameConst(const DBRoot * db,XBAtom atom,CFGGameConst * con)619 RetrieveAnyGameConst (const DBRoot * db, XBAtom atom, CFGGameConst * con)
620 {
621 const DBSection *section;
622 int maj, min, pat;
623 assert (NULL != con);
624 /* set default */
625 memcpy (con, &defaultGame.constants, sizeof (CFGGameConst));
626 /* find according db section */
627 section = DB_GetSection (db, atom);
628 if (NULL == section) {
629 return XBFalse;
630 }
631 /* extract constants */
632 (void)DB_GetEntryInt (section, atomMaxHosts, &con->maxhosts);
633 (void)DB_GetEntryInt (section, atomMaxPlayers, &con->maxplayers);
634 (void)DB_GetEntryInt (section, atomMaxLocals, &con->maxlocals);
635 (void)DB_GetEntryInt (section, atomMaxMaskBytes, &con->maxbytes);
636 /* now extract version data */
637 if (!DB_GetEntryInt (section, atomVersionMajor, &maj)) {
638 return XBTrue;
639 }
640 if (!DB_GetEntryInt (section, atomVersionMinor, &min)) {
641 return XBTrue;
642 }
643 if (!DB_GetEntryInt (section, atomVersionPatch, &pat)) {
644 return XBTrue;
645 }
646 con->version.major = maj & 0xFF;
647 con->version.minor = min & 0xFF;
648 con->version.patch = pat & 0xFF;
649 return XBTrue;
650 } /* RetrieveAnyGameConst */
651
652 /*
653 * get game constants from config database
654 */
655 XBBool
RetrieveGameConst(CFGType cfgType,XBAtom atom,CFGGameConst * con)656 RetrieveGameConst (CFGType cfgType, XBAtom atom, CFGGameConst * con)
657 {
658 return RetrieveAnyGameConst (GetDB (cfgType), atom, con);
659 } /* RetrieveGameConst */
660
661 /*
662 * save game config at once
663 */
664 void
StoreGame(CFGType cfgType,XBAtom atom,const CFGGame * cfg)665 StoreGame (CFGType cfgType, XBAtom atom, const CFGGame * cfg)
666 {
667 assert (NULL != cfg);
668
669 StoreGameSetup (cfgType, atom, &cfg->setup);
670 StoreGamePlayers (cfgType, atom, &cfg->players);
671 StoreGameHost (cfgType, atom, &cfg->host);
672 StoreGameConst (cfgType, atom, &cfg->constants);
673 } /* StoreGame */
674
675 /*
676 * retrieve game config at once
677 */
678 XBBool
RetrieveGame(CFGType cfgType,XBAtom atom,CFGGame * cfg)679 RetrieveGame (CFGType cfgType, XBAtom atom, CFGGame * cfg)
680 {
681 XBBool result = XBTrue;
682
683 assert (NULL != cfg);
684
685 if (!RetrieveGameSetup (cfgType, atom, &cfg->setup)) {
686 result = XBFalse;
687 }
688 if (!RetrieveGamePlayers (cfgType, atom, &cfg->players)) {
689 result = XBFalse;
690 }
691 if (!RetrieveGameHost (cfgType, atom, &cfg->host)) {
692 result = XBFalse;
693 }
694 (void)RetrieveGameConst (cfgType, atom, &cfg->constants);
695 return result;
696 } /* RetrieveGame */
697
698 /*
699 * load game config from file
700 */
701 void
LoadGameConfig(void)702 LoadGameConfig (void)
703 {
704 /* remote database */
705 dbRemote = DB_Create (DT_Config, atomRemoteGame);
706 assert (dbRemote != NULL);
707 /* local database */
708 dbLocal = DB_Create (DT_Config, atomGame);
709 assert (dbLocal != NULL);
710 Dbg_Config ("loading local game config\n");
711 if (DB_Load (dbLocal)) {
712 return;
713 }
714 Dbg_Config ("failed to load local game config, setting defaults\n");
715 /* set default values */
716 DefaultPlayerData ();
717 StoreGame (CT_Local, atomLocal, &defaultGame);
718 StoreGame (CT_Local, atomServer, &defaultGame);
719 StoreGame (CT_Local, atomClient, &defaultGame);
720 /* and save it */
721 DB_Store (dbLocal);
722 } /* LoadGameConfig */
723
724 /*
725 * save game config to file
726 */
727 void
SaveGameConfig(void)728 SaveGameConfig (void)
729 {
730 assert (dbLocal != NULL);
731 if (DB_Changed (dbLocal)) {
732 Dbg_Config ("saving local game config\n");
733 DB_Store (dbLocal);
734 }
735 #ifdef DEBUG
736 assert (dbRemote != NULL);
737 if (DB_Changed (dbRemote)) {
738 Dbg_Config ("saving remote game config\n");
739 DB_Store (dbRemote);
740 }
741 #endif
742 } /* SaveGameConfig */
743
744 /*
745 * remove game configs
746 */
747 void
FinishGameConfig(void)748 FinishGameConfig (void)
749 {
750 if (NULL != dbLocal) {
751 DB_Delete (dbLocal);
752 dbLocal = NULL;
753 }
754 if (NULL != dbRemote) {
755 DB_Delete (dbRemote);
756 dbRemote = NULL;
757 }
758 Dbg_Config ("game config cleared!\n");
759 } /* FinishGameConfig */
760
761 /*
762 * put game config into telegram send queue
763 */
764 XBBool
SendGameConfig(CFGType cfgType,XBSndQueue * queue,XBTeleCOT cot,XBTeleIOB iob,XBAtom atom)765 SendGameConfig (CFGType cfgType, XBSndQueue * queue, XBTeleCOT cot, XBTeleIOB iob, XBAtom atom)
766 {
767 const DBSection *section;
768 int i;
769 size_t len;
770 XBTelegram *tele;
771 char tmp[256];
772
773 assert (queue != NULL);
774 /* get section with game data */
775 section = DB_GetSection (GetDB (cfgType), atom);
776 if (NULL == section) {
777 return XBFalse;
778 }
779 /* now print and send data */
780 i = 0;
781 while (0 < (len = DB_PrintEntry (tmp, section, i))) {
782 tele = Net_CreateTelegram (cot, XBT_ID_GameConfig, iob, tmp, len + 1);
783 assert (tele != NULL);
784 Net_SendTelegram (queue, tele);
785 i++;
786 }
787 /* no data means end of section */
788 tele = Net_CreateTelegram (cot, XBT_ID_GameConfig, iob, NULL, 0);
789 assert (tele != NULL);
790 Net_SendTelegram (queue, tele);
791 return XBTrue;
792 } /* SendGameConfig */
793
794 /*
795 * delete a game config
796 */
797 void
DeleteGameConfig(CFGType cfgType,XBAtom atom)798 DeleteGameConfig (CFGType cfgType, XBAtom atom)
799 {
800 DB_DeleteSection (GetDB (cfgType), atom);
801 } /* DeleteGameConfig */
802
803 /*
804 * add entry line to game config
805 */
806 void
AddToGameConfig(CFGType cfgType,XBAtom atom,const char * line)807 AddToGameConfig (CFGType cfgType, XBAtom atom, const char *line)
808 {
809 DBSection *section;
810
811 /* sanity check */
812 assert (ATOM_INVALID != atom);
813 /* create new game section */
814 section = DB_CreateSection (GetDB (cfgType), atom);
815 assert (NULL != section);
816 /* add line */
817 (void)DB_ParseEntry (section, line);
818 } /* AddToGameConfig */
819
820 /*
821 * return hostname and port
822 */
823 const char *
GetHostName(CFGType cfgType,XBAtom atom)824 GetHostName (CFGType cfgType, XBAtom atom)
825 {
826 CFGGameHost cfg;
827 static char txt[256];
828
829 /* sanity check */
830 assert (ATOM_INVALID != atom);
831 /* get host config */
832 if (!RetrieveGameHost (cfgType, atom, &cfg)) {
833 strcpy (txt, "unknown");
834 }
835 else {
836 sprintf (txt, "%s:%d", cfg.name, cfg.port);
837 }
838 return txt;
839 } /* GetRemoteHostName */
840
841 /*
842 * push a single ip into ip history database
843 */
844 void
StoreIpHistory(CFGGameHost * host,XBAtom atom)845 StoreIpHistory (CFGGameHost * host, XBAtom atom)
846 {
847 DBSection *section;
848 CFGGameHost hist[10];
849 int i = 0;
850 /* sanity check */
851 assert (ATOM_INVALID != atom);
852 assert (NULL != host);
853 section = (DBSection *) DB_GetSection (GetDB (CT_Local), atom);
854 /* get old history data */
855 assert (NULL != section);
856 RetrieveIpHistory (hist, atom);
857 /* push back server data */
858 for (i = 9; i > 0; i--) {
859 hist[i].name = hist[i - 1].name;
860 hist[i].port = hist[i - 1].port;
861 }
862 /* store latest host data */
863 hist[0].port = host->port;
864 hist[0].name = host->name;
865 /* store back to database, backwards (important for pointer validity!) */
866 for (i = 9; i >= 0; i--) {
867 if (NULL != hist[i].name) {
868 DB_CreateEntryString (section, atomGamehis[i], hist[i].name);
869 DB_CreateEntryInt (section, atomPorthis[i], hist[i].port);
870 }
871 else {
872 DB_DeleteEntry (section, atomGamehis[i]);
873 DB_DeleteEntry (section, atomPorthis[i]);
874 }
875 }
876 RetrieveIpHistory (hist, atom);
877 } /* StoreIpHistory */
878
879 /*
880 * retrieve all ip history data
881 */
882 XBBool
RetrieveIpHistory(CFGGameHost host[10],XBAtom atom)883 RetrieveIpHistory (CFGGameHost host[10], XBAtom atom)
884 {
885 const DBSection *section;
886 int i = 0;
887 section = DB_GetSection (GetDB (CT_Local), atom);
888 /* check if there is section with ip history data */
889 if (NULL == section) {
890 return XBFalse;
891 }
892 /* retrieve data */
893 for (i = 0; i < 10; i++) {
894 /* first default data for entry */
895 host[i].name = NULL;
896 host[i].game = NULL;
897 host[i].port = 0;
898 /* now update from database */
899 (void)DB_GetEntryString (section, atomGamehis[i], &host[i].name);
900 (void)DB_GetEntryInt (section, atomPorthis[i], &host[i].port);
901 }
902 return XBTrue;
903 } /* RetrieveIpHistory */
904
905 /*
906 * end of file cfg_game.c
907 */
908