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;
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 
72  LOG(llevInfo, "Initializing modules, stage %d\n", stage);
73  for (int module = 0; modules[module].name != NULL; module++) {
74  module_information *mod = &modules[module];
75  if (!mod->enabled) {
76  if (stage == STARTUP_STAGE_FIRST) {
77  LOG(llevInfo, " %s (%s): disabled\n", mod->name, mod->description);
78  }
79  } else {
80  mod->init(&settings, &serverSettings, stage);
81  if (stage == STARTUP_STAGE_FIRST) {
82  LOG(llevInfo, " %s (%s): activated\n", mod->name, mod->description);
83  }
84  }
85  }
86 }
87 
91 void close_modules() {
92  LOG(llevInfo, "Cleaning modules\n");
93  for (int module = 0; modules[module].name != NULL; module++) {
94  module_information *mod = &modules[module];
95  if (mod->enabled) {
96  mod->close();
97  LOG(llevInfo, " %s (%s): closed\n", mod->name, mod->description);
98  }
99  }
100 }
101 
105 static void list_modules() {
106  LOG(llevInfo, "Built-in modules:\n");
107  for (int module = 0; modules[module].name != NULL; module++) {
108  LOG(llevInfo, " %s: %s -> %s\n", modules[module].name, modules[module].description, modules[module].enabled ? "enabled" : "disabled");
109  }
110  should_exit = 1;
111 }
112 
117 static void set_logfile(char *val) {
118  settings.logfilename = val;
119 }
120 
122 static void call_version(void) {
123  puts(FULL_VERSION);
124  exit(EXIT_SUCCESS);
125 }
126 
128 static void set_debug(void) {
130 }
131 
133 static void unset_debug(void) {
135 }
136 
138 static void set_mondebug(void) {
140 }
141 
143 static void set_dumpmon1(void) {
144  settings.dumpvalues = 1;
145 }
146 
148 static void set_dumpmon2(void) {
149  settings.dumpvalues = 2;
150 }
151 
153 static void set_dumpmon3(void) {
154  settings.dumpvalues = 3;
155 }
156 
158 static void set_dumpmon4(void) {
159  settings.dumpvalues = 4;
160 }
161 
163 static void set_dumpmon5(void) {
164  settings.dumpvalues = 5;
165 }
166 
168 static void set_dumpmon6(void) {
169  settings.dumpvalues = 6;
170 }
171 
173 static void set_dumpmon7(void) {
174  settings.dumpvalues = 7;
175 }
176 
178 static void set_dumpmon8(void) {
179  settings.dumpvalues = 8;
180 }
181 
183 static void set_dumpmon9(void) {
184  settings.dumpvalues = 9;
185 }
186 
191 static void set_dumpmont(const char *name) {
192  settings.dumpvalues = 10;
194 }
195 
200 static void set_datadir(const char *path) {
201  settings.datadir = path;
202 }
203 
208 static void set_confdir(const char *path) {
209  settings.confdir = path;
210 }
211 
216 static void set_localdir(const char *path) {
217  settings.localdir = path;
218 }
219 
224 static void set_mapdir(const char *path) {
225  settings.mapdir = path;
226 }
227 
232 static void set_regions(const char *path) {
233  settings.regions = path;
234 }
235 
236 static void set_syslog(const char *arg) {
237 #ifdef HAVE_SYSLOG_H
238  int facility = atoi(arg);
239  openlog("crossfire-server", LOG_NDELAY, facility << 3);
240  setlogmask(LOG_UPTO(LOG_DEBUG)); // enable all logs, filtering is still done by LOG()
241 #else
242  LOG(llevError, "syslog is not available in this build\n");
243 #endif
244 }
245 
250 static void set_uniquedir(const char *path) {
251  settings.uniquedir = path;
252 }
253 
258 static void set_playerdir(const char *path) {
259  settings.playerdir = path;
260 }
261 
266 static void set_tmpdir(const char *path) {
267  settings.tmpdir = path;
268 }
269 
275 }
276 
277 static void server_pack_assets(const char *assets, const char *filename) {
278  assets_pack(assets, filename);
279  should_exit = 1;
280 }
281 
282 static void free_materials(void);
283 
290 static void set_csport(const char *val) {
291  int port = atoi(val);
292  if (port <= 0 || port > 65535) {
293  LOG(llevError, "%d is an invalid csport number, must be between 1 and 65535.\n", port);
294  exit(1);
295  }
296  settings.csport = port;
297 }
298 
303 static void set_disable_plugin(const char *name) {
304  serverSettings.disabled_plugins.push_back(std::string(name ? name : ""));
305 }
306 
313 static void do_module(const char *name, bool enabled) {
314  bool one = false;
315  for (int module = 0; modules[module].name; module++) {
316  if (strcmp("All", name) == 0 || strcmp(modules[module].name, name) == 0) {
317  modules[module].enabled = enabled;
318  one = true;
319  }
320  }
321  if (!one) {
322  LOG(llevError, "Invalid module name %s\n", name);
324  }
325 }
326 
331 static void set_disable_module(const char *name) {
332  do_module(name, false);
333 }
334 
339 static void set_enable_module(const char *name) {
340  do_module(name, true);
341 }
342 
346 static void server_dump_animations(void) {
347  dump_animations();
348  cleanup();
349 }
350 
354 static void server_dump_faces(void) {
355  dump_faces();
356  cleanup();
357 }
358 
362 static void server_dump_bonuses() {
364  cleanup();
365 }
366 
369 typedef void (*cmdlinefunc_args0)(void);
370 typedef void (*cmdlinefunc_args1)(const char* arg1);
371 typedef void (*cmdlinefunc_args2)(const char* arg1, const char* arg2);
380  const char *cmd_option;
381  uint8_t num_args;
382  uint8_t pass;
383  void (*func)();
387 };
388 
397 static struct Command_Line_Options options[] = {
401  { "-conf", 1, 1, (cmdlinefunc_args0)set_confdir },
402  { "-d", 0, 1, (cmdlinefunc_args0)set_debug },
403  { "-data", 1, 1, (cmdlinefunc_args0)set_datadir },
404  { "-disable-plugin", 1, 1, (cmdlinefunc_args0)set_disable_plugin },
405  { "-disable-module", 1, 1, (cmdlinefunc_args0)set_disable_module },
406  { "-enable-module", 1, 1, (cmdlinefunc_args0)set_enable_module },
407  { "-list-modules", 0, 1, (cmdlinefunc_args0)list_modules },
408  { "-h", 0, 1, (cmdlinefunc_args0)help },
409  { "-ignore-assets-errors", 0, 1, (cmdlinefunc_args0)set_ignore_assets_errors },
410  { "-local", 1, 1, (cmdlinefunc_args0)set_localdir },
411  { "-log", 1, 1, (cmdlinefunc_args0)set_logfile },
412  { "-maps", 1, 1, (cmdlinefunc_args0)set_mapdir },
413  { "-mon", 0, 1, (cmdlinefunc_args0)set_mondebug },
414  { "-n", 0, 1, (cmdlinefunc_args0)unset_debug },
415  { "-playerdir", 1, 1, (cmdlinefunc_args0)set_playerdir },
416  { "-regions", 1, 1, (cmdlinefunc_args0)set_regions },
417  { "-syslog", 1, 1, (cmdlinefunc_args0)set_syslog },
418  { "-tmpdir", 1, 1, (cmdlinefunc_args0)set_tmpdir },
419  { "-uniquedir", 1, 1, (cmdlinefunc_args0)set_uniquedir },
420  { "-v", 0, 1, (cmdlinefunc_args0)call_version },
421 
422 #ifdef WIN32
423  /* Windows service stuff */
424  { "-regsrv", 0, 1, service_register },
425  { "-unregsrv", 0, 1, service_unregister },
426  { "-srv", 0, 1, service_handle },
427 #endif
428 
432  { "-p", 1, 2, (cmdlinefunc_args0)set_csport },
433 
437  { "-m", 0, 3, (cmdlinefunc_args0)set_dumpmon1 },
438  { "-m2", 0, 3, (cmdlinefunc_args0)set_dumpmon2 },
439  { "-m3", 0, 3, (cmdlinefunc_args0)set_dumpmon3 },
440  { "-m4", 0, 3, (cmdlinefunc_args0)set_dumpmon4 },
441  { "-m5", 0, 3, (cmdlinefunc_args0)set_dumpmon5 },
442  { "-m6", 0, 3, (cmdlinefunc_args0)set_dumpmon6 },
443  { "-m7", 0, 3, (cmdlinefunc_args0)set_dumpmon7 },
444  { "-m8", 0, 3, (cmdlinefunc_args0)set_dumpmon8 },
445  { "-m9", 0, 3, (cmdlinefunc_args0)set_dumpmon9 },
446  { "-mt", 1, 3, (cmdlinefunc_args0)set_dumpmont },
447  { "-mexp", 0, 3, (cmdlinefunc_args0)dump_experience },
448  { "-mq", 0, 3, (cmdlinefunc_args0)dump_quests },
449  { "-dump-anims", 0, 3, (cmdlinefunc_args0)server_dump_animations },
450  { "-dump-faces", 0, 3, (cmdlinefunc_args0)server_dump_faces },
451  { "-pack-assets", 2, 3, (cmdlinefunc_args0)server_pack_assets },
452  { "-dump-stat-bonuses", 0, 3, (cmdlinefunc_args0)server_dump_bonuses },
453 };
454 
469 static void parse_args(int argc, char *argv[], int pass) {
470  size_t i;
471  int on_arg = 1;
472 
473  while (on_arg < argc) {
474  for (i = 0; i < sizeof(options)/sizeof(struct Command_Line_Options); i++) {
475  if (!strcmp(options[i].cmd_option, argv[on_arg])) {
476  /* Found a matching option, but should not be processed on
477  * this pass. Just skip over it
478  */
479  if (options[i].pass != pass) {
480  on_arg += options[i].num_args+1;
481  break;
482  }
483  if (options[i].num_args) {
484  if ((on_arg+options[i].num_args) >= argc) {
485  fprintf(stderr, "%s requires an argument.\n", options[i].cmd_option);
486  exit(1);
487  }
488 
489  if (options[i].num_args == 1)
490  ((cmdlinefunc_args1)options[i].func)(argv[on_arg+1]);
491  if (options[i].num_args == 2)
492  ((cmdlinefunc_args2)options[i].func)(argv[on_arg+1], argv[on_arg+2]);
493  on_arg += options[i].num_args+1;
494  } else { /* takes no args */
496  on_arg++;
497  }
498  break;
499  }
500  }
501  if (i == sizeof(options)/sizeof(struct Command_Line_Options)) {
502  fprintf(stderr, "Unknown option: %s\n", argv[on_arg]);
503  fprintf(stderr, "Type '%s -h' for usage.\n", argv[0]);
504  exit(1);
505  }
506  }
507 
508  if (should_exit) {
509  cleanup();
510  }
511 }
512 
522  materialtype_t *mt;
523  int i;
524 
525  mt = (materialtype_t *)malloc(sizeof(materialtype_t));
526  if (mt == NULL)
528  mt->name = NULL;
529  mt->description = NULL;
530  for (i = 0; i < NROFATTACKS; i++) {
531  mt->save[i] = 0;
532  mt->mod[i] = 0;
533  }
534  return mt;
535 }
536 
541 static void load_materials(BufferReader *reader, const char *filename) {
542  char *buf, *cp, *next;
543  materialtype_t *mt = NULL;
544  int i, value;
545  (void)filename;
546  int line = 0;
547 
548  while ((buf = bufferreader_next_line(reader)) != NULL) {
549  line++;
550  if (*buf == '#')
551  continue;
552  cp = buf;
553  while (*cp == ' ') /* Skip blanks */
554  cp++;
555  if (!strncmp(cp, "name", 4)) {
556  mt = get_empty_mat();
557  materials.push_back(mt);
558  mt->name = add_string(strchr(cp, ' ')+1);
559  mt->description = add_refcount(mt->name);
560  }
561 
562  if (mt == NULL) {
563  LOG(llevError, "%s:%d: fields must come after a name line\n", filename, line);
565  }
566 
567  if (!strncmp(cp, "description", 11)) {
568  FREE_AND_COPY_IF(mt->description, strchr(cp, ' ')+1);
569  } else if (sscanf(cp, "material %d", &value)) {
570  mt->material = value;
571  } else if (!strncmp(cp, "saves", 5)) {
572  cp = strchr(cp, ' ')+1;
573  for (i = 0; i < NROFATTACKS; i++) {
574  if (cp == NULL) {
575  mt->save[i] = 0;
576  continue;
577  }
578  if ((next = strchr(cp, ',')) != NULL)
579  *(next++) = '\0';
580  sscanf(cp, "%d", &value);
581  mt->save[i] = (int8_t)value;
582  cp = next;
583  }
584  } else if (!strncmp(cp, "mods", 4)) {
585  cp = strchr(cp, ' ')+1;
586  for (i = 0; i < NROFATTACKS; i++) {
587  if (cp == NULL) {
588  mt->save[i] = 0;
589  continue;
590  }
591  if ((next = strchr(cp, ',')) != NULL)
592  *(next++) = '\0';
593  sscanf(cp, "%d", &value);
594  mt->mod[i] = (int8_t)value;
595  cp = next;
596  }
597  }
598  }
599  LOG(llevDebug, "loaded %d material type data\n", static_cast<int>(materials.size()));
600 }
601 
605 static void free_materials(void) {
606  for (auto material : materials) {
607  free(material);
608  }
609  materials.clear();
610 }
611 
617 void load_settings(void) {
618  static char motd[MAX_BUF] = { 0 };
619  char buf[MAX_BUF], *cp, dummy[1];
620  int has_val;
621  FILE *fp;
622 
623  dummy[0] = '\0';
624  snprintf(buf, sizeof(buf), "%s/settings", settings.confdir);
625 
626  /* We don't require a settings file at current time, but down the road,
627  * there will probably be so many values that not having a settings file
628  * will not be a good thing.
629  */
630  if ((fp = fopen(buf, "r")) == NULL) {
631  LOG(llevError, "Warning: No settings file found\n");
632  return;
633  }
634  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
635  if (buf[0] == '#')
636  continue;
637  /* eliminate newline */
638  if ((cp = strrchr(buf, '\n')) != NULL)
639  *cp = '\0';
640 
641  /* Skip over empty lines */
642  if (buf[0] == 0)
643  continue;
644 
645  /* Skip all the spaces and set them to nulls. If not space,
646  * set cp to "" to make strcpy's and the like easier down below.
647  */
648  if ((cp = strchr(buf, ' ')) != NULL) {
649  while (*cp == ' ')
650  *cp++ = 0;
651  has_val = 1;
652  } else {
653  cp = dummy;
654  has_val = 0;
655  }
656 
657  if (!strcasecmp(buf, "metaserver_notification")) {
658  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
660  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
662  } else {
663  LOG(llevError, "load_settings: Unknown value for metaserver_notification: %s\n", cp);
664  }
665  } else if (!strcasecmp(buf, "metaserver_server")) {
666  if (has_val)
668  else
669  LOG(llevError, "load_settings: metaserver_server must have a value.\n");
670  } else if (!strcasecmp(buf, "motd")) {
671  if (has_val) {
672  safe_strncpy(motd, cp, sizeof(motd));
673  settings.motd = motd;
674  } else
675  LOG(llevError, "load_settings: motd must have a value.\n");
676  } else if (!strcasecmp(buf, "metaserver_host")) {
677  if (has_val)
679  else
680  LOG(llevError, "load_settings: metaserver_host must have a value.\n");
681  } else if (!strcasecmp(buf, "port")) {
682  set_csport(cp);
683  } else if (!strcasecmp(buf, "metaserver_port")) {
684  int port = atoi(cp);
685 
686  if (port < 1 || port > 65535)
687  LOG(llevError, "load_settings: metaserver_port must be between 1 and 65535, %d is invalid\n", port);
688  else
689  settings.meta_port = port;
690  } else if (!strcasecmp(buf, "metaserver_comment")) {
692  } else if (!strcasecmp(buf, "worldmapstartx")) {
693  int size = atoi(cp);
694 
695  if (size < 0)
696  LOG(llevError, "load_settings: worldmapstartx must be at least 0, %d is invalid\n", size);
697  else
698  settings.worldmapstartx = size;
699  } else if (!strcasecmp(buf, "worldmapstarty")) {
700  int size = atoi(cp);
701 
702  if (size < 0)
703  LOG(llevError, "load_settings: worldmapstarty must be at least 0, %d is invalid\n", size);
704  else
705  settings.worldmapstarty = size;
706  } else if (!strcasecmp(buf, "worldmaptilesx")) {
707  int size = atoi(cp);
708 
709  if (size < 1)
710  LOG(llevError, "load_settings: worldmaptilesx must be greater than 1, %d is invalid\n", size);
711  else
712  settings.worldmaptilesx = size;
713  } else if (!strcasecmp(buf, "worldmaptilesy")) {
714  int size = atoi(cp);
715 
716  if (size < 1)
717  LOG(llevError, "load_settings: worldmaptilesy must be greater than 1, %d is invalid\n", size);
718  else
719  settings.worldmaptilesy = size;
720  } else if (!strcasecmp(buf, "fastclock")) {
721  int lev = atoi(cp);
722 
723  if (lev < 0)
724  LOG(llevError, "load_settings: fastclock must be at least 0, %d is invalid\n", lev);
725  else
726  settings.fastclock = lev;
727  } else if (!strcasecmp(buf, "not_permadeth")) {
728  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
730  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
732  } else {
733  LOG(llevError, "load_settings: Unknown value for not_permadeth: %s\n", cp);
734  }
735  } else if (!strcasecmp(buf, "resurrection")) {
736  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
738  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
740  } else {
741  LOG(llevError, "load_settings: Unknown value for resurrection: %s\n", cp);
742  }
743  } else if (!strcasecmp(buf, "set_title")) {
744  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
746  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
748  } else {
749  LOG(llevError, "load_settings: Unknown value for set_title: %s\n", cp);
750  }
751  } else if (!strcasecmp(buf, "search_items")) {
752  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
754  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
756  } else {
757  LOG(llevError, "load_settings: Unknown value for search_items: %s\n", cp);
758  }
759  } else if (!strcasecmp(buf, "spell_encumbrance")) {
760  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
762  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
764  } else {
765  LOG(llevError, "load_settings: Unknown value for spell_encumbrance: %s\n", cp);
766  }
767  } else if (!strcasecmp(buf, "spell_failure_effects")) {
768  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
770  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
772  } else {
773  LOG(llevError, "load_settings: Unknown value for spell_failure_effects: %s\n", cp);
774  }
775  } else if (!strcasecmp(buf, "casting_time")) {
776  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
778  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
780  } else {
781  LOG(llevError, "load_settings: Unknown value for casting_time: %s\n", cp);
782  }
783  } else if (!strcasecmp(buf, "real_wiz")) {
784  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
786  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
788  } else {
789  LOG(llevError, "load_settings: Unknown value for real_wiz: %s\n", cp);
790  }
791  } else if (!strcasecmp(buf, "recycle_tmp_maps")) {
792  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
794  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
796  } else {
797  LOG(llevError, "load_settings: Unknown value for recycle_tmp_maps: %s\n", cp);
798  }
799  } else if (!strcasecmp(buf, "always_show_hp")) {
800  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
802  } else if (!strcasecmp(cp, "damaged")) {
804  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
806  } else {
807  LOG(llevError, "load_settings: Unknown value for always_show_hp: %s\n", cp);
808  }
809  } else if (!strcasecmp(buf, "who_format")) {
810  if (has_val)
812  sizeof(settings.who_format));
813  } else if (!strcasecmp(buf, "who_wiz_format")) {
814  if (has_val) {
816  sizeof(settings.who_wiz_format));
817  }
818  } else if (!strcasecmp(buf, "spellpoint_level_depend")) {
819  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
821  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
823  } else {
824  LOG(llevError, "load_settings: Unknown value for spellpoint_level_depend: %s\n", cp);
825  }
826  } else if (!strcasecmp(buf, "stat_loss_on_death")) {
827  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
829  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
831  } else {
832  LOG(llevError, "load_settings: Unknown value for stat_loss_on_death: %s\n", cp);
833  }
834  } else if (!strcasecmp(buf, "use_permanent_experience")) {
835  LOG(llevError, "use_permanent_experience is deprecated, usepermenent_experience_percentage instead\n");
836  } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
837  int val = atoi(cp);
838  if (val < 0 || val > 100)
839  LOG(llevError, "load_settings: permenent_experience_percentage must be between 0 and 100, %d is invalid\n", val);
840  else
842  } else if (!strcasecmp(buf, "death_penalty_percentage")) {
843  int val = atoi(cp);
844  if (val < 0 || val > 100)
845  LOG(llevError, "load_settings: death_penalty_percentage must be between 0 and 100, %d is invalid\n", val);
846  else
848  } else if (!strcasecmp(buf, "death_penalty_levels")) {
849  int val = atoi(cp);
850  if (val < 0 || val > 255)
851  LOG(llevError, "load_settings: death_penalty_levels can not be negative, %d is invalid\n", val);
852  else
854  } else if (!strcasecmp(buf, "balanced_stat_loss")) {
855  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
857  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
859  } else {
860  LOG(llevError, "load_settings: Unknown value for balanced_stat_loss: %s\n", cp);
861  }
862  } else if (!strcasecmp(buf, "simple_exp")) {
863  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
865  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
867  } else {
868  LOG(llevError, "load_settings: Unknown value for simple_exp: %s\n", cp);
869  }
870  } else if (!strcasecmp(buf, "item_power_factor")) {
871  float tmp = atof(cp);
872  if (tmp < 0)
873  LOG(llevError, "load_settings: item_power_factor must be a positive number (%f < 0)\n", tmp);
874  else
876  } else if (!strcasecmp(buf, "pk_luck_penalty")) {
877  int16_t val = atoi(cp);
878 
879  if (val < -100 || val > 100)
880  LOG(llevError, "load_settings: pk_luck_penalty must be between -100 and 100, %d is invalid\n", val);
881  else
883  } else if (!strcasecmp(buf, "set_friendly_fire")) {
884  int val = atoi(cp);
885 
886  if (val < 1 || val > 100)
887  LOG(llevError, "load_settings: set_friendly_fire must be between 1 an 100, %d is invalid\n", val);
888  else
890  } else if (!strcasecmp(buf, "armor_max_enchant")) {
891  int max_e = atoi(cp);
892  if (max_e <= 0)
893  LOG(llevError, "load_settings: armor_max_enchant is %d\n", max_e);
894  else
895  settings.armor_max_enchant = max_e;
896  } else if (!strcasecmp(buf, "armor_weight_reduction")) {
897  int wr = atoi(cp);
898  if (wr < 0)
899  LOG(llevError, "load_settings: armor_weight_reduction is %d\n", wr);
900  else
902  } else if (!strcasecmp(buf, "armor_weight_linear")) {
903  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
905  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
907  } else {
908  LOG(llevError, "load_settings: unknown value for armor_weight_linear: %s\n", cp);
909  }
910  } else if (!strcasecmp(buf, "armor_speed_improvement")) {
911  int wr = atoi(cp);
912  if (wr < 0)
913  LOG(llevError, "load_settings: armor_speed_improvement is %d\n", wr);
914  else
916  } else if (!strcasecmp(buf, "armor_speed_linear")) {
917  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
919  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
921  } else {
922  LOG(llevError, "load_settings: unknown value for armor_speed_linear: %s\n", cp);
923  }
924  } else if (!strcasecmp(buf, "no_player_stealing")) {
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 no_player_stealing: %s\n", cp);
931  }
932  } else if (!strcasecmp(buf, "create_home_portals")) {
933  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
934 #ifdef TRY_BROKEN_TOWN_PORTALS
936 #else
937  LOG(llevError, "load_settings: create_home_portals is currently broken. It results in town portals that prematurely reset when the apartment is swapped.\n");
938 #endif
939  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
941  } else {
942  LOG(llevError, "load_settings: unknown value for create_home_portals: %s\n", cp);
943  }
944  } else if (!strcasecmp(buf, "personalized_blessings")) {
945  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
947  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
949  } else {
950  LOG(llevError, "load_settings: unknown value for personalized_blessings: %s\n", cp);
951  }
952  } else if (!strcasecmp(buf, "pk_max_experience")) {
953  int64_t pkme = atoll(cp);
954  if (pkme < 0)
955  pkme = -1;
957  } else if (!strcasecmp(buf, "pk_max_experience_percent")) {
958  int pkmep = atoi(cp);
959  if (pkmep < 0) {
960  LOG(llevError, "load_settings: pk_max_experience_percent should be positive or zero (was \"%s\")\n", cp);
961  } else
963  } else if (!strcasecmp(buf, "allow_denied_spells_writing")) {
964  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
966  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
968  } else {
969  LOG(llevError, "load_settings: unknown value for allow_denied_spells_writing: %s\n", cp);
970  }
971  } else if (!strcasecmp(buf, "allow_broken_converters")) {
972  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
974  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
976  } else {
977  LOG(llevError, "load_settings: unknown value for allow_broken_converters: %s\n", cp);
978  }
979  } else if (!strcasecmp(buf, "log_timestamp")) {
980  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
982  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
984  } else {
985  LOG(llevError, "load_settings: unknown value for log_timestamp: %s\n", cp);
986  }
987  } else if (!strcasecmp(buf, "log_timestamp_format")) {
990  } else if (!strcasecmp(buf, "starting_stat_min")) {
991  int val = atoi(cp);
992 
993  if (val < 1 || val > settings.max_stat || val > settings.starting_stat_max)
994  LOG(llevError, "load_settings: starting_stat_min (%d) need to be within %d-%d (%d)\n",
996  else
998  } else if (!strcasecmp(buf, "starting_stat_max")) {
999  int val = atoi(cp);
1000 
1001  if (val < 1 || val > settings.max_stat || val<settings.starting_stat_min)
1002  LOG(llevError, "load_settings: starting_stat_max (%d) need to be within %d-%d (%d)\n",
1004  else
1006  } else if (!strcasecmp(buf, "starting_stat_points")) {
1007  int val = atoi(cp);
1008 
1009  if (val < NUM_STATS * settings.starting_stat_min ||
1011  LOG(llevError, "load_settings: starting_stat_points (%d) need to be within %d-%d\n",
1013  else
1015  } else if (!strcasecmp(buf, "roll_stat_points")) {
1016  int val = atoi(cp);
1017 
1018  /* The 3 and 18 values are hard coded in because we know that
1019  * roll_stat() generates a value between 3 and 18 - if that ever
1020  * changed, this code should change also, but that code will eventually
1021  * go away.
1022  */
1023  if (val < NUM_STATS * 3 || val > NUM_STATS * 18)
1024  LOG(llevError, "load_settings: roll_stat_points need to be within %d-%d\n",
1025  NUM_STATS * 3, NUM_STATS * 18);
1026  else
1027  settings.roll_stat_points = val;
1028  } else if (!strcasecmp(buf, "special_break_map")) {
1029  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1031  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1033  } else {
1034  LOG(llevError, "load_settings: unknown value for special_break_map: %s\n", cp);
1035  }
1036  } else if (!strcasecmp(buf, "ignore_plugin_compatibility")) {
1037  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1039  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1041  } else {
1042  LOG(llevError, "load_settings: unknown value for ignore_plugin_compatibility: %s\n", cp);
1043  }
1044  } else if (!strcasecmp(buf, "account_block_create")) {
1045  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1047  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1049  } else {
1050  LOG(llevError, "load_settings: unknown value for account_block_create: %s\n", cp);
1051  }
1052  } else if (!strcasecmp(buf, "account_trusted_host")) {
1055  } else if (!strcasecmp(buf, "crypt_mode")) {
1056  int val = atoi(cp);
1057  if (val != 0 && val != 1) {
1058  LOG(llevError, "load_settings: crypt_mode must be 0 or 1\n");
1059  } else {
1060  settings.crypt_mode = val;
1061  }
1062  } else if (!strcasecmp(buf, "min_name")) {
1063  int val = atoi(cp);
1064 
1065  if (val < 1 || val > MAX_NAME )
1066  LOG(llevError, "load_settings: min_name (%d) need to be within %d-%d\n",
1067  val, 1, MAX_NAME);
1068  else
1069  settings.min_name = val;
1070  } else if (!strcasecmp(buf, "stat_file")) {
1072  } else {
1073  LOG(llevError, "Unknown value in settings file: %s\n", buf);
1074  }
1075  }
1076  fclose(fp);
1077  if (settings.log_timestamp_format == NULL)
1078  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
1079 
1080  /*
1081  * The who formats are defined in config to be blank. They should have been
1082  * overridden by the settings file, if there are no entries however, it will
1083  * have stayed blank. Since this probably isn't what is wanted, we will check if
1084  * new formats have been specified, and if not we will use the old defaults.
1085  */
1086  if (!strcmp(settings.who_format, ""))
1087  strcpy(settings.who_format, "%N_%t%h%d%b%n<%M>");
1088  if (!strcmp(settings.who_wiz_format, ""))
1089  strcpy(settings.who_wiz_format, "%N_%t%h%d%b%nLevel %l <%M>(@%i)(%c)");
1090 }
1091 
1096 }
1097 
1102 static void mklocaldirs() {
1103  auto dirs = {"", "account/", "maps/", "players/", "unique-items/"};
1104  std::string localdir(settings.localdir);
1105  for (auto dir : dirs) {
1106  if (!make_path_to_file((localdir + "/" + dir).c_str()))
1107  LOG(llevError, "Could not create server save directories in %s (%s). Some server state may fail to save.\n",
1108  settings.localdir, dir);
1109  }
1110 }
1111 
1119 void init(int argc, char **argv) {
1120  logfile = stderr;
1121 #ifdef HAVE_SYSLOG_H
1122  // disable syslog, then only re-enable it if configured
1123  setlogmask(0);
1124 #endif
1125 
1126  /* First argument pass - right now it does nothing, but in the future specifying
1127  * the LibDir in this pass would be reasonable. */
1128  parse_args(argc, argv, 1);
1129 
1131 
1132  mklocaldirs();
1133  init_library(); /* Must be called early */
1134  load_settings(); /* Load the settings file */
1135  parse_args(argc, argv, 2);
1136 
1137  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
1138  SRANDOM(time(NULL));
1139 
1140  init_startup(); /* Check shutdown/forbid files */
1141  init_signals(); /* Sets up signal interceptions */
1142  commands_init(); /* Sort command tables */
1143  read_map_log(); /* Load up the old temp map files */
1144  init_skills();
1145  init_ob_methods();
1146  cftimer_init();
1147  hiscore_init();
1148 
1149  parse_args(argc, argv, 3);
1150 
1151  init_beforeplay();
1153  if (argc != 0) {
1154  // Invocations from the command-line (e.g. crossfire-server) have the
1155  // binary name in argv[0]. If that is not there, assume we are running
1156  // as a test and don't create sockets.
1157  init_server();
1158  metaserver2_init();
1159  } else {
1160  LOG(llevInfo, "Running server in test mode (no sockets).\n");
1161  }
1162  accounts_load();
1163  reset_sleep();
1164 }
1165 
1171 void free_server(void) {
1172  free_materials();
1173  free_races();
1174  free_quest();
1176 }
1177 
1181 static void help(void) {
1182  printf("Usage: crossfire-server [options]\n\n");
1183 
1184  printf("Options:\n");
1185  printf(" -conf Set the directory to find configuration files.\n");
1186  printf(" -d Turn on extra debugging messages.\n");
1187  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1188  printf(" -disable-module\n"
1189  " Disable specified module, by its name\n"
1190  " Can be specified multiple times. 'All' disables all modules.\n");
1191  printf(" -enable-module\n"
1192  " Enable specified module, by its name\n"
1193  " Can be specified multiple times. 'All' enables all modules.\n");
1194  printf(" -disable-plugin\n"
1195  " Disables specified plugin. Use the name without the extension.\n"
1196  " Can be specified multiple times. 'All' disables all plugins.\n");
1197  printf(" -dump-anims Dump animations.\n");
1198  printf(" -h Print this help message.\n");
1199  printf(" -ignore-assets-errors\n");
1200  printf(" Allow going on even if there are errors in assets.\n");
1201  printf(" Warning: this may lead to strange behaviour.\n");
1202  printf(" -list-modules\n"
1203  " List built-in modules and exit.\n");
1204  printf(" -local Set the local data (var/) directory.\n");
1205  printf(" -log <file> Write logging information to the given file.\n");
1206  printf(" -m List suggested experience for all monsters.\n");
1207  printf(" -m2 Dump monster abilities.\n");
1208  printf(" -m3 Dump artifact information.\n");
1209  printf(" -m4 Dump spell information.\n");
1210  printf(" -m5 Dump skill information.\n");
1211  printf(" -m6 Dump race information.\n");
1212  printf(" -m7 Dump alchemy information.\n");
1213  printf(" -m8 Dump gods information.\n");
1214  printf(" -m9 Dump more alchemy information (formula checking).\n");
1215  printf(" -maps Set the map directory.\n");
1216  printf(" -mexp Dump the experience table.\n");
1217  printf(" -mon Turn on monster debugging.\n");
1218  printf(" -mq Dump the quest list.\n");
1219  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1220  printf(" -n Turn off debugging messages if on by default.\n");
1221  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1222  printf(" -pack-assets <type> <filename>\n");
1223  printf(" Packs specified assets type to the specified filename.\n");
1224  printf(" Valid assets type are: archs, treasures, faces, messages, facesets, artifacts, formulae, images, quests.\n");
1225  printf(" The file format will be tar ('images') or text (everything else).\n");
1226  printf(" It is possible to combine multiple assets by using '+', for instance 'faces+messages+artifacts'.\n");
1227  printf(" In this case the file will be in tar format.\n");
1228  printf(" -playerdir Set the player files directory.\n");
1229  printf(" -regions Set the region file.\n");
1230  printf(" -syslog <no> Log to syslog with the given facility number (e.g. 16 for LOCAL0)\n");
1231  printf(" -templatedir Set the template map directory.\n");
1232  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1233  printf(" -uniquedir Set the unique items/maps directory.\n");
1234  printf(" -v Print version information.\n");
1235  exit(EXIT_SUCCESS);
1236 }
1237 
1242 static void init_beforeplay(void) {
1243  init_archetype_pointers(); /* Setup global pointers to archetypes */
1244  finish_races(); /* overwrite race designations using entries in lib/races file */
1246  init_gods(); /* init linked list of gods from archs*/
1247  init_readable(); /* inits useful arrays for readable texts */
1248 
1249  switch (settings.dumpvalues) {
1250  case 1:
1251  print_monsters();
1252  cleanup();
1253  break;
1254 
1255  case 2:
1256  dump_abilities();
1257  cleanup();
1258  break;
1259 
1260  case 3:
1261  dump_artifacts();
1262  cleanup();
1263  break;
1264 
1265  case 4:
1266  dump_spells();
1267  cleanup();
1268  break;
1269 
1270  case 5:
1271  cleanup();
1272  break;
1273 
1274  case 6:
1275  dump_races();
1276  cleanup();
1277  break;
1278 
1279  case 7:
1280  dump_alchemy();
1281  cleanup();
1282  break;
1283 
1284  case 8:
1285  dump_gods();
1286  cleanup();
1287  break;
1288 
1289  case 9:
1291  cleanup();
1292  break;
1293 
1294  case 10:
1296  cleanup();
1297  break;
1298  }
1299 }
1300 
1306 static void init_startup(void) {
1307 #ifdef SHUTDOWN_FILE
1308  char buf[MAX_BUF];
1309  FILE *fp;
1310 
1311  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1312  if ((fp = fopen(buf, "r")) != NULL) {
1313  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1314  printf("%s", buf);
1315  fclose(fp);
1316  exit(1);
1317  }
1318 #endif
1319 
1320  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1321  LOG(llevError, "CrossFire: Playing not allowed.\n");
1322  exit(-1);
1323  }
1324 }
1325 
1329 static void signal_shutdown(int signum) {
1330  shutdown_flag = signum;
1331 }
1332 
1345 static void rec_sighup(int i) {
1346  (void)i;
1347  /* Don't call LOG(). It calls non-reentrant functions. The other
1348  * signal handlers shouldn't really call LOG() either. */
1349  if (logfile != stderr) {
1350  reopen_logfile = 1;
1351  }
1352 }
1353 
1357 void init_signals(void) {
1358 #ifndef WIN32 /* init_signals() remove signals */
1359  struct sigaction sa;
1360 
1361  sa.sa_sigaction = NULL;
1362  sigemptyset(&sa.sa_mask);
1363  sa.sa_flags = 0;
1364  sa.sa_handler = rec_sighup;
1365  sigaction(SIGHUP, &sa, NULL);
1366  signal(SIGINT, signal_shutdown);
1367  signal(SIGTERM, signal_shutdown);
1368  signal(SIGPIPE, SIG_IGN);
1369 #endif /* win32 */
1370 }
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:379
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
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
options
static struct Command_Line_Options options[]
Actual valid command line options.
Definition: init.cpp:397
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:1119
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:1242
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:200
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:541
FULL_VERSION
#define FULL_VERSION
Definition: version.h:4
init_modules
void init_modules(StartupStage stage)
Init all modules which are not disabled.
Definition: init.cpp:71
set_mapdir
static void set_mapdir(const char *path)
Command line option: set map path.
Definition: init.cpp:224
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:173
dump_faces
void dump_faces(void)
Dump all faces to stderr, for debugging purposes.
Definition: image.cpp:159
STARTUP_STAGE_COLLECT_HOOKS
@ STARTUP_STAGE_COLLECT_HOOKS
Called when adding collect hooks, before assets loading.
Definition: modules.h:23
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:1345
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:105
get_empty_mat
static materialtype_t * get_empty_mat(void)
Creates an empty materialtype_t structure.
Definition: init.cpp:521
set_dumpmont
static void set_dumpmont(const char *name)
Command line option: dump monster treasures.
Definition: init.cpp:191
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:168
Settings::starting_stat_min
uint8_t starting_stat_min
Minimum value of a starting stat.
Definition: global.h:322
citylife_init
void citylife_init(Settings *settings, ServerSettings *serverSettings, StartupStage stage)
Definition: citylife.cpp:429
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
module_information::init
void(* init)(Settings *, ServerSettings *, StartupStage)
Initialisation function.
Definition: init.cpp:55
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:138
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:346
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:258
signal_shutdown
static void signal_shutdown(int signum)
Signal handler that begins a normal server shutdown.
Definition: init.cpp:1329
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:278
version.h
service_register
void service_register()
set_dumpmon2
static void set_dumpmon2(void)
Command line option: dump abilities.
Definition: init.cpp:148
Command_Line_Options::num_args
uint8_t num_args
Number or args it takes.
Definition: init.cpp:381
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:158
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:380
server_dump_faces
static void server_dump_faces(void)
Dump all faces, then exit.
Definition: init.cpp:354
init_signals
void init_signals(void)
Setup our signal handlers.
Definition: init.cpp:1357
parse_args
static void parse_args(int argc, char *argv[], int pass)
Parse command line arguments.
Definition: init.cpp:469
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:153
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:224
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
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:339
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:143
metaserver2_init
int metaserver2_init(void)
Initialize metaserver reporting.
Definition: metaserver.cpp:408
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
random_house_generator_init
void random_house_generator_init(Settings *settings, ServerSettings *serverSettings, StartupStage stage)
Module initialisation.
Definition: random_house_generator.cpp:212
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
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:117
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:266
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:250
STARTUP_STAGE_BEFORE_SERVER
@ STARTUP_STAGE_BEFORE_SERVER
Called when everything is loaded but before the sockets are opened.
Definition: modules.h:24
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:183
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:208
cmdlinefunc_args2
void(* cmdlinefunc_args2)(const char *arg1, const char *arg2)
Definition: init.cpp:371
set_dumpmon8
static void set_dumpmon8(void)
Command line option: dump gods.
Definition: init.cpp:178
Settings::playerdir
const char * playerdir
Where the player files are.
Definition: global.h:255
StartupStage
StartupStage
Definition: modules.h:21
cfweather_close
void cfweather_close()
Definition: cfweather.cpp:4928
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
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:232
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:370
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:1102
free_materials
static void free_materials(void)
Frees all memory allocated to materials.
Definition: init.cpp:605
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:133
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)
Recursively creates missing directories in the path to filename until the last directory separator '/...
Definition: porting.cpp:168
help
static void help(void)
Display the command line options and exits.
Definition: init.cpp:1181
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:369
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:128
load_settings
void load_settings(void)
This loads the settings file.
Definition: init.cpp:617
close_modules
void close_modules()
Clean up all modules which are not disabled.
Definition: init.cpp:91
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:169
set_ignore_assets_errors
static void set_ignore_assets_errors()
Command line option: ignore assets errors.
Definition: init.cpp:273
dump_monster_treasure
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1298
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:1092
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:163
strcasecmp
int strcasecmp(const char *s1, const char *s2)
call_version
static void call_version(void)
Command line option: show version.
Definition: init.cpp:122
set_csport
static void set_csport(const char *val)
Change the server's port.
Definition: init.cpp:290
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:1306
set_disable_plugin
static void set_disable_plugin(const char *name)
Disable a plugin.
Definition: init.cpp:303
set_localdir
static void set_localdir(const char *path)
Command line option: set local path.
Definition: init.cpp:216
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:331
free_server
void free_server(void)
Frees all memory allocated around here:
Definition: init.cpp:1171
citylife_close
void citylife_close()
Definition: citylife.cpp:442
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:362
Command_Line_Options::pass
uint8_t pass
What pass this should be processed on.
Definition: init.cpp:382
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
set_syslog
static void set_syslog(const char *arg)
Definition: init.cpp:236
cfweather_init
void cfweather_init(Settings *settings, ServerSettings *serverSettings, StartupStage stage)
Weather module initialisation.
Definition: cfweather.cpp:4820
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:277
STARTUP_STAGE_FIRST
@ STARTUP_STAGE_FIRST
Dummy stage, don't change, used for logging.
Definition: modules.h:22
Command_Line_Options::func
void(* func)()
function to call when we match this.
Definition: init.cpp:383
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:313
cfcitybell_init
void cfcitybell_init(Settings *settings, ServerSettings *serverSettings, StartupStage stage)
Citybells module initialisation.
Definition: cfcitybell.cpp:154
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:110
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:254