Crossfire Server, Trunk  R20513
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, "who_format")) {
710  if (has_val)
712  sizeof(settings.who_format));
713  } else if (!strcasecmp(buf, "who_wiz_format")) {
714  if (has_val) {
716  sizeof(settings.who_wiz_format));
717  }
718  } else if (!strcasecmp(buf, "spellpoint_level_depend")) {
719  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
721  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
723  } else {
724  LOG(llevError, "load_settings: Unknown value for spellpoint_level_depend: %s\n", cp);
725  }
726  } else if (!strcasecmp(buf, "stat_loss_on_death")) {
727  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
729  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
731  } else {
732  LOG(llevError, "load_settings: Unknown value for stat_loss_on_death: %s\n", cp);
733  }
734  } else if (!strcasecmp(buf, "use_permanent_experience")) {
735  LOG(llevError, "use_permanent_experience is deprecated, usepermenent_experience_percentage instead\n");
736  } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
737  int val = atoi(cp);
738  if (val < 0 || val > 100)
739  LOG(llevError, "load_settings: permenent_experience_percentage must be between 0 and 100, %d is invalid\n", val);
740  else
742  } else if (!strcasecmp(buf, "death_penalty_percentage")) {
743  int val = atoi(cp);
744  if (val < 0 || val > 100)
745  LOG(llevError, "load_settings: death_penalty_percentage must be between 0 and 100, %d is invalid\n", val);
746  else
748  } else if (!strcasecmp(buf, "death_penalty_levels")) {
749  int val = atoi(cp);
750  if (val < 0 || val > 255)
751  LOG(llevError, "load_settings: death_penalty_levels can not be negative, %d is invalid\n", val);
752  else
754  } else if (!strcasecmp(buf, "balanced_stat_loss")) {
755  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
757  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
759  } else {
760  LOG(llevError, "load_settings: Unknown value for balanced_stat_loss: %s\n", cp);
761  }
762  } else if (!strcasecmp(buf, "simple_exp")) {
763  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
765  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
767  } else {
768  LOG(llevError, "load_settings: Unknown value for simple_exp: %s\n", cp);
769  }
770  } else if (!strcasecmp(buf, "item_power_factor")) {
771  float tmp = atof(cp);
772  if (tmp < 0)
773  LOG(llevError, "load_settings: item_power_factor must be a positive number (%f < 0)\n", tmp);
774  else
776  } else if (!strcasecmp(buf, "pk_luck_penalty")) {
777  int16_t val = atoi(cp);
778 
779  if (val < -100 || val > 100)
780  LOG(llevError, "load_settings: pk_luck_penalty must be between -100 and 100, %d is invalid\n", val);
781  else
783  } else if (!strcasecmp(buf, "set_friendly_fire")) {
784  int val = atoi(cp);
785 
786  if (val < 1 || val > 100)
787  LOG(llevError, "load_settings: set_friendly_fire must be between 1 an 100, %d is invalid\n", val);
788  else
790  } else if (!strcasecmp(buf, "armor_max_enchant")) {
791  int max_e = atoi(cp);
792  if (max_e <= 0)
793  LOG(llevError, "load_settings: armor_max_enchant is %d\n", max_e);
794  else
795  settings.armor_max_enchant = max_e;
796  } else if (!strcasecmp(buf, "armor_weight_reduction")) {
797  int wr = atoi(cp);
798  if (wr < 0)
799  LOG(llevError, "load_settings: armor_weight_reduction is %d\n", wr);
800  else
802  } else if (!strcasecmp(buf, "armor_weight_linear")) {
803  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
805  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
807  } else {
808  LOG(llevError, "load_settings: unknown value for armor_weight_linear: %s\n", cp);
809  }
810  } else if (!strcasecmp(buf, "armor_speed_improvement")) {
811  int wr = atoi(cp);
812  if (wr < 0)
813  LOG(llevError, "load_settings: armor_speed_improvement is %d\n", wr);
814  else
816  } else if (!strcasecmp(buf, "armor_speed_linear")) {
817  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
819  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
821  } else {
822  LOG(llevError, "load_settings: unknown value for armor_speed_linear: %s\n", cp);
823  }
824  } else if (!strcasecmp(buf, "no_player_stealing")) {
825  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
827  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
829  } else {
830  LOG(llevError, "load_settings: unknown value for no_player_stealing: %s\n", cp);
831  }
832  } else if (!strcasecmp(buf, "create_home_portals")) {
833  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
835  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
837  } else {
838  LOG(llevError, "load_settings: unknown value for create_home_portals: %s\n", cp);
839  }
840  } else if (!strcasecmp(buf, "personalized_blessings")) {
841  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
843  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
845  } else {
846  LOG(llevError, "load_settings: unknown value for personalized_blessings: %s\n", cp);
847  }
848  } else if (!strcasecmp(buf, "pk_max_experience")) {
849  int64_t pkme = atoll(cp);
850  if (pkme < 0)
851  pkme = -1;
853  } else if (!strcasecmp(buf, "pk_max_experience_percent")) {
854  int pkmep = atoi(cp);
855  if (pkmep < 0) {
856  LOG(llevError, "load_settings: pk_max_experience_percent should be positive or zero (was \"%s\")\n", cp);
857  } else
859  } else if (!strcasecmp(buf, "allow_denied_spells_writing")) {
860  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
862  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
864  } else {
865  LOG(llevError, "load_settings: unknown value for allow_denied_spells_writing: %s\n", cp);
866  }
867  } else if (!strcasecmp(buf, "allow_broken_converters")) {
868  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
870  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
872  } else {
873  LOG(llevError, "load_settings: unknown value for allow_broken_converters: %s\n", cp);
874  }
875  } else if (!strcasecmp(buf, "log_timestamp")) {
876  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
878  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
880  } else {
881  LOG(llevError, "load_settings: unknown value for log_timestamp: %s\n", cp);
882  }
883  } else if (!strcasecmp(buf, "log_timestamp_format")) {
886  } else if (!strcasecmp(buf, "starting_stat_min")) {
887  int val = atoi(cp);
888 
889  if (val < 1 || val > settings.max_stat || val > settings.starting_stat_max)
890  LOG(llevError, "load_settings: starting_stat_min (%d) need to be within %d-%d (%d)\n",
892  else
894  } else if (!strcasecmp(buf, "starting_stat_max")) {
895  int val = atoi(cp);
896 
897  if (val < 1 || val > settings.max_stat || val<settings.starting_stat_min)
898  LOG(llevError, "load_settings: starting_stat_max (%d) need to be within %d-%d (%d)\n",
900  else
902  } else if (!strcasecmp(buf, "starting_stat_points")) {
903  int val = atoi(cp);
904 
905  if (val < NUM_STATS * settings.starting_stat_min ||
907  LOG(llevError, "load_settings: starting_stat_points (%d) need to be within %d-%d\n",
909  else
911  } else if (!strcasecmp(buf, "roll_stat_points")) {
912  int val = atoi(cp);
913 
914  /* The 3 and 18 values are hard coded in because we know that
915  * roll_stat() generates a value between 3 and 18 - if that ever
916  * changed, this code should change also, but that code will eventually
917  * go away.
918  */
919  if (val < NUM_STATS * 3 || val > NUM_STATS * 18)
920  LOG(llevError, "load_settings: roll_stat_points need to be within %d-%d\n",
921  NUM_STATS * 3, NUM_STATS * 18);
922  else
924  } else if (!strcasecmp(buf, "special_break_map")) {
925  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
927  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
929  } else {
930  LOG(llevError, "load_settings: unknown value for special_break_map: %s\n", cp);
931  }
932  } else if (!strcasecmp(buf, "ignore_plugin_compatibility")) {
933  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
935  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
937  } else {
938  LOG(llevError, "load_settings: unknown value for ignore_plugin_compatibility: %s\n", cp);
939  }
940  } else if (!strcasecmp(buf, "account_block_create")) {
941  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
943  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
945  } else {
946  LOG(llevError, "load_settings: unknown value for account_block_create: %s\n", cp);
947  }
948  } else if (!strcasecmp(buf, "account_trusted_host")) {
951  } else {
952  LOG(llevError, "Unknown value in settings file: %s\n", buf);
953  }
954  }
955  fclose(fp);
956  if (settings.log_timestamp_format == NULL)
957  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
958 
959  /*
960  * The who formats are defined in config to be blank. They should have been
961  * overridden by the settings file, if there are no entries however, it will
962  * have stayed blank. Since this probably isn't what is wanted, we will check if
963  * new formats have been specified, and if not we will use the old defaults.
964  */
965  if (!strcmp(settings.who_format, ""))
966  strcpy(settings.who_format, "%N_%T%t%h%d%b%n<%m>");
967  if (!strcmp(settings.who_wiz_format, ""))
968  strcpy(settings.who_wiz_format, "%N_%T%t%h%d%b%nLevel %l <%m>(@%i)(%c)");
969 }
970 
978 void init(int argc, char **argv) {
979  init_done = 0; /* Must be done before init_signal() */
980  logfile = stderr;
981 
982  /* First argument pass - right now it does nothing, but in the future specifying
983  * the LibDir in this pass would be reasonable. */
984  parse_args(argc, argv, 1);
985 
986  init_library(); /* Must be called early */
987  load_settings(); /* Load the settings file */
988  load_materials();
989  parse_args(argc, argv, 2);
990 
991  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
992  SRANDOM(time(NULL));
993 
994  init_startup(); /* Check shutdown/forbid files */
995  init_signals(); /* Sets up signal interceptions */
996  init_commands(); /* Sort command tables */
997  read_map_log(); /* Load up the old temp map files */
998  init_skills();
999  init_ob_methods();
1000  cftimer_init();
1001  hiscore_init();
1002 
1003  parse_args(argc, argv, 3);
1004 
1005  init_beforeplay();
1006  init_server();
1007  metaserver2_init();
1008  accounts_load();
1009  reset_sleep();
1010  init_done = 1;
1011 }
1012 
1018 void free_server(void) {
1019  free_materials();
1020  free_races();
1021  free_quest();
1023  while (settings.disabled_plugins) {
1025  free((void *)settings.disabled_plugins->name);
1026  free(settings.disabled_plugins);
1027  settings.disabled_plugins = next;
1028  }
1029 }
1030 
1034 static void help(void) {
1035  printf("Usage: crossfire-server [options]\n\n");
1036 
1037  printf("Options:\n");
1038  printf(" -arch Set the file with archetype definitions.\n");
1039  printf(" -conf Set the directory to find configuration files.\n");
1040  printf(" -d Turn on extra debugging messages.\n");
1041  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1042  printf(" -disable-plugin\n"
1043  " Disables specified plugin. Use the name without the extension.\n"
1044  " Can be specified multiple times. 'All' disables all plugins.\n");
1045  printf(" -dump-anims Dump animations.\n");
1046  printf(" -h Print this help message.\n");
1047  printf(" -local Set the local data (var/) directory.\n");
1048  printf(" -log <file> Write logging information to the given file.\n");
1049  printf(" -m List suggested experience for all monsters.\n");
1050  printf(" -m2 Dump monster abilities.\n");
1051  printf(" -m3 Dump artifact information.\n");
1052  printf(" -m4 Dump spell information.\n");
1053  printf(" -m5 Dump skill information.\n");
1054  printf(" -m6 Dump race information.\n");
1055  printf(" -m7 Dump alchemy information.\n");
1056  printf(" -m8 Dump gods information.\n");
1057  printf(" -m9 Dump more alchemy information (formula checking).\n");
1058  printf(" -maps Set the map directory.\n");
1059  printf(" -mexp Dump the experience table.\n");
1060  printf(" -mon Turn on monster debugging.\n");
1061  printf(" -mq Dump the quest list.\n");
1062  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1063  printf(" -n Turn off debugging messages if on by default.\n");
1064  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1065  printf(" -playerdir Set the player files directory.\n");
1066  printf(" -regions Set the region file.\n");
1067  printf(" -templatedir Set the template map directory.\n");
1068  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1069  printf(" -treasures Set the treasures file.\n");
1070  printf(" -uniquedir Set the unique items/maps directory.\n");
1071  printf(" -v Print version information.\n");
1072  exit(EXIT_SUCCESS);
1073 }
1074 
1079 static void init_beforeplay(void) {
1080  init_archetypes(); /* If not called before, reads all archetypes from file */
1081  init_artifacts(); /* If not called before, reads all artifacts from file */
1082  check_spells(); /* If not called before, links archtypes used by spells */
1083  init_regions(); /* If not called before, reads all regions from file */
1084  init_archetype_pointers(); /* Setup global pointers to archetypes */
1085  init_races(); /* overwrite race designations using entries in lib/races file */
1086  init_gods(); /* init linked list of gods from archs*/
1087  init_readable(); /* inits useful arrays for readable texts */
1088  init_formulae(); /* If not called before, reads formulae from file */
1089 
1090  switch (settings.dumpvalues) {
1091  case 1:
1092  print_monsters();
1093  cleanup();
1094 
1095  case 2:
1096  dump_abilities();
1097  cleanup();
1098 
1099  case 3:
1100  dump_artifacts();
1101  cleanup();
1102 
1103  case 4:
1104  dump_spells();
1105  cleanup();
1106 
1107  case 5:
1108  cleanup();
1109 
1110  case 6:
1111  dump_races();
1112  cleanup();
1113 
1114  case 7:
1115  dump_alchemy();
1116  cleanup();
1117 
1118  case 8:
1119  dump_gods();
1120  cleanup();
1121 
1122  case 9:
1124  cleanup();
1125 
1126  case 10:
1128  cleanup();
1129  }
1130 }
1131 
1137 static void init_startup(void) {
1138  char buf[MAX_BUF];
1139  FILE *fp;
1140 
1141 #ifdef SHUTDOWN_FILE
1142  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1143  if ((fp = fopen(buf, "r")) != NULL) {
1144  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1145  printf("%s", buf);
1146  fclose(fp);
1147  exit(1);
1148  }
1149 #endif
1150 
1151  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1152  LOG(llevError, "CrossFire: Playing not allowed.\n");
1153  exit(-1);
1154  }
1155 }
1156 
1160 static void signal_shutdown() {
1161  shutdown_flag += 1;
1162 }
1163 
1176 static void rec_sighup(int i) {
1177  /* Don't call LOG(). It calls non-reentrant functions. The other
1178  * signal handlers shouldn't really call LOG() either. */
1179  if (logfile != stderr) {
1180  reopen_logfile = 1;
1181  }
1182 }
1183 
1187 static void init_signals(void) {
1188 #ifndef WIN32 /* init_signals() remove signals */
1189  struct sigaction sa;
1190 
1191  sa.sa_sigaction = NULL;
1192  sigemptyset(&sa.sa_mask);
1193  sa.sa_flags = 0;
1194  sa.sa_handler = rec_sighup;
1195  sigaction(SIGHUP, &sa, NULL);
1196  signal(SIGINT, signal_shutdown);
1197  signal(SIGPIPE, SIG_IGN);
1198 #endif /* win32 */
1199 }
1200 
1207 static void init_races(void) {
1208  FILE *file;
1209  char race[MAX_BUF], fname[MAX_BUF], buf[MAX_BUF], *cp, variable[MAX_BUF];
1210  archetype *mon = NULL;
1211  static int init_done = 0;
1212 
1213  if (init_done)
1214  return;
1215  init_done = 1;
1216  first_race = NULL;
1217 
1218  snprintf(fname, sizeof(fname), "%s/races", settings.datadir);
1219  if (!(file = fopen(fname, "r"))) {
1220  LOG(llevError, "Cannot open races file %s: %s\n", fname, strerror(errno));
1221  return;
1222  }
1223 
1224  while (fgets(buf, MAX_BUF, file) != NULL) {
1225  int set_race = 1, set_list = 1;
1226  if (*buf == '#')
1227  continue;
1228  if ((cp = strchr(buf, '\n')) != NULL)
1229  *cp = '\0';
1230  cp = buf;
1231  while (*cp == ' ' || *cp == '!' || *cp == '@') {
1232  if (*cp == '!')
1233  set_race = 0;
1234  if (*cp == '@')
1235  set_list = 0;
1236  cp++;
1237  }
1238  if (sscanf(cp, "RACE %s", variable)) { /* set new race value */
1239  strcpy(race, variable);
1240  } else {
1241  char *cp1;
1242 
1243  /* Take out beginning spaces */
1244  for (cp1 = cp; *cp1 == ' '; cp1++)
1245  ;
1246  /* Remove newline and trailing spaces */
1247  for (cp1 = cp+strlen(cp)-1; *cp1 == '\n' || *cp1 == ' '; cp1--) {
1248  *cp1 = '\0';
1249  if (cp == cp1)
1250  break;
1251  }
1252 
1253  if (cp[strlen(cp)-1] == '\n')
1254  cp[strlen(cp)-1] = '\0';
1255  /* set creature race to race value */
1256  if ((mon = find_archetype(cp)) == NULL)
1257  LOG(llevError, "Creature %s in race file lacks archetype\n", cp);
1258  else {
1259  if (set_race && (!mon->clone.race || strcmp(mon->clone.race, race))) {
1260  if (mon->clone.race) {
1261  LOG(llevDebug, "races: Resetting to %s from %s for archetype %s\n", race, mon->clone.race, mon->name);
1262  free_string(mon->clone.race);
1263  }
1264  mon->clone.race = add_string(race);
1265  }
1266  /* if the arch is a monster, add it to the race list */
1267  if (set_list && QUERY_FLAG(&mon->clone, FLAG_MONSTER))
1268  add_to_racelist(race, &mon->clone);
1269  }
1270  }
1271  }
1272  fclose(file);
1273  LOG(llevDebug, "loaded races\n");
1274 }
1275 
1279 static void dump_races(void) {
1280  racelink *list;
1281  objectlink *tmp;
1282 
1283  for (list = first_race; list; list = list->next) {
1284  fprintf(stderr, "\nRACE %s:\t", list->name);
1285  for (tmp = list->member; tmp; tmp = tmp->next)
1286  fprintf(stderr, "%s(%d), ", tmp->ob->arch->name, tmp->ob->level);
1287  }
1288  fprintf(stderr, "\n");
1289 }
1290 
1294 static void free_races(void) {
1295  racelink *race;
1296  objectlink *link;
1297 
1298  LOG(llevDebug, "Freeing race information.\n");
1299  while (first_race) {
1300  race = first_race->next;
1301  while (first_race->member) {
1302  link = first_race->member->next;
1303  free(first_race->member);
1304  first_race->member = link;
1305  }
1307  free(first_race);
1308  first_race = race;
1309  }
1310 }
1311 
1320 static void add_to_racelist(const char *race_name, object *op) {
1321  racelink *race;
1322 
1323  if (!op || !race_name)
1324  return;
1325  race = find_racelink(race_name);
1326 
1327  if (!race) { /* add in a new race list */
1328  race = get_racelist();
1329  race->next = first_race;
1330  first_race = race;
1331  race->name = add_string(race_name);
1332  }
1333 
1334  if (race->member->ob) {
1335  objectlink *tmp = get_objectlink();
1336 
1337  tmp->next = race->member;
1338  race->member = tmp;
1339  }
1340  race->nrof++;
1341  race->member->ob = op;
1342 }
1343 
1352 static racelink *get_racelist(void) {
1353  racelink *list;
1354 
1355  list = (racelink *)malloc(sizeof(racelink));
1356  if (!list)
1358  list->name = NULL;
1359  list->nrof = 0;
1360  list->member = get_objectlink();
1361  list->next = NULL;
1362 
1363  return list;
1364 }
1365 
1374 racelink *find_racelink(const char *name) {
1375  racelink *test = NULL;
1376 
1377  if (name && first_race)
1378  for (test = first_race; test && test != test->next; test = test->next)
1379  if (!test->name || !strcmp(name, test->name))
1380  break;
1381 
1382  return test;
1383 }
EXTERN FILE * logfile
Used by server/daemon.c.
Definition: global.h:144
static void set_dumpmon2(void)
Command line option: dump abilities.
Definition: init.c:80
Error, serious thing.
Definition: logger.h:11
uint8_t not_permadeth
If true, death is non-permament.
Definition: global.h:260
static void server_dump_animations(void)
Dump all animations, then exit.
Definition: init.c:249
archetype * find_archetype(const char *name)
Finds, using the hashtable, which archetype matches the given name.
Definition: arch.c:695
static void set_dumpmon8(void)
Command line option: dump gods.
Definition: init.c:110
uint8_t create_home_portals
If 1, can create portals in unique maps (apartments)
Definition: global.h:309
int8_t mod[NROFATTACKS]
Modification to resistances.
Definition: material.h:38
int init_regions(void)
Initialises regions from the regions file.
Definition: region.c:292
uint8_t stat_loss_on_death
If true, chars lose a random stat when they die.
Definition: global.h:254
char meta_host[MAX_BUF]
Hostname of this host.
Definition: global.h:285
Information.
Definition: logger.h:12
uint8_t max_stat
Maximum stat value - 255 should be sufficient.
Definition: global.h:322
uint32_t worldmaptilesx
Number of tiles wide the worldmap is.
Definition: global.h:291
void free_quest_definitions(void)
Free all quest definitions and steps.
Definition: quest.c:1307
uint8_t pass
What pass this should be processed on.
Definition: init.c:269
Used to link together several objects.
Definition: object.h:442
static void free_materials(void)
Frees all memory allocated to materials.
Definition: init.c:494
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
uint8_t spell_encumbrance
Encumbrance effects spells.
Definition: global.h:266
static void set_dumpmon7(void)
Command line option: dump alchemy.
Definition: init.c:105
uint32_t worldmaptilesizey
Number of squares high in a wm tile.
Definition: global.h:294
const char * name
Name of the material.
Definition: material.h:34
uint8_t starting_stat_min
Minimum value of a starting stat.
Definition: global.h:318
void(* func)()
function to call when we match this.
Definition: init.c:270
unsigned int meta_on
True if we should send updates.
Definition: global.h:283
linked_char * disabled_plugins
List of disabled plugins, &#39;All&#39; means all.
Definition: global.h:324
EXTERN materialtype_t * materialt
Material types.
Definition: material.h:43
static void set_mondebug(void)
Command line option: monster debug flag.
Definition: init.c:70
unsigned char uint8_t
Definition: win32.h:161
static struct Command_Line_Options options[]
Actual valid command line options.
Definition: init.c:284
void print_monsters(void)
As dump_abilities(), but with an alternative way of output.
Definition: info.c:95
uint16_t meta_port
Port number to use for updates.
Definition: global.h:286
Contains information about a race.
Definition: race.h:12
uint8_t death_penalty_level
How many levels worth of exp may be lost on one death.
Definition: global.h:258
static void check_spells(void)
This ensures all spells have a skill defined, calling fatal() if any error was found.
Definition: arch.c:511
#define strdup_local
Definition: compat.h:25
char who_wiz_format[MAX_BUF]
The format that the who command should use when called by a dm.
Definition: global.h:274
static void set_dumpmon1(void)
Command line option: dump monsters.
Definition: init.c:75
uint8_t spellpoint_level_depend
Spell costs go up with level.
Definition: global.h:271
int nrof
Number of things belonging to this race.
Definition: race.h:14
char motd[MAX_BUF]
Name of the motd file.
Definition: global.h:275
uint8_t num_args
Number or args it takes.
Definition: init.c:268
int forbid_play(void)
Checks if server should be started.
Definition: server.c:1241
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.c:596
static void set_csport(const char *val)
Change the server&#39;s port.
Definition: init.c:226
object * mon
Definition: comet_perf.c:74
int8_t save[NROFATTACKS]
Save chances for the attacks.
Definition: material.h:37
uint16_t csport
Port for new client/server.
Definition: global.h:239
const char * playerdir
Where the player files are.
Definition: global.h:246
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.c:280
static void unset_debug(void)
Command line option: unset debug flag.
Definition: init.c:65
uint32_t worldmapstarty
Starting y tile for the worldmap.
Definition: global.h:290
int reopen_logfile
Definition: logger.c:26
object clone
An object from which to do object_copy()
Definition: object.h:470
const char * regions
Name of the regions file - libdir is prepended.
Definition: global.h:249
int allow_broken_converters
If set, converters will work even if price of generated item is higher than the price of converted it...
Definition: global.h:314
void init_archetypes(void)
Initialises the internal linked list of archetypes (read from file).
Definition: arch.c:182
int armor_max_enchant
Maximum number of times an armor can be enchanted.
Definition: global.h:303
static void parse_args(int argc, char *argv[], int pass)
Parse command line arguments.
Definition: init.c:351
void dump_gods(void)
Prints all gods to stderr.
Definition: holy.c:386
int material
What basic type(s) it is linked to.
Definition: material.h:36
void init_library(void)
It is vital that init_library() is called by any functions using this library.
Definition: init.c:201
uint8_t starting_stat_max
Maximum value of a starting stat.
Definition: global.h:319
void accounts_load(void)
This loads all the account entries into memory.
Definition: account.c:121
void dump_experience(void)
Dump the experience table, then calls exit() - useful in terms of debugging to make sure the format o...
Definition: exp.c:249
#define TRUE
Definition: compat.h:10
LogLevel debug
Default debugging level.
Definition: global.h:240
#define FALSE
Definition: compat.h:11
static void set_playerdir(const char *path)
Command line option: set player path.
Definition: init.c:204
uint8_t death_penalty_ratio
Hhow much exp should be lost at death.
Definition: global.h:257
char meta_server[MAX_BUF]
Hostname/ip addr of the metaserver.
Definition: global.h:284
static void set_datadir(const char *path)
Command line option: set data path.
Definition: init.c:132
Global type definitions and header inclusions.
#define safe_strncpy
Definition: compat.h:23
void free_quest(void)
Free all quest status structures.
Definition: quest.c:1289
uint32_t worldmaptilesy
Number of tiles high the worldmap is.
Definition: global.h:292
const char * treasures
Location of the treasures file.
Definition: global.h:250
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:465
racelink * find_racelink(const char *name)
Find the race information for the specified name.
Definition: init.c:1374
const char * logfilename
Logfile to use.
Definition: global.h:238
void dump_alchemy_costs(void)
Dumps to output all costs of recipes.
Definition: recipe.c:519
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:268
uint8_t recycle_tmp_maps
Re-use tmp maps.
Definition: global.h:270
static void set_localdir(const char *path)
Command line option: set local path.
Definition: init.c:148
#define SRANDOM(seed)
Definition: define.h:680
char meta_comment[MAX_BUF]
Comment we send to the metaserver.
Definition: global.h:287
static void set_mapdir(const char *path)
Command line option: set map path.
Definition: init.c:156
void cleanup(void)
Clean up everything and exit.
Definition: server.c:1137
void dump_quests(void)
Dump all of the quests, then calls exit() - useful in terms of debugging to make sure that quests are...
Definition: quest.c:1280
void init_formulae(void)
Builds up the lists of formula from the file in the libdir.
Definition: recipe.c:161
static void add_to_racelist(const char *race_name, object *op)
Add an object to the racelist.
Definition: init.c:1320
void dump_animations(void)
Dump all animations to stderr, for debugging purposes.
Definition: anim.c:322
object * ob
Item to link to.
Definition: object.h:443
static void set_dumpmon4(void)
Command line option: dump spells.
Definition: init.c:90
void init_server(void)
This sets up the socket and reads all the image information into memory.
Definition: init.c:262
struct oblnk * member
Linked object list of things belonging to this race.
Definition: race.h:15
struct ralnk * next
Next race.
Definition: race.h:16
char * log_timestamp_format
Format for timestap, if log_timestamp is set.
Definition: global.h:317
int armor_speed_improvement
Speed improvement.
Definition: global.h:306
void init(int argc, char **argv)
This is the main server initialization function.
Definition: init.c:978
const char * dumparg
Additional argument for some dump functions.
Definition: global.h:242
static void set_disable_plugin(const char *name)
Disable a plugin.
Definition: init.c:239
void free_server(void)
Frees all memory allocated around here:
Definition: init.c:1018
Defines for loader.l / loader.c.
signed short int16_t
Definition: win32.h:160
uint8_t search_items
Search_items command.
Definition: global.h:265
static void init_signals(void)
Setup our signal handlers.
Definition: init.c:1187
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:253
int64_t pk_max_experience
Maximum experience one can get for PKing.
Definition: global.h:311
void service_unregister()
Removes the Crossfire service from the service manager.
Definition: win32.c:225
static void init_startup(void)
Checks if starting the server is allowed.
Definition: init.c:1137
#define snprintf
Definition: win32.h:46
void dump_artifacts(void)
For debugging purposes.
Definition: artifact.c:666
void dump_alchemy(void)
Dumps alchemy recipes to output.
Definition: recipe.c:317
struct linked_char * next
Definition: global.h:88
uint8_t armor_weight_linear
If 1, weight reduction is linear, else exponantiel.
Definition: global.h:305
static void load_settings(void)
This loads the settings file.
Definition: init.c:510
void read_map_log(void)
Reads temporary maps information from disk.
Definition: swap.c:70
uint8_t balanced_stat_loss
If true, Death stat depletion based on level etc.
Definition: global.h:259
static void set_dumpmon3(void)
Command line option: dump artifacts.
Definition: init.c:85
const char * cmd_option
How it is called on the command line.
Definition: init.c:267
void(* cmdlinefunc_args1)(const char *arg1)
Definition: init.c:257
static void signal_shutdown()
Signal handler that begins a normal server shutdown.
Definition: init.c:1160
static void load_materials(void)
Loads the materials.
Definition: init.c:420
static void set_tmpdir(const char *path)
Command line option: set temporary file path.
Definition: init.c:212
uint8_t armor_speed_linear
If 1, speed improvement is linear, else exponantiel.
Definition: global.h:307
One material type.
Definition: material.h:33
static void help(void)
Display the command line options and exits.
Definition: init.c:1034
EXTERN racelink * first_race
Race list.
Definition: global.h:125
Number of statistics.
Definition: living.h:18
uint8_t real_wiz
Use mud-like wizards.
Definition: global.h:269
void cftimer_init(void)
Initialize timers.
Definition: timers.c:157
uint8_t ignore_plugin_compatibility
If set, don&#39;t check plugin version.
Definition: global.h:325
const char * templatedir
Directory for the template map.
Definition: global.h:252
static void set_templatedir(const char *path)
Command line option: set template path.
Definition: init.c:196
static void set_archetypes(const char *path)
Command line option: set archetypes file name.
Definition: init.c:164
const char * archetypes
Name of the archetypes file - libdir is prepended.
Definition: global.h:248
uint8_t simple_exp
If true, use the simple experience system.
Definition: global.h:261
static void set_treasures(const char *path)
Command line option: set treasures file name.
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)
Initialize linked lists utilized by message functions in tailor_readable_ob()
Definition: readable.c:1005
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
static void set_logfile(char *val)
Command line option: set logfile name.
Definition: init.c:49
static void set_confdir(const char *path)
Command line option: set configuration path.
Definition: init.c:140
Many many details.
Definition: logger.h:14
char who_format[MAX_BUF]
The format that the who command should use.
Definition: global.h:273
static void dump_races(void)
Dumps all race information to stderr.
Definition: init.c:1279
void reset_sleep(void)
Initialise all variables used in the timing routines.
Definition: time.c:130
const char * confdir
Configuration files.
Definition: global.h:243
signed __int64 int64_t
Definition: win32.h:168
uint8_t account_block_create
Definition: global.h:326
const char * uniquedir
Directory for the unique items.
Definition: global.h:251
static void set_dumpmont(const char *name)
Command line option: dump monster treasures.
Definition: init.c:123
static void set_regions(const char *path)
Command line option: set regions file name.
Definition: init.c:172
uint8_t permanent_exp_ratio
How much exp should be &#39;permenant&#39; and unable to be lost.
Definition: global.h:256
int log_timestamp
If set, log will comport a timestamp.
Definition: global.h:316
const char * datadir
Read only data files.
Definition: global.h:244
void dump_spells(void)
Dumps all the spells - now also dumps skill associated with the spell.
Definition: spell_util.c:146
uint8_t special_break_map
If set, then submaps in random maps can break the walls.
Definition: global.h:323
const char * name
Definition: global.h:87
uint16_t set_friendly_fire
Percent of damage done by peaceful player vs player damage.
Definition: global.h:272
int armor_weight_reduction
Weight reduction per enchantment.
Definition: global.h:304
void dump_abilities(void)
Dump to standard out the abilities of all monsters.
Definition: info.c:63
signed char int8_t
Type definitions for fixed-size integer types.
Definition: win32.h:158
static void set_debug(void)
Command line option: debug flag.
Definition: init.c:60
static void set_dumpmon9(void)
Command line option: dump alchemy costs.
Definition: init.c:115
const char * localdir
Read/write data files.
Definition: global.h:245
uint8_t starting_stat_points
How many stat points character starts with.
Definition: global.h:320
struct archt * arch
Pointer to archetype.
Definition: object.h:412
struct oblnk * next
Next item to link to.
Definition: object.h:444
Only for debugging purposes.
Definition: logger.h:13
uint8_t no_player_stealing
If 1, can not steal from other players.
Definition: global.h:308
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.c:1449
One command line option definition.
Definition: init.c:266
const char * name
Name of this race entry.
Definition: race.h:13
const char * mapdir
Where the map files are.
Definition: global.h:247
struct Settings settings
Server settings.
Definition: init.c:40
static void init_beforeplay(void)
Called before the server starts listening to connections, processes various dump-related options...
Definition: init.c:1079
void service_handle()
Service entry point.
Definition: win32.c:343
char dm_mail[MAX_BUF]
DM&#39;s Email address.
Definition: global.h:278
#define NROFATTACKS
Definition: attack.h:17
#define atoll
Definition: win32.h:170
void init_gods(void)
This takes a look at all of the archetypes to find the objects which correspond to the GODS (type GOD...
Definition: holy.c:53
void init_commands(void)
Sorts the command arrays for easy search through bsearch().
Definition: commands.c:286
uint8_t fastclock
If true, clock goes warp 9.
Definition: global.h:295
void service_register()
Registers the server to the service manager.
Definition: win32.c:180
sstring add_string(const char *str)
This will add &#39;str&#39; to the hash table.
Definition: shstr.c:124
uint8_t dumpvalues
Set to dump various values/tables.
Definition: global.h:241
static void call_version(void)
Command line option: show version.
Definition: init.c:54
int strcasecmp(const char *s1, const char *s2)
Case-insensitive comparaison of strings.
Definition: porting.c:256
static void init_races(void)
Reads the races file in the lib/ directory, then overwrites old &#39;race&#39; entries.
Definition: init.c:1207
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
EXTERN long init_done
Ignores signals until init_done is true.
Definition: global.h:134
char * strdup(const char *str)
Portable implementation of strdup(3).
Definition: porting.c:200
uint8_t set_title
Players can set thier title.
Definition: global.h:263
static void free_races(void)
Frees all race-related information.
Definition: init.c:1294
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
static void set_dumpmon5(void)
Command line option: ?
Definition: init.c:95
struct _materialtype * next
Next item on the list.
Definition: material.h:39
uint32_t worldmapstartx
Starting x tile for the worldmap.
Definition: global.h:289
static void rec_sighup(int i)
SIGHUP handler.
Definition: init.c:1176
#define FULL_VERSION
Definition: version.h:6
int metaserver2_init(void)
This initializes the metaserver2 logic - it reads the metaserver2 file, storing the values away...
Definition: metaserver.c:163
void(* cmdlinefunc_args0)(void)
Typedefs used when calling option handlers.
Definition: init.c:256
int allow_denied_spells_writing
If set, players can write spells they can&#39;t cast.
Definition: global.h:313
#define SHUTDOWN_FILE
If you want to take the game down while installing new versions, or for other reasons, put a message into the SHUTDOWN_FILE file.
Definition: config.h:508
uint8_t roll_stat_points
How many stat points legacy (rolled) chars start with.
Definition: global.h:321
uint32_t worldmaptilesizex
Number of squares wide in a wm tile.
Definition: global.h:293
static void set_uniquedir(const char *path)
Command line option: set unique path.
Definition: init.c:188
void hiscore_init(void)
Initializes the module.
Definition: hiscore.c:284
int pk_max_experience_percent
Percentage of experience of victim the killer gets.
Definition: global.h:312
int16_t level
Level of creature or object.
Definition: object.h:351
uint8_t spell_failure_effects
Nasty backlash to spell failures.
Definition: global.h:267
void init_archetype_pointers(void)
Initialize global archtype pointers:
Definition: treasure.c:64
void(* cmdlinefunc_args2)(const char *arg1, const char *arg2)
Definition: init.c:258
void init_ob_methods(void)
Initializes the ob_method system.
Definition: ob_methods.c:35
float item_power_factor
See note in setings file.
Definition: global.h:301
const char * name
More definite name, like "generate_kobold".
Definition: object.h:466
static void set_dumpmon6(void)
Command line option: dump races.
Definition: init.c:100
void init_artifacts(void)
Builds up the lists of artifacts from the file in the libdir.
Definition: artifact.c:513
uint8_t resurrection
Ressurection possible w/ permadeth on.
Definition: global.h:264
int16_t pk_luck_penalty
Amount by which player luck is reduced if they PK.
Definition: global.h:255
static materialtype_t * get_empty_mat(void)
Creates an empty materialtype_t structure.
Definition: init.c:399
uint8_t personalized_blessings
If 1, blessed weapons get an owner and a willpower value.
Definition: global.h:310
void init_skills(void)
This just sets up the skill_names table above.
Definition: skill_util.c:67
const char * description
Description, unused.
Definition: material.h:35
static racelink * get_racelist(void)
Create a new racelink structure.
Definition: init.c:1352
char * account_trusted_host
Block account creation for untrusted hosts.
Definition: global.h:327