Crossfire Server, Trunk  R20805
init.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <errno.h>
22 #include <signal.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 /* Needed for strcasecmp(). */
27 #ifndef WIN32
28 #include <strings.h>
29 #endif
30 
31 #include "loader.h"
32 #include "version.h"
33 #include "server.h"
34 #include "sproto.h"
35 
36 static void help(void);
37 static void init_beforeplay(void);
38 static void init_startup(void);
39 static void init_signals(void);
40 static void init_races(void);
41 static void dump_races(void);
42 static void add_to_racelist(const char *race_name, object *op);
43 static racelink *get_racelist(void);
44 
49 static void set_logfile(char *val) {
50  settings.logfilename = val;
51 }
52 
54 static void call_version(void) {
55  puts(FULL_VERSION);
56  exit(EXIT_SUCCESS);
57 }
58 
60 static void set_debug(void) {
62 }
63 
65 static void unset_debug(void) {
67 }
68 
70 static void set_mondebug(void) {
72 }
73 
75 static void set_dumpmon1(void) {
76  settings.dumpvalues = 1;
77 }
78 
80 static void set_dumpmon2(void) {
81  settings.dumpvalues = 2;
82 }
83 
85 static void set_dumpmon3(void) {
86  settings.dumpvalues = 3;
87 }
88 
90 static void set_dumpmon4(void) {
91  settings.dumpvalues = 4;
92 }
93 
95 static void set_dumpmon5(void) {
96  settings.dumpvalues = 5;
97 }
98 
100 static void set_dumpmon6(void) {
101  settings.dumpvalues = 6;
102 }
103 
105 static void set_dumpmon7(void) {
106  settings.dumpvalues = 7;
107 }
108 
110 static void set_dumpmon8(void) {
111  settings.dumpvalues = 8;
112 }
113 
115 static void set_dumpmon9(void) {
116  settings.dumpvalues = 9;
117 }
118 
123 static void set_dumpmont(const char *name) {
124  settings.dumpvalues = 10;
125  settings.dumparg = name;
126 }
127 
132 static void set_datadir(const char *path) {
133  settings.datadir = path;
134 }
135 
140 static void set_confdir(const char *path) {
141  settings.confdir = path;
142 }
143 
148 static void set_localdir(const char *path) {
149  settings.localdir = path;
150 }
151 
156 static void set_mapdir(const char *path) {
157  settings.mapdir = path;
158 }
159 
164 static void set_archetypes(const char *path) {
165  settings.archetypes = path;
166 }
167 
172 static void set_regions(const char *path) {
173  settings.regions = path;
174 }
175 
180 static void set_treasures(const char *path) {
181  settings.treasures = path;
182 }
183 
188 static void set_uniquedir(const char *path) {
189  settings.uniquedir = path;
190 }
191 
196 static void set_templatedir(const char *path) {
197  settings.templatedir = path;
198 }
199 
204 static void set_playerdir(const char *path) {
205  settings.playerdir = path;
206 }
207 
212 static void set_tmpdir(const char *path) {
213  settings.tmpdir = path;
214 }
215 
216 static void free_races(void);
217 
218 static void free_materials(void);
219 
226 static void set_csport(const char *val) {
227  int port = atoi(val);
228  if (port <= 0 || port > 65535) {
229  LOG(llevError, "%d is an invalid csport number, must be between 1 and 65535.\n", port);
230  exit(1);
231  }
232  settings.csport = port;
233 }
234 
239 static void set_disable_plugin(const char *name) {
240  linked_char *disable = calloc(1, sizeof(linked_char));
241  disable->next = settings.disabled_plugins;
242  disable->name = strdup(name);
243  settings.disabled_plugins = disable;
244 }
245 
249 static void server_dump_animations(void) {
250  dump_animations();
251  cleanup();
252 }
253 
256 typedef void (*cmdlinefunc_args0)(void);
257 typedef void (*cmdlinefunc_args1)(const char* arg1);
258 typedef void (*cmdlinefunc_args2)(const char* arg1, const char* arg2);
267  const char *cmd_option;
270  void (*func)();
274 };
275 
284 static struct Command_Line_Options options[] = {
288  { "-arch", 1, 1, set_archetypes },
289  { "-conf", 1, 1, set_confdir },
290  { "-d", 0, 1, set_debug },
291  { "-data", 1, 1, set_datadir },
292  { "-disable-plugin", 1, 1, set_disable_plugin },
293  { "-h", 0, 1, help },
294  { "-local", 1, 1, set_localdir },
295  { "-log", 1, 1, set_logfile },
296  { "-maps", 1, 1, set_mapdir },
297  { "-mon", 0, 1, set_mondebug },
298  { "-n", 0, 1, unset_debug },
299  { "-playerdir", 1, 1, set_playerdir },
300  { "-regions", 1, 1, set_regions },
301  { "-templatedir", 1, 1, set_templatedir },
302  { "-tmpdir", 1, 1, set_tmpdir },
303  { "-treasures", 1, 1, set_treasures },
304  { "-uniquedir", 1, 1, set_uniquedir },
305  { "-v", 0, 1, call_version },
306 
307 #ifdef WIN32
308  /* Windows service stuff */
309  { "-regsrv", 0, 1, service_register },
310  { "-unregsrv", 0, 1, service_unregister },
311  { "-srv", 0, 1, service_handle },
312 #endif
313 
317  { "-p", 1, 2, set_csport },
318 
322  { "-m", 0, 3, set_dumpmon1 },
323  { "-m2", 0, 3, set_dumpmon2 },
324  { "-m3", 0, 3, set_dumpmon3 },
325  { "-m4", 0, 3, set_dumpmon4 },
326  { "-m5", 0, 3, set_dumpmon5 },
327  { "-m6", 0, 3, set_dumpmon6 },
328  { "-m7", 0, 3, set_dumpmon7 },
329  { "-m8", 0, 3, set_dumpmon8 },
330  { "-m9", 0, 3, set_dumpmon9 },
331  { "-mt", 1, 3, set_dumpmont },
332  { "-mexp", 0, 3, dump_experience },
333  { "-mq", 0, 3, dump_quests },
334  { "-dump-anims", 0, 3, server_dump_animations },
335 };
336 
351 static void parse_args(int argc, char *argv[], int pass) {
352  size_t i;
353  int on_arg = 1;
354 
355  while (on_arg < argc) {
356  for (i = 0; i < sizeof(options)/sizeof(struct Command_Line_Options); i++) {
357  if (!strcmp(options[i].cmd_option, argv[on_arg])) {
358  /* Found a matching option, but should not be processed on
359  * this pass. Just skip over it
360  */
361  if (options[i].pass != pass) {
362  on_arg += options[i].num_args+1;
363  break;
364  }
365  if (options[i].num_args) {
366  if ((on_arg+options[i].num_args) >= argc) {
367  fprintf(stderr, "%s requires an argument.\n", options[i].cmd_option);
368  exit(1);
369  }
370 
371  if (options[i].num_args == 1)
372  ((cmdlinefunc_args1)options[i].func)(argv[on_arg+1]);
373  if (options[i].num_args == 2)
374  ((cmdlinefunc_args2)options[i].func)(argv[on_arg+1], argv[on_arg+2]);
375  on_arg += options[i].num_args+1;
376  } else { /* takes no args */
377  ((cmdlinefunc_args0)options[i].func)();
378  on_arg++;
379  }
380  break;
381  }
382  }
383  if (i == sizeof(options)/sizeof(struct Command_Line_Options)) {
384  fprintf(stderr, "Unknown option: %s\n", argv[on_arg]);
385  fprintf(stderr, "Type '%s -h' for usage.\n", argv[0]);
386  exit(1);
387  }
388  }
389 }
390 
400  materialtype_t *mt;
401  int i;
402 
403  mt = (materialtype_t *)malloc(sizeof(materialtype_t));
404  if (mt == NULL)
406  mt->name = NULL;
407  mt->description = NULL;
408  for (i = 0; i < NROFATTACKS; i++) {
409  mt->save[i] = 0;
410  mt->mod[i] = 0;
411  }
412  mt->next = NULL;
413  return mt;
414 }
415 
420 static void load_materials(void) {
421  char buf[MAX_BUF], filename[MAX_BUF], *cp, *next;
422  FILE *fp;
423  materialtype_t *mt;
424  int i, value;
425 
426  snprintf(filename, sizeof(filename), "%s/materials", settings.datadir);
427  if ((fp = fopen(filename, "r")) == NULL) {
428  LOG(llevError, "Cannot open %s for reading\n", filename);
429  mt = get_empty_mat();
430  mt->next = NULL;
431  materialt = mt;
432  return;
433  }
434  mt = get_empty_mat();
435  materialt = mt;
436  while (fgets(buf, MAX_BUF, fp) != NULL) {
437  if (*buf == '#')
438  continue;
439  if ((cp = strchr(buf, '\n')) != NULL)
440  *cp = '\0';
441  cp = buf;
442  while (*cp == ' ') /* Skip blanks */
443  cp++;
444  if (!strncmp(cp, "name", 4)) {
445  /* clean up the previous entry */
446  if (mt->next != NULL) {
447  if (mt->description == NULL)
448  mt->description = add_string(mt->name);
449  mt = mt->next;
450  }
451  mt->next = get_empty_mat();
452  mt->name = add_string(strchr(cp, ' ')+1);
453  } else if (!strncmp(cp, "description", 11)) {
454  mt->description = add_string(strchr(cp, ' ')+1);
455  } else if (sscanf(cp, "material %d", &value)) {
456  mt->material = value;
457  } else if (!strncmp(cp, "saves", 5)) {
458  cp = strchr(cp, ' ')+1;
459  for (i = 0; i < NROFATTACKS; i++) {
460  if (cp == NULL) {
461  mt->save[i] = 0;
462  continue;
463  }
464  if ((next = strchr(cp, ',')) != NULL)
465  *(next++) = '\0';
466  sscanf(cp, "%d", &value);
467  mt->save[i] = (int8_t)value;
468  cp = next;
469  }
470  } else if (!strncmp(cp, "mods", 4)) {
471  cp = strchr(cp, ' ')+1;
472  for (i = 0; i < NROFATTACKS; i++) {
473  if (cp == NULL) {
474  mt->save[i] = 0;
475  continue;
476  }
477  if ((next = strchr(cp, ',')) != NULL)
478  *(next++) = '\0';
479  sscanf(cp, "%d", &value);
480  mt->mod[i] = (int8_t)value;
481  cp = next;
482  }
483  }
484  }
485  free(mt->next);
486  mt->next = NULL;
487  LOG(llevDebug, "loaded material type data\n");
488  fclose(fp);
489 }
490 
494 static void free_materials(void) {
495  materialtype_t *next;
496 
497  while (materialt) {
498  next = materialt->next;
499  free(materialt);
500  materialt = next;
501  }
502  materialt = NULL;
503 }
504 
510 static void load_settings(void) {
511  char buf[MAX_BUF], *cp, dummy[1];
512  int has_val;
513  FILE *fp;
514 
515  dummy[0] = '\0';
516  snprintf(buf, sizeof(buf), "%s/settings", settings.confdir);
517 
518  /* We don't require a settings file at current time, but down the road,
519  * there will probably be so many values that not having a settings file
520  * will not be a good thing.
521  */
522  if ((fp = fopen(buf, "r")) == NULL) {
523  LOG(llevError, "Warning: No settings file found\n");
524  return;
525  }
526  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
527  if (buf[0] == '#')
528  continue;
529  /* eliminate newline */
530  if ((cp = strrchr(buf, '\n')) != NULL)
531  *cp = '\0';
532 
533  /* Skip over empty lines */
534  if (buf[0] == 0)
535  continue;
536 
537  /* Skip all the spaces and set them to nulls. If not space,
538  * set cp to "" to make strcpy's and the like easier down below.
539  */
540  if ((cp = strchr(buf, ' ')) != NULL) {
541  while (*cp == ' ')
542  *cp++ = 0;
543  has_val = 1;
544  } else {
545  cp = dummy;
546  has_val = 0;
547  }
548 
549  if (!strcasecmp(buf, "metaserver_notification")) {
550  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
552  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
554  } else {
555  LOG(llevError, "load_settings: Unknown value for metaserver_notification: %s\n", cp);
556  }
557  } else if (!strcasecmp(buf, "metaserver_server")) {
558  if (has_val)
560  else
561  LOG(llevError, "load_settings: metaserver_server must have a value.\n");
562  } else if (!strcasecmp(buf, "motd")) {
563  if (has_val)
564  safe_strncpy(settings.motd, cp, sizeof(settings.motd));
565  else
566  LOG(llevError, "load_settings: motd must have a value.\n");
567  } else if (!strcasecmp(buf, "dm_mail")) {
568  if (has_val)
570  else
571  LOG(llevError, "load_settings: dm_mail must have a value.\n");
572  } else if (!strcasecmp(buf, "metaserver_host")) {
573  if (has_val)
575  else
576  LOG(llevError, "load_settings: metaserver_host must have a value.\n");
577  } else if (!strcasecmp(buf, "port")) {
578  set_csport(cp);
579  } else if (!strcasecmp(buf, "metaserver_port")) {
580  int port = atoi(cp);
581 
582  if (port < 1 || port > 65535)
583  LOG(llevError, "load_settings: metaserver_port must be between 1 and 65535, %d is invalid\n", port);
584  else
585  settings.meta_port = port;
586  } else if (!strcasecmp(buf, "metaserver_comment")) {
588  } else if (!strcasecmp(buf, "worldmapstartx")) {
589  int size = atoi(cp);
590 
591  if (size < 0)
592  LOG(llevError, "load_settings: worldmapstartx must be at least 0, %d is invalid\n", size);
593  else
594  settings.worldmapstartx = size;
595  } else if (!strcasecmp(buf, "worldmapstarty")) {
596  int size = atoi(cp);
597 
598  if (size < 0)
599  LOG(llevError, "load_settings: worldmapstarty must be at least 0, %d is invalid\n", size);
600  else
601  settings.worldmapstarty = size;
602  } else if (!strcasecmp(buf, "worldmaptilesx")) {
603  int size = atoi(cp);
604 
605  if (size < 1)
606  LOG(llevError, "load_settings: worldmaptilesx must be greater than 1, %d is invalid\n", size);
607  else
608  settings.worldmaptilesx = size;
609  } else if (!strcasecmp(buf, "worldmaptilesy")) {
610  int size = atoi(cp);
611 
612  if (size < 1)
613  LOG(llevError, "load_settings: worldmaptilesy must be greater than 1, %d is invalid\n", size);
614  else
615  settings.worldmaptilesy = size;
616  } else if (!strcasecmp(buf, "worldmaptilesizex")) {
617  int size = atoi(cp);
618 
619  if (size < 1)
620  LOG(llevError, "load_settings: worldmaptilesizex must be greater than 1, %d is invalid\n", size);
621  else
623  } else if (!strcasecmp(buf, "worldmaptilesizey")) {
624  int size = atoi(cp);
625 
626  if (size < 1)
627  LOG(llevError, "load_settings: worldmaptilesizey must be greater than 1, %d is invalid\n", size);
628  else
630  } else if (!strcasecmp(buf, "fastclock")) {
631  int lev = atoi(cp);
632 
633  if (lev < 0)
634  LOG(llevError, "load_settings: fastclock must be at least 0, %d is invalid\n", lev);
635  else
636  settings.fastclock = lev;
637  } else if (!strcasecmp(buf, "not_permadeth")) {
638  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
640  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
642  } else {
643  LOG(llevError, "load_settings: Unknown value for not_permadeth: %s\n", cp);
644  }
645  } else if (!strcasecmp(buf, "resurrection")) {
646  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
648  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
650  } else {
651  LOG(llevError, "load_settings: Unknown value for resurrection: %s\n", cp);
652  }
653  } else if (!strcasecmp(buf, "set_title")) {
654  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
656  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
658  } else {
659  LOG(llevError, "load_settings: Unknown value for set_title: %s\n", cp);
660  }
661  } else if (!strcasecmp(buf, "search_items")) {
662  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
664  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
666  } else {
667  LOG(llevError, "load_settings: Unknown value for search_items: %s\n", cp);
668  }
669  } else if (!strcasecmp(buf, "spell_encumbrance")) {
670  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
672  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
674  } else {
675  LOG(llevError, "load_settings: Unknown value for spell_encumbrance: %s\n", cp);
676  }
677  } else if (!strcasecmp(buf, "spell_failure_effects")) {
678  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
680  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
682  } else {
683  LOG(llevError, "load_settings: Unknown value for spell_failure_effects: %s\n", cp);
684  }
685  } else if (!strcasecmp(buf, "casting_time")) {
686  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
688  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
690  } else {
691  LOG(llevError, "load_settings: Unknown value for casting_time: %s\n", cp);
692  }
693  } else if (!strcasecmp(buf, "real_wiz")) {
694  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
696  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
698  } else {
699  LOG(llevError, "load_settings: Unknown value for real_wiz: %s\n", cp);
700  }
701  } else if (!strcasecmp(buf, "recycle_tmp_maps")) {
702  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
704  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
706  } else {
707  LOG(llevError, "load_settings: Unknown value for recycle_tmp_maps: %s\n", cp);
708  }
709  } else if (!strcasecmp(buf, "always_show_hp")) {
710  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
712  } else if (!strcasecmp(cp, "damaged")) {
714  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
716  } else {
717  LOG(llevError, "load_settings: Unknown value for always_show_hp: %s\n", cp);
718  }
719  } else if (!strcasecmp(buf, "who_format")) {
720  if (has_val)
722  sizeof(settings.who_format));
723  } else if (!strcasecmp(buf, "who_wiz_format")) {
724  if (has_val) {
726  sizeof(settings.who_wiz_format));
727  }
728  } else if (!strcasecmp(buf, "spellpoint_level_depend")) {
729  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
731  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
733  } else {
734  LOG(llevError, "load_settings: Unknown value for spellpoint_level_depend: %s\n", cp);
735  }
736  } else if (!strcasecmp(buf, "stat_loss_on_death")) {
737  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
739  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
741  } else {
742  LOG(llevError, "load_settings: Unknown value for stat_loss_on_death: %s\n", cp);
743  }
744  } else if (!strcasecmp(buf, "use_permanent_experience")) {
745  LOG(llevError, "use_permanent_experience is deprecated, usepermenent_experience_percentage instead\n");
746  } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
747  int val = atoi(cp);
748  if (val < 0 || val > 100)
749  LOG(llevError, "load_settings: permenent_experience_percentage must be between 0 and 100, %d is invalid\n", val);
750  else
752  } else if (!strcasecmp(buf, "death_penalty_percentage")) {
753  int val = atoi(cp);
754  if (val < 0 || val > 100)
755  LOG(llevError, "load_settings: death_penalty_percentage must be between 0 and 100, %d is invalid\n", val);
756  else
758  } else if (!strcasecmp(buf, "death_penalty_levels")) {
759  int val = atoi(cp);
760  if (val < 0 || val > 255)
761  LOG(llevError, "load_settings: death_penalty_levels can not be negative, %d is invalid\n", val);
762  else
764  } else if (!strcasecmp(buf, "balanced_stat_loss")) {
765  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
767  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
769  } else {
770  LOG(llevError, "load_settings: Unknown value for balanced_stat_loss: %s\n", cp);
771  }
772  } else if (!strcasecmp(buf, "simple_exp")) {
773  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
775  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
777  } else {
778  LOG(llevError, "load_settings: Unknown value for simple_exp: %s\n", cp);
779  }
780  } else if (!strcasecmp(buf, "item_power_factor")) {
781  float tmp = atof(cp);
782  if (tmp < 0)
783  LOG(llevError, "load_settings: item_power_factor must be a positive number (%f < 0)\n", tmp);
784  else
786  } else if (!strcasecmp(buf, "pk_luck_penalty")) {
787  int16_t val = atoi(cp);
788 
789  if (val < -100 || val > 100)
790  LOG(llevError, "load_settings: pk_luck_penalty must be between -100 and 100, %d is invalid\n", val);
791  else
793  } else if (!strcasecmp(buf, "set_friendly_fire")) {
794  int val = atoi(cp);
795 
796  if (val < 1 || val > 100)
797  LOG(llevError, "load_settings: set_friendly_fire must be between 1 an 100, %d is invalid\n", val);
798  else
800  } else if (!strcasecmp(buf, "armor_max_enchant")) {
801  int max_e = atoi(cp);
802  if (max_e <= 0)
803  LOG(llevError, "load_settings: armor_max_enchant is %d\n", max_e);
804  else
805  settings.armor_max_enchant = max_e;
806  } else if (!strcasecmp(buf, "armor_weight_reduction")) {
807  int wr = atoi(cp);
808  if (wr < 0)
809  LOG(llevError, "load_settings: armor_weight_reduction is %d\n", wr);
810  else
812  } else if (!strcasecmp(buf, "armor_weight_linear")) {
813  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
815  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
817  } else {
818  LOG(llevError, "load_settings: unknown value for armor_weight_linear: %s\n", cp);
819  }
820  } else if (!strcasecmp(buf, "armor_speed_improvement")) {
821  int wr = atoi(cp);
822  if (wr < 0)
823  LOG(llevError, "load_settings: armor_speed_improvement is %d\n", wr);
824  else
826  } else if (!strcasecmp(buf, "armor_speed_linear")) {
827  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
829  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
831  } else {
832  LOG(llevError, "load_settings: unknown value for armor_speed_linear: %s\n", cp);
833  }
834  } else if (!strcasecmp(buf, "no_player_stealing")) {
835  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
837  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
839  } else {
840  LOG(llevError, "load_settings: unknown value for no_player_stealing: %s\n", cp);
841  }
842  } else if (!strcasecmp(buf, "create_home_portals")) {
843  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
845  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
847  } else {
848  LOG(llevError, "load_settings: unknown value for create_home_portals: %s\n", cp);
849  }
850  } else if (!strcasecmp(buf, "personalized_blessings")) {
851  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
853  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
855  } else {
856  LOG(llevError, "load_settings: unknown value for personalized_blessings: %s\n", cp);
857  }
858  } else if (!strcasecmp(buf, "pk_max_experience")) {
859  int64_t pkme = atoll(cp);
860  if (pkme < 0)
861  pkme = -1;
863  } else if (!strcasecmp(buf, "pk_max_experience_percent")) {
864  int pkmep = atoi(cp);
865  if (pkmep < 0) {
866  LOG(llevError, "load_settings: pk_max_experience_percent should be positive or zero (was \"%s\")\n", cp);
867  } else
869  } else if (!strcasecmp(buf, "allow_denied_spells_writing")) {
870  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
872  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
874  } else {
875  LOG(llevError, "load_settings: unknown value for allow_denied_spells_writing: %s\n", cp);
876  }
877  } else if (!strcasecmp(buf, "allow_broken_converters")) {
878  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
880  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
882  } else {
883  LOG(llevError, "load_settings: unknown value for allow_broken_converters: %s\n", cp);
884  }
885  } else if (!strcasecmp(buf, "log_timestamp")) {
886  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
888  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
890  } else {
891  LOG(llevError, "load_settings: unknown value for log_timestamp: %s\n", cp);
892  }
893  } else if (!strcasecmp(buf, "log_timestamp_format")) {
896  } else if (!strcasecmp(buf, "starting_stat_min")) {
897  int val = atoi(cp);
898 
899  if (val < 1 || val > settings.max_stat || val > settings.starting_stat_max)
900  LOG(llevError, "load_settings: starting_stat_min (%d) need to be within %d-%d (%d)\n",
902  else
904  } else if (!strcasecmp(buf, "starting_stat_max")) {
905  int val = atoi(cp);
906 
907  if (val < 1 || val > settings.max_stat || val<settings.starting_stat_min)
908  LOG(llevError, "load_settings: starting_stat_max (%d) need to be within %d-%d (%d)\n",
910  else
912  } else if (!strcasecmp(buf, "starting_stat_points")) {
913  int val = atoi(cp);
914 
915  if (val < NUM_STATS * settings.starting_stat_min ||
917  LOG(llevError, "load_settings: starting_stat_points (%d) need to be within %d-%d\n",
919  else
921  } else if (!strcasecmp(buf, "roll_stat_points")) {
922  int val = atoi(cp);
923 
924  /* The 3 and 18 values are hard coded in because we know that
925  * roll_stat() generates a value between 3 and 18 - if that ever
926  * changed, this code should change also, but that code will eventually
927  * go away.
928  */
929  if (val < NUM_STATS * 3 || val > NUM_STATS * 18)
930  LOG(llevError, "load_settings: roll_stat_points need to be within %d-%d\n",
931  NUM_STATS * 3, NUM_STATS * 18);
932  else
934  } else if (!strcasecmp(buf, "special_break_map")) {
935  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
937  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
939  } else {
940  LOG(llevError, "load_settings: unknown value for special_break_map: %s\n", cp);
941  }
942  } else if (!strcasecmp(buf, "ignore_plugin_compatibility")) {
943  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
945  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
947  } else {
948  LOG(llevError, "load_settings: unknown value for ignore_plugin_compatibility: %s\n", cp);
949  }
950  } else if (!strcasecmp(buf, "account_block_create")) {
951  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
953  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
955  } else {
956  LOG(llevError, "load_settings: unknown value for account_block_create: %s\n", cp);
957  }
958  } else if (!strcasecmp(buf, "account_trusted_host")) {
961  } else if (!strcasecmp(buf, "crypt_mode")) {
962  int val = atoi(cp);
963  if (val != 0 && val != 1) {
964  LOG(llevError, "load_settings: crypt_mode must be 0 or 1\n");
965  } else {
966  settings.crypt_mode = val;
967  }
968  } else {
969  LOG(llevError, "Unknown value in settings file: %s\n", buf);
970  }
971  }
972  fclose(fp);
973  if (settings.log_timestamp_format == NULL)
974  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
975 
976  /*
977  * The who formats are defined in config to be blank. They should have been
978  * overridden by the settings file, if there are no entries however, it will
979  * have stayed blank. Since this probably isn't what is wanted, we will check if
980  * new formats have been specified, and if not we will use the old defaults.
981  */
982  if (!strcmp(settings.who_format, ""))
983  strcpy(settings.who_format, "%N_%T%t%h%d%b%n<%m>");
984  if (!strcmp(settings.who_wiz_format, ""))
985  strcpy(settings.who_wiz_format, "%N_%T%t%h%d%b%nLevel %l <%m>(@%i)(%c)");
986 }
987 
995 void init(int argc, char **argv) {
996  init_done = 0; /* Must be done before init_signal() */
997  logfile = stderr;
998 
999  /* First argument pass - right now it does nothing, but in the future specifying
1000  * the LibDir in this pass would be reasonable. */
1001  parse_args(argc, argv, 1);
1002 
1003  init_library(); /* Must be called early */
1004  load_settings(); /* Load the settings file */
1005  load_materials();
1006  parse_args(argc, argv, 2);
1007 
1008  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
1009  SRANDOM(time(NULL));
1010 
1011  init_startup(); /* Check shutdown/forbid files */
1012  init_signals(); /* Sets up signal interceptions */
1013  init_commands(); /* Sort command tables */
1014  read_map_log(); /* Load up the old temp map files */
1015  init_skills();
1016  init_ob_methods();
1017  cftimer_init();
1018  hiscore_init();
1019 
1020  parse_args(argc, argv, 3);
1021 
1022  init_beforeplay();
1023  init_server();
1024  metaserver2_init();
1025  accounts_load();
1026  reset_sleep();
1027  init_done = 1;
1028 }
1029 
1035 void free_server(void) {
1036  free_materials();
1037  free_races();
1038  free_quest();
1040  while (settings.disabled_plugins) {
1042  free((void *)settings.disabled_plugins->name);
1043  free(settings.disabled_plugins);
1044  settings.disabled_plugins = next;
1045  }
1046 }
1047 
1051 static void help(void) {
1052  printf("Usage: crossfire-server [options]\n\n");
1053 
1054  printf("Options:\n");
1055  printf(" -arch Set the file with archetype definitions.\n");
1056  printf(" -conf Set the directory to find configuration files.\n");
1057  printf(" -d Turn on extra debugging messages.\n");
1058  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1059  printf(" -disable-plugin\n"
1060  " Disables specified plugin. Use the name without the extension.\n"
1061  " Can be specified multiple times. 'All' disables all plugins.\n");
1062  printf(" -dump-anims Dump animations.\n");
1063  printf(" -h Print this help message.\n");
1064  printf(" -local Set the local data (var/) directory.\n");
1065  printf(" -log <file> Write logging information to the given file.\n");
1066  printf(" -m List suggested experience for all monsters.\n");
1067  printf(" -m2 Dump monster abilities.\n");
1068  printf(" -m3 Dump artifact information.\n");
1069  printf(" -m4 Dump spell information.\n");
1070  printf(" -m5 Dump skill information.\n");
1071  printf(" -m6 Dump race information.\n");
1072  printf(" -m7 Dump alchemy information.\n");
1073  printf(" -m8 Dump gods information.\n");
1074  printf(" -m9 Dump more alchemy information (formula checking).\n");
1075  printf(" -maps Set the map directory.\n");
1076  printf(" -mexp Dump the experience table.\n");
1077  printf(" -mon Turn on monster debugging.\n");
1078  printf(" -mq Dump the quest list.\n");
1079  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1080  printf(" -n Turn off debugging messages if on by default.\n");
1081  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1082  printf(" -playerdir Set the player files directory.\n");
1083  printf(" -regions Set the region file.\n");
1084  printf(" -templatedir Set the template map directory.\n");
1085  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1086  printf(" -treasures Set the treasures file.\n");
1087  printf(" -uniquedir Set the unique items/maps directory.\n");
1088  printf(" -v Print version information.\n");
1089  exit(EXIT_SUCCESS);
1090 }
1091 
1096 static void init_beforeplay(void) {
1097  init_archetypes(); /* If not called before, reads all archetypes from file */
1098  init_artifacts(); /* If not called before, reads all artifacts from file */
1099  check_spells(); /* If not called before, links archtypes used by spells */
1100  init_regions(); /* If not called before, reads all regions from file */
1101  init_archetype_pointers(); /* Setup global pointers to archetypes */
1102  init_races(); /* overwrite race designations using entries in lib/races file */
1103  init_gods(); /* init linked list of gods from archs*/
1104  init_readable(); /* inits useful arrays for readable texts */
1105  init_formulae(); /* If not called before, reads formulae from file */
1106 
1107  switch (settings.dumpvalues) {
1108  case 1:
1109  print_monsters();
1110  cleanup();
1111 
1112  case 2:
1113  dump_abilities();
1114  cleanup();
1115 
1116  case 3:
1117  dump_artifacts();
1118  cleanup();
1119 
1120  case 4:
1121  dump_spells();
1122  cleanup();
1123 
1124  case 5:
1125  cleanup();
1126 
1127  case 6:
1128  dump_races();
1129  cleanup();
1130 
1131  case 7:
1132  dump_alchemy();
1133  cleanup();
1134 
1135  case 8:
1136  dump_gods();
1137  cleanup();
1138 
1139  case 9:
1141  cleanup();
1142 
1143  case 10:
1145  cleanup();
1146  }
1147 }
1148 
1154 static void init_startup(void) {
1155  char buf[MAX_BUF];
1156  FILE *fp;
1157 
1158 #ifdef SHUTDOWN_FILE
1159  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1160  if ((fp = fopen(buf, "r")) != NULL) {
1161  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1162  printf("%s", buf);
1163  fclose(fp);
1164  exit(1);
1165  }
1166 #endif
1167 
1168  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1169  LOG(llevError, "CrossFire: Playing not allowed.\n");
1170  exit(-1);
1171  }
1172 }
1173 
1177 static void signal_shutdown(void) {
1178  shutdown_flag += 1;
1179 }
1180 
1193 static void rec_sighup(int i) {
1194  /* Don't call LOG(). It calls non-reentrant functions. The other
1195  * signal handlers shouldn't really call LOG() either. */
1196  if (logfile != stderr) {
1197  reopen_logfile = 1;
1198  }
1199 }
1200 
1204 static void init_signals(void) {
1205 #ifndef WIN32 /* init_signals() remove signals */
1206  struct sigaction sa;
1207 
1208  sa.sa_sigaction = NULL;
1209  sigemptyset(&sa.sa_mask);
1210  sa.sa_flags = 0;
1211  sa.sa_handler = rec_sighup;
1212  sigaction(SIGHUP, &sa, NULL);
1213  signal(SIGINT, signal_shutdown);
1214  signal(SIGPIPE, SIG_IGN);
1215 #endif /* win32 */
1216 }
1217 
1224 static void init_races(void) {
1225  FILE *file;
1226  char race[MAX_BUF], fname[MAX_BUF], buf[MAX_BUF], *cp, variable[MAX_BUF];
1227  archetype *mon = NULL;
1228  static int init_done = 0;
1229 
1230  if (init_done)
1231  return;
1232  init_done = 1;
1233  first_race = NULL;
1234 
1235  snprintf(fname, sizeof(fname), "%s/races", settings.datadir);
1236  if (!(file = fopen(fname, "r"))) {
1237  LOG(llevError, "Cannot open races file %s: %s\n", fname, strerror(errno));
1238  return;
1239  }
1240 
1241  while (fgets(buf, MAX_BUF, file) != NULL) {
1242  int set_race = 1, set_list = 1;
1243  if (*buf == '#')
1244  continue;
1245  if ((cp = strchr(buf, '\n')) != NULL)
1246  *cp = '\0';
1247  cp = buf;
1248  while (*cp == ' ' || *cp == '!' || *cp == '@') {
1249  if (*cp == '!')
1250  set_race = 0;
1251  if (*cp == '@')
1252  set_list = 0;
1253  cp++;
1254  }
1255  if (sscanf(cp, "RACE %s", variable)) { /* set new race value */
1256  strcpy(race, variable);
1257  } else {
1258  char *cp1;
1259 
1260  /* Take out beginning spaces */
1261  for (cp1 = cp; *cp1 == ' '; cp1++)
1262  ;
1263  /* Remove newline and trailing spaces */
1264  for (cp1 = cp+strlen(cp)-1; *cp1 == '\n' || *cp1 == ' '; cp1--) {
1265  *cp1 = '\0';
1266  if (cp == cp1)
1267  break;
1268  }
1269 
1270  if (cp[strlen(cp)-1] == '\n')
1271  cp[strlen(cp)-1] = '\0';
1272  /* set creature race to race value */
1273  if ((mon = find_archetype(cp)) == NULL)
1274  LOG(llevError, "Creature %s in race file lacks archetype\n", cp);
1275  else {
1276  // If the race is specified somewhere in the race field, we are good.
1277  // This allows us to specify multiple races on arches that are in the races file.
1278  if (set_race && (!mon->clone.race || !strstr(mon->clone.race, race))) {
1279  if (mon->clone.race) {
1280  LOG(llevDebug, "races: Appending to %s from %s for archetype %s\n", race, mon->clone.race, mon->name);
1281  // Copy the existing race into the race total list.
1282  strcpy(race+strlen(race), ","); // Arbitrary separator
1283  strncpy(race+strlen(race), mon->clone.race, MAX_BUF - 1 - strlen(race));
1284  // Clear the existing race string so we can add the new one
1285  free_string(mon->clone.race);
1286  }
1287  mon->clone.race = add_string(race);
1288  }
1289  /* if the arch is a monster, add it to the race list */
1290  if (set_list && QUERY_FLAG(&mon->clone, FLAG_MONSTER))
1291  add_to_racelist(race, &mon->clone);
1292  }
1293  }
1294  }
1295  fclose(file);
1296  LOG(llevDebug, "loaded races\n");
1297 }
1298 
1302 static void dump_races(void) {
1303  racelink *list;
1304  objectlink *tmp;
1305 
1306  for (list = first_race; list; list = list->next) {
1307  fprintf(stderr, "\nRACE %s:\t", list->name);
1308  for (tmp = list->member; tmp; tmp = tmp->next)
1309  fprintf(stderr, "%s(%d), ", tmp->ob->arch->name, tmp->ob->level);
1310  }
1311  fprintf(stderr, "\n");
1312 }
1313 
1317 static void free_races(void) {
1318  racelink *race;
1319  objectlink *link;
1320 
1321  LOG(llevDebug, "Freeing race information.\n");
1322  while (first_race) {
1323  race = first_race->next;
1324  while (first_race->member) {
1325  link = first_race->member->next;
1326  free(first_race->member);
1327  first_race->member = link;
1328  }
1330  free(first_race);
1331  first_race = race;
1332  }
1333 }
1334 
1343 static void add_to_racelist(const char *race_name, object *op) {
1344  racelink *race;
1345 
1346  if (!op || !race_name)
1347  return;
1348  race = find_racelink(race_name);
1349 
1350  if (!race) { /* add in a new race list */
1351  race = get_racelist();
1352  race->next = first_race;
1353  first_race = race;
1354  race->name = add_string(race_name);
1355  }
1356 
1357  if (race->member->ob) {
1358  objectlink *tmp = get_objectlink();
1359 
1360  tmp->next = race->member;
1361  race->member = tmp;
1362  }
1363  race->nrof++;
1364  race->member->ob = op;
1365 }
1366 
1375 static racelink *get_racelist(void) {
1376  racelink *list;
1377 
1378  list = (racelink *)malloc(sizeof(racelink));
1379  if (!list)
1381  list->name = NULL;
1382  list->nrof = 0;
1383  list->member = get_objectlink();
1384  list->next = NULL;
1385 
1386  return list;
1387 }
1388 
1397 racelink *find_racelink(const char *name) {
1398  racelink *test = NULL;
1399 
1400  if (name && first_race)
1401  for (test = first_race; test && test != test->next; test = test->next)
1402  if (!test->name || !strcmp(name, test->name))
1403  break;
1404 
1405  return test;
1406 }
EXTERN FILE * logfile
Definition: global.h:142
static void set_dumpmon2(void)
Definition: init.c:80
uint8_t not_permadeth
Definition: global.h:258
static void server_dump_animations(void)
Definition: init.c:249
archetype * find_archetype(const char *name)
Definition: arch.c:692
static void set_dumpmon8(void)
Definition: init.c:110
uint8_t create_home_portals
Definition: global.h:308
int8_t mod[NROFATTACKS]
Definition: material.h:38
int init_regions(void)
Definition: region.c:292
uint8_t stat_loss_on_death
Definition: global.h:252
char meta_host[MAX_BUF]
Definition: global.h:284
uint8_t max_stat
Definition: global.h:321
uint32_t worldmaptilesx
Definition: global.h:290
void free_quest_definitions(void)
Definition: quest.c:1307
uint8_t pass
Definition: init.c:269
Definition: object.h:442
static void free_materials(void)
Definition: init.c:494
const char * race
Definition: object.h:318
uint8_t spell_encumbrance
Definition: global.h:264
static void set_dumpmon7(void)
Definition: init.c:105
uint32_t worldmaptilesizey
Definition: global.h:293
const char * name
Definition: material.h:34
uint8_t starting_stat_min
Definition: global.h:317
void(* func)()
Definition: init.c:270
unsigned int meta_on
Definition: global.h:282
linked_char * disabled_plugins
Definition: global.h:323
EXTERN materialtype_t * materialt
Definition: material.h:43
static void set_mondebug(void)
Definition: init.c:70
unsigned char uint8_t
Definition: win32.h:161
static struct Command_Line_Options options[]
Definition: init.c:284
void print_monsters(void)
Definition: info.c:95
uint16_t meta_port
Definition: global.h:285
Definition: race.h:12
uint8_t death_penalty_level
Definition: global.h:256
static void check_spells(void)
Definition: arch.c:511
#define strdup_local
Definition: compat.h:25
char who_wiz_format[MAX_BUF]
Definition: global.h:273
static void set_dumpmon1(void)
Definition: init.c:75
uint8_t spellpoint_level_depend
Definition: global.h:270
int nrof
Definition: race.h:14
char motd[MAX_BUF]
Definition: global.h:274
uint8_t num_args
Definition: init.c:268
int forbid_play(void)
Definition: server.c:1243
void fatal(enum fatal_error err)
Definition: utils.c:597
static void set_csport(const char *val)
Definition: init.c:226
object * mon
Definition: comet_perf.c:74
int8_t save[NROFATTACKS]
Definition: material.h:37
uint16_t csport
Definition: global.h:237
const char * playerdir
Definition: global.h:244
void free_string(sstring str)
Definition: shstr.c:280
static void unset_debug(void)
Definition: init.c:65
uint32_t worldmapstarty
Definition: global.h:289
int reopen_logfile
Definition: logger.c:26
object clone
Definition: object.h:470
const char * regions
Definition: global.h:247
int allow_broken_converters
Definition: global.h:313
void init_archetypes(void)
Definition: arch.c:182
int armor_max_enchant
Definition: global.h:302
static void parse_args(int argc, char *argv[], int pass)
Definition: init.c:351
void dump_gods(void)
Definition: holy.c:386
int material
Definition: material.h:36
void init_library(void)
Definition: init.c:203
uint8_t starting_stat_max
Definition: global.h:318
void accounts_load(void)
Definition: account.c:121
void dump_experience(void)
Definition: exp.c:249
static void signal_shutdown(void)
Definition: init.c:1177
#define TRUE
Definition: compat.h:10
LogLevel debug
Definition: global.h:238
#define FALSE
Definition: compat.h:11
static void set_playerdir(const char *path)
Definition: init.c:204
uint8_t death_penalty_ratio
Definition: global.h:255
char meta_server[MAX_BUF]
Definition: global.h:283
static void set_datadir(const char *path)
Definition: init.c:132
#define safe_strncpy
Definition: compat.h:23
void free_quest(void)
Definition: quest.c:1289
uint32_t worldmaptilesy
Definition: global.h:291
const char * treasures
Definition: global.h:248
Definition: object.h:465
racelink * find_racelink(const char *name)
Definition: init.c:1397
const char * logfilename
Definition: global.h:236
void dump_alchemy_costs(void)
Definition: recipe.c:501
uint8_t casting_time
Definition: global.h:266
uint8_t recycle_tmp_maps
Definition: global.h:268
static void set_localdir(const char *path)
Definition: init.c:148
#define SRANDOM(seed)
Definition: define.h:680
char meta_comment[MAX_BUF]
Definition: global.h:286
static void set_mapdir(const char *path)
Definition: init.c:156
void cleanup(void)
Definition: server.c:1139
void dump_quests(void)
Definition: quest.c:1280
void init_formulae(void)
Definition: recipe.c:143
static void add_to_racelist(const char *race_name, object *op)
Definition: init.c:1343
void dump_animations(void)
Definition: anim.c:348
object * ob
Definition: object.h:443
static void set_dumpmon4(void)
Definition: init.c:90
void init_server(void)
Definition: init.c:262
struct oblnk * member
Definition: race.h:15
struct ralnk * next
Definition: race.h:16
char * log_timestamp_format
Definition: global.h:316
int armor_speed_improvement
Definition: global.h:305
void init(int argc, char **argv)
Definition: init.c:995
const char * dumparg
Definition: global.h:240
static void set_disable_plugin(const char *name)
Definition: init.c:239
void free_server(void)
Definition: init.c:1035
signed short int16_t
Definition: win32.h:160
uint8_t search_items
Definition: global.h:263
static void init_signals(void)
Definition: init.c:1204
const char * tmpdir
Definition: global.h:251
int64_t pk_max_experience
Definition: global.h:310
uint8_t always_show_hp
Definition: global.h:269
void service_unregister()
Definition: win32.c:225
static void init_startup(void)
Definition: init.c:1154
#define snprintf
Definition: win32.h:46
void dump_artifacts(void)
Definition: artifact.c:683
void dump_alchemy(void)
Definition: recipe.c:299
struct linked_char * next
Definition: global.h:88
uint8_t armor_weight_linear
Definition: global.h:304
static void load_settings(void)
Definition: init.c:510
void read_map_log(void)
Definition: swap.c:70
uint8_t balanced_stat_loss
Definition: global.h:257
static void set_dumpmon3(void)
Definition: init.c:85
const char * cmd_option
Definition: init.c:267
void(* cmdlinefunc_args1)(const char *arg1)
Definition: init.c:257
static void load_materials(void)
Definition: init.c:420
static void set_tmpdir(const char *path)
Definition: init.c:212
uint8_t armor_speed_linear
Definition: global.h:306
static void help(void)
Definition: init.c:1051
EXTERN racelink * first_race
Definition: global.h:125
uint8_t real_wiz
Definition: global.h:267
void cftimer_init(void)
Definition: timers.c:157
uint8_t ignore_plugin_compatibility
Definition: global.h:324
const char * templatedir
Definition: global.h:250
static void set_templatedir(const char *path)
Definition: init.c:196
static void set_archetypes(const char *path)
Definition: init.c:164
const char * archetypes
Definition: global.h:246
uint8_t simple_exp
Definition: global.h:259
static void set_treasures(const char *path)
Definition: init.c:180
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
volatile sig_atomic_t shutdown_flag
Definition: server.h:6
void init_readable(void)
Definition: readable.c:1027
#define MAX_BUF
Definition: define.h:35
static void set_logfile(char *val)
Definition: init.c:49
static void set_confdir(const char *path)
Definition: init.c:140
char who_format[MAX_BUF]
Definition: global.h:272
static void dump_races(void)
Definition: init.c:1302
void reset_sleep(void)
Definition: time.c:130
const char * confdir
Definition: global.h:241
signed __int64 int64_t
Definition: win32.h:168
uint8_t account_block_create
Definition: global.h:325
const char * uniquedir
Definition: global.h:249
static void set_dumpmont(const char *name)
Definition: init.c:123
static void set_regions(const char *path)
Definition: init.c:172
uint8_t permanent_exp_ratio
Definition: global.h:254
int log_timestamp
Definition: global.h:315
const char * datadir
Definition: global.h:242
void dump_spells(void)
Definition: spell_util.c:146
uint8_t special_break_map
Definition: global.h:322
const char * name
Definition: global.h:87
uint16_t set_friendly_fire
Definition: global.h:271
int armor_weight_reduction
Definition: global.h:303
void dump_abilities(void)
Definition: info.c:63
signed char int8_t
Definition: win32.h:158
static void set_debug(void)
Definition: init.c:60
static void set_dumpmon9(void)
Definition: init.c:115
const char * localdir
Definition: global.h:243
uint8_t starting_stat_points
Definition: global.h:319
struct archt * arch
Definition: object.h:412
struct oblnk * next
Definition: object.h:444
uint8_t no_player_stealing
Definition: global.h:307
void dump_monster_treasure(const char *name)
Definition: treasure.c:1449
const char * name
Definition: race.h:13
const char * mapdir
Definition: global.h:245
struct Settings settings
Definition: init.c:40
static void init_beforeplay(void)
Definition: init.c:1096
void service_handle()
Definition: win32.c:343
char dm_mail[MAX_BUF]
Definition: global.h:277
#define NROFATTACKS
Definition: attack.h:17
#define atoll
Definition: win32.h:170
void init_gods(void)
Definition: holy.c:53
void init_commands(void)
Definition: commands.c:286
uint8_t fastclock
Definition: global.h:294
void service_register()
Definition: win32.c:180
uint8_t crypt_mode
Definition: global.h:327
sstring add_string(const char *str)
Definition: shstr.c:124
uint8_t dumpvalues
Definition: global.h:239
static void call_version(void)
Definition: init.c:54
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
static void init_races(void)
Definition: init.c:1224
#define FLAG_MONSTER
Definition: define.h:245
EXTERN long init_done
Definition: global.h:132
char * strdup(const char *str)
Definition: porting.c:200
uint8_t set_title
Definition: global.h:261
static void free_races(void)
Definition: init.c:1317
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
static void set_dumpmon5(void)
Definition: init.c:95
struct _materialtype * next
Definition: material.h:39
uint32_t worldmapstartx
Definition: global.h:288
static void rec_sighup(int i)
Definition: init.c:1193
#define FULL_VERSION
Definition: version.h:6
int metaserver2_init(void)
Definition: metaserver.c:163
void(* cmdlinefunc_args0)(void)
Definition: init.c:256
int allow_denied_spells_writing
Definition: global.h:312
#define SHUTDOWN_FILE
Definition: config.h:509
uint8_t roll_stat_points
Definition: global.h:320
uint32_t worldmaptilesizex
Definition: global.h:292
static void set_uniquedir(const char *path)
Definition: init.c:188
void hiscore_init(void)
Definition: hiscore.c:285
int pk_max_experience_percent
Definition: global.h:311
int16_t level
Definition: object.h:351
uint8_t spell_failure_effects
Definition: global.h:265
void init_archetype_pointers(void)
Definition: treasure.c:64
void(* cmdlinefunc_args2)(const char *arg1, const char *arg2)
Definition: init.c:258
void init_ob_methods(void)
Definition: ob_methods.c:35
float item_power_factor
Definition: global.h:300
const char * name
Definition: object.h:466
static void set_dumpmon6(void)
Definition: init.c:100
void init_artifacts(void)
Definition: artifact.c:530
uint8_t resurrection
Definition: global.h:262
int16_t pk_luck_penalty
Definition: global.h:253
static materialtype_t * get_empty_mat(void)
Definition: init.c:399
uint8_t personalized_blessings
Definition: global.h:309
void init_skills(void)
Definition: skill_util.c:67
const char * description
Definition: material.h:35
static racelink * get_racelist(void)
Definition: init.c:1375
char * account_trusted_host
Definition: global.h:326