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 <filesystem>
36 
37 #include "loader.h"
38 #include "version.h"
39 #include "server.h"
40 #include "sproto.h"
41 #include "assets.h"
42 #include "modules.h"
43 
44 static void help(void);
45 static void init_beforeplay(void);
46 static void init_startup(void);
47 
49 
51 static int should_exit = 0;
52 
54  const char *name;
55  char const *description;
56  bool enabled;
57  void (*init)(Settings *, ServerSettings *);
58  void (*close)();
59 };
60 
63  { "citybell", "Ring bells every hour for defined temples", true, cfcitybell_init, cfcitybell_close },
64  { "citylife", "Add NPCs in towns", true, citylife_init, citylife_close },
65  { "rhg", "Add random maps to exits in towns", false, random_house_generator_init, random_house_generator_close },
66  { "weather", "Add weather effects to the world map.", false, cfweather_init, cfweather_close },
67  { NULL, NULL, false, NULL, NULL }
68 };
69 
73 void init_modules() {
74  LOG(llevInfo, "Initializing modules\n");
75  for (int module = 0; modules[module].name != NULL; module++) {
76  module_information *mod = &modules[module];
77  if (!mod->enabled) {
78  LOG(llevInfo, " %s (%s): disabled\n", mod->name, mod->description);
79  } else {
80  mod->init(&settings, &serverSettings);
81  LOG(llevInfo, " %s (%s): activated\n", mod->name, mod->description);
82  }
83  }
84 }
85 
89 void close_modules() {
90  LOG(llevInfo, "Cleaning modules\n");
91  for (int module = 0; modules[module].name != NULL; module++) {
92  module_information *mod = &modules[module];
93  if (mod->enabled) {
94  mod->close();
95  LOG(llevInfo, " %s (%s): closed\n", mod->name, mod->description);
96  }
97  }
98 }
99 
103 static void list_modules() {
104  LOG(llevInfo, "Built-in modules:\n");
105  for (int module = 0; modules[module].name != NULL; module++) {
106  LOG(llevInfo, " %s: %s -> %s\n", modules[module].name, modules[module].description, modules[module].enabled ? "enabled" : "disabled");
107  }
108  should_exit = 1;
109 }
110 
115 static void set_logfile(char *val) {
116  settings.logfilename = val;
117 }
118 
120 static void call_version(void) {
121  puts(FULL_VERSION);
122  exit(EXIT_SUCCESS);
123 }
124 
126 static void set_debug(void) {
128 }
129 
131 static void unset_debug(void) {
133 }
134 
136 static void set_mondebug(void) {
138 }
139 
141 static void set_dumpmon1(void) {
142  settings.dumpvalues = 1;
143 }
144 
146 static void set_dumpmon2(void) {
147  settings.dumpvalues = 2;
148 }
149 
151 static void set_dumpmon3(void) {
152  settings.dumpvalues = 3;
153 }
154 
156 static void set_dumpmon4(void) {
157  settings.dumpvalues = 4;
158 }
159 
161 static void set_dumpmon5(void) {
162  settings.dumpvalues = 5;
163 }
164 
166 static void set_dumpmon6(void) {
167  settings.dumpvalues = 6;
168 }
169 
171 static void set_dumpmon7(void) {
172  settings.dumpvalues = 7;
173 }
174 
176 static void set_dumpmon8(void) {
177  settings.dumpvalues = 8;
178 }
179 
181 static void set_dumpmon9(void) {
182  settings.dumpvalues = 9;
183 }
184 
189 static void set_dumpmont(const char *name) {
190  settings.dumpvalues = 10;
192 }
193 
198 static void set_datadir(const char *path) {
199  settings.datadir = path;
200 }
201 
206 static void set_confdir(const char *path) {
207  settings.confdir = path;
208 }
209 
214 static void set_localdir(const char *path) {
215  settings.localdir = path;
216 }
217 
222 static void set_mapdir(const char *path) {
223  settings.mapdir = path;
224 }
225 
230 static void set_regions(const char *path) {
231  settings.regions = path;
232 }
233 
234 static void set_syslog(const char *arg) {
235 #ifdef HAVE_SYSLOG_H
236  int facility = atoi(arg);
237  openlog("crossfire-server", LOG_NDELAY, facility << 3);
238  setlogmask(LOG_UPTO(LOG_DEBUG)); // enable all logs, filtering is still done by LOG()
239 #else
240  LOG(llevError, "syslog is not available in this build\n");
241 #endif
242 }
243 
248 static void set_uniquedir(const char *path) {
249  settings.uniquedir = path;
250 }
251 
256 static void set_templatedir(const char *path) {
257  settings.templatedir = path;
258 }
259 
264 static void set_playerdir(const char *path) {
265  settings.playerdir = path;
266 }
267 
272 static void set_tmpdir(const char *path) {
273  settings.tmpdir = path;
274 }
275 
281 }
282 
283 static void server_pack_assets(const char *assets, const char *filename) {
284  assets_pack(assets, filename);
285  should_exit = 1;
286 }
287 
288 static void free_materials(void);
289 
296 static void set_csport(const char *val) {
297  int port = atoi(val);
298  if (port <= 0 || port > 65535) {
299  LOG(llevError, "%d is an invalid csport number, must be between 1 and 65535.\n", port);
300  exit(1);
301  }
302  settings.csport = port;
303 }
304 
309 static void set_disable_plugin(const char *name) {
310  serverSettings.disabled_plugins.push_back(std::string(name ? name : ""));
311 }
312 
319 static void do_module(const char *name, bool enabled) {
320  bool one = false;
321  for (int module = 0; modules[module].name; module++) {
322  if (strcmp("All", name) == 0 || strcmp(modules[module].name, name) == 0) {
323  modules[module].enabled = enabled;
324  one = true;
325  }
326  }
327  if (!one) {
328  LOG(llevError, "Invalid module name %s\n", name);
330  }
331 }
332 
337 static void set_disable_module(const char *name) {
338  do_module(name, false);
339 }
340 
345 static void set_enable_module(const char *name) {
346  do_module(name, true);
347 }
348 
352 static void server_dump_animations(void) {
353  dump_animations();
354  cleanup();
355 }
356 
360 static void server_dump_faces(void) {
361  dump_faces();
362  cleanup();
363 }
364 
368 static void server_dump_bonuses() {
370  cleanup();
371 }
372 
375 typedef void (*cmdlinefunc_args0)(void);
376 typedef void (*cmdlinefunc_args1)(const char* arg1);
377 typedef void (*cmdlinefunc_args2)(const char* arg1, const char* arg2);
386  const char *cmd_option;
387  uint8_t num_args;
388  uint8_t pass;
389  void (*func)();
393 };
394 
403 static struct Command_Line_Options options[] = {
407  { "-conf", 1, 1, (cmdlinefunc_args0)set_confdir },
408  { "-d", 0, 1, (cmdlinefunc_args0)set_debug },
409  { "-data", 1, 1, (cmdlinefunc_args0)set_datadir },
410  { "-disable-plugin", 1, 1, (cmdlinefunc_args0)set_disable_plugin },
411  { "-disable-module", 1, 1, (cmdlinefunc_args0)set_disable_module },
412  { "-enable-module", 1, 1, (cmdlinefunc_args0)set_enable_module },
413  { "-list-modules", 0, 1, (cmdlinefunc_args0)list_modules },
414  { "-h", 0, 1, (cmdlinefunc_args0)help },
415  { "-ignore-assets-errors", 0, 1, (cmdlinefunc_args0)set_ignore_assets_errors },
416  { "-local", 1, 1, (cmdlinefunc_args0)set_localdir },
417  { "-log", 1, 1, (cmdlinefunc_args0)set_logfile },
418  { "-maps", 1, 1, (cmdlinefunc_args0)set_mapdir },
419  { "-mon", 0, 1, (cmdlinefunc_args0)set_mondebug },
420  { "-n", 0, 1, (cmdlinefunc_args0)unset_debug },
421  { "-playerdir", 1, 1, (cmdlinefunc_args0)set_playerdir },
422  { "-regions", 1, 1, (cmdlinefunc_args0)set_regions },
423  { "-syslog", 1, 1, (cmdlinefunc_args0)set_syslog },
424  { "-templatedir", 1, 1, (cmdlinefunc_args0)set_templatedir },
425  { "-tmpdir", 1, 1, (cmdlinefunc_args0)set_tmpdir },
426  { "-uniquedir", 1, 1, (cmdlinefunc_args0)set_uniquedir },
427  { "-v", 0, 1, (cmdlinefunc_args0)call_version },
428 
429 #ifdef WIN32
430  /* Windows service stuff */
431  { "-regsrv", 0, 1, service_register },
432  { "-unregsrv", 0, 1, service_unregister },
433  { "-srv", 0, 1, service_handle },
434 #endif
435 
439  { "-p", 1, 2, (cmdlinefunc_args0)set_csport },
440 
444  { "-m", 0, 3, (cmdlinefunc_args0)set_dumpmon1 },
445  { "-m2", 0, 3, (cmdlinefunc_args0)set_dumpmon2 },
446  { "-m3", 0, 3, (cmdlinefunc_args0)set_dumpmon3 },
447  { "-m4", 0, 3, (cmdlinefunc_args0)set_dumpmon4 },
448  { "-m5", 0, 3, (cmdlinefunc_args0)set_dumpmon5 },
449  { "-m6", 0, 3, (cmdlinefunc_args0)set_dumpmon6 },
450  { "-m7", 0, 3, (cmdlinefunc_args0)set_dumpmon7 },
451  { "-m8", 0, 3, (cmdlinefunc_args0)set_dumpmon8 },
452  { "-m9", 0, 3, (cmdlinefunc_args0)set_dumpmon9 },
453  { "-mt", 1, 3, (cmdlinefunc_args0)set_dumpmont },
454  { "-mexp", 0, 3, (cmdlinefunc_args0)dump_experience },
455  { "-mq", 0, 3, (cmdlinefunc_args0)dump_quests },
456  { "-dump-anims", 0, 3, (cmdlinefunc_args0)server_dump_animations },
457  { "-dump-faces", 0, 3, (cmdlinefunc_args0)server_dump_faces },
458  { "-pack-assets", 2, 3, (cmdlinefunc_args0)server_pack_assets },
459  { "-dump-stat-bonuses", 0, 3, (cmdlinefunc_args0)server_dump_bonuses },
460 };
461 
476 static void parse_args(int argc, char *argv[], int pass) {
477  size_t i;
478  int on_arg = 1;
479 
480  while (on_arg < argc) {
481  for (i = 0; i < sizeof(options)/sizeof(struct Command_Line_Options); i++) {
482  if (!strcmp(options[i].cmd_option, argv[on_arg])) {
483  /* Found a matching option, but should not be processed on
484  * this pass. Just skip over it
485  */
486  if (options[i].pass != pass) {
487  on_arg += options[i].num_args+1;
488  break;
489  }
490  if (options[i].num_args) {
491  if ((on_arg+options[i].num_args) >= argc) {
492  fprintf(stderr, "%s requires an argument.\n", options[i].cmd_option);
493  exit(1);
494  }
495 
496  if (options[i].num_args == 1)
497  ((cmdlinefunc_args1)options[i].func)(argv[on_arg+1]);
498  if (options[i].num_args == 2)
499  ((cmdlinefunc_args2)options[i].func)(argv[on_arg+1], argv[on_arg+2]);
500  on_arg += options[i].num_args+1;
501  } else { /* takes no args */
503  on_arg++;
504  }
505  break;
506  }
507  }
508  if (i == sizeof(options)/sizeof(struct Command_Line_Options)) {
509  fprintf(stderr, "Unknown option: %s\n", argv[on_arg]);
510  fprintf(stderr, "Type '%s -h' for usage.\n", argv[0]);
511  exit(1);
512  }
513  }
514 
515  if (should_exit) {
516  cleanup();
517  }
518 }
519 
529  materialtype_t *mt;
530  int i;
531 
532  mt = (materialtype_t *)malloc(sizeof(materialtype_t));
533  if (mt == NULL)
535  mt->name = NULL;
536  mt->description = NULL;
537  for (i = 0; i < NROFATTACKS; i++) {
538  mt->save[i] = 0;
539  mt->mod[i] = 0;
540  }
541  return mt;
542 }
543 
548 static void load_materials(BufferReader *reader, const char *filename) {
549  char *buf, *cp, *next;
550  materialtype_t *mt = NULL;
551  int i, value;
552  (void)filename;
553  int line = 0;
554 
555  while ((buf = bufferreader_next_line(reader)) != NULL) {
556  line++;
557  if (*buf == '#')
558  continue;
559  cp = buf;
560  while (*cp == ' ') /* Skip blanks */
561  cp++;
562  if (!strncmp(cp, "name", 4)) {
563  mt = get_empty_mat();
564  materials.push_back(mt);
565  mt->name = add_string(strchr(cp, ' ')+1);
566  mt->description = add_refcount(mt->name);
567  }
568 
569  if (mt == NULL) {
570  LOG(llevError, "%s:%d: fields must come after a name line\n", filename, line);
572  }
573 
574  if (!strncmp(cp, "description", 11)) {
575  FREE_AND_COPY_IF(mt->description, strchr(cp, ' ')+1);
576  } else if (sscanf(cp, "material %d", &value)) {
577  mt->material = value;
578  } else if (!strncmp(cp, "saves", 5)) {
579  cp = strchr(cp, ' ')+1;
580  for (i = 0; i < NROFATTACKS; i++) {
581  if (cp == NULL) {
582  mt->save[i] = 0;
583  continue;
584  }
585  if ((next = strchr(cp, ',')) != NULL)
586  *(next++) = '\0';
587  sscanf(cp, "%d", &value);
588  mt->save[i] = (int8_t)value;
589  cp = next;
590  }
591  } else if (!strncmp(cp, "mods", 4)) {
592  cp = strchr(cp, ' ')+1;
593  for (i = 0; i < NROFATTACKS; i++) {
594  if (cp == NULL) {
595  mt->save[i] = 0;
596  continue;
597  }
598  if ((next = strchr(cp, ',')) != NULL)
599  *(next++) = '\0';
600  sscanf(cp, "%d", &value);
601  mt->mod[i] = (int8_t)value;
602  cp = next;
603  }
604  }
605  }
606  LOG(llevDebug, "loaded %d material type data\n", static_cast<int>(materials.size()));
607 }
608 
612 static void free_materials(void) {
613  for (auto material : materials) {
614  free(material);
615  }
616  materials.clear();
617 }
618 
624 void load_settings(void) {
625  static char motd[MAX_BUF] = { 0 };
626  char buf[MAX_BUF], *cp, dummy[1];
627  int has_val;
628  FILE *fp;
629 
630  dummy[0] = '\0';
631  snprintf(buf, sizeof(buf), "%s/settings", settings.confdir);
632 
633  /* We don't require a settings file at current time, but down the road,
634  * there will probably be so many values that not having a settings file
635  * will not be a good thing.
636  */
637  if ((fp = fopen(buf, "r")) == NULL) {
638  LOG(llevError, "Warning: No settings file found\n");
639  return;
640  }
641  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
642  if (buf[0] == '#')
643  continue;
644  /* eliminate newline */
645  if ((cp = strrchr(buf, '\n')) != NULL)
646  *cp = '\0';
647 
648  /* Skip over empty lines */
649  if (buf[0] == 0)
650  continue;
651 
652  /* Skip all the spaces and set them to nulls. If not space,
653  * set cp to "" to make strcpy's and the like easier down below.
654  */
655  if ((cp = strchr(buf, ' ')) != NULL) {
656  while (*cp == ' ')
657  *cp++ = 0;
658  has_val = 1;
659  } else {
660  cp = dummy;
661  has_val = 0;
662  }
663 
664  if (!strcasecmp(buf, "metaserver_notification")) {
665  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
667  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
669  } else {
670  LOG(llevError, "load_settings: Unknown value for metaserver_notification: %s\n", cp);
671  }
672  } else if (!strcasecmp(buf, "metaserver_server")) {
673  if (has_val)
675  else
676  LOG(llevError, "load_settings: metaserver_server must have a value.\n");
677  } else if (!strcasecmp(buf, "motd")) {
678  if (has_val) {
679  safe_strncpy(motd, cp, sizeof(motd));
680  settings.motd = motd;
681  } else
682  LOG(llevError, "load_settings: motd must have a value.\n");
683  } else if (!strcasecmp(buf, "metaserver_host")) {
684  if (has_val)
686  else
687  LOG(llevError, "load_settings: metaserver_host must have a value.\n");
688  } else if (!strcasecmp(buf, "port")) {
689  set_csport(cp);
690  } else if (!strcasecmp(buf, "metaserver_port")) {
691  int port = atoi(cp);
692 
693  if (port < 1 || port > 65535)
694  LOG(llevError, "load_settings: metaserver_port must be between 1 and 65535, %d is invalid\n", port);
695  else
696  settings.meta_port = port;
697  } else if (!strcasecmp(buf, "metaserver_comment")) {
699  } else if (!strcasecmp(buf, "worldmapstartx")) {
700  int size = atoi(cp);
701 
702  if (size < 0)
703  LOG(llevError, "load_settings: worldmapstartx must be at least 0, %d is invalid\n", size);
704  else
705  settings.worldmapstartx = size;
706  } else if (!strcasecmp(buf, "worldmapstarty")) {
707  int size = atoi(cp);
708 
709  if (size < 0)
710  LOG(llevError, "load_settings: worldmapstarty must be at least 0, %d is invalid\n", size);
711  else
712  settings.worldmapstarty = size;
713  } else if (!strcasecmp(buf, "worldmaptilesx")) {
714  int size = atoi(cp);
715 
716  if (size < 1)
717  LOG(llevError, "load_settings: worldmaptilesx must be greater than 1, %d is invalid\n", size);
718  else
719  settings.worldmaptilesx = size;
720  } else if (!strcasecmp(buf, "worldmaptilesy")) {
721  int size = atoi(cp);
722 
723  if (size < 1)
724  LOG(llevError, "load_settings: worldmaptilesy must be greater than 1, %d is invalid\n", size);
725  else
726  settings.worldmaptilesy = size;
727  } else if (!strcasecmp(buf, "fastclock")) {
728  int lev = atoi(cp);
729 
730  if (lev < 0)
731  LOG(llevError, "load_settings: fastclock must be at least 0, %d is invalid\n", lev);
732  else
733  settings.fastclock = lev;
734  } else if (!strcasecmp(buf, "not_permadeth")) {
735  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
737  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
739  } else {
740  LOG(llevError, "load_settings: Unknown value for not_permadeth: %s\n", cp);
741  }
742  } else if (!strcasecmp(buf, "resurrection")) {
743  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
745  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
747  } else {
748  LOG(llevError, "load_settings: Unknown value for resurrection: %s\n", cp);
749  }
750  } else if (!strcasecmp(buf, "set_title")) {
751  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
753  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
755  } else {
756  LOG(llevError, "load_settings: Unknown value for set_title: %s\n", cp);
757  }
758  } else if (!strcasecmp(buf, "search_items")) {
759  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
761  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
763  } else {
764  LOG(llevError, "load_settings: Unknown value for search_items: %s\n", cp);
765  }
766  } else if (!strcasecmp(buf, "spell_encumbrance")) {
767  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
769  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
771  } else {
772  LOG(llevError, "load_settings: Unknown value for spell_encumbrance: %s\n", cp);
773  }
774  } else if (!strcasecmp(buf, "spell_failure_effects")) {
775  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
777  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
779  } else {
780  LOG(llevError, "load_settings: Unknown value for spell_failure_effects: %s\n", cp);
781  }
782  } else if (!strcasecmp(buf, "casting_time")) {
783  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
785  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
787  } else {
788  LOG(llevError, "load_settings: Unknown value for casting_time: %s\n", cp);
789  }
790  } else if (!strcasecmp(buf, "real_wiz")) {
791  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
793  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
795  } else {
796  LOG(llevError, "load_settings: Unknown value for real_wiz: %s\n", cp);
797  }
798  } else if (!strcasecmp(buf, "recycle_tmp_maps")) {
799  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
801  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
803  } else {
804  LOG(llevError, "load_settings: Unknown value for recycle_tmp_maps: %s\n", cp);
805  }
806  } else if (!strcasecmp(buf, "always_show_hp")) {
807  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
809  } else if (!strcasecmp(cp, "damaged")) {
811  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
813  } else {
814  LOG(llevError, "load_settings: Unknown value for always_show_hp: %s\n", cp);
815  }
816  } else if (!strcasecmp(buf, "who_format")) {
817  if (has_val)
819  sizeof(settings.who_format));
820  } else if (!strcasecmp(buf, "who_wiz_format")) {
821  if (has_val) {
823  sizeof(settings.who_wiz_format));
824  }
825  } else if (!strcasecmp(buf, "spellpoint_level_depend")) {
826  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
828  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
830  } else {
831  LOG(llevError, "load_settings: Unknown value for spellpoint_level_depend: %s\n", cp);
832  }
833  } else if (!strcasecmp(buf, "stat_loss_on_death")) {
834  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
836  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
838  } else {
839  LOG(llevError, "load_settings: Unknown value for stat_loss_on_death: %s\n", cp);
840  }
841  } else if (!strcasecmp(buf, "use_permanent_experience")) {
842  LOG(llevError, "use_permanent_experience is deprecated, usepermenent_experience_percentage instead\n");
843  } else if (!strcasecmp(buf, "permanent_experience_percentage")) {
844  int val = atoi(cp);
845  if (val < 0 || val > 100)
846  LOG(llevError, "load_settings: permenent_experience_percentage must be between 0 and 100, %d is invalid\n", val);
847  else
849  } else if (!strcasecmp(buf, "death_penalty_percentage")) {
850  int val = atoi(cp);
851  if (val < 0 || val > 100)
852  LOG(llevError, "load_settings: death_penalty_percentage must be between 0 and 100, %d is invalid\n", val);
853  else
855  } else if (!strcasecmp(buf, "death_penalty_levels")) {
856  int val = atoi(cp);
857  if (val < 0 || val > 255)
858  LOG(llevError, "load_settings: death_penalty_levels can not be negative, %d is invalid\n", val);
859  else
861  } else if (!strcasecmp(buf, "balanced_stat_loss")) {
862  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
864  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
866  } else {
867  LOG(llevError, "load_settings: Unknown value for balanced_stat_loss: %s\n", cp);
868  }
869  } else if (!strcasecmp(buf, "simple_exp")) {
870  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
872  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
874  } else {
875  LOG(llevError, "load_settings: Unknown value for simple_exp: %s\n", cp);
876  }
877  } else if (!strcasecmp(buf, "item_power_factor")) {
878  float tmp = atof(cp);
879  if (tmp < 0)
880  LOG(llevError, "load_settings: item_power_factor must be a positive number (%f < 0)\n", tmp);
881  else
883  } else if (!strcasecmp(buf, "pk_luck_penalty")) {
884  int16_t val = atoi(cp);
885 
886  if (val < -100 || val > 100)
887  LOG(llevError, "load_settings: pk_luck_penalty must be between -100 and 100, %d is invalid\n", val);
888  else
890  } else if (!strcasecmp(buf, "set_friendly_fire")) {
891  int val = atoi(cp);
892 
893  if (val < 1 || val > 100)
894  LOG(llevError, "load_settings: set_friendly_fire must be between 1 an 100, %d is invalid\n", val);
895  else
897  } else if (!strcasecmp(buf, "armor_max_enchant")) {
898  int max_e = atoi(cp);
899  if (max_e <= 0)
900  LOG(llevError, "load_settings: armor_max_enchant is %d\n", max_e);
901  else
902  settings.armor_max_enchant = max_e;
903  } else if (!strcasecmp(buf, "armor_weight_reduction")) {
904  int wr = atoi(cp);
905  if (wr < 0)
906  LOG(llevError, "load_settings: armor_weight_reduction is %d\n", wr);
907  else
909  } else if (!strcasecmp(buf, "armor_weight_linear")) {
910  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
912  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
914  } else {
915  LOG(llevError, "load_settings: unknown value for armor_weight_linear: %s\n", cp);
916  }
917  } else if (!strcasecmp(buf, "armor_speed_improvement")) {
918  int wr = atoi(cp);
919  if (wr < 0)
920  LOG(llevError, "load_settings: armor_speed_improvement is %d\n", wr);
921  else
923  } else if (!strcasecmp(buf, "armor_speed_linear")) {
924  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
926  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
928  } else {
929  LOG(llevError, "load_settings: unknown value for armor_speed_linear: %s\n", cp);
930  }
931  } else if (!strcasecmp(buf, "no_player_stealing")) {
932  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
934  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
936  } else {
937  LOG(llevError, "load_settings: unknown value for no_player_stealing: %s\n", cp);
938  }
939  } else if (!strcasecmp(buf, "create_home_portals")) {
940  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
941 #ifdef TRY_BROKEN_TOWN_PORTALS
943 #else
944  LOG(llevError, "load_settings: create_home_portals is currently broken. It results in town portals that prematurely reset when the apartment is swapped.\n");
945 #endif
946  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
948  } else {
949  LOG(llevError, "load_settings: unknown value for create_home_portals: %s\n", cp);
950  }
951  } else if (!strcasecmp(buf, "personalized_blessings")) {
952  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
954  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
956  } else {
957  LOG(llevError, "load_settings: unknown value for personalized_blessings: %s\n", cp);
958  }
959  } else if (!strcasecmp(buf, "pk_max_experience")) {
960  int64_t pkme = atoll(cp);
961  if (pkme < 0)
962  pkme = -1;
964  } else if (!strcasecmp(buf, "pk_max_experience_percent")) {
965  int pkmep = atoi(cp);
966  if (pkmep < 0) {
967  LOG(llevError, "load_settings: pk_max_experience_percent should be positive or zero (was \"%s\")\n", cp);
968  } else
970  } else if (!strcasecmp(buf, "allow_denied_spells_writing")) {
971  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
973  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
975  } else {
976  LOG(llevError, "load_settings: unknown value for allow_denied_spells_writing: %s\n", cp);
977  }
978  } else if (!strcasecmp(buf, "allow_broken_converters")) {
979  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
981  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
983  } else {
984  LOG(llevError, "load_settings: unknown value for allow_broken_converters: %s\n", cp);
985  }
986  } else if (!strcasecmp(buf, "log_timestamp")) {
987  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
989  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
991  } else {
992  LOG(llevError, "load_settings: unknown value for log_timestamp: %s\n", cp);
993  }
994  } else if (!strcasecmp(buf, "log_timestamp_format")) {
997  } else if (!strcasecmp(buf, "starting_stat_min")) {
998  int val = atoi(cp);
999 
1000  if (val < 1 || val > settings.max_stat || val > settings.starting_stat_max)
1001  LOG(llevError, "load_settings: starting_stat_min (%d) need to be within %d-%d (%d)\n",
1003  else
1005  } else if (!strcasecmp(buf, "starting_stat_max")) {
1006  int val = atoi(cp);
1007 
1008  if (val < 1 || val > settings.max_stat || val<settings.starting_stat_min)
1009  LOG(llevError, "load_settings: starting_stat_max (%d) need to be within %d-%d (%d)\n",
1011  else
1013  } else if (!strcasecmp(buf, "starting_stat_points")) {
1014  int val = atoi(cp);
1015 
1016  if (val < NUM_STATS * settings.starting_stat_min ||
1018  LOG(llevError, "load_settings: starting_stat_points (%d) need to be within %d-%d\n",
1020  else
1022  } else if (!strcasecmp(buf, "roll_stat_points")) {
1023  int val = atoi(cp);
1024 
1025  /* The 3 and 18 values are hard coded in because we know that
1026  * roll_stat() generates a value between 3 and 18 - if that ever
1027  * changed, this code should change also, but that code will eventually
1028  * go away.
1029  */
1030  if (val < NUM_STATS * 3 || val > NUM_STATS * 18)
1031  LOG(llevError, "load_settings: roll_stat_points need to be within %d-%d\n",
1032  NUM_STATS * 3, NUM_STATS * 18);
1033  else
1034  settings.roll_stat_points = val;
1035  } else if (!strcasecmp(buf, "special_break_map")) {
1036  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1038  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1040  } else {
1041  LOG(llevError, "load_settings: unknown value for special_break_map: %s\n", cp);
1042  }
1043  } else if (!strcasecmp(buf, "ignore_plugin_compatibility")) {
1044  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1046  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1048  } else {
1049  LOG(llevError, "load_settings: unknown value for ignore_plugin_compatibility: %s\n", cp);
1050  }
1051  } else if (!strcasecmp(buf, "account_block_create")) {
1052  if (!strcasecmp(cp, "on") || !strcasecmp(cp, "true")) {
1054  } else if (!strcasecmp(cp, "off") || !strcasecmp(cp, "false")) {
1056  } else {
1057  LOG(llevError, "load_settings: unknown value for account_block_create: %s\n", cp);
1058  }
1059  } else if (!strcasecmp(buf, "account_trusted_host")) {
1062  } else if (!strcasecmp(buf, "crypt_mode")) {
1063  int val = atoi(cp);
1064  if (val != 0 && val != 1) {
1065  LOG(llevError, "load_settings: crypt_mode must be 0 or 1\n");
1066  } else {
1067  settings.crypt_mode = val;
1068  }
1069  } else if (!strcasecmp(buf, "min_name")) {
1070  int val = atoi(cp);
1071 
1072  if (val < 1 || val > MAX_NAME )
1073  LOG(llevError, "load_settings: min_name (%d) need to be within %d-%d\n",
1074  val, 1, MAX_NAME);
1075  else
1076  settings.min_name = val;
1077  } else if (!strcasecmp(buf, "stat_file")) {
1079  } else {
1080  LOG(llevError, "Unknown value in settings file: %s\n", buf);
1081  }
1082  }
1083  fclose(fp);
1084  if (settings.log_timestamp_format == NULL)
1085  settings.log_timestamp_format = strdup_local("%y/%m/%d %H:%M:%S");
1086 
1087  /*
1088  * The who formats are defined in config to be blank. They should have been
1089  * overridden by the settings file, if there are no entries however, it will
1090  * have stayed blank. Since this probably isn't what is wanted, we will check if
1091  * new formats have been specified, and if not we will use the old defaults.
1092  */
1093  if (!strcmp(settings.who_format, ""))
1094  strcpy(settings.who_format, "%N_%t%h%d%b%n<%M>");
1095  if (!strcmp(settings.who_wiz_format, ""))
1096  strcpy(settings.who_wiz_format, "%N_%t%h%d%b%nLevel %l <%M>(@%i)(%c)");
1097 }
1098 
1102 }
1103 
1108 static void mklocaldirs() {
1109  auto dirs = {"account", "maps", "players", "template-maps", "unique-items"};
1110  std::string localdir(settings.localdir);
1111  try {
1112  std::filesystem::create_directories(localdir);
1113  for (auto dir : dirs) {
1114  std::filesystem::create_directories(localdir + "/" + dir);
1115  }
1116  } catch (std::filesystem::filesystem_error e) {
1117  LOG(llevError, "Could not create server save directories in %s (%s). Some server state may fail to save.\n",
1118  settings.localdir, e.what());
1119  }
1120 }
1121 
1129 void init(int argc, char **argv) {
1130  logfile = stderr;
1131 #ifdef HAVE_SYSLOG_H
1132  // disable syslog, then only re-enable it if configured
1133  setlogmask(0);
1134 #endif
1135 
1136  /* First argument pass - right now it does nothing, but in the future specifying
1137  * the LibDir in this pass would be reasonable. */
1138  parse_args(argc, argv, 1);
1139 
1141 
1142  mklocaldirs();
1143  init_library(); /* Must be called early */
1144  load_settings(); /* Load the settings file */
1145  parse_args(argc, argv, 2);
1146 
1147  LOG(llevInfo, "Crossfire %s\n", FULL_VERSION);
1148  SRANDOM(time(NULL));
1149 
1150  init_startup(); /* Check shutdown/forbid files */
1151  init_signals(); /* Sets up signal interceptions */
1152  commands_init(); /* Sort command tables */
1153  read_map_log(); /* Load up the old temp map files */
1154  init_skills();
1155  init_ob_methods();
1156  cftimer_init();
1157  hiscore_init();
1158 
1159  parse_args(argc, argv, 3);
1160 
1161  init_beforeplay();
1162  init_modules();
1163  if (argc != 0) {
1164  // Invocations from the command-line (e.g. crossfire-server) have the
1165  // binary name in argv[0]. If that is not there, assume we are running
1166  // as a test and don't create sockets.
1167  init_server();
1168  } else {
1169  LOG(llevInfo, "Running server in test mode (no sockets).\n");
1170  }
1171  metaserver2_init();
1172  accounts_load();
1173  reset_sleep();
1174 }
1175 
1181 void free_server(void) {
1182  free_materials();
1183  free_races();
1184  free_quest();
1186 }
1187 
1191 static void help(void) {
1192  printf("Usage: crossfire-server [options]\n\n");
1193 
1194  printf("Options:\n");
1195  printf(" -conf Set the directory to find configuration files.\n");
1196  printf(" -d Turn on extra debugging messages.\n");
1197  printf(" -data Set the data (share/) directory (archetypes, treasures, etc).\n");
1198  printf(" -disable-module\n"
1199  " Disable specified module, by its name\n"
1200  " Can be specified multiple times. 'All' disables all modules.\n");
1201  printf(" -enable-module\n"
1202  " Enable specified module, by its name\n"
1203  " Can be specified multiple times. 'All' enables all modules.\n");
1204  printf(" -disable-plugin\n"
1205  " Disables specified plugin. Use the name without the extension.\n"
1206  " Can be specified multiple times. 'All' disables all plugins.\n");
1207  printf(" -dump-anims Dump animations.\n");
1208  printf(" -h Print this help message.\n");
1209  printf(" -ignore-assets-errors\n");
1210  printf(" Allow going on even if there are errors in assets.\n");
1211  printf(" Warning: this may lead to strange behaviour.\n");
1212  printf(" -list-modules\n"
1213  " List built-in modules and exit.\n");
1214  printf(" -local Set the local data (var/) directory.\n");
1215  printf(" -log <file> Write logging information to the given file.\n");
1216  printf(" -m List suggested experience for all monsters.\n");
1217  printf(" -m2 Dump monster abilities.\n");
1218  printf(" -m3 Dump artifact information.\n");
1219  printf(" -m4 Dump spell information.\n");
1220  printf(" -m5 Dump skill information.\n");
1221  printf(" -m6 Dump race information.\n");
1222  printf(" -m7 Dump alchemy information.\n");
1223  printf(" -m8 Dump gods information.\n");
1224  printf(" -m9 Dump more alchemy information (formula checking).\n");
1225  printf(" -maps Set the map directory.\n");
1226  printf(" -mexp Dump the experience table.\n");
1227  printf(" -mon Turn on monster debugging.\n");
1228  printf(" -mq Dump the quest list.\n");
1229  printf(" -mt <name> Dump a list of treasures for a monster.\n");
1230  printf(" -n Turn off debugging messages if on by default.\n");
1231  printf(" -p <port> Specifies the port to listen on for incoming connections.\n");
1232  printf(" -pack-assets <type> <filename>\n");
1233  printf(" Packs specified assets type to the specified filename.\n");
1234  printf(" Valid assets type are: archs, treasures, faces, messages, facesets, artifacts, formulae, images, quests.\n");
1235  printf(" The file format will be tar ('images') or text (everything else).\n");
1236  printf(" It is possible to combine multiple assets by using '+', for instance 'faces+messages+artifacts'.\n");
1237  printf(" In this case the file will be in tar format.\n");
1238  printf(" -playerdir Set the player files directory.\n");
1239  printf(" -regions Set the region file.\n");
1240  printf(" -syslog <no> Log to syslog with the given facility number (e.g. 16 for LOCAL0)\n");
1241  printf(" -templatedir Set the template map directory.\n");
1242  printf(" -tmpdir Set the directory for temporary files (mostly maps.)\n");
1243  printf(" -uniquedir Set the unique items/maps directory.\n");
1244  printf(" -v Print version information.\n");
1245  exit(EXIT_SUCCESS);
1246 }
1247 
1252 static void init_beforeplay(void) {
1253  init_archetype_pointers(); /* Setup global pointers to archetypes */
1254  finish_races(); /* overwrite race designations using entries in lib/races file */
1256  init_gods(); /* init linked list of gods from archs*/
1257  init_readable(); /* inits useful arrays for readable texts */
1258 
1259  switch (settings.dumpvalues) {
1260  case 1:
1261  print_monsters();
1262  cleanup();
1263  break;
1264 
1265  case 2:
1266  dump_abilities();
1267  cleanup();
1268  break;
1269 
1270  case 3:
1271  dump_artifacts();
1272  cleanup();
1273  break;
1274 
1275  case 4:
1276  dump_spells();
1277  cleanup();
1278  break;
1279 
1280  case 5:
1281  cleanup();
1282  break;
1283 
1284  case 6:
1285  dump_races();
1286  cleanup();
1287  break;
1288 
1289  case 7:
1290  dump_alchemy();
1291  cleanup();
1292  break;
1293 
1294  case 8:
1295  dump_gods();
1296  cleanup();
1297  break;
1298 
1299  case 9:
1301  cleanup();
1302  break;
1303 
1304  case 10:
1306  cleanup();
1307  break;
1308  }
1309 }
1310 
1316 static void init_startup(void) {
1317 #ifdef SHUTDOWN_FILE
1318  char buf[MAX_BUF];
1319  FILE *fp;
1320 
1321  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, SHUTDOWN_FILE);
1322  if ((fp = fopen(buf, "r")) != NULL) {
1323  while (fgets(buf, MAX_BUF-1, fp) != NULL)
1324  printf("%s", buf);
1325  fclose(fp);
1326  exit(1);
1327  }
1328 #endif
1329 
1330  if (forbid_play()) { /* Maybe showing highscore should be allowed? */
1331  LOG(llevError, "CrossFire: Playing not allowed.\n");
1332  exit(-1);
1333  }
1334 }
1335 
1339 static void signal_shutdown(int signum_unused) {
1340  (void) signum_unused; /* avoid unused warning if enambled */
1341  shutdown_flag += 1;
1342 }
1343 
1356 static void rec_sighup(int i) {
1357  (void)i;
1358  /* Don't call LOG(). It calls non-reentrant functions. The other
1359  * signal handlers shouldn't really call LOG() either. */
1360  if (logfile != stderr) {
1361  reopen_logfile = 1;
1362  }
1363 }
1364 
1368 void init_signals(void) {
1369 #ifndef WIN32 /* init_signals() remove signals */
1370  struct sigaction sa;
1371 
1372  sa.sa_sigaction = NULL;
1373  sigemptyset(&sa.sa_mask);
1374  sa.sa_flags = 0;
1375  sa.sa_handler = rec_sighup;
1376  sigaction(SIGHUP, &sa, NULL);
1377  signal(SIGINT, signal_shutdown);
1378  signal(SIGPIPE, SIG_IGN);
1379 #endif /* win32 */
1380 }
Settings::casting_time
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:275
Settings::special_break_map
uint8_t special_break_map
If set, then submaps in random maps can break the walls.
Definition: global.h:328
Settings::meta_comment
char meta_comment[MAX_BUF]
Comment we send to the metaserver.
Definition: global.h:294
Command_Line_Options
One command line option definition.
Definition: init.cpp:385
module_information::name
const char * name
Module name, without space.
Definition: init.cpp:54
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:291
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:268
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:403
Settings::recycle_tmp_maps
uint8_t recycle_tmp_maps
Re-use tmp maps.
Definition: global.h:277
init
void init(int argc, char **argv)
This is the main server initialization function.
Definition: init.cpp:1129
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:1252
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:319
Settings::log_timestamp_format
char * log_timestamp_format
Format for timestap, if log_timestamp is set.
Definition: global.h:322
Settings::armor_speed_linear
uint8_t armor_speed_linear
If 1, speed improvement is linear, else exponantiel.
Definition: global.h:312
module_information::close
void(* close)()
Cleanup function.
Definition: init.cpp:58
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:271
serverSettings
ServerSettings serverSettings
Definition: init.cpp:48
service_handle
void service_handle()
Settings::set_title
uint8_t set_title
Players can set thier title.
Definition: global.h:270
dump_alchemy_costs
void dump_alchemy_costs(void)
Dumps to output all costs of recipes.
Definition: recipe.cpp:591
ServerSettings::disabled_plugins
std::vector< std::string > disabled_plugins
List of disabled plugins, 'All' means all.
Definition: server.h:16
Settings::ignore_plugin_compatibility
uint8_t ignore_plugin_compatibility
If set, don't check plugin version.
Definition: global.h:329
FALSE
#define FALSE
Definition: compat.h:14
Settings::not_permadeth
uint8_t not_permadeth
If true, death is non-permament.
Definition: global.h:267
Settings::permanent_exp_ratio
uint8_t permanent_exp_ratio
How much exp should be 'permenant' and unable to be lost.
Definition: global.h:263
Settings::crypt_mode
uint8_t crypt_mode
0 for legacy behavior, 1 for always Traditional
Definition: global.h:332
set_datadir
static void set_datadir(const char *path)
Command line option: set data path.
Definition: init.cpp:198
module_information::description
const char * description
Module long description.
Definition: init.cpp:55
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:548
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:222
cleanup
void cleanup(void)
Clean up everything and exit.
Definition: server.cpp:1262
set_dumpmon7
static void set_dumpmon7(void)
Command line option: dump alchemy.
Definition: init.cpp:171
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:299
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:1356
Settings::min_name
uint8_t min_name
Minimum characters for an account or player name.
Definition: global.h:333
SRANDOM
#define SRANDOM(seed)
Definition: define.h:629
Settings::worldmapstartx
uint32_t worldmapstartx
Starting x tile for the worldmap.
Definition: global.h:296
list_modules
static void list_modules()
List all modules, then exit.
Definition: init.cpp:103
time
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long time
Definition: arch-handbook.txt:206
get_empty_mat
static materialtype_t * get_empty_mat(void)
Creates an empty materialtype_t structure.
Definition: init.cpp:528
set_dumpmont
static void set_dumpmont(const char *name)
Command line option: dump monster treasures.
Definition: init.cpp:189
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:166
Settings::starting_stat_min
uint8_t starting_stat_min
Minimum value of a starting stat.
Definition: global.h:323
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:326
Settings::pk_luck_penalty
int16_t pk_luck_penalty
Amount by which player luck is reduced if they PK.
Definition: global.h:262
FREE_AND_COPY_IF
#define FREE_AND_COPY_IF(sv, nv)
Definition: global.h:212
Settings::stat_file
char * stat_file
Definition: global.h:337
set_mondebug
static void set_mondebug(void)
Command line option: monster debug flag.
Definition: init.cpp:136
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:352
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:264
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:15
motd
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old full of dirt and partially destroyed[hand] My dear as you two years i had to leave quickly Words have come to me of powerful magic scrolls discovered in an old temple by my uncle I have moved to study them I not forgot your knowledge in ancient languages I need your help for[print][b] Some parts of document are to damaged to be readable[/b][arcane] Arghis[color=Red] k h[color=dark slate blue] ark[color=#004000] fido[/color][hand] please come as fast as possible my friend[print][b] The bottom of letter seems deliberatly shredded What is but not limited book signs motd
Definition: media-tags.txt:31
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:334
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:67
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:146
Command_Line_Options::num_args
uint8_t num_args
Number or args it takes.
Definition: init.cpp:387
Settings::meta_host
char meta_host[MAX_BUF]
Hostname of this host.
Definition: global.h:292
set_dumpmon4
static void set_dumpmon4(void)
Command line option: dump spells.
Definition: init.cpp:156
forbid_play
int forbid_play(void)
Checks if server should be started.
Definition: server.cpp:1369
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:298
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:316
Command_Line_Options::cmd_option
const char * cmd_option
How it is called on the command line.
Definition: init.cpp:386
server_dump_faces
static void server_dump_faces(void)
Dump all faces, then exit.
Definition: init.cpp:360
init_signals
void init_signals(void)
Setup our signal handlers.
Definition: init.cpp:1368
cfweather_init
void cfweather_init(Settings *settings, ServerSettings *servserSettings)
Weather module initialisation.
Definition: cfweather.cpp:4824
parse_args
static void parse_args(int argc, char *argv[], int pass)
Parse command line arguments.
Definition: init.cpp:476
Settings::spell_encumbrance
uint8_t spell_encumbrance
Encumbrance effects spells.
Definition: global.h:273
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:293
modules
static module_information modules[]
All built modules.
Definition: init.cpp:62
Settings::balanced_stat_loss
uint8_t balanced_stat_loss
If true, Death stat depletion based on level etc.
Definition: global.h:266
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:317
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:264
set_dumpmon3
static void set_dumpmon3(void)
Command line option: dump artifacts.
Definition: init.cpp:151
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:280
Settings::account_block_create
uint8_t account_block_create
Definition: global.h:330
Settings::motd
const char * motd
Name of the motd file.
Definition: global.h:283
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:297
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:893
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:345
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:141
metaserver2_init
int metaserver2_init(void)
This initializes the metaserver2 logic - it reads the metaserver2 file, storing the values away.
Definition: metaserver.cpp:331
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:309
Settings::stat_loss_on_death
uint8_t stat_loss_on_death
If true, chars lose a random stat when they die.
Definition: global.h:261
signal_shutdown
static void signal_shutdown(int signum_unused)
Signal handler that begins a normal server shutdown.
Definition: init.cpp:1339
Settings::item_power_factor
float item_power_factor
See note in setings file.
Definition: global.h:306
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:115
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:272
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:248
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:265
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:181
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:206
cmdlinefunc_args2
void(* cmdlinefunc_args2)(const char *arg1, const char *arg2)
Definition: init.cpp:377
set_dumpmon8
static void set_dumpmon8(void)
Command line option: dump gods.
Definition: init.cpp:176
Settings::playerdir
const char * playerdir
Where the player files are.
Definition: global.h:255
cfweather_close
void cfweather_close()
Definition: cfweather.cpp:4930
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:274
Settings::starting_stat_points
uint8_t starting_stat_points
How many stat points character starts with.
Definition: global.h:325
Settings
Server settings.
Definition: global.h:245
module_information::init
void(* init)(Settings *, ServerSettings *)
Initialisation function.
Definition: init.cpp:57
Settings::meta_on
unsigned int meta_on
True if we should send updates.
Definition: global.h:290
Settings::allow_denied_spells_writing
int allow_denied_spells_writing
If set, players can write spells they can't cast.
Definition: global.h:318
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:230
should_exit
static int should_exit
If set after command line argument parsing, then the server will exit.
Definition: init.cpp:51
init_library
void init_library(void)
It is vital that init_library() is called by any functions using this library.
Definition: init.cpp:313
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:282
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:279
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:884
Settings::fastclock
uint8_t fastclock
If true, clock goes warp 9.
Definition: global.h:300
cmdlinefunc_args1
void(* cmdlinefunc_args1)(const char *arg1)
Definition: init.cpp:376
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:1108
free_materials
static void free_materials(void)
Frees all memory allocated to materials.
Definition: init.cpp:612
Settings::personalized_blessings
uint8_t personalized_blessings
If 1, blessed weapons get an owner and a willpower value.
Definition: global.h:315
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:131
dump_alchemy
void dump_alchemy(void)
Dumps alchemy recipes to output.
Definition: recipe.cpp:352
help
static void help(void)
Display the command line options and exits.
Definition: init.cpp:1191
Settings::max_stat
uint8_t max_stat
Maximum stat value - 255 should be sufficient.
Definition: global.h:327
cmdlinefunc_args0
void(* cmdlinefunc_args0)(void)
Typedefs used when calling option handlers.
Definition: init.cpp:375
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:126
load_settings
void load_settings(void)
This loads the settings file.
Definition: init.cpp:624
close_modules
void close_modules()
Clean up all modules which are not disabled.
Definition: init.cpp:89
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:308
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:279
dump_monster_treasure
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1284
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:1099
Settings::armor_weight_linear
uint8_t armor_weight_linear
If 1, weight reduction is linear, else exponantiel.
Definition: global.h:310
set_dumpmon5
static void set_dumpmon5(void)
Command line option: ?
Definition: init.cpp:161
strcasecmp
int strcasecmp(const char *s1, const char *s2)
init_modules
void init_modules()
Init all modules which are not disabled.
Definition: init.cpp:73
call_version
static void call_version(void)
Command line option: show version.
Definition: init.cpp:120
set_csport
static void set_csport(const char *val)
Change the server's port.
Definition: init.cpp:296
loader.h
Settings::real_wiz
uint8_t real_wiz
Use mud-like wizards.
Definition: global.h:276
init_startup
static void init_startup(void)
Checks if starting the server is allowed.
Definition: init.cpp:1316
Settings::templatedir
const char * templatedir
Directory for the template map.
Definition: global.h:259
set_disable_plugin
static void set_disable_plugin(const char *name)
Disable a plugin.
Definition: init.cpp:309
set_localdir
static void set_localdir(const char *path)
Command line option: set local path.
Definition: init.cpp:214
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:337
free_server
void free_server(void)
Frees all memory allocated around here:
Definition: init.cpp:1181
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:313
Settings::account_trusted_host
char * account_trusted_host
Block account creation for untrusted hosts.
Definition: global.h:331
Settings::search_items
uint8_t search_items
Search_items command.
Definition: global.h:272
module_information
Definition: init.cpp:53
server.h
Settings::tmpdir
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:260
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:278
TRUE
#define TRUE
Definition: compat.h:11
set_templatedir
static void set_templatedir(const char *path)
Command line option: set template path.
Definition: init.cpp:256
Settings::create_home_portals
uint8_t create_home_portals
If 1, can create portals in unique maps (apartments)
Definition: global.h:314
server_dump_bonuses
static void server_dump_bonuses()
Dump all bonuses (from the stat_bonus file) then exit.
Definition: init.cpp:368
Command_Line_Options::pass
uint8_t pass
What pass this should be processed on.
Definition: init.cpp:388
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
set_syslog
static void set_syslog(const char *arg)
Definition: init.cpp:234
BufferReader
Definition: bufferreader.cpp:21
Settings::armor_speed_improvement
int armor_speed_improvement
Speed improvement.
Definition: global.h:311
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:321
Settings::who_format
char who_format[MAX_BUF]
The format that the who command should use.
Definition: global.h:281
server_pack_assets
static void server_pack_assets(const char *assets, const char *filename)
Definition: init.cpp:283
Command_Line_Options::func
void(* func)()
function to call when we match this.
Definition: init.cpp:389
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:56
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:319
Settings::starting_stat_max
uint8_t starting_stat_max
Maximum value of a starting stat.
Definition: global.h:324
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:102
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:254