Crossfire Server, Trunk  R21466
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 if (!strcasecmp(buf, "min_name")) {
969  int val = atoi(cp);
970 
971  if (val < 1 || val > MAX_NAME )
972  LOG(llevError, "load_settings: min_name (%d) need to be within %d-%d\n",
973  val, 1, MAX_NAME);
974  else
975  settings.min_name = val;
976  } else {
977  LOG(llevError, "Unknown value in settings file: %s\n", buf);
978  }
979  }
980  fclose(fp);
981  if (settings.log_timestamp_format == NULL)
982  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
983 
984  /*
985  * The who formats are defined in config to be blank. They should have been
986  * overridden by the settings file, if there are no entries however, it will
987  * have stayed blank. Since this probably isn't what is wanted, we will check if
988  * new formats have been specified, and if not we will use the old defaults.
989  */
990  if (!strcmp(settings.who_format, ""))
991  strcpy(settings.who_format, "%N_%T%t%h%d%b%n<%m>");
992  if (!strcmp(settings.who_wiz_format, ""))
993  strcpy(settings.who_wiz_format, "%N_%T%t%h%d%b%nLevel %l <%m>(@%i)(%c)");
994 }
995 
1003 void init(int argc, char **argv) {
1004  init_done = 0; /* Must be done before init_signal() */
1005  logfile = stderr;
1006 
1007  /* First argument pass - right now it does nothing, but in the future specifying
1008  * the LibDir in this pass would be reasonable. */
1009  parse_args(argc, argv, 1);
1010 
1011  init_library(); /* Must be called early */
1012  load_settings(); /* Load the settings file */
1013  load_materials();
1014  parse_args(argc, argv, 2);
1015 
1016  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
1017  SRANDOM(time(NULL));
1018 
1019  init_startup(); /* Check shutdown/forbid files */
1020  init_signals(); /* Sets up signal interceptions */
1021  init_commands(); /* Sort command tables */
1022  read_map_log(); /* Load up the old temp map files */
1023  init_skills();
1024  init_ob_methods();
1025  cftimer_init();
1026  hiscore_init();
1027 
1028  parse_args(argc, argv, 3);
1029 
1030  init_beforeplay();
1031  init_server();
1032  metaserver2_init();
1033  accounts_load();
1034  reset_sleep();
1035  init_done = 1;
1036 }
1037 
1043 void free_server(void) {
1044  free_materials();
1045  free_races();
1046  free_quest();
1048  while (settings.disabled_plugins) {
1050  free((void *)settings.disabled_plugins->name);
1051  free(settings.disabled_plugins);
1052  settings.disabled_plugins = next;
1053  }
1054 }
1055 
1059 static void help(void) {
1060  printf("Usage: crossfire-server [options]\n\n");
1061 
1062  printf("Options:\n");
1063  printf(" -arch Set the file with archetype definitions.\n");
1064  printf(" -conf Set the directory to find configuration files.\n");
1065  printf(" -d Turn on extra debugging messages.\n");
1066  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1067  printf(" -disable-plugin\n"
1068  " Disables specified plugin. Use the name without the extension.\n"
1069  " Can be specified multiple times. 'All' disables all plugins.\n");
1070  printf(" -dump-anims Dump animations.\n");
1071  printf(" -h Print this help message.\n");
1072  printf(" -local Set the local data (var/) directory.\n");
1073  printf(" -log <file> Write logging information to the given file.\n");
1074  printf(" -m List suggested experience for all monsters.\n");
1075  printf(" -m2 Dump monster abilities.\n");
1076  printf(" -m3 Dump artifact information.\n");
1077  printf(" -m4 Dump spell information.\n");
1078  printf(" -m5 Dump skill information.\n");
1079  printf(" -m6 Dump race information.\n");
1080  printf(" -m7 Dump alchemy information.\n");
1081  printf(" -m8 Dump gods information.\n");
1082  printf(" -m9 Dump more alchemy information (formula checking).\n");
1083  printf(" -maps Set the map directory.\n");
1084  printf(" -mexp Dump the experience table.\n");
1085  printf(" -mon Turn on monster debugging.\n");
1086  printf(" -mq Dump the quest list.\n");
1087  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1088  printf(" -n Turn off debugging messages if on by default.\n");
1089  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1090  printf(" -playerdir Set the player files directory.\n");
1091  printf(" -regions Set the region file.\n");
1092  printf(" -templatedir Set the template map directory.\n");
1093  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1094  printf(" -treasures Set the treasures file.\n");
1095  printf(" -uniquedir Set the unique items/maps directory.\n");
1096  printf(" -v Print version information.\n");
1097  exit(EXIT_SUCCESS);
1098 }
1099 
1104 static void init_beforeplay(void) {
1105  init_archetypes(); /* If not called before, reads all archetypes from file */
1106  init_artifacts(); /* If not called before, reads all artifacts from file */
1107  check_spells(); /* If not called before, links archtypes used by spells */
1108  init_regions(); /* If not called before, reads all regions from file */
1109  init_archetype_pointers(); /* Setup global pointers to archetypes */
1110  init_races(); /* overwrite race designations using entries in lib/races file */
1111  init_gods(); /* init linked list of gods from archs*/
1112  init_readable(); /* inits useful arrays for readable texts */
1113  init_formulae(); /* If not called before, reads formulae from file */
1114 
1115  switch (settings.dumpvalues) {
1116  case 1:
1117  print_monsters();
1118  cleanup();
1119 
1120  case 2:
1121  dump_abilities();
1122  cleanup();
1123 
1124  case 3:
1125  dump_artifacts();
1126  cleanup();
1127 
1128  case 4:
1129  dump_spells();
1130  cleanup();
1131 
1132  case 5:
1133  cleanup();
1134 
1135  case 6:
1136  dump_races();
1137  cleanup();
1138 
1139  case 7:
1140  dump_alchemy();
1141  cleanup();
1142 
1143  case 8:
1144  dump_gods();
1145  cleanup();
1146 
1147  case 9:
1149  cleanup();
1150 
1151  case 10:
1153  cleanup();
1154  }
1155 }
1156 
1162 static void init_startup(void) {
1163  char buf[MAX_BUF];
1164  FILE *fp;
1165 
1166 #ifdef SHUTDOWN_FILE
1167  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1168  if ((fp = fopen(buf, "r")) != NULL) {
1169  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1170  printf("%s", buf);
1171  fclose(fp);
1172  exit(1);
1173  }
1174 #endif
1175 
1176  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1177  LOG(llevError, "CrossFire: Playing not allowed.\n");
1178  exit(-1);
1179  }
1180 }
1181 
1185 static void signal_shutdown(int signum_unused) {
1186  (void) signum_unused; /* avoid unused warning if enambled */
1187  shutdown_flag += 1;
1188 }
1189 
1202 static void rec_sighup(int i) {
1203  /* Don't call LOG(). It calls non-reentrant functions. The other
1204  * signal handlers shouldn't really call LOG() either. */
1205  if (logfile != stderr) {
1206  reopen_logfile = 1;
1207  }
1208 }
1209 
1213 static void init_signals(void) {
1214 #ifndef WIN32 /* init_signals() remove signals */
1215  struct sigaction sa;
1216 
1217  sa.sa_sigaction = NULL;
1218  sigemptyset(&sa.sa_mask);
1219  sa.sa_flags = 0;
1220  sa.sa_handler = rec_sighup;
1221  sigaction(SIGHUP, &sa, NULL);
1222  signal(SIGINT, signal_shutdown);
1223  signal(SIGPIPE, SIG_IGN);
1224 #endif /* win32 */
1225 }
1226 
1233 static void init_races(void) {
1234  FILE *file;
1235  char race[MAX_BUF], fname[MAX_BUF], buf[MAX_BUF], *cp, variable[MAX_BUF];
1236  archetype *mon = NULL;
1237  static int init_done = 0;
1238 
1239  if (init_done)
1240  return;
1241  init_done = 1;
1242  first_race = NULL;
1243 
1244  snprintf(fname, sizeof(fname), "%s/races", settings.datadir);
1245  if (!(file = fopen(fname, "r"))) {
1246  LOG(llevError, "Cannot open races file %s: %s\n", fname, strerror(errno));
1247  return;
1248  }
1249 
1250  while (fgets(buf, MAX_BUF, file) != NULL) {
1251  int set_race = 1, set_list = 1;
1252  if (*buf == '#')
1253  continue;
1254  if ((cp = strchr(buf, '\n')) != NULL)
1255  *cp = '\0';
1256  cp = buf;
1257  while (*cp == ' ' || *cp == '!' || *cp == '@') {
1258  if (*cp == '!')
1259  set_race = 0;
1260  if (*cp == '@')
1261  set_list = 0;
1262  cp++;
1263  }
1264  if (sscanf(cp, "RACE %s", variable)) { /* set new race value */
1265  strcpy(race, variable);
1266  } else {
1267  char *cp1;
1268 
1269  /* Take out beginning spaces */
1270  for (cp1 = cp; *cp1 == ' '; cp1++)
1271  ;
1272  /* Remove newline and trailing spaces */
1273  for (cp1 = cp+strlen(cp)-1; *cp1 == '\n' || *cp1 == ' '; cp1--) {
1274  *cp1 = '\0';
1275  if (cp == cp1)
1276  break;
1277  }
1278 
1279  if (cp[strlen(cp)-1] == '\n')
1280  cp[strlen(cp)-1] = '\0';
1281  /* set creature race to race value */
1282  if ((mon = find_archetype(cp)) == NULL)
1283  LOG(llevError, "Creature %s in race file lacks archetype\n", cp);
1284  else {
1285  // If the race is specified somewhere in the race field, we are good.
1286  // This allows us to specify multiple races on arches that are in the races file.
1287  if (set_race && (!mon->clone.race || !strstr(mon->clone.race, race))) {
1288  if (mon->clone.race) {
1289  LOG(llevDebug, "races: Appending to %s from %s for archetype %s\n", race, mon->clone.race, mon->name);
1290  // Copy the existing race into the race total list.
1291  strcpy(race+strlen(race), ","); // Arbitrary separator
1292  strncpy(race+strlen(race), mon->clone.race, MAX_BUF - 1 - strlen(race));
1293  // Clear the existing race string so we can add the new one
1294  free_string(mon->clone.race);
1295  }
1296  mon->clone.race = add_string(race);
1297  }
1298  /* if the arch is a monster, add it to the race list */
1299  if (set_list && QUERY_FLAG(&mon->clone, FLAG_MONSTER))
1300  add_to_racelist(race, &mon->clone);
1301  }
1302  }
1303  }
1304  fclose(file);
1305  LOG(llevDebug, "loaded races\n");
1306 }
1307 
1311 static void dump_races(void) {
1312  racelink *list;
1313  objectlink *tmp;
1314 
1315  for (list = first_race; list; list = list->next) {
1316  fprintf(stderr, "\nRACE %s:\t", list->name);
1317  for (tmp = list->member; tmp; tmp = tmp->next)
1318  fprintf(stderr, "%s(%d), ", tmp->ob->arch->name, tmp->ob->level);
1319  }
1320  fprintf(stderr, "\n");
1321 }
1322 
1326 static void free_races(void) {
1327  racelink *race;
1328  objectlink *link;
1329 
1330  LOG(llevDebug, "Freeing race information.\n");
1331  while (first_race) {
1332  race = first_race->next;
1333  while (first_race->member) {
1334  link = first_race->member->next;
1335  free(first_race->member);
1336  first_race->member = link;
1337  }
1339  free(first_race);
1340  first_race = race;
1341  }
1342 }
1343 
1352 static void add_to_racelist(const char *race_name, object *op) {
1353  racelink *race;
1354 
1355  if (!op || !race_name)
1356  return;
1357  race = find_racelink(race_name);
1358 
1359  if (!race) { /* add in a new race list */
1360  race = get_racelist();
1361  race->next = first_race;
1362  first_race = race;
1363  race->name = add_string(race_name);
1364  }
1365 
1366  if (race->member->ob) {
1367  objectlink *tmp = get_objectlink();
1368 
1369  tmp->next = race->member;
1370  race->member = tmp;
1371  }
1372  race->nrof++;
1373  race->member->ob = op;
1374 }
1375 
1384 static racelink *get_racelist(void) {
1385  racelink *list;
1386 
1387  list = (racelink *)malloc(sizeof(racelink));
1388  if (!list)
1390  list->name = NULL;
1391  list->nrof = 0;
1392  list->member = get_objectlink();
1393  list->next = NULL;
1394 
1395  return list;
1396 }
1397 
1406 racelink *find_racelink(const char *name) {
1407  racelink *test = NULL;
1408 
1409  if (name && first_race)
1410  for (test = first_race; test && test != test->next; test = test->next)
1411  if (!test->name || !strcmp(name, test->name))
1412  break;
1413 
1414  return test;
1415 }
EXTERN FILE * logfile
Definition: global.h:142
static void set_dumpmon2(void)
Definition: init.c:80
uint8_t not_permadeth
Definition: global.h:264
static void server_dump_animations(void)
Definition: init.c:249
archetype * find_archetype(const char *name)
Definition: arch.c:695
static void set_dumpmon8(void)
Definition: init.c:110
uint8_t create_home_portals
Definition: global.h:314
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:258
char meta_host[MAX_BUF]
Definition: global.h:290
uint8_t max_stat
Definition: global.h:327
uint32_t worldmaptilesx
Definition: global.h:296
void free_quest_definitions(void)
Definition: quest.c:1307
uint8_t pass
Definition: init.c:269
Definition: object.h:444
static void free_materials(void)
Definition: init.c:494
const char * race
Definition: object.h:318
uint8_t spell_encumbrance
Definition: global.h:270
static void set_dumpmon7(void)
Definition: init.c:105
uint32_t worldmaptilesizey
Definition: global.h:299
const char * name
Definition: material.h:34
uint8_t starting_stat_min
Definition: global.h:323
void(* func)()
Definition: init.c:270
unsigned int meta_on
Definition: global.h:288
linked_char * disabled_plugins
Definition: global.h:329
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:291
Definition: race.h:12
uint8_t death_penalty_level
Definition: global.h:262
static void check_spells(void)
Definition: arch.c:513
#define strdup_local
Definition: compat.h:25
char who_wiz_format[MAX_BUF]
Definition: global.h:279
static void set_dumpmon1(void)
Definition: init.c:75
uint8_t spellpoint_level_depend
Definition: global.h:276
int nrof
Definition: race.h:14
char motd[MAX_BUF]
Definition: global.h:280
uint8_t num_args
Definition: init.c:268
int forbid_play(void)
Definition: server.c:1271
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:243
const char * playerdir
Definition: global.h:250
void free_string(sstring str)
Definition: shstr.c:280
static void unset_debug(void)
Definition: init.c:65
uint32_t worldmapstarty
Definition: global.h:295
int reopen_logfile
Definition: logger.c:26
object clone
Definition: object.h:472
const char * regions
Definition: global.h:253
int allow_broken_converters
Definition: global.h:319
void init_archetypes(void)
Definition: arch.c:182
int armor_max_enchant
Definition: global.h:308
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:186
uint8_t starting_stat_max
Definition: global.h:324
void accounts_load(void)
Definition: account.c:121
void dump_experience(void)
Definition: exp.c:250
#define TRUE
Definition: compat.h:10
LogLevel debug
Definition: global.h:244
#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:261
char meta_server[MAX_BUF]
Definition: global.h:289
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:297
const char * treasures
Definition: global.h:254
Definition: object.h:467
racelink * find_racelink(const char *name)
Definition: init.c:1406
const char * logfilename
Definition: global.h:242
void dump_alchemy_costs(void)
Definition: recipe.c:523
uint8_t casting_time
Definition: global.h:272
uint8_t recycle_tmp_maps
Definition: global.h:274
static void set_localdir(const char *path)
Definition: init.c:148
#define SRANDOM(seed)
Definition: define.h:683
char meta_comment[MAX_BUF]
Definition: global.h:292
static void set_mapdir(const char *path)
Definition: init.c:156
void cleanup(void)
Definition: server.c:1167
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:1352
void dump_animations(void)
Definition: anim.c:349
object * ob
Definition: object.h:445
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:322
int armor_speed_improvement
Definition: global.h:311
void init(int argc, char **argv)
Definition: init.c:1003
const char * dumparg
Definition: global.h:246
static void set_disable_plugin(const char *name)
Definition: init.c:239
void free_server(void)
Definition: init.c:1043
signed short int16_t
Definition: win32.h:160
uint8_t search_items
Definition: global.h:269
static void signal_shutdown(int signum_unused)
Definition: init.c:1185
uint8_t min_name
Definition: global.h:334
static void init_signals(void)
Definition: init.c:1213
const char * tmpdir
Definition: global.h:257
int64_t pk_max_experience
Definition: global.h:316
uint8_t always_show_hp
Definition: global.h:275
void service_unregister()
Definition: win32.c:225
static void init_startup(void)
Definition: init.c:1162
#define snprintf
Definition: win32.h:46
void dump_artifacts(void)
Definition: artifact.c:683
void dump_alchemy(void)
Definition: recipe.c:321
struct linked_char * next
Definition: global.h:88
uint8_t armor_weight_linear
Definition: global.h:310
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:263
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:312
static void help(void)
Definition: init.c:1059
EXTERN racelink * first_race
Definition: global.h:125
uint8_t real_wiz
Definition: global.h:273
void cftimer_init(void)
Definition: timers.c:157
uint8_t ignore_plugin_compatibility
Definition: global.h:330
const char * templatedir
Definition: global.h:256
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:252
uint8_t simple_exp
Definition: global.h:265
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.c:53
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:278
static void dump_races(void)
Definition: init.c:1311
void reset_sleep(void)
Definition: time.c:130
const char * confdir
Definition: global.h:247
signed __int64 int64_t
Definition: win32.h:168
uint8_t account_block_create
Definition: global.h:331
const char * uniquedir
Definition: global.h:255
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:260
int log_timestamp
Definition: global.h:321
const char * datadir
Definition: global.h:248
void dump_spells(void)
Definition: spell_util.c:146
uint8_t special_break_map
Definition: global.h:328
const char * name
Definition: global.h:87
uint16_t set_friendly_fire
Definition: global.h:277
int armor_weight_reduction
Definition: global.h:309
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:249
uint8_t starting_stat_points
Definition: global.h:325
struct archt * arch
Definition: object.h:414
struct oblnk * next
Definition: object.h:446
uint8_t no_player_stealing
Definition: global.h:313
void dump_monster_treasure(const char *name)
Definition: treasure.c:1448
const char * name
Definition: race.h:13
const char * mapdir
Definition: global.h:251
struct Settings settings
Definition: init.c:39
static void init_beforeplay(void)
Definition: init.c:1104
void service_handle()
Definition: win32.c:343
char dm_mail[MAX_BUF]
Definition: global.h:283
#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:289
uint8_t fastclock
Definition: global.h:300
void service_register()
Definition: win32.c:180
uint8_t crypt_mode
Definition: global.h:333
sstring add_string(const char *str)
Definition: shstr.c:124
uint8_t dumpvalues
Definition: global.h:245
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:1233
#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:267
static void free_races(void)
Definition: init.c:1326
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
#define MAX_NAME
Definition: define.h:41
uint32_t worldmapstartx
Definition: global.h:294
static void rec_sighup(int i)
Definition: init.c:1202
#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:318
#define SHUTDOWN_FILE
Definition: config.h:462
uint8_t roll_stat_points
Definition: global.h:326
uint32_t worldmaptilesizex
Definition: global.h:298
static void set_uniquedir(const char *path)
Definition: init.c:188
void hiscore_init(void)
Definition: hiscore.c:286
int pk_max_experience_percent
Definition: global.h:317
int16_t level
Definition: object.h:352
uint8_t spell_failure_effects
Definition: global.h:271
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:306
const char * name
Definition: object.h:468
static void set_dumpmon6(void)
Definition: init.c:100
void init_artifacts(void)
Definition: artifact.c:530
uint8_t resurrection
Definition: global.h:268
int16_t pk_luck_penalty
Definition: global.h:259
static materialtype_t * get_empty_mat(void)
Definition: init.c:399
uint8_t personalized_blessings
Definition: global.h:315
void init_skills(void)
Definition: skill_util.c:68
const char * description
Definition: material.h:35
static racelink * get_racelist(void)
Definition: init.c:1384
char * account_trusted_host
Definition: global.h:332