Crossfire Server, Trunk  1.75.0
init.cpp
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 #ifdef HAVE_SYSLOG_H
27 #include <syslog.h>
28 #endif
29 
30 /* Needed for strcasecmp(). */
31 #ifndef WIN32
32 #include <strings.h>
33 #endif
34 
35 #include "loader.h"
36 #include "version.h"
37 #include "server.h"
38 #include "sproto.h"
39 #include "assets.h"
40 #include "modules.h"
41 
42 static void help(void);
43 static void init_beforeplay(void);
44 static void init_startup(void);
45 
47 
49 static int should_exit = 0;
50 
52  const char *name;
53  char const *description;
54  bool enabled;
55  void (*init)(Settings *, ServerSettings *);
56  void (*close)();
57 };
58 
61  { "citybell", "Ring bells every hour for defined temples", true, cfcitybell_init, cfcitybell_close },
62  { "citylife", "Add NPCs in towns", true, citylife_init, citylife_close },
63  { "rhg", "Add random maps to exits in towns", false, random_house_generator_init, random_house_generator_close },
64  { "weather", "Add weather effects to the world map.", false, cfweather_init, cfweather_close },
65  { NULL, NULL, false, NULL, NULL }
66 };
67 
71 void init_modules() {
72  LOG(llevInfo, "Initializing modules\n");
73  for (int module = 0; modules[module].name != NULL; module++) {
74  module_information *mod = &modules[module];
75  if (!mod->enabled) {
76  LOG(llevInfo, " %s (%s): disabled\n", mod->name, mod->description);
77  } else {
78  mod->init(&settings, &serverSettings);
79  LOG(llevInfo, " %s (%s): activated\n", mod->name, mod->description);
80  }
81  }
82 }
83 
87 void close_modules() {
88  LOG(llevInfo, "Cleaning modules\n");
89  for (int module = 0; modules[module].name != NULL; module++) {
90  module_information *mod = &modules[module];
91  if (mod->enabled) {
92  mod->close();
93  LOG(llevInfo, " %s (%s): closed\n", mod->name, mod->description);
94  }
95  }
96 }
97 
101 static void list_modules() {
102  LOG(llevInfo, "Built-in modules:\n");
103  for (int module = 0; modules[module].name != NULL; module++) {
104  LOG(llevInfo, " %s: %s -> %s\n", modules[module].name, modules[module].description, modules[module].enabled ? "enabled" : "disabled");
105  }
106  should_exit = 1;
107 }
108 
113 static void set_logfile(char *val) {
114  settings.logfilename = val;
115 }
116 
118 static void call_version(void) {
119  puts(FULL_VERSION);
120  exit(EXIT_SUCCESS);
121 }
122 
124 static void set_debug(void) {
126 }
127 
129 static void unset_debug(void) {
131 }
132 
134 static void set_mondebug(void) {
136 }
137 
139 static void set_dumpmon1(void) {
140  settings.dumpvalues = 1;
141 }
142 
144 static void set_dumpmon2(void) {
145  settings.dumpvalues = 2;
146 }
147 
149 static void set_dumpmon3(void) {
150  settings.dumpvalues = 3;
151 }
152 
154 static void set_dumpmon4(void) {
155  settings.dumpvalues = 4;
156 }
157 
159 static void set_dumpmon5(void) {
160  settings.dumpvalues = 5;
161 }
162 
164 static void set_dumpmon6(void) {
165  settings.dumpvalues = 6;
166 }
167 
169 static void set_dumpmon7(void) {
170  settings.dumpvalues = 7;
171 }
172 
174 static void set_dumpmon8(void) {
175  settings.dumpvalues = 8;
176 }
177 
179 static void set_dumpmon9(void) {
180  settings.dumpvalues = 9;
181 }
182 
187 static void set_dumpmont(const char *name) {
188  settings.dumpvalues = 10;
190 }
191 
196 static void set_datadir(const char *path) {
197  settings.datadir = path;
198 }
199 
204 static void set_confdir(const char *path) {
205  settings.confdir = path;
206 }
207 
212 static void set_localdir(const char *path) {
213  settings.localdir = path;
214 }
215 
220 static void set_mapdir(const char *path) {
221  settings.mapdir = path;
222 }
223 
228 static void set_regions(const char *path) {
229  settings.regions = path;
230 }
231 
232 static void set_syslog(const char *arg) {
233 #ifdef HAVE_SYSLOG_H
234  int facility = atoi(arg);
235  openlog("crossfire-server", LOG_NDELAY, facility << 3);
236  setlogmask(LOG_UPTO(LOG_DEBUG)); // enable all logs, filtering is still done by LOG()
237 #else
238  LOG(llevError, "syslog is not available in this build\n");
239 #endif
240 }
241 
246 static void set_uniquedir(const char *path) {
247  settings.uniquedir = path;
248 }
249 
254 static void set_playerdir(const char *path) {
255  settings.playerdir = path;
256 }
257 
262 static void set_tmpdir(const char *path) {
263  settings.tmpdir = path;
264 }
265 
271 }
272 
273 static void server_pack_assets(const char *assets, const char *filename) {
274  assets_pack(assets, filename);
275  should_exit = 1;
276 }
277 
278 static void free_materials(void);
279 
286 static void set_csport(const char *val) {
287  int port = atoi(val);
288  if (port <= 0 || port > 65535) {
289  LOG(llevError, "%d is an invalid csport number, must be between 1 and 65535.\n", port);
290  exit(1);
291  }
292  settings.csport = port;
293 }
294 
299 static void set_disable_plugin(const char *name) {
300  serverSettings.disabled_plugins.push_back(std::string(name ? name : ""));
301 }
302 
309 static void do_module(const char *name, bool enabled) {
310  bool one = false;
311  for (int module = 0; modules[module].name; module++) {
312  if (strcmp("All", name) == 0 || strcmp(modules[module].name, name) == 0) {
313  modules[module].enabled = enabled;
314  one = true;
315  }
316  }
317  if (!one) {
318  LOG(llevError, "Invalid module name %s\n", name);
320  }
321 }
322 
327 static void set_disable_module(const char *name) {
328  do_module(name, false);
329 }
330 
335 static void set_enable_module(const char *name) {
336  do_module(name, true);
337 }
338 
342 static void server_dump_animations(void) {
343  dump_animations();
344  cleanup();
345 }
346 
350 static void server_dump_faces(void) {
351  dump_faces();
352  cleanup();
353 }
354 
358 static void server_dump_bonuses() {
360  cleanup();
361 }
362 
365 typedef void (*cmdlinefunc_args0)(void);
366 typedef void (*cmdlinefunc_args1)(const char* arg1);
367 typedef void (*cmdlinefunc_args2)(const char* arg1, const char* arg2);
376  const char *cmd_option;
377  uint8_t num_args;
378  uint8_t pass;
379  void (*func)();
383 };
384 
393 static struct Command_Line_Options options[] = {
397  { "-conf", 1, 1, (cmdlinefunc_args0)set_confdir },
398  { "-d", 0, 1, (cmdlinefunc_args0)set_debug },
399  { "-data", 1, 1, (cmdlinefunc_args0)set_datadir },
400  { "-disable-plugin", 1, 1, (cmdlinefunc_args0)set_disable_plugin },
401  { "-disable-module", 1, 1, (cmdlinefunc_args0)set_disable_module },
402  { "-enable-module", 1, 1, (cmdlinefunc_args0)set_enable_module },
403  { "-list-modules", 0, 1, (cmdlinefunc_args0)list_modules },
404  { "-h", 0, 1, (cmdlinefunc_args0)help },
405  { "-ignore-assets-errors", 0, 1, (cmdlinefunc_args0)set_ignore_assets_errors },
406  { "-local", 1, 1, (cmdlinefunc_args0)set_localdir },
407  { "-log", 1, 1, (cmdlinefunc_args0)set_logfile },
408  { "-maps", 1, 1, (cmdlinefunc_args0)set_mapdir },
409  { "-mon", 0, 1, (cmdlinefunc_args0)set_mondebug },
410  { "-n", 0, 1, (cmdlinefunc_args0)unset_debug },
411  { "-playerdir", 1, 1, (cmdlinefunc_args0)set_playerdir },
412  { "-regions", 1, 1, (cmdlinefunc_args0)set_regions },
413  { "-syslog", 1, 1, (cmdlinefunc_args0)set_syslog },
414  { "-tmpdir", 1, 1, (cmdlinefunc_args0)set_tmpdir },
415  { "-uniquedir", 1, 1, (cmdlinefunc_args0)set_uniquedir },
416  { "-v", 0, 1, (cmdlinefunc_args0)call_version },
417 
418 #ifdef WIN32
419  /* Windows service stuff */
420  { "-regsrv", 0, 1, service_register },
421  { "-unregsrv", 0, 1, service_unregister },
422  { "-srv", 0, 1, service_handle },
423 #endif
424 
428  { "-p", 1, 2, (cmdlinefunc_args0)set_csport },
429 
433  { "-m", 0, 3, (cmdlinefunc_args0)set_dumpmon1 },
434  { "-m2", 0, 3, (cmdlinefunc_args0)set_dumpmon2 },
435  { "-m3", 0, 3, (cmdlinefunc_args0)set_dumpmon3 },
436  { "-m4", 0, 3, (cmdlinefunc_args0)set_dumpmon4 },
437  { "-m5", 0, 3, (cmdlinefunc_args0)set_dumpmon5 },
438  { "-m6", 0, 3, (cmdlinefunc_args0)set_dumpmon6 },
439  { "-m7", 0, 3, (cmdlinefunc_args0)set_dumpmon7 },
440  { "-m8", 0, 3, (cmdlinefunc_args0)set_dumpmon8 },
441  { "-m9", 0, 3, (cmdlinefunc_args0)set_dumpmon9 },
442  { "-mt", 1, 3, (cmdlinefunc_args0)set_dumpmont },
443  { "-mexp", 0, 3, (cmdlinefunc_args0)dump_experience },
444  { "-mq", 0, 3, (cmdlinefunc_args0)dump_quests },
445  { "-dump-anims", 0, 3, (cmdlinefunc_args0)server_dump_animations },
446  { "-dump-faces", 0, 3, (cmdlinefunc_args0)server_dump_faces },
447  { "-pack-assets", 2, 3, (cmdlinefunc_args0)server_pack_assets },
448  { "-dump-stat-bonuses", 0, 3, (cmdlinefunc_args0)server_dump_bonuses },
449 };
450 
465 static void parse_args(int argc, char *argv[], int pass) {
466  size_t i;
467  int on_arg = 1;
468 
469  while (on_arg < argc) {
470  for (i = 0; i < sizeof(options)/sizeof(struct Command_Line_Options); i++) {
471  if (!strcmp(options[i].cmd_option, argv[on_arg])) {
472  /* Found a matching option, but should not be processed on
473  * this pass. Just skip over it
474  */
475  if (options[i].pass != pass) {
476  on_arg += options[i].num_args+1;
477  break;
478  }
479  if (options[i].num_args) {
480  if ((on_arg+options[i].num_args) >= argc) {
481  fprintf(stderr, "%s requires an argument.\n", options[i].cmd_option);
482  exit(1);
483  }
484 
485  if (options[i].num_args == 1)
486  ((cmdlinefunc_args1)options[i].func)(argv[on_arg+1]);
487  if (options[i].num_args == 2)
488  ((cmdlinefunc_args2)options[i].func)(argv[on_arg+1], argv[on_arg+2]);
489  on_arg += options[i].num_args+1;
490  } else { /* takes no args */
492  on_arg++;
493  }
494  break;
495  }
496  }
497  if (i == sizeof(options)/sizeof(struct Command_Line_Options)) {
498  fprintf(stderr, "Unknown option: %s\n", argv[on_arg]);
499  fprintf(stderr, "Type '%s -h' for usage.\n", argv[0]);
500  exit(1);
501  }
502  }
503 
504  if (should_exit) {
505  cleanup();
506  }
507 }
508 
518  materialtype_t *mt;
519  int i;
520 
521  mt = (materialtype_t *)malloc(sizeof(materialtype_t));
522  if (mt == NULL)
524  mt->name = NULL;
525  mt->description = NULL;
526  for (i = 0; i < NROFATTACKS; i++) {
527  mt->save[i] = 0;
528  mt->mod[i] = 0;
529  }
530  return mt;
531 }
532 
537 static void load_materials(BufferReader *reader, const char *filename) {
538  char *buf, *cp, *next;
539  materialtype_t *mt = NULL;
540  int i, value;
541  (void)filename;
542  int line = 0;
543 
544  while ((buf = bufferreader_next_line(reader)) != NULL) {
545  line++;
546  if (*buf == '#')
547  continue;
548  cp = buf;
549  while (*cp == ' ') /* Skip blanks */
550  cp++;
551  if (!strncmp(cp, "name", 4)) {
552  mt = get_empty_mat();
553  materials.push_back(mt);
554  mt->name = add_string(strchr(cp, ' ')+1);
555  mt->description = add_refcount(mt->name);
556  }
557 
558  if (mt == NULL) {
559  LOG(llevError, "%s:%d: fields must come after a name line\n", filename, line);
561  }
562 
563  if (!strncmp(cp, "description", 11)) {
564  FREE_AND_COPY_IF(mt->description, strchr(cp, ' ')+1);
565  } else if (sscanf(cp, "material %d", &value)) {
566  mt->material = value;
567  } else if (!strncmp(cp, "saves", 5)) {
568  cp = strchr(cp, ' ')+1;
569  for (i = 0; i < NROFATTACKS; i++) {
570  if (cp == NULL) {
571  mt->save[i] = 0;
572  continue;
573  }
574  if ((next = strchr(cp, ',')) != NULL)
575  *(next++) = '\0';
576  sscanf(cp, "%d", &value);
577  mt->save[i] = (int8_t)value;
578  cp = next;
579  }
580  } else if (!strncmp(cp, "mods", 4)) {
581  cp = strchr(cp, ' ')+1;
582  for (i = 0; i < NROFATTACKS; i++) {
583  if (cp == NULL) {
584  mt->save[i] = 0;
585  continue;
586  }
587  if ((next = strchr(cp, ',')) != NULL)
588  *(next++) = '\0';
589  sscanf(cp, "%d", &value);
590  mt->mod[i] = (int8_t)value;
591  cp = next;
592  }
593  }
594  }
595  LOG(llevDebug, "loaded %d material type data\n", static_cast<int>(materials.size()));
596 }
597 
601 static void free_materials(void) {
602  for (auto material : materials) {
603  free(material);
604  }
605  materials.clear();
606 }
607 
613 void load_settings(void) {
614  static char motd[MAX_BUF] = { 0 };
615  char buf[MAX_BUF], *cp, dummy[1];
616  int has_val;
617  FILE *fp;
618 
619  dummy[0] = '\0';
620  snprintf(buf, sizeof(buf), "%s/settings", settings.confdir);
621 
622  /* We don't require a settings file at current time, but down the road,
623  * there will probably be so many values that not having a settings file
624  * will not be a good thing.
625  */
626  if ((fp = fopen(buf, "r")) == NULL) {
627  LOG(llevError, "Warning: No settings file found\n");
628  return;
629  }
630  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
631  if (buf[0] == '#')
632  continue;
633  /* eliminate newline */
634  if ((cp = strrchr(buf, '\n')) != NULL)
635  *cp = '\0';
636 
637  /* Skip over empty lines */
638  if (buf[0] == 0)
639  continue;
640 
641  /* Skip all the spaces and set them to nulls. If not space,
642  * set cp to "" to make strcpy's and the like easier down below.
643  */
644  if ((cp = strchr(buf, ' ')) != NULL) {
645  while (*cp == ' ')
646  *cp++ = 0;
647  has_val = 1;
648  } else {
649  cp = dummy;
650  has_val = 0;
651  }
652 
653  if (!strcasecmp(buf, "metaserver_notification")) {
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 metaserver_notification: %s\n", cp);
660  }
661  } else if (!strcasecmp(buf, "metaserver_server")) {
662  if (has_val)
664  else
665  LOG(llevError, "load_settings: metaserver_server must have a value.\n");
666  } else if (!strcasecmp(buf, "motd")) {
667  if (has_val) {
668  safe_strncpy(motd, cp, sizeof(motd));
669  settings.motd = motd;
670  } else
671  LOG(llevError, "load_settings: motd must have a value.\n");
672  } else if (!strcasecmp(buf, "metaserver_host")) {
673  if (has_val)
675  else
676  LOG(llevError, "load_settings: metaserver_host must have a value.\n");
677  } else if (!strcasecmp(buf, "port")) {
678  set_csport(cp);
679  } else if (!strcasecmp(buf, "metaserver_port")) {
680  int port = atoi(cp);
681 
682  if (port < 1 || port > 65535)
683  LOG(llevError, "load_settings: metaserver_port must be between 1 and 65535, %d is invalid\n", port);
684  else
685  settings.meta_port = port;
686  } else if (!strcasecmp(buf, "metaserver_comment")) {
688  } else if (!strcasecmp(buf, "worldmapstartx")) {
689  int size = atoi(cp);
690 
691  if (size < 0)
692  LOG(llevError, "load_settings: worldmapstartx must be at least 0, %d is invalid\n", size);
693  else
694  settings.worldmapstartx = size;
695  } else if (!strcasecmp(buf, "worldmapstarty")) {
696  int size = atoi(cp);
697 
698  if (size < 0)
699  LOG(llevError, "load_settings: worldmapstarty must be at least 0, %d is invalid\n", size);
700  else
701  settings.worldmapstarty = size;
702  } else if (!strcasecmp(buf, "worldmaptilesx")) {
703  int size = atoi(cp);
704 
705  if (size < 1)
706  LOG(llevError, "load_settings: worldmaptilesx must be greater than 1, %d is invalid\n", size);
707  else
708  settings.worldmaptilesx = size;
709  } else if (!strcasecmp(buf, "worldmaptilesy")) {
710  int size = atoi(cp);
711 
712  if (size < 1)
713  LOG(llevError, "load_settings: worldmaptilesy must be greater than 1, %d is invalid\n", size);
714  else
715  settings.worldmaptilesy = size;
716  } else if (!strcasecmp(buf, "fastclock")) {
717  int lev = atoi(cp);
718 
719  if (lev < 0)
720  LOG(llevError, "load_settings: fastclock must be at least 0, %d is invalid\n", lev);
721  else
722  settings.fastclock = lev;
723  } else if (!strcasecmp(buf, "not_permadeth")) {
724  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
726  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
728  } else {
729  LOG(llevError, "load_settings: Unknown value for not_permadeth: %s\n", cp);
730  }
731  } else if (!strcasecmp(buf, "resurrection")) {
732  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
734  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
736  } else {
737  LOG(llevError, "load_settings: Unknown value for resurrection: %s\n", cp);
738  }
739  } else if (!strcasecmp(buf, "set_title")) {
740  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
742  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
744  } else {
745  LOG(llevError, "load_settings: Unknown value for set_title: %s\n", cp);
746  }
747  } else if (!strcasecmp(buf, "search_items")) {
748  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
750  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
752  } else {
753  LOG(llevError, "load_settings: Unknown value for search_items: %s\n", cp);
754  }
755  } else if (!strcasecmp(buf, "spell_encumbrance")) {
756  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
758  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
760  } else {
761  LOG(llevError, "load_settings: Unknown value for spell_encumbrance: %s\n", cp);
762  }
763  } else if (!strcasecmp(buf, "spell_failure_effects")) {
764  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
766  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
768  } else {
769  LOG(llevError, "load_settings: Unknown value for spell_failure_effects: %s\n", cp);
770  }
771  } else if (!strcasecmp(buf, "casting_time")) {
772  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
774  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
776  } else {
777  LOG(llevError, "load_settings: Unknown value for casting_time: %s\n", cp);
778  }
779  } else if (!strcasecmp(buf, "real_wiz")) {
780  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
782  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
784  } else {
785  LOG(llevError, "load_settings: Unknown value for real_wiz: %s\n", cp);
786  }
787  } else if (!strcasecmp(buf, "recycle_tmp_maps")) {
788  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
790  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
792  } else {
793  LOG(llevError, "load_settings: Unknown value for recycle_tmp_maps: %s\n", cp);
794  }
795  } else if (!strcasecmp(buf, "always_show_hp")) {
796  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
798  } else if (!strcasecmp(cp, "damaged")) {
800  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
802  } else {
803  LOG(llevError, "load_settings: Unknown value for always_show_hp: %s\n", cp);
804  }
805  } else if (!strcasecmp(buf, "who_format")) {
806  if (has_val)
808  sizeof(settings.who_format));
809  } else if (!strcasecmp(buf, "who_wiz_format")) {
810  if (has_val) {
812  sizeof(settings.who_wiz_format));
813  }
814  } else if (!strcasecmp(buf, "spellpoint_level_depend")) {
815  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
817  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
819  } else {
820  LOG(llevError, "load_settings: Unknown value for spellpoint_level_depend: %s\n", cp);
821  }
822  } else if (!strcasecmp(buf, "stat_loss_on_death")) {
823  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
825  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
827  } else {
828  LOG(llevError, "load_settings: Unknown value for stat_loss_on_death: %s\n", cp);
829  }
830  } else if (!strcasecmp(buf, "use_permanent_experience")) {
831  LOG(llevError, "use_permanent_experience is deprecated, usepermenent_experience_percentage instead\n");
832  } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
833  int val = atoi(cp);
834  if (val < 0 || val > 100)
835  LOG(llevError, "load_settings: permenent_experience_percentage must be between 0 and 100, %d is invalid\n", val);
836  else
838  } else if (!strcasecmp(buf, "death_penalty_percentage")) {
839  int val = atoi(cp);
840  if (val < 0 || val > 100)
841  LOG(llevError, "load_settings: death_penalty_percentage must be between 0 and 100, %d is invalid\n", val);
842  else
844  } else if (!strcasecmp(buf, "death_penalty_levels")) {
845  int val = atoi(cp);
846  if (val < 0 || val > 255)
847  LOG(llevError, "load_settings: death_penalty_levels can not be negative, %d is invalid\n", val);
848  else
850  } else if (!strcasecmp(buf, "balanced_stat_loss")) {
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 balanced_stat_loss: %s\n", cp);
857  }
858  } else if (!strcasecmp(buf, "simple_exp")) {
859  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
861  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
863  } else {
864  LOG(llevError, "load_settings: Unknown value for simple_exp: %s\n", cp);
865  }
866  } else if (!strcasecmp(buf, "item_power_factor")) {
867  float tmp = atof(cp);
868  if (tmp < 0)
869  LOG(llevError, "load_settings: item_power_factor must be a positive number (%f < 0)\n", tmp);
870  else
872  } else if (!strcasecmp(buf, "pk_luck_penalty")) {
873  int16_t val = atoi(cp);
874 
875  if (val < -100 || val > 100)
876  LOG(llevError, "load_settings: pk_luck_penalty must be between -100 and 100, %d is invalid\n", val);
877  else
879  } else if (!strcasecmp(buf, "set_friendly_fire")) {
880  int val = atoi(cp);
881 
882  if (val < 1 || val > 100)
883  LOG(llevError, "load_settings: set_friendly_fire must be between 1 an 100, %d is invalid\n", val);
884  else
886  } else if (!strcasecmp(buf, "armor_max_enchant")) {
887  int max_e = atoi(cp);
888  if (max_e <= 0)
889  LOG(llevError, "load_settings: armor_max_enchant is %d\n", max_e);
890  else
891  settings.armor_max_enchant = max_e;
892  } else if (!strcasecmp(buf, "armor_weight_reduction")) {
893  int wr = atoi(cp);
894  if (wr < 0)
895  LOG(llevError, "load_settings: armor_weight_reduction is %d\n", wr);
896  else
898  } else if (!strcasecmp(buf, "armor_weight_linear")) {
899  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
901  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
903  } else {
904  LOG(llevError, "load_settings: unknown value for armor_weight_linear: %s\n", cp);
905  }
906  } else if (!strcasecmp(buf, "armor_speed_improvement")) {
907  int wr = atoi(cp);
908  if (wr < 0)
909  LOG(llevError, "load_settings: armor_speed_improvement is %d\n", wr);
910  else
912  } else if (!strcasecmp(buf, "armor_speed_linear")) {
913  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
915  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
917  } else {
918  LOG(llevError, "load_settings: unknown value for armor_speed_linear: %s\n", cp);
919  }
920  } else if (!strcasecmp(buf, "no_player_stealing")) {
921  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
923  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
925  } else {
926  LOG(llevError, "load_settings: unknown value for no_player_stealing: %s\n", cp);
927  }
928  } else if (!strcasecmp(buf, "create_home_portals")) {
929  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
930 #ifdef TRY_BROKEN_TOWN_PORTALS
932 #else
933  LOG(llevError, "load_settings: create_home_portals is currently broken. It results in town portals that prematurely reset when the apartment is swapped.\n");
934 #endif
935  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
937  } else {
938  LOG(llevError, "load_settings: unknown value for create_home_portals: %s\n", cp);
939  }
940  } else if (!strcasecmp(buf, "personalized_blessings")) {
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 personalized_blessings: %s\n", cp);
947  }
948  } else if (!strcasecmp(buf, "pk_max_experience")) {
949  int64_t pkme = atoll(cp);
950  if (pkme < 0)
951  pkme = -1;
953  } else if (!strcasecmp(buf, "pk_max_experience_percent")) {
954  int pkmep = atoi(cp);
955  if (pkmep < 0) {
956  LOG(llevError, "load_settings: pk_max_experience_percent should be positive or zero (was \"%s\")\n", cp);
957  } else
959  } else if (!strcasecmp(buf, "allow_denied_spells_writing")) {
960  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
962  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
964  } else {
965  LOG(llevError, "load_settings: unknown value for allow_denied_spells_writing: %s\n", cp);
966  }
967  } else if (!strcasecmp(buf, "allow_broken_converters")) {
968  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
970  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
972  } else {
973  LOG(llevError, "load_settings: unknown value for allow_broken_converters: %s\n", cp);
974  }
975  } else if (!strcasecmp(buf, "log_timestamp")) {
976  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
978  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
980  } else {
981  LOG(llevError, "load_settings: unknown value for log_timestamp: %s\n", cp);
982  }
983  } else if (!strcasecmp(buf, "log_timestamp_format")) {
986  } else if (!strcasecmp(buf, "starting_stat_min")) {
987  int val = atoi(cp);
988 
989  if (val < 1 || val > settings.max_stat || val > settings.starting_stat_max)
990  LOG(llevError, "load_settings: starting_stat_min (%d) need to be within %d-%d (%d)\n",
992  else
994  } else if (!strcasecmp(buf, "starting_stat_max")) {
995  int val = atoi(cp);
996 
997  if (val < 1 || val > settings.max_stat || val<settings.starting_stat_min)
998  LOG(llevError, "load_settings: starting_stat_max (%d) need to be within %d-%d (%d)\n",
1000  else
1002  } else if (!strcasecmp(buf, "starting_stat_points")) {
1003  int val = atoi(cp);
1004 
1005  if (val < NUM_STATS * settings.starting_stat_min ||
1007  LOG(llevError, "load_settings: starting_stat_points (%d) need to be within %d-%d\n",
1009  else
1011  } else if (!strcasecmp(buf, "roll_stat_points")) {
1012  int val = atoi(cp);
1013 
1014  /* The 3 and 18 values are hard coded in because we know that
1015  * roll_stat() generates a value between 3 and 18 - if that ever
1016  * changed, this code should change also, but that code will eventually
1017  * go away.
1018  */
1019  if (val < NUM_STATS * 3 || val > NUM_STATS * 18)
1020  LOG(llevError, "load_settings: roll_stat_points need to be within %d-%d\n",
1021  NUM_STATS * 3, NUM_STATS * 18);
1022  else
1023  settings.roll_stat_points = val;
1024  } else if (!strcasecmp(buf, "special_break_map")) {
1025  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1027  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1029  } else {
1030  LOG(llevError, "load_settings: unknown value for special_break_map: %s\n", cp);
1031  }
1032  } else if (!strcasecmp(buf, "ignore_plugin_compatibility")) {
1033  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1035  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1037  } else {
1038  LOG(llevError, "load_settings: unknown value for ignore_plugin_compatibility: %s\n", cp);
1039  }
1040  } else if (!strcasecmp(buf, "account_block_create")) {
1041  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1043  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1045  } else {
1046  LOG(llevError, "load_settings: unknown value for account_block_create: %s\n", cp);
1047  }
1048  } else if (!strcasecmp(buf, "account_trusted_host")) {
1051  } else if (!strcasecmp(buf, "crypt_mode")) {
1052  int val = atoi(cp);
1053  if (val != 0 && val != 1) {
1054  LOG(llevError, "load_settings: crypt_mode must be 0 or 1\n");
1055  } else {
1056  settings.crypt_mode = val;
1057  }
1058  } else if (!strcasecmp(buf, "min_name")) {
1059  int val = atoi(cp);
1060 
1061  if (val < 1 || val > MAX_NAME )
1062  LOG(llevError, "load_settings: min_name (%d) need to be within %d-%d\n",
1063  val, 1, MAX_NAME);
1064  else
1065  settings.min_name = val;
1066  } else if (!strcasecmp(buf, "stat_file")) {
1068  } else {
1069  LOG(llevError, "Unknown value in settings file: %s\n", buf);
1070  }
1071  }
1072  fclose(fp);
1073  if (settings.log_timestamp_format == NULL)
1074  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
1075 
1076  /*
1077  * The who formats are defined in config to be blank. They should have been
1078  * overridden by the settings file, if there are no entries however, it will
1079  * have stayed blank. Since this probably isn't what is wanted, we will check if
1080  * new formats have been specified, and if not we will use the old defaults.
1081  */
1082  if (!strcmp(settings.who_format, ""))
1083  strcpy(settings.who_format, "%N_%t%h%d%b%n<%M>");
1084  if (!strcmp(settings.who_wiz_format, ""))
1085  strcpy(settings.who_wiz_format, "%N_%t%h%d%b%nLevel %l <%M>(@%i)(%c)");
1086 }
1087 
1091 }
1092 
1097 static void mklocaldirs() {
1098  auto dirs = {"", "/account", "/maps", "/players", "/unique-items"};
1099  std::string localdir(settings.localdir);
1100  for (auto dir : dirs) {
1101  if (!make_path_to_file((localdir + "/" + dir).c_str()))
1102  LOG(llevError, "Could not create server save directories in %s (%s). Some server state may fail to save.\n",
1103  settings.localdir, dir);
1104  }
1105 }
1106 
1114 void init(int argc, char **argv) {
1115  logfile = stderr;
1116 #ifdef HAVE_SYSLOG_H
1117  // disable syslog, then only re-enable it if configured
1118  setlogmask(0);
1119 #endif
1120 
1121  /* First argument pass - right now it does nothing, but in the future specifying
1122  * the LibDir in this pass would be reasonable. */
1123  parse_args(argc, argv, 1);
1124 
1126 
1127  mklocaldirs();
1128  init_library(); /* Must be called early */
1129  load_settings(); /* Load the settings file */
1130  parse_args(argc, argv, 2);
1131 
1132  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
1133  SRANDOM(time(NULL));
1134 
1135  init_startup(); /* Check shutdown/forbid files */
1136  init_signals(); /* Sets up signal interceptions */
1137  commands_init(); /* Sort command tables */
1138  read_map_log(); /* Load up the old temp map files */
1139  init_skills();
1140  init_ob_methods();
1141  cftimer_init();
1142  hiscore_init();
1143 
1144  parse_args(argc, argv, 3);
1145 
1146  init_beforeplay();
1147  init_modules();
1148  if (argc != 0) {
1149  // Invocations from the command-line (e.g. crossfire-server) have the
1150  // binary name in argv[0]. If that is not there, assume we are running
1151  // as a test and don't create sockets.
1152  init_server();
1153  metaserver2_init();
1154  } else {
1155  LOG(llevInfo, "Running server in test mode (no sockets).\n");
1156  }
1157  accounts_load();
1158  reset_sleep();
1159 }
1160 
1166 void free_server(void) {
1167  free_materials();
1168  free_races();
1169  free_quest();
1171 }
1172 
1176 static void help(void) {
1177  printf("Usage: crossfire-server [options]\n\n");
1178 
1179  printf("Options:\n");
1180  printf(" -conf Set the directory to find configuration files.\n");
1181  printf(" -d Turn on extra debugging messages.\n");
1182  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1183  printf(" -disable-module\n"
1184  " Disable specified module, by its name\n"
1185  " Can be specified multiple times. 'All' disables all modules.\n");
1186  printf(" -enable-module\n"
1187  " Enable specified module, by its name\n"
1188  " Can be specified multiple times. 'All' enables all modules.\n");
1189  printf(" -disable-plugin\n"
1190  " Disables specified plugin. Use the name without the extension.\n"
1191  " Can be specified multiple times. 'All' disables all plugins.\n");
1192  printf(" -dump-anims Dump animations.\n");
1193  printf(" -h Print this help message.\n");
1194  printf(" -ignore-assets-errors\n");
1195  printf(" Allow going on even if there are errors in assets.\n");
1196  printf(" Warning: this may lead to strange behaviour.\n");
1197  printf(" -list-modules\n"
1198  " List built-in modules and exit.\n");
1199  printf(" -local Set the local data (var/) directory.\n");
1200  printf(" -log <file> Write logging information to the given file.\n");
1201  printf(" -m List suggested experience for all monsters.\n");
1202  printf(" -m2 Dump monster abilities.\n");
1203  printf(" -m3 Dump artifact information.\n");
1204  printf(" -m4 Dump spell information.\n");
1205  printf(" -m5 Dump skill information.\n");
1206  printf(" -m6 Dump race information.\n");
1207  printf(" -m7 Dump alchemy information.\n");
1208  printf(" -m8 Dump gods information.\n");
1209  printf(" -m9 Dump more alchemy information (formula checking).\n");
1210  printf(" -maps Set the map directory.\n");
1211  printf(" -mexp Dump the experience table.\n");
1212  printf(" -mon Turn on monster debugging.\n");
1213  printf(" -mq Dump the quest list.\n");
1214  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1215  printf(" -n Turn off debugging messages if on by default.\n");
1216  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1217  printf(" -pack-assets <type> <filename>\n");
1218  printf(" Packs specified assets type to the specified filename.\n");
1219  printf(" Valid assets type are: archs, treasures, faces, messages, facesets, artifacts, formulae, images, quests.\n");
1220  printf(" The file format will be tar ('images') or text (everything else).\n");
1221  printf(" It is possible to combine multiple assets by using '+', for instance 'faces+messages+artifacts'.\n");
1222  printf(" In this case the file will be in tar format.\n");
1223  printf(" -playerdir Set the player files directory.\n");
1224  printf(" -regions Set the region file.\n");
1225  printf(" -syslog <no> Log to syslog with the given facility number (e.g. 16 for LOCAL0)\n");
1226  printf(" -templatedir Set the template map directory.\n");
1227  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1228  printf(" -uniquedir Set the unique items/maps directory.\n");
1229  printf(" -v Print version information.\n");
1230  exit(EXIT_SUCCESS);
1231 }
1232 
1237 static void init_beforeplay(void) {
1238  init_archetype_pointers(); /* Setup global pointers to archetypes */
1239  finish_races(); /* overwrite race designations using entries in lib/races file */
1241  init_gods(); /* init linked list of gods from archs*/
1242  init_readable(); /* inits useful arrays for readable texts */
1243 
1244  switch (settings.dumpvalues) {
1245  case 1:
1246  print_monsters();
1247  cleanup();
1248  break;
1249 
1250  case 2:
1251  dump_abilities();
1252  cleanup();
1253  break;
1254 
1255  case 3:
1256  dump_artifacts();
1257  cleanup();
1258  break;
1259 
1260  case 4:
1261  dump_spells();
1262  cleanup();
1263  break;
1264 
1265  case 5:
1266  cleanup();
1267  break;
1268 
1269  case 6:
1270  dump_races();
1271  cleanup();
1272  break;
1273 
1274  case 7:
1275  dump_alchemy();
1276  cleanup();
1277  break;
1278 
1279  case 8:
1280  dump_gods();
1281  cleanup();
1282  break;
1283 
1284  case 9:
1286  cleanup();
1287  break;
1288 
1289  case 10:
1291  cleanup();
1292  break;
1293  }
1294 }
1295 
1301 static void init_startup(void) {
1302 #ifdef SHUTDOWN_FILE
1303  char buf[MAX_BUF];
1304  FILE *fp;
1305 
1306  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1307  if ((fp = fopen(buf, "r")) != NULL) {
1308  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1309  printf("%s", buf);
1310  fclose(fp);
1311  exit(1);
1312  }
1313 #endif
1314 
1315  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1316  LOG(llevError, "CrossFire: Playing not allowed.\n");
1317  exit(-1);
1318  }
1319 }
1320 
1324 static void signal_shutdown(int signum_unused) {
1325  (void) signum_unused; /* avoid unused warning if enambled */
1326  shutdown_flag += 1;
1327 }
1328 
1341 static void rec_sighup(int i) {
1342  (void)i;
1343  /* Don't call LOG(). It calls non-reentrant functions. The other
1344  * signal handlers shouldn't really call LOG() either. */
1345  if (logfile != stderr) {
1346  reopen_logfile = 1;
1347  }
1348 }
1349 
1353 void init_signals(void) {
1354 #ifndef WIN32 /* init_signals() remove signals */
1355  struct sigaction sa;
1356 
1357  sa.sa_sigaction = NULL;
1358  sigemptyset(&sa.sa_mask);
1359  sa.sa_flags = 0;
1360  sa.sa_handler = rec_sighup;
1361  sigaction(SIGHUP, &sa, NULL);
1362  signal(SIGINT, signal_shutdown);
1363  signal(SIGPIPE, SIG_IGN);
1364 #endif /* win32 */
1365 }
Settings::casting_time
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:274
Settings::special_break_map
uint8_t special_break_map
If set, then submaps in random maps can break the walls.
Definition: global.h:327
Settings::meta_comment
char meta_comment[MAX_BUF]
Comment we send to the metaserver.
Definition: global.h:293
Command_Line_Options
One command line option definition.
Definition: init.cpp:375
module_information::name
const char * name
Module name, without space.
Definition: init.cpp:52
Settings::mapdir
const char * mapdir
Where the map files are.
Definition: global.h:256
global.h
Settings::meta_server
char meta_server[MAX_BUF]
Hostname/ip addr of the metaserver.
Definition: global.h:290
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
Settings::simple_exp
uint8_t simple_exp
If true, use the simple experience system.
Definition: global.h:267
citylife_init
void citylife_init(Settings *settings, ServerSettings *serverSettings)
Definition: citylife.cpp:426
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
options
static struct Command_Line_Options options[]
Actual valid command line options.
Definition: init.cpp:393
Settings::recycle_tmp_maps
uint8_t recycle_tmp_maps
Re-use tmp maps.
Definition: global.h:276
init
void init(int argc, char **argv)
This is the main server initialization function.
Definition: init.cpp:1114
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
init_beforeplay
static void init_beforeplay(void)
Called before the server starts listening to connections, processes various dump-related options.
Definition: init.cpp:1237
Settings::regions
const char * regions
Name of the regions file - libdir is prepended.
Definition: global.h:257
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:82
Settings::allow_broken_converters
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:318
Settings::log_timestamp_format
char * log_timestamp_format
Format for timestap, if log_timestamp is set.
Definition: global.h:321
Settings::armor_speed_linear
uint8_t armor_speed_linear
If 1, speed improvement is linear, else exponantiel.
Definition: global.h:311
module_information::close
void(* close)()
Cleanup function.
Definition: init.cpp:56
strdup_local
#define strdup_local
Definition: compat.h:29
materialtype_t::mod
int8_t mod[NROFATTACKS]
Modification to resistances.
Definition: material.h:37
Settings::resurrection
uint8_t resurrection
Ressurection possible w/ permadeth on.
Definition: global.h:270
serverSettings
ServerSettings serverSettings
Definition: init.cpp:46
service_handle
void service_handle()
Settings::set_title
uint8_t set_title
Players can set thier title.
Definition: global.h:269
dump_alchemy_costs
void dump_alchemy_costs(void)
Dumps to output all costs of recipes.
Definition: recipe.cpp:591
time
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs and afterward any time the value is but over time
Definition: protocol.txt:416
ServerSettings::disabled_plugins
std::vector< std::string > disabled_plugins
List of disabled plugins, 'All' means all.
Definition: server.h:16
motd
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific motd
Definition: server-directories.txt:37
Settings::ignore_plugin_compatibility
uint8_t ignore_plugin_compatibility
If set, don't check plugin version.
Definition: global.h:328
FALSE
#define FALSE
Definition: compat.h:14
Settings::not_permadeth
uint8_t not_permadeth
If true, death is non-permament.
Definition: global.h:266
Settings::permanent_exp_ratio
uint8_t permanent_exp_ratio
How much exp should be 'permenant' and unable to be lost.
Definition: global.h:262
Settings::crypt_mode
uint8_t crypt_mode
0 for legacy behavior, 1 for always Traditional
Definition: global.h:331
set_datadir
static void set_datadir(const char *path)
Command line option: set data path.
Definition: init.cpp:196
module_information::description
const char * description
Module long description.
Definition: init.cpp:53
Settings::dumpvalues
uint8_t dumpvalues
Set to dump various values/tables.
Definition: global.h:250
Settings::datadir
const char * datadir
Read only data files.
Definition: global.h:253
load_materials
static void load_materials(BufferReader *reader, const char *filename)
Loads the materials.
Definition: init.cpp:537
FULL_VERSION
#define FULL_VERSION
Definition: version.h:4
set_mapdir
static void set_mapdir(const char *path)
Command line option: set map path.
Definition: init.cpp:220
cleanup
void cleanup(void)
Clean up everything and exit.
Definition: server.cpp:1085
set_dumpmon7
static void set_dumpmon7(void)
Command line option: dump alchemy.
Definition: init.cpp:169
dump_faces
void dump_faces(void)
Dump all faces to stderr, for debugging purposes.
Definition: image.cpp:159
Settings::worldmaptilesy
uint32_t worldmaptilesy
Number of tiles high the worldmap is.
Definition: global.h:298
SHUTDOWN_FILE
#define SHUTDOWN_FILE
If you want to take the game down while installing new versions, or for other reasons,...
Definition: config.h:463
rec_sighup
static void rec_sighup(int i)
SIGHUP handler.
Definition: init.cpp:1341
Settings::min_name
uint8_t min_name
Minimum characters for an account or player name.
Definition: global.h:332
SRANDOM
#define SRANDOM(seed)
Definition: define.h:629
Settings::worldmapstartx
uint32_t worldmapstartx
Starting x tile for the worldmap.
Definition: global.h:295
list_modules
static void list_modules()
List all modules, then exit.
Definition: init.cpp:101
get_empty_mat
static materialtype_t * get_empty_mat(void)
Creates an empty materialtype_t structure.
Definition: init.cpp:517
set_dumpmont
static void set_dumpmont(const char *name)
Command line option: dump monster treasures.
Definition: init.cpp:187
init_ob_methods
void init_ob_methods(void)
Initializes the ob_method system.
Definition: ob_methods.cpp:35
set_dumpmon6
static void set_dumpmon6(void)
Command line option: dump races.
Definition: init.cpp:164
Settings::starting_stat_min
uint8_t starting_stat_min
Minimum value of a starting stat.
Definition: global.h:322
read_map_log
void read_map_log(void)
Reads temporary maps information from disk.
Definition: swap.cpp:71
Settings::roll_stat_points
uint8_t roll_stat_points
How many stat points legacy (rolled) chars start with.
Definition: global.h:325
Settings::pk_luck_penalty
int16_t pk_luck_penalty
Amount by which player luck is reduced if they PK.
Definition: global.h:261
FREE_AND_COPY_IF
#define FREE_AND_COPY_IF(sv, nv)
Definition: global.h:212
Settings::stat_file
char * stat_file
Definition: global.h:336
set_mondebug
static void set_mondebug(void)
Command line option: monster debug flag.
Definition: init.cpp:134
llevMonster
@ llevMonster
Many many details.
Definition: logger.h:16
server_dump_animations
static void server_dump_animations(void)
Dump all animations, then exit.
Definition: init.cpp:342
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
set_playerdir
static void set_playerdir(const char *path)
Command line option: set player path.
Definition: init.cpp:254
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:15
dump_gods
void dump_gods(void)
Prints all gods to stderr.
Definition: holy.cpp:367
Settings::csport
uint16_t csport
Port for new client/server.
Definition: global.h:247
materials
std::vector< materialtype_t * > materials
Definition: init.cpp:128
Settings::ignore_assets_errors
int ignore_assets_errors
If set then go on running even if there are errors in assets.
Definition: global.h:333
localdir
the server will also quite happily load unpacked files as long as they have the right file which is convenient if you want to edit your maps and archetypes live It also contains a few like which have hard coded names and are not identified by extension localdir Usually var crossfire Modern systems probably want var lib crossfire instead Contains data that the server does need to live apartment high the contents of player edited etc mapdir Usually maps Always relative to datadir or localdir
Definition: server-directories.txt:66
load_races
void load_races(BufferReader *reader, const char *filename)
Reads the races file in the lib/ directory, then overwrites old 'race' entries.
Definition: races.cpp:47
buf
StringBuffer * buf
Definition: readable.cpp:1564
init_server
void init_server(void)
This sets up the listening socket.
Definition: init.cpp:283
version.h
service_register
void service_register()
set_dumpmon2
static void set_dumpmon2(void)
Command line option: dump abilities.
Definition: init.cpp:144
Command_Line_Options::num_args
uint8_t num_args
Number or args it takes.
Definition: init.cpp:377
Settings::meta_host
char meta_host[MAX_BUF]
Hostname of this host.
Definition: global.h:291
set_dumpmon4
static void set_dumpmon4(void)
Command line option: dump spells.
Definition: init.cpp:154
forbid_play
int forbid_play(void)
Checks if server should be started.
Definition: server.cpp:1192
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
Settings::worldmaptilesx
uint32_t worldmaptilesx
Number of tiles wide the worldmap is.
Definition: global.h:297
dump_races
void dump_races(void)
Dumps all race information to stderr.
Definition: races.cpp:81
Settings::pk_max_experience
int64_t pk_max_experience
Maximum experience one can get for PKing.
Definition: global.h:315
Command_Line_Options::cmd_option
const char * cmd_option
How it is called on the command line.
Definition: init.cpp:376
server_dump_faces
static void server_dump_faces(void)
Dump all faces, then exit.
Definition: init.cpp:350
init_signals
void init_signals(void)
Setup our signal handlers.
Definition: init.cpp:1353
cfweather_init
void cfweather_init(Settings *settings, ServerSettings *servserSettings)
Weather module initialisation.
Definition: cfweather.cpp:4819
parse_args
static void parse_args(int argc, char *argv[], int pass)
Parse command line arguments.
Definition: init.cpp:465
Settings::spell_encumbrance
uint8_t spell_encumbrance
Encumbrance effects spells.
Definition: global.h:272
init_gods
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.cpp:59
materialtype_t::material
int material
What basic type(s) it is linked to.
Definition: material.h:35
dump_experience
void dump_experience(void)
Dump the experience table, then calls exit() - useful in terms of debugging to make sure the format o...
Definition: exp.cpp:251
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
Settings::meta_port
uint16_t meta_port
Port number to use for updates.
Definition: global.h:292
modules
static module_information modules[]
All built modules.
Definition: init.cpp:60
Settings::balanced_stat_loss
uint8_t balanced_stat_loss
If true, Death stat depletion based on level etc.
Definition: global.h:265
dump_stat_bonuses
void dump_stat_bonuses()
Definition: living.cpp:2651
Settings::debug
LogLevel debug
Default debugging level.
Definition: global.h:248
init_archetype_pointers
void init_archetype_pointers(void)
Initialize global archtype pointers:
Definition: treasure.cpp:62
Settings::pk_max_experience_percent
int pk_max_experience_percent
Percentage of experience of victim the killer gets.
Definition: global.h:316
add_refcount
sstring add_refcount(sstring str)
Like add_string(), but the string is already a shared string.
Definition: shstr.cpp:224
Settings::death_penalty_ratio
uint8_t death_penalty_ratio
Hhow much exp should be lost at death.
Definition: global.h:263
set_dumpmon3
static void set_dumpmon3(void)
Command line option: dump artifacts.
Definition: init.cpp:149
random_house_generator_init
void random_house_generator_init(Settings *settings, ServerSettings *serverSettings)
Module initialisation.
Definition: random_house_generator.cpp:211
assets_add_collector_hook
void assets_add_collector_hook(const char *name, collectorHook hook)
Definition: assets.cpp:556
cftimer_init
void cftimer_init(void)
Initialize timers.
Definition: timers.cpp:157
random_house_generator_close
void random_house_generator_close()
Close the module.
Definition: random_house_generator.cpp:221
free_races
void free_races(void)
Frees all race-related information.
Definition: races.cpp:93
Settings::set_friendly_fire
uint16_t set_friendly_fire
Percent of damage done by peaceful player vs player damage.
Definition: global.h:279
Settings::account_block_create
uint8_t account_block_create
Definition: global.h:329
Settings::motd
const char * motd
Name of the motd file.
Definition: global.h:282
Settings::logfilename
const char * logfilename
Logfile to use.
Definition: global.h:246
Settings::worldmapstarty
uint32_t worldmapstarty
Starting y tile for the worldmap.
Definition: global.h:296
cfcitybell_init
void cfcitybell_init(Settings *settings, ServerSettings *serverSettings)
Citybells module initialisation.
Definition: cfcitybell.cpp:153
add_string
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
free_quest
void free_quest(void)
Free all quest status structures.
Definition: quest.cpp:895
init_readable
void init_readable(void)
Initialize linked lists utilized by message functions in tailor_readable_ob()
Definition: readable.cpp:904
set_enable_module
static void set_enable_module(const char *name)
Enable a module.
Definition: init.cpp:335
materialtype_t::name
const char * name
Name of the material.
Definition: material.h:33
set_dumpmon1
static void set_dumpmon1(void)
Command line option: dump monsters.
Definition: init.cpp:139
metaserver2_init
int metaserver2_init(void)
Initialize metaserver reporting.
Definition: metaserver.cpp:462
description
spell prayer lvl t sp speed range duration short description
Definition: spell-summary.txt:2
Settings::armor_weight_reduction
int armor_weight_reduction
Weight reduction per enchantment.
Definition: global.h:308
Settings::stat_loss_on_death
uint8_t stat_loss_on_death
If true, chars lose a random stat when they die.
Definition: global.h:260
signal_shutdown
static void signal_shutdown(int signum_unused)
Signal handler that begins a normal server shutdown.
Definition: init.cpp:1324
Settings::item_power_factor
float item_power_factor
See note in setings file.
Definition: global.h:305
MAX_NAME
#define MAX_NAME
Definition: define.h:41
set_logfile
static void set_logfile(char *val)
Command line option: set logfile name.
Definition: init.cpp:113
service_unregister
void service_unregister()
Settings::dumparg
const char * dumparg
Additional argument for some dump functions.
Definition: global.h:251
assets_finish_archetypes_for_play
void assets_finish_archetypes_for_play()
Definition: assets.cpp:513
dump_spells
void dump_spells(void)
Dumps all the spells - now also dumps skill associated with the spell.
Definition: spell_util.cpp:108
Settings::confdir
const char * confdir
Configuration files.
Definition: global.h:252
sproto.h
logfile
FILE * logfile
Used by server/daemon.c.
Definition: init.cpp:114
set_tmpdir
static void set_tmpdir(const char *path)
Command line option: set temporary file path.
Definition: init.cpp:262
dump_abilities
void dump_abilities(void)
Dump to standard out the abilities of all monsters.
Definition: info.cpp:52
set_uniquedir
static void set_uniquedir(const char *path)
Command line option: set unique path.
Definition: init.cpp:246
materialtype_t::save
int8_t save[NROFATTACKS]
Save chances for the attacks.
Definition: material.h:36
Settings::death_penalty_level
uint8_t death_penalty_level
How many levels worth of exp may be lost on one death.
Definition: global.h:264
modules.h
fatal
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:595
accounts_load
void accounts_load(void)
This loads all the account entries into memory.
Definition: account.cpp:161
set_dumpmon9
static void set_dumpmon9(void)
Command line option: dump alchemy costs.
Definition: init.cpp:179
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
set_confdir
static void set_confdir(const char *path)
Command line option: set configuration path.
Definition: init.cpp:204
cmdlinefunc_args2
void(* cmdlinefunc_args2)(const char *arg1, const char *arg2)
Definition: init.cpp:367
set_dumpmon8
static void set_dumpmon8(void)
Command line option: dump gods.
Definition: init.cpp:174
Settings::playerdir
const char * playerdir
Where the player files are.
Definition: global.h:255
cfweather_close
void cfweather_close()
Definition: cfweather.cpp:4924
init_skills
void init_skills(void)
This just sets up the skill_names table above.
Definition: skill_util.cpp:97
Settings::spell_failure_effects
uint8_t spell_failure_effects
Nasty backlash to spell failures.
Definition: global.h:273
Settings::starting_stat_points
uint8_t starting_stat_points
How many stat points character starts with.
Definition: global.h:324
Settings
Server settings.
Definition: global.h:245
module_information::init
void(* init)(Settings *, ServerSettings *)
Initialisation function.
Definition: init.cpp:55
Settings::meta_on
unsigned int meta_on
True if we should send updates.
Definition: global.h:289
Settings::allow_denied_spells_writing
int allow_denied_spells_writing
If set, players can write spells they can't cast.
Definition: global.h:317
llevInfo
@ llevInfo
Information.
Definition: logger.h:14
hiscore_init
void hiscore_init(void)
Initializes the module.
Definition: hiscore.cpp:296
set_regions
static void set_regions(const char *path)
Command line option: set regions file name.
Definition: init.cpp:228
should_exit
static int should_exit
If set after command line argument parsing, then the server will exit.
Definition: init.cpp:49
init_library
void init_library(void)
It is vital that init_library() is called by any functions using this library.
Definition: init.cpp:312
Settings::who_wiz_format
char who_wiz_format[MAX_BUF]
The format that the who command should use when called by a dm.
Definition: global.h:281
commands_init
void commands_init(void)
Init standard commands.
Definition: commands.cpp:108
Settings::spellpoint_level_depend
uint8_t spellpoint_level_depend
Spell costs go up with level.
Definition: global.h:278
dump_quests
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.cpp:886
Settings::fastclock
uint8_t fastclock
If true, clock goes warp 9.
Definition: global.h:299
cmdlinefunc_args1
void(* cmdlinefunc_args1)(const char *arg1)
Definition: init.cpp:366
ServerSettings
Definition: server.h:15
mklocaldirs
static void mklocaldirs()
Create empty directories in localdir that the server expects to exist (and writes to without checking...
Definition: init.cpp:1097
free_materials
static void free_materials(void)
Frees all memory allocated to materials.
Definition: init.cpp:601
Settings::personalized_blessings
uint8_t personalized_blessings
If 1, blessed weapons get an owner and a willpower value.
Definition: global.h:314
print_monsters
void print_monsters(void)
As dump_abilities(), but with an alternative way of output.
Definition: info.cpp:87
unset_debug
static void unset_debug(void)
Command line option: unset debug flag.
Definition: init.cpp:129
dump_alchemy
void dump_alchemy(void)
Dumps alchemy recipes to output.
Definition: recipe.cpp:352
make_path_to_file
bool make_path_to_file(const char *filename)
Checks if any directories in the given path doesn't exist, and creates if necessary.
Definition: porting.cpp:165
help
static void help(void)
Display the command line options and exits.
Definition: init.cpp:1176
Settings::max_stat
uint8_t max_stat
Maximum stat value - 255 should be sufficient.
Definition: global.h:326
cmdlinefunc_args0
void(* cmdlinefunc_args0)(void)
Typedefs used when calling option handlers.
Definition: init.cpp:365
materialtype_t::description
const char * description
Description, unused.
Definition: material.h:34
set_debug
static void set_debug(void)
Command line option: debug flag.
Definition: init.cpp:124
load_settings
void load_settings(void)
This loads the settings file.
Definition: init.cpp:613
close_modules
void close_modules()
Clean up all modules which are not disabled.
Definition: init.cpp:87
reset_sleep
void reset_sleep(void)
Initialise all variables used in the timing routines.
Definition: time.cpp:134
assets.h
Settings::armor_max_enchant
int armor_max_enchant
Maximum number of times an armor can be enchanted.
Definition: global.h:307
cfcitybell_close
void cfcitybell_close()
Definition: cfcitybell.cpp:165
set_ignore_assets_errors
static void set_ignore_assets_errors()
Command line option: ignore assets errors.
Definition: init.cpp:269
dump_monster_treasure
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1287
dump_animations
void dump_animations(void)
Dump all animations to stderr, for debugging purposes.
Definition: anim.cpp:180
add_server_collect_hooks
void add_server_collect_hooks()
Definition: init.cpp:1088
Settings::armor_weight_linear
uint8_t armor_weight_linear
If 1, weight reduction is linear, else exponantiel.
Definition: global.h:309
set_dumpmon5
static void set_dumpmon5(void)
Command line option: ?
Definition: init.cpp:159
strcasecmp
int strcasecmp(const char *s1, const char *s2)
init_modules
void init_modules()
Init all modules which are not disabled.
Definition: init.cpp:71
call_version
static void call_version(void)
Command line option: show version.
Definition: init.cpp:118
set_csport
static void set_csport(const char *val)
Change the server's port.
Definition: init.cpp:286
loader.h
Settings::real_wiz
uint8_t real_wiz
Use mud-like wizards.
Definition: global.h:275
init_startup
static void init_startup(void)
Checks if starting the server is allowed.
Definition: init.cpp:1301
set_disable_plugin
static void set_disable_plugin(const char *name)
Disable a plugin.
Definition: init.cpp:299
set_localdir
static void set_localdir(const char *path)
Command line option: set local path.
Definition: init.cpp:212
reopen_logfile
int reopen_logfile
Definition: logger.cpp:31
assets_pack
void assets_pack(const char *what, const char *filename)
Pack the specified assets in a file.
Definition: assets.cpp:422
set_disable_module
static void set_disable_module(const char *name)
Disable a module.
Definition: init.cpp:327
free_server
void free_server(void)
Frees all memory allocated around here:
Definition: init.cpp:1166
citylife_close
void citylife_close()
Definition: citylife.cpp:437
finish_races
void finish_races()
Definition: races.cpp:98
materialtype_t
One material type.
Definition: material.h:32
Settings::no_player_stealing
uint8_t no_player_stealing
If 1, can not steal from other players.
Definition: global.h:312
Settings::account_trusted_host
char * account_trusted_host
Block account creation for untrusted hosts.
Definition: global.h:330
Settings::search_items
uint8_t search_items
Search_items command.
Definition: global.h:271
module_information
Definition: init.cpp:51
server.h
Settings::tmpdir
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:259
dump_artifacts
void dump_artifacts(void)
For debugging purposes.
Definition: artifact.cpp:610
Settings::always_show_hp
uint8_t always_show_hp
'probe' spell HP bars for all living things (0, 1, or 2)
Definition: global.h:277
TRUE
#define TRUE
Definition: compat.h:11
Settings::create_home_portals
uint8_t create_home_portals
If 1, can create portals in unique maps (apartments)
Definition: global.h:313
server_dump_bonuses
static void server_dump_bonuses()
Dump all bonuses (from the stat_bonus file) then exit.
Definition: init.cpp:358
Command_Line_Options::pass
uint8_t pass
What pass this should be processed on.
Definition: init.cpp:378
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
set_syslog
static void set_syslog(const char *arg)
Definition: init.cpp:232
BufferReader
Definition: bufferreader.cpp:22
Settings::armor_speed_improvement
int armor_speed_improvement
Speed improvement.
Definition: global.h:310
NUM_STATS
@ NUM_STATS
Number of statistics.
Definition: living.h:18
Settings::log_timestamp
int log_timestamp
If set, log will comport a timestamp.
Definition: global.h:320
Settings::who_format
char who_format[MAX_BUF]
The format that the who command should use.
Definition: global.h:280
server_pack_assets
static void server_pack_assets(const char *assets, const char *filename)
Definition: init.cpp:273
Command_Line_Options::func
void(* func)()
function to call when we match this.
Definition: init.cpp:379
shutdown_flag
volatile sig_atomic_t shutdown_flag
Definition: server.cpp:53
module_information::enabled
bool enabled
Whether the module is enabled or not.
Definition: init.cpp:54
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:15
do_module
static void do_module(const char *name, bool enabled)
Change the 'enabled' flag of a module.
Definition: init.cpp:309
Settings::starting_stat_max
uint8_t starting_stat_max
Maximum value of a starting stat.
Definition: global.h:323
Settings::uniquedir
const char * uniquedir
Directory for the unique items.
Definition: global.h:258
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:104
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:254