Crossfire Server, Branches 1.12  R18729
init.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_init_c =
3  * "$Id: init.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
34 #define EXTERN
35 #define INIT_C
36 #include <global.h>
37 #include <object.h>
38 
39 static void init_environ(void);
40 static void init_defaults(void);
41 static void init_dynamic(void);
42 static void init_clocks(void);
43 static void init_attackmess(void);
44 
48 struct Settings settings = {
49  LOGFILE, /* Logfile */
50  CSPORT, /* Client/server port */
51 
52  /* Debug level */
53 #ifdef DEBUG
54  llevDebug,
55 #else
56  llevInfo,
57 #endif
58  0, NULL, 0, /* dumpvalues, dumparg, daemonmode */
59  0, /* argc */
60  NULL, /* argv */
61  CONFDIR,
62  DATADIR,
63  LOCALDIR,
66  TMPDIR,
74  SIMPLE_EXP,
76  SET_TITLE,
82  REAL_WIZ,
87  "", /* Who format specifier */
88  "", /* who wiz format specifier */
89  MOTD,
90  "rules",
91  "news",
92  "", /* DM_MAIL */
93  0, /* This and the next 3 values are metaserver values */
94  "",
95  "",
96  0,
97  "",
98  0, 0, 0, 0, 0, 0, 0, /* worldmap settings*/
100  0,
101  1.0,
102  /* Armor enchantment stuff */
108  1, /* no_player_stealing */
109  0, /* create_home_portals */
110  1, /* personalized_blessings */
111  5000000, /* pk_max_experience */
112  10, /* pk_max_experience_percent */
113  0, /* allow_denied_spells_writing */
114  0, /* allow_broken_converters */
115  0, /* log_timestamp */
116  NULL, /* log_timestamp_format */
117 };
118 
120 
126 const char *const spellpathnames[NRSPELLPATHS] = {
127  "Protection",
128  "Fire",
129  "Frost",
130  "Electricity",
131  "Missiles",
132  "Self",
133  "Summoning",
134  "Abjuration",
135  "Restoration",
136  "Detonation",
137  "Mind",
138  "Creation",
139  "Teleportation",
140  "Information",
141  "Transmutation",
142  "Transferrence",
143  "Turning",
144  "Wounding",
145  "Death",
146  "Light"
147 };
148 
149 
161 static void init_emergency_mappath(void) {
162  char filename[MAX_BUF], tmpbuf[MAX_BUF];
163  FILE *fp;
164  int online = 0;
165 
166  /* If this file doesn't exist, not a big deal */
167  snprintf(filename, sizeof(filename), "%s/%s/.emergency", settings.datadir, settings.mapdir);
168  if ((fp = fopen(filename, "r")) != NULL) {
169  while (fgets(tmpbuf, MAX_BUF-1, fp)) {
170  if (tmpbuf[0] == '#')
171  continue; /* ignore comments */
172 
173  if (online == 0) {
174  tmpbuf[strlen(tmpbuf)-1] = 0; /* kill newline */
175  settings.emergency_mapname = strdup_local(tmpbuf);
176  } else if (online == 1) {
177  settings.emergency_x = atoi(tmpbuf);
178  } else if (online == 2) {
179  settings.emergency_y = atoi(tmpbuf);
180  }
181  online++;
182  if (online > 2)
183  break;
184  }
185  fclose(fp);
186  if (online <= 2)
187  LOG(llevError, "Online read partial data from %s\n", filename);
188  LOG(llevDebug, "Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname, settings.emergency_x, settings.emergency_y);
189  }
190 }
191 
192 
201 void init_library(void) {
202  init_environ();
203  init_globals();
204  init_hash_table();
205  i18n_init();
206  init_objects();
207  init_vars();
208  init_block();
209  read_bmap_names();
210  read_smooth();
211  init_anim(); /* Must be after we read in the bitmaps */
212  init_archetypes(); /* Reads all archetypes from file */
213  init_attackmess();
214  init_clocks();
216  init_experience();
217  init_dynamic();
218 }
219 
225 static void init_environ(void) {
226  char *cp;
227 
228  cp = getenv("CROSSFIRE_LIBDIR");
229  if (cp)
230  settings.datadir = cp;
231  cp = getenv("CROSSFIRE_LOCALDIR");
232  if (cp)
233  settings.localdir = cp;
234  cp = getenv("CROSSFIRE_PLAYERDIR");
235  if (cp)
236  settings.playerdir = cp;
237  cp = getenv("CROSSFIRE_MAPDIR");
238  if (cp)
239  settings.mapdir = cp;
240  cp = getenv("CROSSFIRE_ARCHETYPES");
241  if (cp)
242  settings.archetypes = cp;
243  cp = getenv("CROSSFIRE_TREASURES");
244  if (cp)
245  settings.treasures = cp;
246  cp = getenv("CROSSFIRE_UNIQUEDIR");
247  if (cp)
248  settings.uniquedir = cp;
249  cp = getenv("CROSSFIRE_TEMPLATEDIR");
250  if (cp)
251  settings.templatedir = cp;
252  cp = getenv("CROSSFIRE_TMPDIR");
253  if (cp)
254  settings.tmpdir = cp;
255 }
256 
263 void init_globals(void) {
264 
265  memset(&statistics, 0, sizeof(struct Statistics));
266  if (settings.logfilename[0] == 0) {
267  logfile = stderr;
268  } else if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
269  fprintf(stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
270  logfile = stderr;
271  } else {
272  setvbuf(logfile, NULL, _IOLBF, 0);
273  }
274  exiting = 0;
275  first_player = NULL;
276  first_friendly_object = NULL;
277  first_map = NULL;
278  first_treasurelist = NULL;
279  first_artifactlist = NULL;
280  first_archetype = NULL;
281  *first_map_ext_path = 0;
282  warn_archetypes = 0;
283  nroftreasures = 0;
284  nrofartifacts = 0;
285  nrofallowedstr = 0;
286  ring_arch = NULL;
287  amulet_arch = NULL;
288  staff_arch = NULL;
289  undead_name = add_string("undead");
291  num_animations = 0;
292  animations = NULL;
294  init_defaults();
295 }
296 
307 void free_globals(void) {
308  int msg, attack;
309  objectlink *friend;
310  region *reg;
311 
313  for (msg = 0; msg < NROFATTACKMESS; msg++)
314  for (attack = 0; attack < MAXATTACKMESS; attack++) {
315  free(attack_mess[msg][attack].buf1);
316  free(attack_mess[msg][attack].buf2);
317  free(attack_mess[msg][attack].buf3);
318  }
319 
320  free(settings.emergency_mapname);
321 
322  while (first_friendly_object) {
323  friend = first_friendly_object->next;
325  first_friendly_object = friend;
326  }
327 
328  free_experience();
329 
330  while (first_region) {
331  reg = first_region->next;
338  first_region = reg;
339  }
340 }
341 
347 void init_objects(void) {
348  int i;
349  /* Initialize all objects: */
350  objects = NULL;
351  active_objects = NULL;
352 
353 #ifdef MEMORY_DEBUG
354  free_objects = NULL;
355 #else
357  objarray[0].prev = NULL,
358  objarray[0].next = &objarray[1],
361  for (i = 1; i < STARTMAX-1; i++) {
362  objarray[i].next = &objarray[i+1];
363  objarray[i].prev = &objarray[i-1];
366  }
367  objarray[STARTMAX-1].next = NULL;
368  objarray[STARTMAX-1].prev = &objarray[STARTMAX-2];
369  SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
370  SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
371 #endif
372 }
373 
378 static void init_defaults(void) {
379  nroferrors = 0;
380 }
381 
390 static void init_dynamic(void) {
392  while (at) {
393  if (at->clone.type == MAP) {
394  if (at->clone.race) {
395  strcpy(first_map_ext_path, at->clone.race);
396  }
397  if (EXIT_PATH(&at->clone)) {
398  mapstruct *first;
399 
400  snprintf(first_map_path, sizeof(first_map_path), "%s", EXIT_PATH(&at->clone));
401  first = ready_map_name(first_map_path, 0);
402  if (!first) {
403  LOG(llevError, "Initial map %s can't be found! Please ensure maps are correctly installed.\n", first_map_path);
404  LOG(llevError, "Unable to continue without initial map.\n");
405  abort();
406  }
407  delete_map(first);
408  return;
409  }
410  }
411  at = at->next;
412  }
413  LOG(llevError, "You need a archetype called 'map' and it have to contain start map\n");
414  exit(-1);
415 }
416 
418 unsigned long todtick;
419 
424 void write_todclock(void) {
425  char filename[MAX_BUF];
426  FILE *fp;
427 
428  snprintf(filename, sizeof(filename), "%s/clockdata", settings.localdir);
429  if ((fp = fopen(filename, "w")) == NULL) {
430  LOG(llevError, "Cannot open %s for writing\n", filename);
431  return;
432  }
433  fprintf(fp, "%lu", todtick);
434  fclose(fp);
435 }
436 
441 static void init_clocks(void) {
442  char filename[MAX_BUF];
443  FILE *fp;
444  static int has_been_done = 0;
445 
446  if (has_been_done)
447  return;
448  else
449  has_been_done = 1;
450 
451  snprintf(filename, sizeof(filename), "%s/clockdata", settings.localdir);
452  LOG(llevDebug, "Reading clockdata from %s...\n", filename);
453  if ((fp = fopen(filename, "r")) == NULL) {
454  LOG(llevError, "Can't open %s.\n", filename);
455  todtick = 0;
456  write_todclock();
457  return;
458  }
459  fscanf(fp, "%lu", &todtick);
460  LOG(llevDebug, "todtick=%lu\n", todtick);
461  fclose(fp);
462 }
463 
466 
473 static void init_attackmess(void) {
474  char buf[MAX_BUF];
475  char filename[MAX_BUF];
476  char *cp, *p;
477  FILE *fp;
478  static int has_been_done = 0;
479  int mess, level, comp;
480  int mode = 0, total = 0;
481 
482  if (has_been_done)
483  return;
484  else
485  has_been_done = 1;
486 
487  snprintf(filename, sizeof(filename), "%s/attackmess", settings.datadir);
488  LOG(llevDebug, "Reading attack messages from %s...\n", filename);
489  if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
490  LOG(llevError, "Can't open %s.\n", filename);
491  return;
492  }
493 
494  level = 0;
495  while (fgets(buf, MAX_BUF, fp) != NULL) {
496  if (*buf == '#')
497  continue;
498  if ((cp = strchr(buf, '\n')) != NULL)
499  *cp = '\0';
500  cp = buf;
501  while (*cp == ' ') /* Skip blanks */
502  cp++;
503 
504  if (strncmp(cp, "TYPE:", 5) == 0) {
505  p = strtok(buf, ":");
506  p = strtok(NULL, ":");
507  if (mode == 1) {
508  attack_mess[mess][level].level = -1;
509  attack_mess[mess][level].buf1 = NULL;
510  attack_mess[mess][level].buf2 = NULL;
511  attack_mess[mess][level].buf3 = NULL;
512  }
513  level = 0;
514  mess = atoi(p);
515  mode = 1;
516  continue;
517  }
518  if (mode == 1) {
519  p = strtok(buf, "=");
520  attack_mess[mess][level].level = atoi(buf);
521  p = strtok(NULL, "=");
522  if (p != NULL)
523  attack_mess[mess][level].buf1 = strdup_local(p);
524  else
525  attack_mess[mess][level].buf1 = strdup_local("");
526  mode = 2;
527  continue;
528  } else if (mode == 2) {
529  p = strtok(buf, "=");
530  attack_mess[mess][level].level = atoi(buf);
531  p = strtok(NULL, "=");
532  if (p != NULL)
533  attack_mess[mess][level].buf2 = strdup_local(p);
534  else
535  attack_mess[mess][level].buf2 = strdup_local("");
536  mode = 3;
537  continue;
538  } else if (mode == 3) {
539  p = strtok(buf, "=");
540  attack_mess[mess][level].level = atoi(buf);
541  p = strtok(NULL, "=");
542  if (p != NULL)
543  attack_mess[mess][level].buf3 = strdup_local(p);
544  else
545  attack_mess[mess][level].buf3 = strdup_local("");
546  mode = 1;
547  level++;
548  total++;
549  continue;
550  }
551  }
552  LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
553  close_and_delete(fp, comp);
554 }
EXTERN FILE * logfile
Definition: global.h:220
#define RESURRECTION
Definition: config.h:135
#define EXPLORE_MODE
Definition: config.h:138
#define STAT_LOSS_ON_DEATH
Definition: config.h:139
#define SPELL_FAILURE_EFFECTS
Definition: config.h:132
uint16 emergency_y
Definition: global.h:389
#define BALANCED_STAT_LOSS
Definition: config.h:124
#define SPELLPOINT_LEVEL_DEPEND
Definition: config.h:130
void init_anim(void)
Definition: anim.c:55
struct Statistics statistics
Definition: init.c:119
Definition: object.h:298
const char * race
Definition: object.h:171
void init_block(void)
Definition: los.c:102
uint16 emergency_x
Definition: global.h:389
#define TEMPLATE_DIR
Definition: config.h:583
#define DEATH_PENALTY_RATIO
Definition: config.h:126
#define SET_FLAG(xyz, p)
Definition: define.h:510
int level
Definition: attack.h:147
attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS]
Definition: init.c:465
#define SEARCH_ITEMS
Definition: config.h:136
EXTERN int num_animations
Definition: global.h:242
EXTERN objectlink * first_friendly_object
Definition: global.h:196
#define PERMANENT_EXPERIENCE_RATIO
Definition: config.h:125
#define ARMOR_SPEED_IMPROVEMENT
Definition: config.h:146
char * buf1
Definition: attack.h:148
#define PK_LUCK_PENALTY
Definition: config.h:140
#define EMERGENCY_MAPPATH
Definition: config.h:573
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1809
const char * playerdir
Definition: global.h:336
#define MAP
Definition: define.h:134
void init_vars(void)
object clone
Definition: object.h:326
struct obj * prev
Definition: object.h:136
void init_archetypes(void)
Definition: arch.c:195
#define TMPDIR
Definition: config.h:541
void init_globals(void)
Definition: init.c:263
#define ARMOR_SPEED_LINEAR
Definition: config.h:147
#define NOT_PERMADETH
Definition: config.h:137
#define ARMOR_MAX_ENCHANT
Definition: config.h:143
void init_library(void)
Definition: init.c:201
void close_and_delete(FILE *fp, int compressed)
Definition: porting.c:748
static void init_attackmess(void)
Definition: init.c:473
void init_experience(void)
Definition: exp.c:170
#define SPELL_ENCUMBRANCE
Definition: config.h:131
EXTERN char first_map_ext_path[MAX_BUF]
Definition: global.h:230
#define DEATH_PENALTY_LEVEL
Definition: config.h:127
const char * treasures
Definition: global.h:340
Definition: object.h:321
const char * logfilename
Definition: global.h:325
const char * parent_name
Definition: map.h:300
const char *const spellpathnames[NRSPELLPATHS]
Definition: init.c:126
#define FLAG_REMOVED
Definition: define.h:528
object * active_objects
Definition: object.c:72
const char * name
Definition: map.h:299
EXTERN archetype * amulet_arch
Definition: global.h:238
void init_hash_table(void)
Definition: shstr.c:47
void i18n_init(void)
Definition: languages.c:108
#define ARMOR_WEIGHT_LINEAR
Definition: config.h:145
int read_smooth(void)
Definition: image.c:348
void write_todclock(void)
Definition: init.c:424
#define STARTMAX
Definition: config.h:591
static void init_emergency_mappath(void)
Definition: init.c:161
static void init_defaults(void)
Definition: init.c:378
static void init_environ(void)
Definition: init.c:225
EXTERN const char * undead_name
Definition: global.h:239
const char * tmpdir
Definition: global.h:343
#define EMERGENCY_Y
Definition: config.h:576
struct regiondef * next
Definition: map.h:298
Definition: map.h:297
#define EMERGENCY_X
Definition: config.h:575
#define MAXATTACKMESS
Definition: attack.h:47
#define RESET_LOCATION_TIME
Definition: config.h:700
object * objects
Definition: object.c:70
#define SIMPLE_EXP
Definition: config.h:129
#define EXIT_PATH(xyz)
Definition: define.h:748
EXTERN long nroferrors
Definition: global.h:212
EXTERN Animations * animations
Definition: global.h:241
#define REGIONS
Definition: config.h:585
static void init_dynamic(void)
Definition: init.c:390
#define NROFATTACKMESS
Definition: attack.h:46
#define LOCALDIR
Definition: win32.h:114
#define PLAYERDIR
Definition: config.h:620
const char * templatedir
Definition: global.h:342
void free_experience(void)
Definition: exp.c:269
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:283
const char * archetypes
Definition: global.h:338
void free_globals(void)
Definition: init.c:307
EXTERN treasurelist * first_treasurelist
Definition: global.h:193
const char * longname
Definition: map.h:312
EXTERN artifactlist * first_artifactlist
Definition: global.h:194
char * strdup_local(const char *str)
Definition: porting.c:310
#define MAX_BUF
Definition: define.h:81
#define NRSPELLPATHS
Definition: spells.h:68
#define ARCHETYPES
Definition: config.h:584
object * free_objects
Definition: object.c:71
#define RECYCLE_TMP_MAPS
Definition: config.h:134
void read_bmap_names(void)
Definition: image.c:198
struct obj * next
Definition: object.h:135
const char * uniquedir
Definition: global.h:341
#define CSPORT
Definition: config.h:367
EXTERN long nrofartifacts
Definition: global.h:224
const char * datadir
Definition: global.h:334
#define TREASURES
Definition: config.h:587
EXTERN long nrofallowedstr
Definition: global.h:225
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
void init_objects(void)
Definition: init.c:347
const char * localdir
Definition: global.h:335
#define DATADIR
Definition: win32.h:109
char * jailmap
Definition: map.h:318
struct oblnk * next
Definition: object.h:300
EXTERN archetype * staff_arch
Definition: global.h:238
const char * mapdir
Definition: global.h:337
EXTERN int exiting
Definition: global.h:222
struct Settings settings
Definition: init.c:48
EXTERN long trying_emergency_save
Definition: global.h:211
struct archt * next
Definition: object.h:323
EXTERN int animations_allocated
Definition: global.h:242
object objarray[STARTMAX]
Definition: object.c:65
void delete_map(mapstruct *m)
Definition: map.c:1745
EXTERN char first_map_path[MAX_BUF]
Definition: global.h:229
const char * msg
Definition: map.h:314
#define MAPDIR
Definition: config.h:582
#define UNIQUE_DIR
Definition: config.h:549
sstring add_string(const char *str)
Definition: shstr.c:116
EXTERN player * first_player
Definition: global.h:190
#define ARMOR_WEIGHT_REDUCTION
Definition: config.h:144
#define MOTD
Definition: config.h:497
#define CASTING_TIME
Definition: config.h:141
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
EXTERN long warn_archetypes
Definition: global.h:208
EXTERN archetype * ring_arch
Definition: global.h:238
EXTERN region * first_region
Definition: global.h:192
static void init_clocks(void)
Definition: init.c:441
char * buf3
Definition: attack.h:150
unsigned long todtick
Definition: init.c:418
char * emergency_mapname
Definition: global.h:388
Definition: map.h:346
char * buf2
Definition: attack.h:149
#define REAL_WIZ
Definition: config.h:133
#define FREE_AND_CLEAR(xyz)
Definition: global.h:282
#define SET_TITLE
Definition: config.h:128
#define LOGFILE
Definition: config.h:385
#define SET_FRIENDLY_FIRE
Definition: config.h:142
EXTERN mapstruct * first_map
Definition: global.h:191
EXTERN archetype * first_archetype
Definition: global.h:195
FILE * open_and_uncompress(const char *name, int flag, int *compressed)
Definition: porting.c:724
#define CONFDIR
Definition: win32.h:111
uint8 type
Definition: object.h:189
#define FLAG_FREED
Definition: define.h:529
EXTERN long nroftreasures
Definition: global.h:223