1 /*
2  * cfg_player.c - player configuration data
3  *
4  * $Id: cfg_player.c,v 1.15 2006/06/12 10:51:48 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  * global variables
28  */
29 static const char *defaultShape[NUM_DEFAULT_PLAYERS] = {
30 	"normal", "normal", "normal", "fat", "girl", "tall",
31 };
32 static CFGPlayerGraphics defaultPlayerGraphics[NUM_DEFAULT_PLAYERS] = {
33 	{
34 	 ATOM_INVALID,
35 	 COLOR_TURQUOISE, COLOR_LIGHT_SALMON, COLOR_WHITE, COLOR_GRAY_75,
36 	 COLOR_GRAY_25, COLOR_ROYAL_BLUE, COLOR_WHITE,
37 	 },
38 	{
39 	 ATOM_INVALID,
40 	 COLOR_MIDNIGHT_BLUE, COLOR_LIGHT_SALMON, COLOR_NAVY_BLUE, COLOR_RED,
41 	 COLOR_ROYAL_BLUE, COLOR_GOLD, COLOR_WHITE,
42 	 },
43 	{
44 	 ATOM_INVALID,
45 	 COLOR_RED, COLOR_LIGHT_SALMON, COLOR_RED, COLOR_FOREST_GREEN,
46 	 COLOR_INDIAN_RED, COLOR_DARK_SEA_GREEN, COLOR_WHITE,
47 	 },
48 	{
49 	 ATOM_INVALID,
50 	 COLOR_YELLOW, COLOR_LIGHT_SALMON, COLOR_SPRING_GREEN, COLOR_ORANGE_RED,
51 	 COLOR_LIGHT_YELLOW, COLOR_ROYAL_BLUE, COLOR_WHITE,
52 	 },
53 	{
54 	 ATOM_INVALID,
55 	 COLOR_DEEP_PINK, COLOR_LIGHT_SALMON, COLOR_ORCHID, COLOR_SPRING_GREEN,
56 	 COLOR_ROYAL_BLUE, COLOR_DEEP_PINK, COLOR_WHITE,
57 	 },
58 	{
59 	 ATOM_INVALID,
60 	 COLOR_BLACK, COLOR_TAN, COLOR_BLACK, COLOR_ORANGE,
61 	 COLOR_BLACK, COLOR_ORANGE, COLOR_WHITE,
62 	 },
63 };
64 
65 static const char *administratorShape = "normal";
66 static CFGPlayerGraphics administratorPlayerGraphics = {
67 	ATOM_INVALID,
68 	COLOR_TURQUOISE, COLOR_LIGHT_SALMON, COLOR_WHITE, COLOR_GRAY_75,
69 	COLOR_GRAY_25, COLOR_ROYAL_BLUE, COLOR_WHITE,
70 };
71 
72 /*
73  * local variables
74  */
75 static DBRoot *dbLocal = NULL;
76 static DBRoot *dbRemote = NULL;
77 
78 static DBRoot *dbCentral = NULL;	// XBCC central database
79 XBBool isCentral;
80 
81 /* default values for new or empty configs */
82 static CFGPlayerGraphics newGfx = {
83 	ATOM_INVALID,
84 	COLOR_WHITE, COLOR_LIGHT_SALMON, COLOR_WHITE,
85 	COLOR_WHITE, COLOR_WHITE, COLOR_WHITE, COLOR_WHITE,
86 };
87 static CFGPlayerMessages newMsg = {
88 	NULL, NULL, NULL, NULL, NULL, NULL,
89 };
90 static CFGPlayerMisc newMisc = {
91 	XBTrue, 0, 4,
92 };
93 static CFGPlayerID newID = {
94 	-1, NULL
95 };
96 
97 /* names for default players */
98 static const char *defaultName[NUM_DEFAULT_PLAYERS] = {
99 	"Olli",
100 	"Norbert",
101 	"Rodi",
102 	"Harald",
103 	"Alex",
104 	"Olaf",
105 };
106 
107 /* XBCC  values for administrator config */
108 static CFGPlayerMessages administratorMsg = {
109 	NULL, NULL, NULL, NULL, NULL, "Welcome",
110 };
111 static CFGPlayerMisc administratorMisc = {
112 	XBTrue, 0, 4,
113 };
114 static CFGPlayerID administratorID = {
115 	0, "adminpass",
116 };
117 static CFGPlayerRating newRating = {
118 	0.0, 0, 0, 0, 0, 0,
119 };
120 static const char *administratorName = "Administrator";
121 
122 /*
123  * convert type to database
124  */
125 static DBRoot *
GetDB(CFGType cfgType)126 GetDB (CFGType cfgType)
127 {
128 	switch (cfgType) {
129 	case CT_Local:
130 		return dbLocal;
131 	case CT_Remote:
132 		return dbRemote;
133 	case CT_Demo:
134 		return dbDemo;
135 	case CT_Central:
136 		return dbCentral;
137 	default:
138 		return NULL;
139 	}
140 }								/* GetDB */
141 
142 /*
143  *
144  */
145 const CFGPlayerGraphics *
DefaultPlayerGraphics(size_t i)146 DefaultPlayerGraphics (size_t i)
147 {
148 	assert (i < NUM_DEFAULT_PLAYERS);
149 	if (ATOM_INVALID == defaultPlayerGraphics[i].shape) {
150 		defaultPlayerGraphics[i].shape = GUI_StringToAtom (defaultShape[i]);
151 	}
152 	return defaultPlayerGraphics + i;
153 }								/* DefaultPlayerGraphics */
154 
155 /*
156  * XBCC
157  */
158 static const CFGPlayerGraphics *
AdministratorPlayerGraphics(void)159 AdministratorPlayerGraphics (void)
160 {
161 	if (ATOM_INVALID == administratorPlayerGraphics.shape) {
162 		administratorPlayerGraphics.shape = GUI_StringToAtom (administratorShape);
163 	}
164 	return &administratorPlayerGraphics;
165 }								/* AdministratorPlayerGraphics */
166 
167 /*
168  *
169  */
170 static void
StoreAnyPlayerName(DBRoot * db,XBAtom atom,const char * name)171 StoreAnyPlayerName (DBRoot * db, XBAtom atom, const char *name)
172 {
173 	DBSection *section;
174 
175 	assert (name != NULL);
176 	assert (ATOM_INVALID != atom);
177 
178 	section = DB_CreateSection (db, atom);
179 	assert (section != NULL);
180 	/* graphics */
181 	DB_CreateEntryString (section, atomName, name);
182 }								/* StorePlayerName */
183 
184 /*
185  *
186  */
187 static void
StorePlayerName(CFGType cfgType,XBAtom atom,const char * name)188 StorePlayerName (CFGType cfgType, XBAtom atom, const char *name)
189 {
190 	StoreAnyPlayerName (GetDB (cfgType), atom, name);
191 }								/* StoreLocalPlayerName */
192 
193 /*
194  *
195  */
196 static void
StoreAnyPlayerGraphics(DBRoot * db,XBAtom atom,const CFGPlayerGraphics * gfx)197 StoreAnyPlayerGraphics (DBRoot * db, XBAtom atom, const CFGPlayerGraphics * gfx)
198 {
199 	DBSection *section;
200 
201 	assert (db != NULL);
202 	assert (gfx != NULL);
203 	assert (ATOM_INVALID != atom);
204 
205 	section = DB_CreateSection (db, atom);
206 	assert (section != NULL);
207 	/* graphics */
208 	(void)DB_CreateEntryAtom (section, atomShape, gfx->shape);
209 	(void)DB_CreateEntryColor (section, atomHelmet, gfx->helmet);
210 	(void)DB_CreateEntryColor (section, atomFace, gfx->face);
211 	(void)DB_CreateEntryColor (section, atomBody, gfx->body);
212 	(void)DB_CreateEntryColor (section, atomArmsLegs, gfx->armsLegs);
213 	(void)DB_CreateEntryColor (section, atomHandsFeet, gfx->handsFeet);
214 	(void)DB_CreateEntryColor (section, atomBackpack, gfx->backpack);
215 }								/* StorePlayerGraphics */
216 
217 /*
218  *
219  */
220 void
StorePlayerGraphics(CFGType cfgType,XBAtom atom,const CFGPlayerGraphics * gfx)221 StorePlayerGraphics (CFGType cfgType, XBAtom atom, const CFGPlayerGraphics * gfx)
222 {
223 	StoreAnyPlayerGraphics (GetDB (cfgType), atom, gfx);
224 }								/* StoreLocalPlayerGraphics */
225 
226 /*
227  *
228  */
229 static XBBool
RetrieveAnyPlayerGraphics(const DBRoot * db,XBAtom atom,XBColor teamColor,CFGPlayerGraphics * gfx)230 RetrieveAnyPlayerGraphics (const DBRoot * db, XBAtom atom, XBColor teamColor,
231 						   CFGPlayerGraphics * gfx)
232 {
233 	const DBSection *section;
234 
235 	assert (db != NULL);
236 	assert (gfx != NULL);
237 	/* set to defaults */
238 	*gfx = newGfx;
239 	/* find section for player */
240 	section = DB_GetSection (db, atom);
241 	if (NULL == section) {
242 		return XBFalse;
243 	}
244 	(void)DB_GetEntryAtom (section, atomShape, &gfx->shape);
245 	(void)DB_GetEntryColor (section, atomHelmet, &gfx->helmet);
246 	(void)DB_GetEntryColor (section, atomFace, &gfx->face);
247 	(void)DB_GetEntryColor (section, atomBody, &gfx->body);
248 	(void)DB_GetEntryColor (section, atomArmsLegs, &gfx->armsLegs);
249 	(void)DB_GetEntryColor (section, atomHandsFeet, &gfx->handsFeet);
250 	(void)DB_GetEntryColor (section, atomBackpack, &gfx->backpack);
251 	/* set white color */
252 	gfx->white = COLOR_WHITE;
253 	/* save original colors */
254 	gfx->bodySave = gfx->body;
255 	gfx->handsFeetSave = gfx->handsFeet;
256 	/* set team colors */
257 	if (teamColor != COLOR_INVALID) {
258 		/* KOEN */
259 		/* gfx->helmet    = teamColor; */
260 		gfx->body = teamColor;
261 		gfx->handsFeet = teamColor;
262 	}
263 	/* that's all */
264 	return XBTrue;
265 }								/* RetrievePlayerGraphics */
266 
267 /*
268  * retrieve indexed player graphics
269  */
270 XBBool
RetrievePlayerGraphics(CFGType cfgType,XBAtom atom,XBColor teamColor,CFGPlayerGraphics * gfx)271 RetrievePlayerGraphics (CFGType cfgType, XBAtom atom, XBColor teamColor, CFGPlayerGraphics * gfx)
272 {
273 	return RetrieveAnyPlayerGraphics (GetDB (cfgType), atom, teamColor, gfx);
274 }								/* RetrievePlayerGraphics */
275 
276 /*
277  * store a signle message
278  */
279 static void
StoreMessage(DBSection * section,XBAtom atom,const char * text)280 StoreMessage (DBSection * section, XBAtom atom, const char *text)
281 {
282 	if (NULL != text) {
283 		DB_CreateEntryString (section, atom, text);
284 	}
285 	else {
286 		DB_DeleteEntry (section, atom);
287 	}
288 }								/* StoreMessage */
289 
290 /*
291  *
292  */
293 static void
StoreAnyPlayerMessages(DBRoot * db,XBAtom atom,const CFGPlayerMessages * msg)294 StoreAnyPlayerMessages (DBRoot * db, XBAtom atom, const CFGPlayerMessages * msg)
295 {
296 	DBSection *section;
297 
298 	assert (db != NULL);
299 	assert (ATOM_INVALID != atom);
300 	assert (msg != NULL);
301 
302 	section = DB_CreateSection (db, atom);
303 	assert (section != NULL);
304 	/* messages */
305 	StoreMessage (section, atomMsgWinLevel, msg->msgWinLevel);
306 	StoreMessage (section, atomMsgWinGame, msg->msgWinGame);
307 	StoreMessage (section, atomMsgLoseLife, msg->msgLoseLife);
308 	StoreMessage (section, atomMsgLoseLevel, msg->msgLoseLevel);
309 	StoreMessage (section, atomMsgGloat, msg->msgGloat);
310 	StoreMessage (section, atomMsgLaola, msg->msgLaola);
311 	StoreMessage (section, atomMsgLoser, msg->msgLoser);
312 	StoreMessage (section, atomMsgWelcome, msg->msgWelcome);
313 }								/* StorePlayerMessages */
314 
315 /*
316  *
317  */
318 void
StorePlayerMessages(CFGType cfgType,XBAtom atom,const CFGPlayerMessages * msg)319 StorePlayerMessages (CFGType cfgType, XBAtom atom, const CFGPlayerMessages * msg)
320 {
321 	StoreAnyPlayerMessages (GetDB (cfgType), atom, msg);
322 }								/* StoreLocalPlayerMessages */
323 
324 /*
325  *
326  */
327 static XBBool
RetrieveAnyPlayerMessages(const DBRoot * db,XBAtom atom,CFGPlayerMessages * msg)328 RetrieveAnyPlayerMessages (const DBRoot * db, XBAtom atom, CFGPlayerMessages * msg)
329 {
330 	const DBSection *section;
331 
332 	assert (db != NULL);
333 	assert (msg != NULL);
334 	/* set to defaults */
335 	*msg = newMsg;
336 	/* find section for player */
337 	section = DB_GetSection (db, atom);
338 	if (NULL == section) {
339 		return XBFalse;
340 	}
341 	(void)DB_GetEntryString (section, atomMsgWinLevel, &msg->msgWinLevel);
342 	(void)DB_GetEntryString (section, atomMsgWinGame, &msg->msgWinGame);
343 	(void)DB_GetEntryString (section, atomMsgLoseLife, &msg->msgLoseLife);
344 	(void)DB_GetEntryString (section, atomMsgLoseLevel, &msg->msgLoseLevel);
345 	(void)DB_GetEntryString (section, atomMsgGloat, &msg->msgGloat);
346 	(void)DB_GetEntryString (section, atomMsgLaola, &msg->msgLaola);
347 	(void)DB_GetEntryString (section, atomMsgLoser, &msg->msgLoser);
348 	(void)DB_GetEntryString (section, atomMsgWelcome, &msg->msgWelcome);
349 	/* that's all */
350 	return XBTrue;
351 }								/* RetrievePlayerMessages */
352 
353 /*
354  * retrieve messages for local players
355  */
356 XBBool
RetrievePlayerMessages(CFGType cfgType,XBAtom atom,CFGPlayerMessages * msg)357 RetrievePlayerMessages (CFGType cfgType, XBAtom atom, CFGPlayerMessages * msg)
358 {
359 	return RetrieveAnyPlayerMessages (GetDB (cfgType), atom, msg);
360 }								/* RetrievePlayerMessages */
361 
362 /*
363  * store misc player options
364  */
365 static void
StoreAnyPlayerMisc(DBRoot * db,XBAtom atom,const CFGPlayerMisc * misc)366 StoreAnyPlayerMisc (DBRoot * db, XBAtom atom, const CFGPlayerMisc * misc)
367 {
368 	DBSection *section;
369 
370 	assert (db != NULL);
371 	assert (misc != NULL);
372 	assert (ATOM_INVALID != atom);
373 	section = DB_CreateSection (db, atom);
374 	assert (section != NULL);
375 	/* store data */
376 	DB_CreateEntryBool (section, atomUseStopKey, misc->useStopKey);
377 	DB_CreateEntryInt (section, atomTurnStepKeyboard, misc->turnStepKeyboard);
378 	DB_CreateEntryInt (section, atomTurnStepJoystick, misc->turnStepJoystick);
379 }								/* StorePlayerMisc */
380 
381 /*
382  * store misc player options
383  */
384 void
StorePlayerMisc(CFGType cfgType,XBAtom atom,const CFGPlayerMisc * misc)385 StorePlayerMisc (CFGType cfgType, XBAtom atom, const CFGPlayerMisc * misc)
386 {
387 	StoreAnyPlayerMisc (GetDB (cfgType), atom, misc);
388 }								/* StoreLocalPlayerMisc */
389 
390 /*
391  * retrive misc player data
392  */
393 static XBBool
RetrieveAnyPlayerMisc(const DBRoot * db,XBAtom atom,CFGPlayerMisc * misc)394 RetrieveAnyPlayerMisc (const DBRoot * db, XBAtom atom, CFGPlayerMisc * misc)
395 {
396 	const DBSection *section;
397 
398 	assert (db != NULL);
399 	assert (misc != NULL);
400 	/* set default values */
401 	*misc = newMisc;
402 	/* find section for player */
403 	section = DB_GetSection (db, atom);
404 	if (NULL == section) {
405 		return XBFalse;
406 	}
407 	/* store data */
408 	(void)DB_GetEntryBool (section, atomUseStopKey, &misc->useStopKey);
409 	(void)DB_GetEntryInt (section, atomTurnStepKeyboard, &misc->turnStepKeyboard);
410 	(void)DB_GetEntryInt (section, atomTurnStepJoystick, &misc->turnStepJoystick);
411 	return XBTrue;
412 }								/* RetrievePlayerMisc */
413 
414 /*
415  * retrieve misc player data
416  */
417 XBBool
RetrievePlayerMisc(CFGType cfgType,XBAtom atom,CFGPlayerMisc * misc)418 RetrievePlayerMisc (CFGType cfgType, XBAtom atom, CFGPlayerMisc * misc)
419 {
420 	return RetrieveAnyPlayerMisc (GetDB (cfgType), atom, misc);
421 }								/* RetrieveLocalPlayerMisc */
422 
423 /*
424  * save player config at once
425  */
426 void
StorePlayer(CFGType cfgType,XBAtom atom,const CFGPlayer * cfg)427 StorePlayer (CFGType cfgType, XBAtom atom, const CFGPlayer * cfg)
428 {
429 	assert (NULL != cfg);
430 
431 	StorePlayerGraphics (cfgType, atom, &cfg->graphics);
432 	StorePlayerMessages (cfgType, atom, &cfg->messages);
433 	StorePlayerMisc (cfgType, atom, &cfg->misc);
434 	StorePlayerID (cfgType, atom, &cfg->id);
435 	StorePlayerName (cfgType, atom, cfg->name);
436 }								/* StorePlayer */
437 
438 /*
439  * load player config at once
440  */
441 XBBool
RetrievePlayer(CFGType cfgType,XBAtom atom,XBColor color,CFGPlayer * cfg)442 RetrievePlayer (CFGType cfgType, XBAtom atom, XBColor color, CFGPlayer * cfg)
443 {
444 	XBBool result = XBTrue;
445 
446 	assert (NULL != cfg);
447 
448 	if (!RetrievePlayerGraphics (cfgType, atom, color, &cfg->graphics)) {
449 		result = XBFalse;
450 	}
451 	if (!RetrievePlayerMessages (cfgType, atom, &cfg->messages)) {
452 		result = XBFalse;
453 	}
454 	if (!RetrievePlayerMisc (cfgType, atom, &cfg->misc)) {
455 		result = XBFalse;
456 	}
457 	if (!RetrievePlayerID (cfgType, atom, &cfg->id)) {
458 		result = XBFalse;
459 	}
460 	cfg->name = GetPlayerName (cfgType, atom);
461 	return result;
462 }								/* RetrievePlayer */
463 
464 /*
465  * load player config at once
466  */
467 XBBool
RetrievePlayerEx(CFGType cfgType,XBAtom atom,CFGPlayerEx * cfg)468 RetrievePlayerEx (CFGType cfgType, XBAtom atom, CFGPlayerEx * cfg)
469 {
470 	XBBool result = XBTrue;
471 
472 	assert (NULL != cfg);
473 
474 	if (!RetrievePlayerGraphics (cfgType, atom, COLOR_INVALID, &cfg->graphics)) {
475 		result = XBFalse;
476 	}
477 	if (!RetrievePlayerMessages (cfgType, atom, &cfg->messages)) {
478 		result = XBFalse;
479 	}
480 	if (!RetrievePlayerMisc (cfgType, atom, &cfg->misc)) {
481 		result = XBFalse;
482 	}
483 	if (!RetrievePlayerID (cfgType, atom, &cfg->id)) {
484 		result = XBFalse;
485 	}
486 	if (!RetrievePlayerRating (cfgType, atom, &cfg->rating)) {
487 		result = XBFalse;
488 	}
489 	cfg->name = GetPlayerName (cfgType, atom);
490 	return result;
491 }								/* RetrievePlayerEx */
492 
493 /*
494  * XBCC save player EX config at once
495  */
496 void
StorePlayerEx(CFGType cfgType,XBAtom atom,const CFGPlayerEx * cfg)497 StorePlayerEx (CFGType cfgType, XBAtom atom, const CFGPlayerEx * cfg)
498 {
499 	assert (NULL != cfg);
500 
501 	StorePlayerGraphics (cfgType, atom, &cfg->graphics);
502 	StorePlayerMessages (cfgType, atom, &cfg->messages);
503 	StorePlayerMisc (cfgType, atom, &cfg->misc);
504 	StorePlayerID (cfgType, atom, &cfg->id);
505 	StorePlayerRating (cfgType, atom, &cfg->rating);
506 	StorePlayerName (cfgType, atom, cfg->name);
507 }								/* StorePlayerEx */
508 
509 /*
510  * init and load player config
511  */
512 void
LoadPlayerConfig(void)513 LoadPlayerConfig (void)
514 {
515 	int i;
516 	XBAtom atom;
517 
518 	/* set default values */
519 	newGfx.shape = GUI_StringToAtom ("normal");
520 	/* initialize remote databse */
521 	dbRemote = DB_Create (DT_Config, atomRemotePlayer);
522 	assert (dbRemote != NULL);
523 	/* initialiaze config database */
524 	dbLocal = DB_Create (DT_Config, atomPlayer);
525 	assert (dbLocal != NULL);
526 	Dbg_Config ("loading local player configs\n");
527 	if (DB_Load (dbLocal)) {
528 		return;
529 	}
530 	Dbg_Config ("failed to load player config, setting defaults\n");
531 	/* set some useful default values */
532 	for (i = 0; i < NUM_DEFAULT_PLAYERS; i++) {
533 		atom = GUI_StringToAtom (defaultName[i]);
534 		StorePlayerName (CT_Local, atom, defaultName[i]);
535 		StorePlayerGraphics (CT_Local, atom, DefaultPlayerGraphics (i));
536 		StorePlayerMisc (CT_Local, atom, &newMisc);
537 		StorePlayerMessages (CT_Local, atom, &newMsg);
538 		StorePlayerID (CT_Local, atom, &newID);
539 	}
540 	DB_Store (dbLocal);
541 }								/* InitPlayerConfig */
542 
543 /*
544  * finish player config
545  */
546 void
SavePlayerConfig(void)547 SavePlayerConfig (void)
548 {
549 	assert (dbLocal != NULL);
550 	if (DB_Changed (dbLocal)) {
551 		Dbg_Config ("saving local player configs\n");
552 		DB_Store (dbLocal);
553 	}
554 #ifdef DEBUG
555 	assert (dbRemote != NULL);
556 	if (DB_Changed (dbRemote)) {
557 		Dbg_Config ("saving remote player configs\n");
558 		DB_Store (dbRemote);
559 	}
560 #endif
561 }								/* SavePlayerConfig */
562 
563 /*
564  *
565  */
566 void
FinishPlayerConfig(void)567 FinishPlayerConfig (void)
568 {
569 	if (NULL != dbLocal) {
570 		DB_Delete (dbLocal);
571 		dbLocal = NULL;
572 	}
573 	if (NULL != dbRemote) {
574 		DB_Delete (dbRemote);
575 		dbRemote = NULL;
576 	}
577 	Dbg_Config ("player configs cleared\n");
578 }								/* FinishPlayerConfig */
579 
580 /*
581  * XBCC init and load player central statistics
582  */
583 void
LoadPlayerCentral(XBBool amCentral)584 LoadPlayerCentral (XBBool amCentral)
585 {
586 	XBAtom atom;
587 	isCentral = amCentral;
588 
589 	/* set default values */
590 	newGfx.shape = GUI_StringToAtom ("normal");
591 	if (amCentral) {
592 		/* initialiaze config database */
593 		dbCentral = DB_Create (DT_Central, atomCentralLocal);
594 	}
595 	else {
596 		/* initialize remote databse */
597 		dbCentral = DB_Create (DT_Central, atomCentralRemote);
598 	}
599 	assert (dbCentral != NULL);
600 	if (DB_Load (dbCentral)) {
601 		return;
602 	}
603 	/* set administrator defaults */
604 	if (amCentral) {
605 		atom = GUI_IntToAtom (administratorID.PID);
606 		StorePlayerName (CT_Central, atom, administratorName);
607 		StorePlayerGraphics (CT_Central, atom, AdministratorPlayerGraphics ());
608 		StorePlayerMisc (CT_Central, atom, &administratorMisc);
609 		StorePlayerMessages (CT_Central, atom, &administratorMsg);
610 		StorePlayerID (CT_Central, atom, &administratorID);
611 		StorePlayerRating (CT_Central, atom, &newRating);
612 	}
613 	DB_Store (dbCentral);
614 }								/* InitPlayerConfig */
615 
616 /*
617  * finish player config
618  */
619 void
SavePlayerCentral(void)620 SavePlayerCentral (void)
621 {
622 	assert (dbCentral != NULL);
623 	if (DB_Changed (dbCentral)) {
624 		DB_Store (dbCentral);
625 	}
626 }								/* SavePlayerConfig */
627 
628 /*
629  *
630  */
631 void
FinishPlayerCentral(void)632 FinishPlayerCentral (void)
633 {
634 	if (NULL != dbCentral) {
635 		DB_Delete (dbCentral);
636 		dbCentral = NULL;
637 	}
638 }								/* FinishPlayerCentral */
639 
640 void
RemoveAllPlayers(CFGType cfgType)641 RemoveAllPlayers (CFGType cfgType)
642 {
643 	DB_DeleteAll (GetDB (cfgType));
644 }
645 
646 /*
647  * get number of configs stored
648  */
649 int
GetNumPlayerConfigs(CFGType cfgType)650 GetNumPlayerConfigs (CFGType cfgType)
651 {
652 	return DB_NumSections (GetDB (cfgType));
653 }								/* GetNumPlayerConfigs */
654 
655 /*
656  * index atoms for player config
657  */
658 XBAtom
GetPlayerAtom(CFGType cfgType,int i)659 GetPlayerAtom (CFGType cfgType, int i)
660 {
661 	return DB_IndexSection (GetDB (cfgType), i);
662 }								/* GetPlayerConfigName */
663 
664 /*
665  * get name of player
666  */
667 static const char *
GetAnyPlayerName(DBRoot * db,XBAtom atom)668 GetAnyPlayerName (DBRoot * db, XBAtom atom)
669 {
670 	const DBSection *section;
671 	const char *s;
672 
673 	assert (NULL != db);
674   /*---*/
675 	section = DB_GetSection (db, atom);
676 	if (NULL == section) {
677 		return NULL;
678 	}
679 	while (!DB_GetEntryString (section, atomName, &s)) {
680 		const char *name = GUI_AtomToString (atom);
681 		DB_CreateEntryString (DB_CreateSection (db, atom), atomName, name);
682 	}
683 	return s;
684 }								/* GetPlayerName */
685 
686 /*
687  * get name of player
688  */
689 const char *
GetPlayerName(CFGType cfgType,XBAtom atom)690 GetPlayerName (CFGType cfgType, XBAtom atom)
691 {
692 	return GetAnyPlayerName (GetDB (cfgType), atom);
693 }								/* GetLocalPlayerName */
694 
695 /*
696  * search player names for newplayer name
697  */
698 int
FindDoubleName(CFGType cfgType,XBAtom newplayer)699 FindDoubleName (CFGType cfgType, XBAtom newplayer)
700 {
701 	XBAtom atom;
702 	const char *cmp;
703 	int j;
704 	cmp = GetPlayerName (cfgType, newplayer);
705 	for (j = 0; j < GetNumPlayerConfigs (cfgType); j++) {
706 		atom = GetPlayerAtom (cfgType, j);
707 		if (atom != newplayer) {
708 			if (0 == strcmp (cmp, GetPlayerName (cfgType, atom))) {
709 				return (j);
710 			}
711 		}
712 	}
713 	return (-1);
714 }								/* FindDoubleName */
715 
716 /*
717  * XBCC
718  */
719 static void
StoreAnyPlayerID(DBRoot * db,XBAtom atom,const CFGPlayerID * id)720 StoreAnyPlayerID (DBRoot * db, XBAtom atom, const CFGPlayerID * id)
721 {
722 	DBSection *section;
723 
724 	assert (db != NULL);
725 	assert (id != NULL);
726 	assert (ATOM_INVALID != atom);
727 
728 	section = DB_CreateSection (db, atom);
729 	assert (section != NULL);
730 	/* graphics */
731 	StoreMessage (section, atomPass, id->pass);
732 	(void)DB_CreateEntryInt (section, atomPID, id->PID);
733 }								/* StorePlayerGraphics */
734 
735 /*
736  *
737  */
738 void
StorePlayerID(CFGType cfgType,XBAtom atom,const CFGPlayerID * id)739 StorePlayerID (CFGType cfgType, XBAtom atom, const CFGPlayerID * id)
740 {
741 	StoreAnyPlayerID (GetDB (cfgType), atom, id);
742 }								/* StoreLocalPlayerGraphics */
743 
744 /*
745  *
746  */
747 static XBBool
RetrieveAnyPlayerID(const DBRoot * db,XBAtom atom,CFGPlayerID * id)748 RetrieveAnyPlayerID (const DBRoot * db, XBAtom atom, CFGPlayerID * id)
749 {
750 	const DBSection *section;
751 
752 	assert (db != NULL);
753 	assert (id != NULL);
754 	/* set to defaults */
755 	*id = newID;
756 	/* find section for player */
757 	section = DB_GetSection (db, atom);
758 	if (NULL == section) {
759 		return XBFalse;
760 	}
761 	/* set default PID to invalid */
762 	id->PID = -1;
763 	(void)DB_GetEntryString (section, atomPass, &id->pass);
764 	(void)DB_GetEntryInt (section, atomPID, &id->PID);
765 	/* that's all */
766 	return XBTrue;
767 }								/* RetrievePlayerMessages */
768 
769 /*
770  * retrieve messages for local players
771  */
772 XBBool
RetrievePlayerID(CFGType cfgType,XBAtom atom,CFGPlayerID * id)773 RetrievePlayerID (CFGType cfgType, XBAtom atom, CFGPlayerID * id)
774 {
775 	return RetrieveAnyPlayerID (GetDB (cfgType), atom, id);
776 }								/* RetrievePlayerMessages */
777 
778 /*
779  * XBCC rating
780  */
781 static void
StoreAnyPlayerRating(DBRoot * db,XBAtom atom,const CFGPlayerRating * rating)782 StoreAnyPlayerRating (DBRoot * db, XBAtom atom, const CFGPlayerRating * rating)
783 {
784 	DBSection *section;
785 
786 	assert (db != NULL);
787 	assert (rating != NULL);
788 	assert (ATOM_INVALID != atom);
789 
790 	section = DB_CreateSection (db, atom);
791 	assert (section != NULL);
792 	/* graphics */
793 	(void)DB_CreateEntryFloat (section, atomXBCCRating, rating->rating);
794 	(void)DB_CreateEntryInt (section, atomXBCCGamesPlayed, rating->gamesPlayed);
795 	(void)DB_CreateEntryInt (section, atomXBCCRealWins, rating->realWins);
796 	(void)DB_CreateEntryInt (section, atomXBCCRelativeWins, rating->relativeWins);
797 	(void)DB_CreateEntryTime (section, atomXBCCTimeUpdate, rating->timeUpdate);
798 	(void)DB_CreateEntryTime (section, atomXBCCTimeRegister, rating->timeRegister);
799 }								/* StorePlayerRating */
800 
801 /*
802  *
803  */
804 void
StorePlayerRating(CFGType cfgType,XBAtom atom,const CFGPlayerRating * rating)805 StorePlayerRating (CFGType cfgType, XBAtom atom, const CFGPlayerRating * rating)
806 {
807 	StoreAnyPlayerRating (GetDB (cfgType), atom, rating);
808 }								/* StoreLocalPlayerRating */
809 
810 /*
811  *
812  */
813 static XBBool
RetrieveAnyPlayerRating(const DBRoot * db,XBAtom atom,CFGPlayerRating * rating)814 RetrieveAnyPlayerRating (const DBRoot * db, XBAtom atom, CFGPlayerRating * rating)
815 {
816 	const DBSection *section;
817 
818 	assert (db != NULL);
819 	assert (rating != NULL);
820 	/* set to defaults */
821 	*rating = newRating;
822 	/* find section for player */
823 	section = DB_GetSection (db, atom);
824 	if (NULL == section) {
825 		return XBFalse;
826 	}
827 	(void)DB_GetEntryFloat (section, atomXBCCRating, &rating->rating);
828 	(void)DB_GetEntryInt (section, atomXBCCGamesPlayed, &rating->gamesPlayed);
829 	(void)DB_GetEntryInt (section, atomXBCCRealWins, &rating->realWins);
830 	(void)DB_GetEntryInt (section, atomXBCCRelativeWins, &rating->relativeWins);
831 	(void)DB_GetEntryTime (section, atomXBCCTimeUpdate, &rating->timeUpdate);
832 	(void)DB_GetEntryTime (section, atomXBCCTimeRegister, &rating->timeRegister);
833 	/* that's all */
834 	return XBTrue;
835 }								/* RetrievePlayerRating */
836 
837 /*
838  * retrieve messages for local players
839  */
840 XBBool
RetrievePlayerRating(CFGType cfgType,XBAtom atom,CFGPlayerRating * rating)841 RetrievePlayerRating (CFGType cfgType, XBAtom atom, CFGPlayerRating * rating)
842 {
843 	return RetrieveAnyPlayerRating (GetDB (cfgType), atom, rating);
844 }								/* RetrievePlayerRating */
845 
846 /* XBCC */
847 
848 /*
849  * delete a new player
850  */
851 void
DeletePlayerConfig(CFGType cfgType,XBAtom atom)852 DeletePlayerConfig (CFGType cfgType, XBAtom atom)
853 {
854 	DB_DeleteSection (GetDB (cfgType), atom);
855 }								/* DeletePlayerConfig */
856 
857 /*
858  * create new player config
859  */
860 static XBAtom
CreatePlayerConfig(CFGType cfgType,const char * name,const CFGPlayerGraphics * cfgGfx,const CFGPlayerMessages * cfgMsg,const CFGPlayerMisc * cfgMisc,const CFGPlayerID * cfgID)861 CreatePlayerConfig (CFGType cfgType, const char *name, const CFGPlayerGraphics * cfgGfx,
862 					const CFGPlayerMessages * cfgMsg, const CFGPlayerMisc * cfgMisc,
863 					const CFGPlayerID * cfgID)
864 {
865 	XBAtom atom;
866 
867 	/* sanity checks */
868 	assert (NULL != name);
869 	assert (NULL != cfgGfx);
870 	assert (NULL != cfgMsg);
871 	assert (NULL != cfgMisc);
872 	assert (NULL != cfgID);
873 	/* convert name to atom */
874 	atom = GUI_StringToAtom (name);
875 	assert (ATOM_INVALID != atom);
876 	/* look for config with the same name */
877 	if (NULL != GetPlayerName (cfgType, atom) || strlen (name) == 0) {
878 		return ATOM_INVALID;
879 	}
880 	/* create new dataset */
881 	StorePlayerName (cfgType, atom, name);
882 	StorePlayerGraphics (cfgType, atom, cfgGfx);
883 	StorePlayerMessages (cfgType, atom, cfgMsg);
884 	StorePlayerMisc (cfgType, atom, cfgMisc);
885 	StorePlayerID (cfgType, atom, cfgID);
886 	/* that's all */
887 	return atom;
888 }								/* CopyPlayerConfig */
889 
890 /*
891  * create a new player
892  */
893 XBAtom
CreateNewPlayerConfig(CFGType cfgType,const char * name)894 CreateNewPlayerConfig (CFGType cfgType, const char *name)
895 {
896 	CFGPlayerGraphics cfgGfx = newGfx;
897 
898 	/* use random colors */
899 	cfgGfx.helmet = RandomColor ();
900 	cfgGfx.body = RandomColor ();
901 	cfgGfx.handsFeet = RandomColor ();
902 	cfgGfx.armsLegs = RandomColor ();
903 	cfgGfx.backpack = RandomColor ();
904 
905 	return CreatePlayerConfig (cfgType, name, &cfgGfx, &newMsg, &newMisc, &newID);
906 }								/* CreatePlayerConfig */
907 
908 /*
909  * rename existing player
910  */
911 XBAtom
RenamePlayerConfig(CFGType cfgType,XBAtom atom,const char * name)912 RenamePlayerConfig (CFGType cfgType, XBAtom atom, const char *name)
913 {
914 	CFGPlayer cfgPlayer;
915 	XBAtom newAtom;
916 
917 	/* sanity check */
918 	assert (atom != ATOM_INVALID);
919 	assert (name != NULL);
920 	/* retrieve existing player configs */
921 	(void)RetrievePlayer (cfgType, atom, COLOR_INVALID, &cfgPlayer);
922 	/* create new player with it */
923 	newAtom =
924 		CreatePlayerConfig (cfgType, name, &cfgPlayer.graphics, &cfgPlayer.messages,
925 							&cfgPlayer.misc, &cfgPlayer.id);
926 	if (newAtom != atom) {
927 		if (newAtom != ATOM_INVALID) {
928 			/* if successful, delete old entry */
929 			DB_DeleteSection (dbLocal, atom);
930 		}
931 		return newAtom;
932 	}
933 	return atom;
934 }								/* RenameLocalPlayerConfig */
935 
936 /*
937  * compare to graphics sets
938  */
939 XBBool
ComparePlayerGraphics(const CFGPlayerGraphics * a,const CFGPlayerGraphics * b)940 ComparePlayerGraphics (const CFGPlayerGraphics * a, const CFGPlayerGraphics * b)
941 {
942 	assert (a != NULL);
943 	assert (b != NULL);
944 	return (a->shape == b->shape &&
945 			a->helmet == b->helmet &&
946 			a->face == b->face &&
947 			a->body == b->body &&
948 			a->handsFeet == b->handsFeet &&
949 			a->armsLegs == b->armsLegs && a->backpack == b->backpack);
950 }								/* ComparePlayerGraphics */
951 
952 /*
953  * put player config into telegram send queue
954  */
955 static XBBool
SendAnyPlayerConfig(const DBRoot * db,XBSndQueue * queue,XBTeleCOT cot,XBTeleIOB iob,XBAtom atom,XBBool toCentral)956 SendAnyPlayerConfig (const DBRoot * db, XBSndQueue * queue, XBTeleCOT cot, XBTeleIOB iob,
957 					 XBAtom atom, XBBool toCentral)
958 {
959 	const DBSection *section;
960 	int i, k, l;
961 	size_t len;
962 	XBTelegram *tele;
963 	char tmp[256];
964 	char pass[256];
965 
966 	assert (db != NULL);
967 	assert (queue != NULL);
968 	/* get section with player data */
969 	section = DB_GetSection (db, atom);
970 	if (NULL == section) {
971 		return XBFalse;
972 	}
973 	/* now print and send data */
974 	i = 0;
975 	l = sprintf (pass, "%s", GUI_AtomToString (atomPass));	// XBCC
976 	while (0 < (len = DB_PrintEntry (tmp, section, i))) {
977 		k = strncmp (pass, tmp, l) == 0;
978 		if ((k && toCentral) || !k) {	// XBCC only send password to central
979 			tele = Net_CreateTelegram (cot, XBT_ID_PlayerConfig, iob, tmp, len + 1);
980 			assert (tele != NULL);
981 			Net_SendTelegram (queue, tele);
982 		}
983 		i++;
984 	}
985 	/* no data means end of section */
986 	tele = Net_CreateTelegram (cot, XBT_ID_PlayerConfig, iob, NULL, 0);
987 	assert (tele != NULL);
988 	Net_SendTelegram (queue, tele);
989 	return XBTrue;
990 }								/* SendAnyPlayerConfig */
991 
992 /*
993  * put player config into telegram send queue
994  */
995 XBBool
SendPlayerConfig(CFGType cfgType,XBSndQueue * queue,XBTeleCOT cot,XBTeleIOB iob,XBAtom atom,XBBool toCentral)996 SendPlayerConfig (CFGType cfgType, XBSndQueue * queue, XBTeleCOT cot, XBTeleIOB iob, XBAtom atom,
997 				  XBBool toCentral)
998 {
999 	return SendAnyPlayerConfig (GetDB (cfgType), queue, cot, iob, atom, toCentral);
1000 }								/* SendLocalPlayerConfig */
1001 
1002 /*
1003  * add entry line to player config
1004  */
1005 void
AddToPlayerConfig(CFGType cfgType,XBAtom atom,const char * line)1006 AddToPlayerConfig (CFGType cfgType, XBAtom atom, const char *line)
1007 {
1008 	DBRoot *db;
1009 	DBSection *section;
1010 
1011 	/* sanity check */
1012 	assert (ATOM_INVALID != atom);
1013 	/* get database */
1014 	db = GetDB (cfgType);
1015 	assert (NULL != db);
1016 	/* create new player section */
1017 	section = DB_CreateSection (db, atom);
1018 	assert (NULL != section);
1019 	/* add line */
1020 	(void)DB_ParseEntry (section, line);
1021 }								/* AddToPlayerConfig */
1022 
1023 /*
1024  * XBST Store game results
1025  */
1026 static void
StoreAnyGameResult(DBRoot * db,XBAtom atom,int k,int * regPl,int * PID,int * Score)1027 StoreAnyGameResult (DBRoot * db, XBAtom atom, int k, int *regPl, int *PID, int *Score)	// XBST
1028 {
1029 	DBSection *section;
1030 	int i, j;
1031 
1032 	assert (db != NULL);
1033 	assert (PID != NULL);
1034 	assert (Score != NULL);
1035 	assert (ATOM_INVALID != atom);
1036 
1037 	section = DB_CreateSection (db, atom);
1038 	assert (section != NULL);
1039 	for (i = 0; i < k; i++) {
1040 		j = regPl[i];
1041 		(void)DB_CreateEntryGameResult (section, GUI_IntToAtom (PID[j]), abs (Score[j]));
1042 	}
1043 }								/* StorePlayerRating */
1044 
1045 /*
1046  * store game result in database
1047  */
1048 void
StoreGameResult(CFGType cfgType,XBAtom atom,int k,int * regPl,int * PID,int * Score)1049 StoreGameResult (CFGType cfgType, XBAtom atom, int k, int *regPl, int *PID, int *Score)
1050 {								// XBST
1051 	StoreAnyGameResult (GetDB (cfgType), atom, k, regPl, PID, Score);
1052 }								/* StoreGameResult */
1053 
1054 /*
1055  * store game result, append to file and delete in database
1056  */
1057 void
AppendGameResult(CFGType cfgType,XBAtom fname,XBAtom atom,int k,int * regPl,int * PID,int * Score)1058 AppendGameResult (CFGType cfgType, XBAtom fname, XBAtom atom, int k, int *regPl, int *PID,
1059 				  int *Score)
1060 {								/*  XBST */
1061 	DBRoot *res;
1062 	res = DB_Create (cfgType, fname);
1063 	assert (res != NULL);
1064 	StoreAnyGameResult (res, atom, k, regPl, PID, Score);
1065 	DB_Append (res);
1066 	DB_Delete (res);
1067 }								/* AppendGameResult */
1068 
1069 static void
StoreAnyTimePlayerRating(DBRoot * db,XBAtom atom,int k,int * regPl,int * PID,float * rating)1070 StoreAnyTimePlayerRating (DBRoot * db, XBAtom atom, int k, int *regPl, int *PID, float *rating)	// XBST
1071 {
1072 	DBSection *section;
1073 	int i, j;
1074 
1075 	assert (db != NULL);
1076 	assert (PID != NULL);
1077 	assert (rating != NULL);
1078 	assert (ATOM_INVALID != atom);
1079 
1080 	section = DB_CreateSection (db, atom);
1081 	assert (section != NULL);
1082 	for (i = 0; i < k; i++) {
1083 		j = regPl[i];
1084 		(void)DB_CreateEntryFloat (section, GUI_IntToAtom (PID[j]), rating[j]);
1085 	}
1086 }								/* StorePlayerRating */
1087 
1088 /*
1089  * store timed player rating to database
1090  */
1091 void
StoreTimePlayerRating(CFGType cfgType,XBAtom atom,int k,int * regPl,int * PID,float * rating)1092 StoreTimePlayerRating (CFGType cfgType, XBAtom atom, int k, int *regPl, int *PID, float *rating)
1093 {								// XBST
1094 	StoreAnyTimePlayerRating (GetDB (cfgType), atom, k, regPl, PID, rating);
1095 }								/* StoreGameResult */
1096 
1097 /*
1098  * store timed player rating, append to file and delete in database
1099  */
1100 void
AppendTimePlayerRating(CFGType cfgType,XBAtom fname,XBAtom atom,int k,int * regPl,int * PID,float * rating)1101 AppendTimePlayerRating (CFGType cfgType, XBAtom fname, XBAtom atom, int k, int *regPl, int *PID,
1102 						float *rating)
1103 {								/*  XBST */
1104 	DBRoot *res;
1105 	res = DB_Create (cfgType, fname);
1106 	assert (res != NULL);
1107 	StoreAnyTimePlayerRating (res, atom, k, regPl, PID, rating);
1108 	DB_Append (res);
1109 	DB_Delete (res);
1110 }								/* StoreGameResult */
1111 
1112 /*
1113  * end of file cfg_player.c
1114  */
1115