Crossfire Server, Trunk  1.75.0
server.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 <assert.h>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 
29 #ifndef WIN32
30 #include <unistd.h>
31 #endif
32 
33 /* FIXME: This is required on certain systems to get crypt(3) to work. */
34 #ifdef HAVE_CRYPT_H
35 #include <crypt.h>
36 #endif
37 
38 #include "object.h"
39 #include "path.h"
40 #include "random_maps/random_map.h"
41 #include "random_maps/rproto.h"
42 #include "sproto.h"
43 #include "tod.h"
44 #include "version.h"
45 #include "server.h"
46 
48 static const int shutdown_warn_times[] = {120, 90, 60, 45, 30, 15, 10, 5, 4, 3, 2, 1};
49 
51 static const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
52 
53 volatile sig_atomic_t shutdown_flag;
54 
70 static char const* crypt_string(char const *str, char const* salt) {
71 #if defined(WIN32)
72  // Windows will never attempt to crypt()
73  return str;
74 #else
75 #if (defined(__FreeBSD__))
76  // If legacy mode is enabled, do not crypt() on FreeBSD
77  if (settings.crypt_mode == 0) {
78  return str;
79  }
80 #endif
81  char s[3];
82 
83  if (salt == NULL) {
84  /* Generate a two-character salt for the DES cipher.
85  * We want the salt to be in this character set.
86  */
87  static const char *const c =
88  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
89  s[0] = c[RANDOM()%(int)strlen(c)],
90  s[1] = c[RANDOM()%(int)strlen(c)];
91  } else {
92  s[0] = salt[0],
93  s[1] = salt[1];
94  }
95  s[2] = '\0';
96 
97  return crypt(str, s);
98 #endif
99 }
100 
101 char const* newhash(char const *password) {
102  return crypt_string(password, NULL);
103 }
104 
114 bool check_password(const char *typed, const char *crypted) {
115  if (getenv("CF_DEBUG_BYPASS_LOGIN")) {
116  return true;
117  }
118 
119  // An empty hashed password only matches an empty input password.
120  if (strlen(crypted) == 0) {
121  return strlen(typed) == 0 ? true : false;
122  }
123 
124  const char *typed_hashed = crypt_string(typed, crypted);
125  if (typed_hashed != NULL) {
126  return strcmp(typed_hashed, crypted) == 0;
127  } else {
128  LOG(llevError, "Could not check password with stored hash %s\n", crypted);
129  return false;
130  }
131 }
132 
142 void enter_player_savebed(object *op) {
143  mapstruct *oldmap = op->map;
144  object *tmp;
145 
146  tmp = object_new();
147 
148  EXIT_PATH(tmp) = add_string(op->contr->savebed_map);
149  EXIT_X(tmp) = op->contr->bed_x;
150  EXIT_Y(tmp) = op->contr->bed_y;
151  enter_exit(op, tmp);
152  /* If the player has not changed maps and the name does not match
153  * that of the savebed, his savebed map is gone. Lets go back
154  * to the emergency path. Update what the players savebed is
155  * while we're at it.
156  */
157  if (oldmap == op->map && strcmp(op->contr->savebed_map, oldmap->path)) {
158  LOG(llevDebug, "Player %s savebed location %s is invalid - going to emergency location (%s)\n",
164  EXIT_PATH(tmp) = add_string(op->contr->savebed_map);
165  EXIT_X(tmp) = op->contr->bed_x;
166  EXIT_Y(tmp) = op->contr->bed_y;
167  enter_exit(op, tmp);
168  }
170 }
171 
183 static void enter_map(object *op, mapstruct *newmap, int x, int y) {
184  mapstruct *oldmap = op->map;
185 
186  /* Default hp/sp for exits changed to -1 to use enter_x/enter_y values by default, but if one value
187  * is specified, we want the other to default to zero like before the change.
188  */
189  if (x < 0 && y >= 0) x=0;
190  if (y < 0 && x >= 0) y=0;
191 
192  if (out_of_map(newmap, x, y)) {
193  if (x != -1 || y != -1) {
194  LOG(llevError, "enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->path, x, y);
195  }
196  /* If op has invalid (probably -1,-1) coordinates, force them to a correct value, else issues later on. */
197  if (op->x == x)
198  op->x = MAP_ENTER_X(newmap);
199  if (op->y == y)
200  op->y = MAP_ENTER_Y(newmap);
201  x = MAP_ENTER_X(newmap);
202  y = MAP_ENTER_Y(newmap);
203  if (out_of_map(newmap, x, y)) {
204  LOG(llevError, "enter_map: map %s provides invalid default enter location (%d, %d) > (%d, %d)\n", newmap->path, x, y, MAP_WIDTH(newmap), MAP_HEIGHT(newmap));
206  "The exit is closed");
207  return;
208  }
209  }
210  /* try to find a spot for the player */
211  if (ob_blocked(op, newmap, x, y)) { /* First choice blocked */
212  /* We try to find a spot for the player, starting closest in.
213  * We could use object_find_first_free_spot(), but that doesn't randomize it at all,
214  * So for example, if the north space is free, you would always end up there even
215  * if other spaces around are available.
216  * Note that for the second and third calls, we could start at a position other
217  * than one, but then we could end up on the other side of walls and so forth.
218  */
219  int i = object_find_free_spot(op, newmap, x, y, 1, SIZEOFFREE1+1);
220  if (i == -1) {
221  i = object_find_free_spot(op, newmap, x, y, 1, SIZEOFFREE2+1);
222  if (i == -1)
223  i = object_find_free_spot(op, newmap, x, y, 1, SIZEOFFREE);
224  }
225  if (i != -1) {
226  x += freearr_x[i];
227  y += freearr_y[i];
228  } else {
229  /* not much we can do in this case. */
230  LOG(llevInfo, "enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->path, x, y);
231  }
232  } /* end if looking for free spot */
233 
234  /* If it is a player login, he has yet to be inserted anyplace.
235  * otherwise, we need to deal with removing the playe here.
236  */
237  if (!QUERY_FLAG(op, FLAG_REMOVED))
238  object_remove(op);
239  /* object_remove clears these so they must be reset after the object_remove() call */
240  object_insert_in_map_at(op, newmap, NULL, INS_NO_WALK_ON, x, y);
241 
242  object_set_enemy(op, NULL);
243 
244  if (op->contr) {
245  safe_strncpy(op->contr->maplevel, newmap->path,
246  sizeof(op->contr->maplevel));
247  op->contr->count = 0;
248  }
249 
250  /* Update any golems */
251  if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL) {
252  int i = object_find_free_spot(op->contr->ranges[range_golem], newmap, x, y, 1, SIZEOFFREE);
254  if (i == -1) {
257  op->contr->ranges[range_golem] = NULL;
258  op->contr->golem_count = 0;
259  } else {
260  object_insert_in_map_at(op->contr->ranges[range_golem], newmap, NULL, 0, x+freearr_x[i], y+freearr_y[i]);
262  }
263  }
264  op->direction = 0;
265 
266  /* since the players map is already loaded, we don't need to worry
267  * about pending objects.
268  */
269  pets_attempt_follow(op, 1);
270 
271  /* If the player is changing maps, we need to do some special things
272  * Do this after the player is on the new map - otherwise the force swap of the
273  * old map does not work.
274  */
275  if (oldmap != newmap) {
276  player_map_change_common(op, oldmap, newmap);
277  }
278 
280 }
281 
282 void player_map_change_common(object* op, mapstruct* const oldmap,
283  mapstruct* const newmap) {
284  if (oldmap != NULL) {
286 
287  /* can be less than zero due to errors in tracking this */
288  if (oldmap->players <= 0) {
289  set_map_timeout(oldmap);
290  }
291  }
292 
294  newmap->timeout = 0;
296 }
297 
305 void set_map_timeout(mapstruct *oldmap) {
306  oldmap->timeout = MAP_MINTIMEOUT;
307 }
308 
322 static char *clean_path(const char *file, char *newpath, int size) {
323  char *cp;
324 
325  strlcpy(newpath, file, size);
326  for (cp = newpath; *cp != '\0'; cp++) {
327  if (*cp == '/')
328  *cp = '_';
329  }
330  return newpath;
331 }
332 
350 static char *unclean_path(const char *src, char *newpath, int size) {
351  char *cp;
352 
353  cp = const_cast<char *>(strrchr(src, '/'));
354  if (cp)
355  strlcpy(newpath, cp+1, size);
356  else
357  strlcpy(newpath, src, size);
358 
359  for (cp = newpath; *cp != '\0'; cp++) {
360  if (*cp == '_')
361  *cp = '/';
362  }
363  return newpath;
364 }
365 
375 static void enter_random_map(object *pl, object *exit_ob) {
376  mapstruct *new_map;
377  char newmap_name[HUGE_BUF], buf[HUGE_BUF], *cp;
378  static int reference_number = 0;
379  RMParms rp;
380 
381  memset(&rp, 0, sizeof(RMParms));
382  rp.Xsize = -1;
383  rp.Ysize = -1;
384  rp.region = get_region_by_map(exit_ob->map);
385  if (exit_ob->msg)
386  set_random_map_variable(&rp, exit_ob->msg);
387  rp.origin_x = exit_ob->x;
388  rp.origin_y = exit_ob->y;
389  safe_strncpy(rp.origin_map, pl->map->path, sizeof(rp.origin_map));
390 
391  /* If we have a final_map, use it as a base name to give some clue
392  * as where the player is. Otherwise, use the origin map.
393  * Take the last component (after the last slash) to give
394  * shorter names without bogus slashes.
395  */
396  if (rp.final_map[0]) {
397  cp = strrchr(rp.final_map, '/');
398  if (!cp)
399  cp = rp.final_map;
400  } else {
401  cp = strrchr(rp.origin_map, '/');
402  if (!cp)
403  cp = rp.origin_map;
404  /* Need to strip of any trailing digits, if it has them */
405  strlcpy(buf, cp, sizeof(buf));
406  while (isdigit(buf[strlen(buf)-1]))
407  buf[strlen(buf)-1] = 0;
408  cp = buf;
409  }
410 
411  snprintf(newmap_name, sizeof(newmap_name), "/random/%s%04d", cp+1, reference_number++);
412 
413  /* now to generate the actual map. */
414  new_map = generate_random_map(newmap_name, &rp, NULL, exit_ob->map ? exit_ob->map->reset_group : NULL);
415 
416  /* Update the exit_ob so it now points directly at the newly created
417  * random maps. Not that it is likely to happen, but it does mean that a
418  * exit in a unique map leading to a random map will not work properly.
419  * It also means that if the created random map gets reset before
420  * the exit leading to it, that the exit will no longer work.
421  */
422  if (new_map) {
423  int x, y;
424 
425  x = EXIT_X(exit_ob) = MAP_ENTER_X(new_map);
426  y = EXIT_Y(exit_ob) = MAP_ENTER_Y(new_map);
427  EXIT_PATH(exit_ob) = add_string(newmap_name);
428  strlcpy(new_map->path, newmap_name, sizeof(new_map->path));
429  enter_map(pl, new_map, x, y);
430 
431  /* Make the initial map part of the same reset group so it doesn't
432  * reset before the random maps */
433  if (exit_ob->map && exit_ob->map->reset_group == NULL && new_map->reset_group && rp.link_source_map) {
434  exit_ob->map->reset_group = add_string(new_map->reset_group);
435  }
436  }
437 }
438 
447 static void enter_unique_map(object *op, object *exit_ob) {
448  char apartment[2 * HUGE_BUF], path[MAX_BUF];
449  mapstruct *newmap;
450  const char* player = op->name;
451  if (op->contr->followed_player) {
453  }
454 
455  if (EXIT_PATH(exit_ob)[0] == '/') {
456  snprintf(apartment, sizeof(apartment), "~%s/%s", player, clean_path(EXIT_PATH(exit_ob), path, sizeof(path)));
457  newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE);
458  if (!newmap) {
459  newmap = mapfile_load(EXIT_PATH(exit_ob), 0);
460  }
461  } else { /* relative directory */
462  char reldir[HUGE_BUF], tmpc[HUGE_BUF], *cp;
463 
464  if (exit_ob->map->unique) {
465  // Use player's current map path to construct base of relative path in 'src'
466  char* src = strdup(op->map->path);
467  char* slash = strrchr(src, '/');
468  if (slash == NULL) {
469  abort();
470  }
471  *slash = '\0';
472 
473  unclean_path(exit_ob->map->path, reldir, sizeof(reldir));
474 
475  /* Need to copy this over, as clean_path only has one static return buffer */
476  clean_path(reldir, tmpc, sizeof(tmpc));
477  /* Remove final component, if any */
478  if ((cp = strrchr(tmpc, '_')) != NULL)
479  *cp = 0;
480 
481  snprintf(apartment, sizeof(apartment), "%s/%s_%s", src, tmpc, clean_path(EXIT_PATH(exit_ob), path, sizeof(path)));
482 
483  newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE);
484  if (!newmap) {
485  newmap = mapfile_load(path_combine_and_normalize(reldir, EXIT_PATH(exit_ob), tmpc, sizeof(tmpc)), 0);
486  }
487  } else {
488  /* The exit is unique, but the map we are coming from is not unique. So
489  * use the basic logic - don't need to demangle the path name
490  */
491  path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob), reldir, sizeof(reldir));
492  snprintf(apartment, sizeof(apartment), "~%s/%s", player, clean_path(reldir, path, sizeof(path)));
493  newmap = ready_map_name(apartment, MAP_PLAYER_UNIQUE);
494  if (!newmap) {
495  path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob), reldir, sizeof(reldir));
496  newmap = ready_map_name(reldir, 0);
497  if (newmap)
498  apply_auto_fix(newmap);
499  }
500  }
501  }
502 
503  if (newmap) {
504  strlcpy(newmap->path, apartment, sizeof(newmap->path));
505  newmap->unique = 1;
506  enter_map(op, newmap, EXIT_X(exit_ob), EXIT_Y(exit_ob));
507  } else {
510  "The %s is closed.",
511  exit_ob->name);
512  /* Perhaps not critical, but I would think that the unique maps
513  * should be new enough this does not happen. This also creates
514  * a strange situation where some players could perhaps have visited
515  * such a map before it was removed, so they have the private
516  * map, but other players can't get it anymore.
517  */
518  LOG(llevDebug, "enter_unique_map: Exit %s (%d,%d) on map %s is leads no where.\n", exit_ob->name, exit_ob->x, exit_ob->y, exit_ob->map->path);
519  }
520 }
521 
522 void enter_player_maplevel(object *op) {
523  assert(op != NULL);
524  int flags = 0, x = op->x, y = op->y;
525  mapstruct *newmap;
526 
527  assert(op->type == PLAYER);
528 
529  /* newmap returns the map (if already loaded), or loads it for us. */
530  newmap = ready_map_name(op->contr->maplevel, flags);
531  if (!newmap) {
533  x = settings.emergency_x;
534  y = settings.emergency_y;
535  if (!newmap) {
536  LOG(llevError, "Fatal: Could not load emergency map!\n");
537  abort();
538  }
539 
541  "You find yourself somewhere unexpected...");
542  }
543 
544  /* as a special case, if coordinates are (-1, -1), then the item should
545  * be put at the default location. Used for loginmethod 0 (old clients). */
546  if (x == -1 && y == -1) {
547  x = MAP_ENTER_X(newmap);
548  y = MAP_ENTER_Y(newmap);
549  }
550 
551  enter_map(op, newmap, x, y);
552 }
553 
567 void enter_exit(object *op, object *exit_ob) {
568 #define PORTAL_DESTINATION_NAME "Town portal destination" /* this one should really be in a header file */
569  /* It may be nice to support other creatures moving across
570  * exits, but right now a lot of the code looks at op->contr,
571  * so thta is an RFE.
572  */
573  if (op->type != PLAYER)
574  return;
575 
576  assert(exit_ob != NULL);
577  assert(EXIT_PATH(exit_ob) != NULL);
578 
579  /* Don't word-of-recall out of a shop */
580  if ( exit_ob->subtype == SP_WORD_OF_RECALL ) {
581  /* Scan inventory for unpaid objects */
582  object *item = op->inv;
584  if (QUERY_FLAG(item, FLAG_UNPAID)) {
585  char buf[MAX_BUF];
586 
587  ob_describe(item, op, 1, buf, sizeof(buf));
589  "You feel a force fizzling away. You feel a vibration from: %s",buf);
590  return;
591  }
593  }
594 
595  /* Need to remove player from transport */
596  if (op->contr->transport)
597  ob_apply(op->contr->transport, op, AP_UNAPPLY);
598  /* check to see if we make a randomly generated map */
599  else if (EXIT_PATH(exit_ob) && EXIT_PATH(exit_ob)[1] == '!') {
600  enter_random_map(op, exit_ob);
601  } else if (QUERY_FLAG(exit_ob, FLAG_UNIQUE)) {
602  enter_unique_map(op, exit_ob);
603  } else {
604  int x = EXIT_X(exit_ob), y = EXIT_Y(exit_ob);
605  /* 'Normal' exits that do not do anything special
606  * Simple enough we don't need another routine for it.
607  */
608  mapstruct *newmap;
609  if (exit_ob->map) {
610  char tmp_path[HUGE_BUF];
611 
612  path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob), tmp_path, sizeof(tmp_path));
613  newmap = ready_map_name(tmp_path, 0);
614  /* Random map was previously generated, but is no longer about. Lets generate a new
615  * map.
616  */
617  if (!newmap && !strncmp(EXIT_PATH(exit_ob), "/random/", 8)) {
618  /* Maps that go down have a message set. However, maps that go
619  * up, don't. If the going home has reset, there isn't much
620  * point generating a random map, because it won't match the maps.
621  */
622  if (exit_ob->msg) {
623  enter_random_map(op, exit_ob);
624  } else {
627  "The %s is closed.",
628  exit_ob->name);
629  return;
630  }
631 
632  /* For exits that cause damages (like pits). Don't know if any
633  * random maps use this or not.
634  */
635  if (exit_ob->stats.dam && op->type == PLAYER)
636  hit_player(op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
637  return;
638  }
639  } else {
640  /* For word of recall and other force objects
641  * They contain the full pathname of the map to go back to,
642  * so we don't need to normalize it.
643  * But we do need to see if it is unique or not
644  */
645  if (map_path_unique(EXIT_PATH(exit_ob)))
646  newmap = ready_map_name(EXIT_PATH(exit_ob), MAP_PLAYER_UNIQUE);
647  else
648  newmap = ready_map_name(EXIT_PATH(exit_ob), 0);
649  }
650  if (!newmap) {
651  if (exit_ob->name)
654  "The %s is closed.",
655  exit_ob->name);
656  /* don't cry to momma if name is not set - as in tmp objects
657  * used by the savebed code and character creation */
658  return;
659  }
660 
661  if (x == -1 && y == -1) {
662  x = MAP_ENTER_X(newmap);
663  y = MAP_ENTER_Y(newmap);
664  }
665 
666  /* mids 02/13/2002 if exit is damned, update players death & WoR home-position and delete town portal */
667  if (QUERY_FLAG(exit_ob, FLAG_DAMNED)) {
668  object *tmp;
669 
670  /* remove an old force with a slaying field == PORTAL_DESTINATION_NAME */
672  if (tmp) {
673  object_remove(tmp);
675  }
676 
677  path_combine_and_normalize(exit_ob->map->path, EXIT_PATH(exit_ob), op->contr->savebed_map, sizeof(op->contr->savebed_map));
678  op->contr->bed_x = EXIT_X(exit_ob), op->contr->bed_y = EXIT_Y(exit_ob);
679  save_player(op, 1);
680  }
681 
682  enter_map(op, newmap, x, y);
683  }
684 
685  LOG(llevDebug, "%s enters %s\n", op->name, EXIT_PATH(exit_ob));
686 
687  /* For exits that cause damages (like pits) */
688  if (exit_ob->stats.dam && op->type == PLAYER)
689  hit_player(op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
690 
691  if (op->contr) {
692  object* exit_copy = object_new();
693  object_copy(exit_ob, exit_copy);
694  exit_copy->speed = 0; // Item isn't on map or in inv, but object_copy() may have added it to active list
695  object_update_speed(exit_copy);
696  exit_copy->map = exit_ob->map; // hack to set map without actually inserting
697  if (op->contr->last_exit) {
699  }
700  op->contr->last_exit = exit_copy;
701  }
702 }
703 
709 static int move_towards(object *ob, object *towards, unsigned int mindist) {
710  rv_vector rv;
711  get_rangevector(ob, towards, &rv, 0);
712  if (rv.direction != 0 && rv.distance > mindist && ob->speed_left > 0) {
713  move_player(ob, rv.direction);
714  }
715  return rv.direction;
716 }
717 
722 static bool object_on_exit(object* ob, object* exit) {
723  int x = exit->x;
724  int y = exit->y;
725  int sx, sy, sx2, sy2;
726  object_get_multi_size(exit, &sx, &sy, &sx2, &sy2);
727  return (ob->x >= x+sx2) && (ob->x <= x+sx) && (ob->y >= y+sy2) && (ob->y <= y+sy);
728 }
729 
733 static void do_follow(player *pl) {
734  assert(pl->followed_player != NULL);
736  if (followed && followed->ob && followed->ob->map) {
737  if (query_flag(pl->ob, FLAG_WIZ)) {
738  rv_vector rv;
739  if (!get_rangevector(pl->ob, followed->ob, &rv, 0) || rv.distance > 4) {
740  int space = object_find_free_spot(pl->ob, followed->ob->map, followed->ob->x, followed->ob->y, 1, 25);
741  if (space == -1) {
743  space = 0;
744  }
745  object_remove(pl->ob);
746  object_insert_in_map_at(pl->ob, followed->ob->map, NULL, 0, followed->ob->x+freearr_x[space], followed->ob->y+freearr_y[space]);
747  map_newmap_cmd(pl->socket);
749  }
750  } else {
751  if (!can_follow(pl->ob, followed)) {
753  "%s stops letting you follow them.", pl->followed_player);
755  return;
756  }
757  if (move_towards(pl->ob, followed->ob, 1)== 0 && followed->ob->contr->last_exit != NULL) {
758  // Move to and apply exit
759  object* exit = followed->ob->contr->last_exit;
760  if (!object_on_exit(pl->ob, exit)) {
761  move_towards(pl->ob, exit, 0);
762  } else {
763  enter_exit(pl->ob, exit);
764  }
765  }
766  }
767  } else {
769  "You stop following %s.", pl->followed_player);
771  }
772 }
773 
779 static void process_players1(void) {
780  int flag;
781  player *pl, *plnext;
782 
783  // Loop until no more players can do more actions. We have to do this because really fast
784  // players may be able to move twice in a tick.
785  for (flag = 1; flag != 0; ) {
786  flag = 0;
787  for (pl = first_player; pl != NULL; pl = plnext) {
788  plnext = pl->next; /* In case a player exits the game in handle_player() */
789 
790  if (pl->ob == NULL)
791  continue;
792 
793  /* Only do this on the first pass - what we are recording
794  * here is the number of ticks the player has been online - not
795  * how many actions/moves the player has done.
796  */
797  if (!flag) pl->ticks_played++;
798 
799  if (pl->followed_player) {
800  do_follow(pl);
801  }
802 
803  if (pl->ob->speed_left > 0) {
804  if (handle_newcs_player(pl->ob))
805  flag = 1;
806  } /* end if player has speed left */
807 
808  /* If the player is not actively playing, don't make a
809  * backup save - nothing to save anyway. Plus, the
810  * map may not longer be valid. This can happen when the
811  * player quits - they exist for purposes of tracking on the map,
812  * but don't actually reside on any actual map.
813  */
814  if (QUERY_FLAG(pl->ob, FLAG_REMOVED))
815  continue;
816 
817 #ifdef AUTOSAVE
818  /* check for ST_PLAYING state so that we don't try to save off when
819  * the player is logging in.
820  */
821  if ((pl->last_save_tick+AUTOSAVE) < pticks && pl->state == ST_PLAYING) {
822  /* Don't save the player on unholy ground. Instead, increase the
823  * tick time so it will be about 10 seconds before we try and save
824  * again.
825  */
826  if (get_map_flags(pl->ob->map, NULL, pl->ob->x, pl->ob->y, NULL, NULL)&P_NO_CLERIC) {
827  pl->last_save_tick += 100;
828  } else {
829  save_player(pl->ob, 1);
830  pl->last_save_tick = pticks;
831  hiscore_check(pl->ob, 1);
832  }
833  }
834 #endif
835  } /* end of for loop for all the players */
836  } /* for flag */
837 
838  // Player processing that happen once per tick, regardless of player speed, e.g. health
839  // regeneration.
840  for (pl = first_player; pl != NULL; pl = pl->next) {
841  int has_action = 1;
842 
843  pl->ob->weapon_speed_left += pl->ob->weapon_speed;
844  if (pl->ob->weapon_speed_left > 1.0)
845  pl->ob->weapon_speed_left = 1.0;
846 
847  pl->socket->sounds_this_tick = 0;
848 
849  if (settings.casting_time == TRUE) {
850  if (pl->ob->casting_time > 0) {
851  pl->ob->casting_time--;
852  has_action = 0;
853  }
854  }
855 
856  /* If the character is idle (standing around resting) increase
857  * regen rates.
858  */
859  if (has_action && pl->ob->speed_left > 0) {
860  pl->ob->last_heal -= 2;
861  pl->ob->last_sp -= 2;
862  pl->ob->last_grace -= 2;
863  pl->ob->last_eat += 2; /* Slow down food consumption */
864  }
865  do_some_living(pl->ob);
866  }
867 }
868 
876 static void process_players2(void) {
877  player *pl;
878 
879  /* Then check if any players should use weapon-speed instead of speed */
880  for (pl = first_player; pl != NULL; pl = pl->next) {
881  /* The code that did weapon_sp handling here was out of place -
882  * this isn't called until after the player has finished there
883  * actions, and is thus out of place. All we do here is bounds
884  * checking.
885  */
886  if (pl->has_hit) {
887  /* This needs to be here - if the player is running, we need to
888  * clear this each tick, but new commands are not being received
889  * so execute_newserver_command() is never called
890  */
891  pl->has_hit = 0;
892  } else if (pl->ob->speed_left > pl->ob->speed)
893  pl->ob->speed_left = pl->ob->speed;
894 
895  // Send delayed buffers. This has to be here (after speed processing)
896  // because delayed messages can still be generated as result of a FIRE
897  // command.
899  }
900 }
901 
902 #define SPEED_DEBUG
903 
904 static bool object_in_icecube(object *op) {
905  return op->env != NULL && strcmp(op->env->arch->name, "icecube") == 0;
906 }
907 
911 void process_events(void) {
912  object *op;
913  object marker;
914  tag_t tag;
915 
917 
918  memset(&marker, 0, sizeof(object));
919  /* Put marker object at beginning of active list */
920  marker.active_next = active_objects;
921 
922  if (marker.active_next)
923  marker.active_next->active_prev = &marker;
924  marker.active_prev = NULL;
925  active_objects = &marker;
926 
927  while (marker.active_next) {
928  op = marker.active_next;
929  tag = op->count;
930 
931  /* Move marker forward - swap op and marker */
932  op->active_prev = marker.active_prev;
933 
934  if (op->active_prev)
935  op->active_prev->active_next = op;
936  else
937  active_objects = op;
938 
939  marker.active_next = op->active_next;
940 
941  if (marker.active_next)
942  marker.active_next->active_prev = &marker;
943  marker.active_prev = op;
944  op->active_next = &marker;
945 
946  /* Now process op */
947  if (QUERY_FLAG(op, FLAG_FREED)) {
948  LOG(llevError, "BUG: process_events(): Free object on list\n");
949  op->speed = 0;
951  continue;
952  }
953 
954  /* I've seen occasional crashes due to this - the object is removed,
955  * and thus the map it points to (last map it was on) may be bogus
956  * The real bug is to try to find out the cause of this - someone
957  * is probably calling object_remove() without either an insert_ob or
958  * object_free_drop_inventory() afterwards, leaving an object dangling.
959  * But I'd rather log this and continue on instead of crashing.
960  * Don't remove players - when a player quits, the object is in
961  * sort of a limbo, of removed, but something we want to keep
962  * around.
963  */
964  if (QUERY_FLAG(op, FLAG_REMOVED)
965  && op->type != PLAYER
966  && op->map
967  && op->map->in_memory != MAP_IN_MEMORY) {
968  StringBuffer *sb;
969  char *diff;
970 
971  LOG(llevError, "BUG: process_events(): Removed object on list\n");
972  sb = stringbuffer_new();
973  object_dump(op, sb);
974  diff = stringbuffer_finish(sb);
975  LOG(llevError, "%s\n", diff);
976  free(diff);
978  continue;
979  }
980 
981  if (!op->speed) {
982  LOG(llevError, "BUG: process_events(): Object %s has no speed, but is on active list\n", op->arch->name);
984  continue;
985  }
986 
987  if (op->map == NULL
988  && op->env == NULL
989  && op->name
990  && op->type != MAP) {
991  LOG(llevError, "BUG: process_events(): Object without map or inventory is on active list: %s (%d)\n", op->name, op->count);
992  op->speed = 0;
994  continue;
995  }
996 
997  /* Seen some cases where process_object() is crashing because
998  * the object is on a swapped out map. But can't be sure if
999  * something in the chain of events caused the object to
1000  * change maps or was just never removed - this will
1001  * give some clue as to its state before call to
1002  * process_object
1003  */
1004  if (op->map && op->map->in_memory != MAP_IN_MEMORY) {
1005  LOG(llevError, "BUG: process_events(): Processing object on swapped out map: %s (%d), map=%s\n", op->name, op->count, op->map->path);
1006  }
1007 
1008  /* Animate the object. Bug of feature that andim_speed
1009  * is based on ticks, and not the creatures speed?
1010  */
1011  if ((op->anim_speed && op->last_anim >= op->anim_speed)
1012  || (op->temp_animation && op->last_anim >= op->temp_anim_speed)) {
1013  op->state++;
1014  if ((op->type == PLAYER) || (op->type == MONSTER))
1015  animate_object(op, op->facing);
1016  else
1017  animate_object(op, op->direction);
1018  op->last_anim = 1;
1019  } else {
1020  op->last_anim++;
1021  }
1022 
1023  if (op->speed_left > 0) {
1024  // Players are special because their speed_left has already been
1025  // reduced in do_server(). Players effectively process every tick
1026  // so long they have non-zero speed left.
1027  if (op->type != PLAYER) {
1028  // Objects in icecubes decay at a slower rate
1029  if (object_in_icecube(op)) {
1030  op->speed_left -= 10;
1031  } else {
1032  op->speed_left -= 1;
1033  }
1034  }
1035  process_object(op);
1036  if (object_was_destroyed(op, tag))
1037  continue;
1038  } else {
1039  // Custom-made creatures for random maps can still have negative speeds, so catch that with FABS().
1040  op->speed_left += FABS(op->speed);
1041  }
1042  if (settings.casting_time == TRUE && op->casting_time > 0)
1043  op->casting_time--;
1044  }
1045 
1046  /* Remove marker object from active list */
1047  if (marker.active_prev != NULL)
1048  marker.active_prev->active_next = NULL;
1049  else
1050  active_objects = NULL;
1051 
1052  process_players2();
1053 }
1054 
1059 void clean_tmp_files(void) {
1060  mapstruct *m, *next;
1061  for (m = first_map; m != NULL; m = next) {
1062  next = m->next;
1063  if (m->in_memory == MAP_IN_MEMORY) {
1064  // Save all maps currently in memory, because they might contain
1065  // unique tiles that have not been written to disk.
1066  if (settings.recycle_tmp_maps) {
1067  // swap_map() also updates the write log.
1068  swap_map(m);
1069  } else {
1071  // FIXME: Unfortunately, save_map() also unnecessarily saves
1072  // non-unique tiles to a new temporary file, so we have to
1073  // get rid of it here.
1074  clean_tmp_map(m);
1075  }
1076  } else {
1077  // Remove the swap file.
1078  clean_tmp_map(m);
1079  }
1080  }
1081  write_todclock(); /* lets just write the clock here */
1082 }
1083 
1085 void cleanup(void) {
1086  metaserver2_exit();
1087  LOG(llevInfo, "Cleaning up...\n");
1088  clean_tmp_files();
1090  accounts_save();
1091 
1092  close_modules();
1093 
1094 #ifdef MEMORY_DEBUG
1095  free_all_maps();
1096  free_style_maps();
1097 #endif
1098  cleanupPlugins();
1099  commands_clear();
1100 #ifdef MEMORY_DEBUG
1101  free_all_archs();
1103  free_all_images();
1105  free_all_recipes();
1107  free_all_god();
1108  free_all_anim();
1109  i18n_free();
1110  free_loader();
1111  free_globals();
1112  free_server();
1114  free_knowledge();
1115  free_quest();
1117  /* See what the string data that is out there that hasn't been freed. */
1118  /* LOG(llevDebug, "%s", ss_dump_table(0xff));*/
1119 #endif
1120  exit(0);
1121 }
1122 
1131 void leave(player *pl, int draw_exit) {
1132  if (!QUERY_FLAG(pl->ob, FLAG_REMOVED)) {
1133  pets_terminate_all(pl->ob);
1134  object_remove(pl->ob);
1135  }
1136 
1137  pl->socket->status = Ns_Dead;
1138  LOG(llevInfo, "logout: %s from %s\n", pl->ob->name, pl->socket->host);
1139 
1140  strcpy(pl->ob->contr->killer, "left");
1141  hiscore_check(pl->ob, 1);
1142 
1143  /* If this player is the captain of the transport, need to do
1144  * some extra work. By the time we get here, object_remove()
1145  * should have already been called.
1146  */
1147  if (pl->transport && pl->transport->contr == pl) {
1148  /* If inv is a non player, inv->contr will be NULL, but that
1149  * is OK.
1150  */
1151  if (pl->transport->inv)
1152  pl->transport->contr = pl->transport->inv->contr;
1153  else
1154  pl->transport->contr = NULL;
1155 
1156  if (pl->transport->contr) {
1157  char name[MAX_BUF];
1158 
1162  "%s has left. You are now the captain of %s",
1163  pl->ob->name, name);
1164  }
1165  }
1166 
1167  if (pl->ob->map) {
1168  if (pl->ob->map->in_memory == MAP_IN_MEMORY)
1169  pl->ob->map->timeout = MAP_TIMEOUT(pl->ob->map);
1170  pl->ob->map = NULL;
1171  }
1172  pl->ob->type = DEAD_OBJECT; /* To avoid problems with inventory window */
1173  party_leave(pl->ob);
1174  /* If a hidden dm dropped connection do not create
1175  * inconsistencies by showing that they have left the game
1176  */
1177  if (!(QUERY_FLAG(pl->ob, FLAG_WIZ) && pl->ob->contr->hidden)
1178  && (draw_exit) && (pl->state != ST_GET_NAME && pl->state != ST_GET_PASSWORD && pl->state != ST_CONFIRM_PASSWORD))
1181  "%s left the game.",
1182  pl->ob->name);
1183 }
1184 
1192 int forbid_play(void) {
1193 #if !defined(_IBMR2) && !defined(___IBMR2) && defined(PERM_FILE)
1194  char buf[MAX_BUF], day[MAX_BUF];
1195  FILE *fp;
1196  time_t clock;
1197  struct tm *tm;
1198  int i, start, stop, forbit = 0;
1199 
1200  clock = time(NULL);
1201  tm = (struct tm *)localtime(&clock);
1202 
1203  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, PERM_FILE);
1204  if ((fp = fopen(buf, "r")) == NULL)
1205  return 0;
1206 
1207  while (fgets(buf, sizeof(buf), fp)) {
1208  if (buf[0] == '#')
1209  continue;
1210  if (!strncmp(buf, "msg", 3)) {
1211  if (forbit)
1212  while (fgets(buf, sizeof(buf), fp)) /* print message */
1213  fputs(buf, logfile);
1214  break;
1215  } else if (sscanf(buf, "%s %d%*c%d\n", day, &start, &stop) != 3) {
1216  LOG(llevDebug, "Warning: Incomplete line in permission file ignored.\n");
1217  continue;
1218  }
1219 
1220  for (i = 0; i < 7; i++) {
1221  if (!strncmp(buf, days[i], 3)
1222  && (tm->tm_wday == i)
1223  && (tm->tm_hour >= start)
1224  && (tm->tm_hour < stop))
1225  forbit = 1;
1226  }
1227  }
1228 
1229  fclose(fp);
1230 
1231  return forbit;
1232 #else
1233  return 0;
1234 #endif
1235 }
1236 
1237 static void save_and_kick_all_players(void) {
1238  for (player *pl = first_player; pl != NULL; ) {
1239  player *npl = pl->next;
1240  save_player(pl->ob, 0);
1241  leave(pl, 0);
1242  final_free_player(pl);
1243  pl = npl;
1244  }
1245 }
1246 
1247 static void do_shutdown(void) {
1249  MSG_TYPE_ADMIN_DM, "The server has shut down.");
1251 
1252  // Maps are saved out in clean_tmp_files(), called by cleanup().
1253  cleanup();
1254 }
1255 
1259 static bool check_shutdown(void) {
1260  if (shutdown_flag == 1) {
1261  LOG(llevInfo, "Received SIGINT; shutting down...\n");
1262  return true;
1263  }
1264 
1266  return false;
1267  }
1268 
1270  if (count_players() == 0) {
1271  if (shutdown_state.time == 0) {
1272  // Start idle countdown
1273  shutdown_state.time = time(NULL);
1274  return false;
1275  } else {
1276  time_t diff = time(NULL) - shutdown_state.time;
1277  if (diff > 60) {
1278  LOG(llevInfo, "No active players in the last %ld seconds, shutting down...\n", diff);
1279  return true;
1280  } else {
1281  return false;
1282  }
1283  }
1284  } else {
1285  // Reset idle time, since there are players
1286  shutdown_state.time = 0;
1287  }
1288  return false;
1289  }
1290 
1291  assert(shutdown_state.type == SHUTDOWN_TIME);
1292 
1293  /* If a timed shutdown is coming, remind players periodically. */
1294  time_t time_left = shutdown_state.time - time(NULL);
1295 
1296  for (unsigned int i = shutdown_state.next_warn; i < sizeof(shutdown_warn_times) / sizeof(int); i++) {
1297  if (shutdown_warn_times[i] == (int)ceil(time_left / 60.0)) {
1300  "Server shutting down in %d minutes.", shutdown_warn_times[i]);
1301  shutdown_state.next_warn = i + 1;
1302  return false;
1303  }
1304  }
1305 
1306  if (time_left <= 0) {
1307  return true;
1308  }
1309  return false;
1310 }
1311 
1316 void login_check_shutdown(object* const op) {
1318  return;
1319  }
1320 
1324  "This server will shut down when all players leave.");
1325  return;
1326  }
1327 
1328  assert(shutdown_state.type == SHUTDOWN_TIME);
1329 
1330  time_t time_left = shutdown_state.time - time(NULL);
1331  if (time_left <= 60*shutdown_warn_times[0]) {
1334  "This server will shut down in %lu minutes.", time_left / 60);
1335  }
1336 }
1337 
1352 static void do_specials(void) {
1353  if (check_shutdown()) {
1354  do_shutdown();
1355  }
1356 
1357 #ifdef CS_LOGSTATS
1358  if ((time(NULL)-cst_lst.time_start) >= CS_LOGTIME) {
1359  write_cs_stats();
1360  }
1361 #endif
1362 
1363  if (!(pticks%10))
1365 
1366 #ifdef WATCHDOG
1367  if (!(pticks%503))
1368  watchdog();
1369 #endif
1370 
1371  if (!(pticks%PTICKS_PER_CLOCK))
1372  tick_the_clock();
1373 
1374  if (!(pticks%509))
1375  flush_old_maps(); /* Clears the tmp-files of maps which have reset */
1376 
1377  if (!(pticks%2503))
1378  fix_weight(); /* Hack to fix weightproblems caused by bugs */
1379 
1380  if (!(pticks%2521))
1381  metaserver_update(); /* 2500 ticks is about 5 minutes */
1382 
1383  if (!(pticks%2531))
1384  accounts_save();
1385 
1386  if (!(pticks%5003))
1388 
1389  if (!(pticks%5009))
1391 
1392  if (!(pticks%5011))
1394 
1395  if (!(pticks%12503))
1396  fix_luck();
1397 }
1398 
1407 void server_main(int argc, char *argv[]) {
1408  PROFILE_BEGIN();
1409 #ifdef WIN32 /* ---win32 this sets the win32 from 0d0a to 0a handling */
1410  _fmode = _O_BINARY;
1411 #endif
1412 
1413 #ifndef WIN32
1414  /* Here we check that we aren't root or suid */
1415  if (getuid() == 0 || geteuid() == 0) {
1416  fprintf(stderr,
1417  "Running crossfire-server as root is a bad idea; aborting!\n"
1418  "Please run it again as a normal, unprivileged user.\n");
1419  exit(EXIT_FAILURE);
1420  }
1421 #endif
1422 
1423 #ifdef DEBUG_MALLOC_LEVEL
1424  malloc_debug(DEBUG_MALLOC_LEVEL);
1425 #endif
1426 
1427  init(argc, argv);
1428  initPlugins(); /* GROS - Init the Plugins */
1429  // Give feedback that loading is complete. This prevents confusion on when it is done loading.
1430  PROFILE_END(diff, LOG(llevInfo, "Initialization complete (%ld ms). Waiting for connections.\n", diff/1000));
1431 #ifdef WIN32
1432  while (bRunning) {
1433 #else
1434  while (TRUE) {
1435 #endif
1436  nroferrors = 0;
1437 
1438  tick_game_time();
1439  do_server();
1440  process_events(); /* "do" something with objects with speed */
1441  cftimer_process_timers(); /* Process the crossfire Timers */
1443  check_active_maps(); /* Removes unused maps after a certain timeout */
1444  do_specials(); /* Routines called from time to time. */
1445  update_players();
1446  }
1447 
1448  /* This is unreachable. */
1449  abort();
1450 }
write_book_archive
void write_book_archive(void)
Write out the updated book archive to bookarch file.
Definition: readable.cpp:2009
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Checks if an object still exists.
Definition: object.h:70
Settings::casting_time
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:274
fix_weight
void fix_weight(void)
Check recursively the weight of all players, and fix what needs to be fixed.
Definition: player.cpp:3920
check_shutdown
static bool check_shutdown(void)
Check if we're ready to shut the server down.
Definition: server.cpp:1259
handle_newcs_player
int handle_newcs_player(object *op)
Handles commands the player can send us, and various checks on invisibility, golem and such.
Definition: player.cpp:3104
player::bed_y
int16_t bed_y
x,y - coordinates of respawn (savebed).
Definition: player.h:113
object::weapon_speed_left
float weapon_speed_left
How much speed is left to spend this round.
Definition: object.h:340
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:108
path.h
global.h
i18n_free
void i18n_free(void)
Clears all i18n-related data.
Definition: languages.cpp:210
first_player
player * first_player
First player.
Definition: init.cpp:106
clean_tmp_files
void clean_tmp_files(void)
Save unique maps and clean up temporary map files unless recycling temporary maps.
Definition: server.cpp:1059
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
random_map.h
tick_the_clock
void tick_the_clock(void)
This performs the basic function of advancing the clock one tick forward.
Definition: weather.cpp:116
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
MAP
@ MAP
Definition: object.h:130
remove_friendly_object
void remove_friendly_object(object *op)
Removes the specified object from the linked list of friendly objects.
Definition: friend.cpp:52
pets_terminate_all
void pets_terminate_all(object *owner)
Removes all pets someone owns.
Definition: pets.cpp:242
enter_player_savebed
void enter_player_savebed(object *op)
This is a basic little function to put the player back to his savebed.
Definition: server.cpp:142
send_delayed_buffers
void send_delayed_buffers(player *pl)
Send all delayed buffers for a player.
Definition: player.cpp:4539
MONSTER
@ MONSTER
A real, living creature.
Definition: object.h:205
Settings::recycle_tmp_maps
uint8_t recycle_tmp_maps
Re-use tmp maps.
Definition: global.h:276
Settings::emergency_y
uint16_t emergency_y
Coordinates to use on that map.
Definition: global.h:302
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
RMParms::origin_map
char origin_map[RM_SIZE]
Path to the map this random map is generated from, to make an exit back.
Definition: random_map.h:55
FABS
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
ST_GET_PASSWORD
#define ST_GET_PASSWORD
Name entered, now for password.
Definition: define.h:531
MSG_TYPE_ADMIN_PLAYER
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
Definition: newclient.h:500
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:82
SHUTDOWN_IDLE
@ SHUTDOWN_IDLE
Definition: commands.h:44
PTICKS_PER_CLOCK
#define PTICKS_PER_CLOCK
Number of ticks per in-game hour.
Definition: tod.h:12
free_all_readable
void free_all_readable(void)
Free all readable-related information.
Definition: readable.cpp:1978
ST_GET_NAME
#define ST_GET_NAME
Player just connected.
Definition: define.h:530
player
One player.
Definition: player.h:107
object_free_all_data
void object_free_all_data(void)
Destroys all allocated objects.
Definition: object.cpp:752
object::inv
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
player::golem_count
uint32_t golem_count
To track the golem.
Definition: player.h:121
enter_map
static void enter_map(object *op, mapstruct *newmap, int x, int y)
Moves the player and pets from current map (if any) to new map.
Definition: server.cpp:183
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Makes sure the given map is loaded and swapped in.
Definition: map.cpp:1768
SIZEOFFREE1
#define SIZEOFFREE1
Definition: define.h:153
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:371
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
ST_CONFIRM_PASSWORD
#define ST_CONFIRM_PASSWORD
New character, confirm password.
Definition: define.h:532
flush_old_maps
void flush_old_maps(void)
Reset maps that need to, remove their swap file.
Definition: swap.cpp:291
set_map_timeout
void set_map_timeout(mapstruct *oldmap)
Enable swapping for the given map.
Definition: server.cpp:305
Settings::crypt_mode
uint8_t crypt_mode
0 for legacy behavior, 1 for always Traditional
Definition: global.h:331
c
static event_registration c
Definition: citylife.cpp:424
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
P_NO_CLERIC
#define P_NO_CLERIC
No clerical spells cast here.
Definition: map.h:243
player::bed_x
int16_t bed_x
Definition: player.h:113
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.cpp:57
mapstruct::players
int16_t players
How many players are on this level right now.
Definition: map.h:338
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
object_set_enemy
void object_set_enemy(object *op, object *enemy)
Sets the enemy of an object.
Definition: object.cpp:900
accounts_save
void accounts_save(void)
Save all the account information.
Definition: account.cpp:255
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:424
object::x
int16_t x
Definition: object.h:335
player::ob
object * ob
The object representing the player.
Definition: player.h:179
do_server
void do_server(void)
This checks the sockets for input and exceptions, does the right thing.
Definition: loop.cpp:530
RMParms::Ysize
int Ysize
Definition: random_map.h:75
do_follow
static void do_follow(player *pl)
Called from process_players1() to move a player who is following someone.
Definition: server.cpp:733
player::transport
object * transport
Transport the player is in.
Definition: player.h:216
object::speed_left
float speed_left
How much speed is left to spend this round.
Definition: object.h:338
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Map is fully loaded.
Definition: map.h:131
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
AP_UNAPPLY
#define AP_UNAPPLY
Item is to be remvoed.
Definition: define.h:559
set_random_map_variable
int set_random_map_variable(RMParms *rp, const char *buf)
Definition: reader.cpp:2526
enter_random_map
static void enter_random_map(object *pl, object *exit_ob)
The player is trying to enter a randomly generated map.
Definition: server.cpp:375
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
FLAG_WIZ
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:218
move_player
int move_player(object *op, int dir)
Move player in the given direction.
Definition: player.cpp:2966
free_all_newserver
void free_all_newserver(void)
Free's all the memory that ericserver allocates.
Definition: init.cpp:401
object::direction
int8_t direction
Means the object is moving that way.
Definition: object.h:344
object::count
tag_t count
Unique object number for this object.
Definition: object.h:307
flags
static const flag_definition flags[]
Flag mapping.
Definition: gridarta-types-convert.cpp:101
object::last_grace
int16_t last_grace
As last_sp, except for grace.
Definition: object.h:369
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Copy object first frees everything allocated by the second object, and then copies the contents of th...
Definition: object.cpp:1177
player::savebed_map
char savebed_map[MAX_BUF]
Map where player will respawn after death.
Definition: player.h:112
ST_PLAYING
#define ST_PLAYING
Usual state.
Definition: define.h:525
PROFILE_BEGIN
#define PROFILE_BEGIN(expr)
Definition: global.h:365
RMParms::origin_y
int origin_y
Definition: random_map.h:88
free_knowledge
void free_knowledge(void)
Free all knowledge data.
Definition: knowledge.cpp:1280
Settings::emergency_x
uint16_t emergency_x
Definition: global.h:302
player::hidden
uint32_t hidden
If True, player (DM) is hidden from view.
Definition: player.h:149
generate_random_map
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
Main random map routine.
Definition: random_map.cpp:75
cleanupPlugins
void cleanupPlugins(void)
Call the crossfire_plugin::closefunc on the various plugins, used at server shutdown.
Definition: plugins.cpp:4639
range_golem
@ range_golem
Control golem.
Definition: player.h:34
enter_player_maplevel
void enter_player_maplevel(object *op)
Move a player to its stored map level.
Definition: server.cpp:522
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:360
MSG_TYPE_MISC
#define MSG_TYPE_MISC
Messages that don't go elsewhere.
Definition: newclient.h:417
party_obsolete_parties
void party_obsolete_parties(void)
Remove unused parties (no players).
Definition: party.cpp:215
free_all_maps
void free_all_maps(void)
Frees all allocated maps.
Definition: map.cpp:1983
pticks
uint32_t pticks
Number of ticks since time reset.
Definition: time.cpp:47
buf
StringBuffer * buf
Definition: readable.cpp:1564
active_objects
object * active_objects
List of active objects that need to be processed.
Definition: object.cpp:296
initPlugins
void initPlugins(void)
Plugins initialization.
Definition: plugins.cpp:4591
hiscore_check
void hiscore_check(object *op, int quiet)
Checks if player should enter the hiscore, and if so writes her into the list.
Definition: hiscore.cpp:348
version.h
RMParms
Random map parameters.
Definition: random_map.h:14
HUGE_BUF
#define HUGE_BUF
Used for messages - some can be quite long.
Definition: define.h:37
query_flag
static int query_flag(const object *op, int flag)
Definition: object.h:505
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:408
move_towards
static int move_towards(object *ob, object *towards, unsigned int mindist)
Move 'ob' in the direction of 'towards' (without any pathfinding) if the two objects are farther than...
Definition: server.cpp:709
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:219
Ns_Dead
@ Ns_Dead
Definition: newserver.h:71
MSG_TYPE_ADMIN_DM
#define MSG_TYPE_ADMIN_DM
DM related admin actions.
Definition: newclient.h:501
free_loader
void free_loader(void)
Frees all memory allocated by the loader.
Definition: loader.cpp:39087
CS_Stats::time_start
time_t time_start
Definition: newclient.h:702
PROFILE_END
#define PROFILE_END(var, expr)
Definition: global.h:370
RMParms::origin_x
int origin_x
Definition: random_map.h:89
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:424
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.cpp:76
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Go through the entire map (only the first time when an original map is loaded) and performs special a...
Definition: main.cpp:266
login_check_shutdown
void login_check_shutdown(object *const op)
Warn op if a server shutdown is scheduled.
Definition: server.cpp:1316
FLAG_FREED
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:220
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1545
shutdown_s::time
time_t time
When using SHUTDOWN_TIME, time of shutdown.
Definition: commands.h:49
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
forbid_play
int forbid_play(void)
Checks if server should be started.
Definition: server.cpp:1192
object::temp_anim_speed
uint8_t temp_anim_speed
Ticks between temporary animation-frames.
Definition: object.h:432
MAP_MINTIMEOUT
#define MAP_MINTIMEOUT
At least that many ticks before swapout.
Definition: config.h:409
write_todclock
void write_todclock(void)
Write out the current time to the file so time does not reset every time the server reboots.
Definition: init.cpp:505
final_free_player
void final_free_player(player *pl)
Sends the 'goodbye' command to the player, and closes connection.
Definition: init.cpp:455
player::killer
char killer[BIG_NAME]
Who killed this player.
Definition: player.h:192
object::last_heal
int32_t last_heal
Last healed.
Definition: object.h:367
object::subtype
uint8_t subtype
Subtype of object.
Definition: object.h:349
freearr_y
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.cpp:305
object::anim_speed
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:429
clean_path
static char * clean_path(const char *file, char *newpath, int size)
Takes a path and replaces all / with _ We do a strcpy so that we do not change the original string.
Definition: server.cpp:322
FLAG_UNPAID
#define FLAG_UNPAID
Object hasn't been paid for yet.
Definition: define.h:223
query_name
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.cpp:593
object::weapon_speed
float weapon_speed
The overall speed of this object.
Definition: object.h:339
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
player::followed_player
sstring followed_player
Player the DM is following.
Definition: player.h:220
player::ranges
object * ranges[range_size]
Object for each range.
Definition: player.h:118
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Combines the 2 paths.
Definition: path.cpp:172
free_all_artifacts
void free_all_artifacts(void)
Free all artifact-related information.
Definition: artifact.cpp:117
clean_friendly_list
void clean_friendly_list(void)
It traverses the friendly list removing objects that should not be here (ie, do not have friendly fla...
Definition: friend.cpp:80
RMParms::final_map
char final_map[RM_SIZE]
If not empty, the path of the final map this whole maze leads to.
Definition: random_map.h:57
object_dump
void object_dump(const object *op, StringBuffer *sb)
Dumps an object.
Definition: object.cpp:630
party_leave
void party_leave(object *op)
Makes a player leave his party.
Definition: party.cpp:123
add_string
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
first_map
mapstruct * first_map
First map.
Definition: init.cpp:107
FOR_OB_AND_BELOW_FINISH
#define FOR_OB_AND_BELOW_FINISH()
Finishes FOR_OB_AND_BELOW_PREPARE().
Definition: define.h:738
object_get_multi_size
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
Computes the size of a multitile object.
Definition: object.cpp:4729
clean_tmp_map
void clean_tmp_map(mapstruct *m)
Removse the temporary file used by the map.
Definition: map.cpp:1974
free_quest
void free_quest(void)
Free all quest status structures.
Definition: quest.cpp:895
shutdown_s::type
enum shutdown_type type
Definition: commands.h:48
object::casting_time
int16_t casting_time
Time left before spell goes off.
Definition: object.h:414
process_events
void process_events(void)
Process all active objects.
Definition: server.cpp:911
server_main
void server_main(int argc, char *argv[])
Server main function.
Definition: server.cpp:1407
out_of_map
int out_of_map(mapstruct *m, int x, int y)
Return 1 if coordinates X and Y are out of the map M, taking into account tiling.
Definition: map.cpp:2315
socket_struct::host
char * host
Which host it is connected from (ip address).
Definition: newserver.h:104
do_specials
static void do_specials(void)
Collection of functions to call from time to time.
Definition: server.cpp:1352
PORTAL_DESTINATION_NAME
#define PORTAL_DESTINATION_NAME
object::last_eat
int32_t last_eat
How long since we last ate.
Definition: object.h:366
nroferrors
long nroferrors
If it exceeds MAX_ERRORS, call fatal()
Definition: init.cpp:112
ob_describe
char * ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
Returns the description (short item name) of an object, as seen by the given observer.
Definition: ob_methods.cpp:92
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1334
object::last_anim
uint8_t last_anim
Last sequence used to draw face.
Definition: object.h:430
object_on_exit
static bool object_on_exit(object *ob, object *exit)
Return true if the player object is on the given exit.
Definition: server.cpp:722
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
enter_exit
void enter_exit(object *op, object *exit_ob)
Tries to move 'op' to exit_ob.
Definition: server.cpp:567
EVENT_CLOCK
#define EVENT_CLOCK
Global time event.
Definition: events.h:53
newhash
char const * newhash(char const *password)
Definition: server.cpp:101
living::dam
int16_t dam
How much damage this object does when hitting.
Definition: living.h:46
object::active_prev
object * active_prev
Previous object in the 'active list This is used in process_events so that the entire object list doe...
Definition: object.h:291
object_free
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1577
tag_t
uint32_t tag_t
Object tag, unique during the whole game.
Definition: object.h:14
mapstruct::reset_group
sstring reset_group
For reset purpose, all maps in the same group reset at the same time.
Definition: map.h:332
rproto.h
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
FOR_OB_AND_BELOW_PREPARE
#define FOR_OB_AND_BELOW_PREPARE(op_)
Constructs a loop iterating over an object and all objects below it in the same pile.
Definition: define.h:734
process_players1
static void process_players1(void)
Do all player-related stuff before objects have been updated.
Definition: server.cpp:779
MSG_TYPE_SPELL
#define MSG_TYPE_SPELL
Spell related info.
Definition: newclient.h:415
cftimer_process_timers
void cftimer_process_timers(void)
Processes all timers.
Definition: timers.cpp:44
object_in_icecube
static bool object_in_icecube(object *op)
Definition: server.cpp:904
object::facing
int8_t facing
Object is oriented/facing that way.
Definition: object.h:345
player::maplevel
char maplevel[MAX_BUF]
On which level is the player?
Definition: player.h:111
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Don't call check_walk_on against the originator.
Definition: object.h:582
SHUTDOWN_NONE
@ SHUTDOWN_NONE
Definition: commands.h:42
ob_blocked
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
Returns true if the given object can't fit in the given spot.
Definition: map.cpp:469
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.cpp:2085
SAVE_MODE_NORMAL
#define SAVE_MODE_NORMAL
No special handling.
Definition: map.h:121
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:76
SIZEOFFREE
#define SIZEOFFREE
Definition: define.h:155
EXIT_X
#define EXIT_X(xyz)
Definition: define.h:426
shutdown_flag
volatile sig_atomic_t shutdown_flag
Definition: server.cpp:53
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
free_all_recipes
void free_all_recipes(void)
Frees all memory allocated to recipes and recipes lists.
Definition: recipe.cpp:814
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
Definition: porting.cpp:225
EVENT_MAPLEAVE
#define EVENT_MAPLEAVE
A player left a map.
Definition: events.h:60
object_new
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it.
Definition: object.cpp:1258
free_all_god
void free_all_god(void)
Frees all god information.
Definition: holy.cpp:327
PERM_FILE
#define PERM_FILE
You can restrict playing in certain times by creating a PERMIT_FILE in CONFDIR.
Definition: config.h:454
free_string
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
RANDOM
#define RANDOM()
Definition: define.h:628
metaserver2_exit
void metaserver2_exit()
Stop metaserver updates.
Definition: metaserver.cpp:485
StringBuffer
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.cpp:25
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:204
free_quest_definitions
void free_quest_definitions(void)
bRunning
int bRunning
FLAG_DAMNED
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:304
enter_unique_map
static void enter_unique_map(object *op, object *exit_ob)
Player is entering a unique map.
Definition: server.cpp:447
MSG_TYPE_COMMAND_FAILURE
#define MSG_TYPE_COMMAND_FAILURE
Failed result from command.
Definition: newclient.h:535
can_follow
bool can_follow(object *, player *)
Definition: c_wiz.cpp:2730
socket_struct::sounds_this_tick
int8_t sounds_this_tick
Number of sounds sent this tick.
Definition: newserver.h:126
player_map_change_common
void player_map_change_common(object *op, mapstruct *const oldmap, mapstruct *const newmap)
Definition: server.cpp:282
find_dir_2
int find_dir_2(int x, int y)
Computes a direction which you should travel to move of x and y.
Definition: object.cpp:3662
pets_attempt_follow
void pets_attempt_follow(object *for_owner, int force)
Check pets so they try to follow their master around the world.
Definition: pets.cpp:262
object_find_by_type_and_slaying
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
Find object in inventory by type and slaying.
Definition: object.cpp:4143
swap_map
int swap_map(mapstruct *map)
Swaps a map to disk.
Definition: swap.cpp:136
Settings::emergency_mapname
char * emergency_mapname
Map to return players to in emergency.
Definition: global.h:301
llevInfo
@ llevInfo
Information.
Definition: logger.h:14
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
player::has_hit
uint32_t has_hit
If set, weapon_sp instead of speed will count.
Definition: player.h:146
MSG_TYPE_SPELL_FAILURE
#define MSG_TYPE_SPELL_FAILURE
Spell failure messages.
Definition: newclient.h:637
SIZEOFFREE2
#define SIZEOFFREE2
Definition: define.h:154
free_style_maps
void free_style_maps(void)
Frees cached style maps.
Definition: style.cpp:312
check_password
bool check_password(const char *typed, const char *crypted)
Hash a password and compare it to the stored version.
Definition: server.cpp:114
shutdown_warn_times
static const int shutdown_warn_times[]
How many minutes before a shutdown to warn players, in reverse order.
Definition: server.cpp:48
metaserver_update
void metaserver_update(void)
Updates our info in the metaserver Note that this is used for both metaserver1 and metaserver2 - for ...
Definition: metaserver.cpp:82
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
This rolls up wall, blocks_magic, blocks_view, etc, all into one function that just returns a P_.
Definition: map.cpp:280
save_and_kick_all_players
static void save_and_kick_all_players(void)
Definition: server.cpp:1237
mapstruct
This is a game-map.
Definition: map.h:320
object::env
object * env
Pointer to the object which is the environment.
Definition: object.h:301
write_cs_stats
void write_cs_stats(void)
SHUTDOWN_TIME
@ SHUTDOWN_TIME
Definition: commands.h:43
object::last_sp
int32_t last_sp
As last_heal, but for spell points.
Definition: object.h:368
EVENT_MAPENTER
#define EVENT_MAPENTER
A player entered a map.
Definition: events.h:59
NDI_ALL
#define NDI_ALL
Inform all players of this message.
Definition: newclient.h:267
socket_struct::status
enum Sock_Status status
Definition: newserver.h:94
animate_object
void animate_object(object *op, int dir)
Updates the face-variable of an object.
Definition: anim.cpp:44
update_players
void update_players(void)
Send updates to players.
Definition: loop.cpp:680
player::state
uint8_t state
Input state of the player (name, password, etc).
Definition: player.h:133
object_find_free_spot
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
object_find_free_spot(object, map, x, y, start, stop) will search for a spot at the given map and coo...
Definition: object.cpp:3544
mapstruct::in_memory
uint32_t in_memory
Combination of IN_MEMORY_xxx flags.
Definition: map.h:339
object::msg
sstring msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:330
rv_vector
This is used by get_rangevector to determine where the other creature is.
Definition: map.h:375
init
void init(int argc, char **argv)
This is the main server initialization function.
Definition: init.cpp:1114
hit_player
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
Object is attacked by something.
Definition: attack.cpp:1907
EXIT_Y
#define EXIT_Y(xyz)
Definition: define.h:427
free_globals
void free_globals(void)
Cleans all memory allocated for global variables.
Definition: init.cpp:426
map_path_unique
bool map_path_unique(const char *path)
Return true if the given map path leads to a unique map.
Definition: map.cpp:2705
free_server
void free_server(void)
Frees all memory allocated around here:
Definition: init.cpp:1166
ob_apply
method_ret ob_apply(object *op, object *applier, int aflags)
Apply an object by running an event hook or an object method.
Definition: ob_methods.cpp:44
mapstruct::timeout
int32_t timeout
Swapout is set to this.
Definition: map.h:336
MAP_HEIGHT
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:78
MAP_ENTER_Y
#define MAP_ENTER_Y(m)
Default Y coordinate for map enter.
Definition: map.h:85
NDI_DK_ORANGE
#define NDI_DK_ORANGE
DarkOrange2.
Definition: newclient.h:252
find_player_partial_name
player * find_player_partial_name(const char *plname)
Find a player by a partial name.
Definition: player.cpp:114
watchdog
void watchdog(void)
map_newmap_cmd
void map_newmap_cmd(socket_struct *ns)
Sound related function.
Definition: request.cpp:691
get_rangevector
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
From map.c This is used by get_player to determine where the other creature is.
Definition: map.cpp:2514
DEAD_OBJECT
@ DEAD_OBJECT
Definition: object.h:161
player::count
uint32_t count
Any numbers typed before a command.
Definition: player.h:124
MAP_PLAYER_UNIQUE
#define MAP_PLAYER_UNIQUE
This map is player-specific.
Definition: map.h:97
get_region_by_map
region * get_region_by_map(mapstruct *m)
Gets a region from a map.
Definition: region.cpp:71
save_player
int save_player(object *op, int flag)
Saves a player to disk.
Definition: login.cpp:239
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.cpp:316
MAP_ENTER_X
#define MAP_ENTER_X(m)
Default X coordinate for map enter.
Definition: map.h:83
process_object
void process_object(object *op)
Main object move function.
Definition: time.cpp:796
object::active_next
object * active_next
Next object in the 'active' list This is used in process_events so that the entire object list does n...
Definition: object.h:287
object_remove
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to.
Definition: object.cpp:1818
shutdown_state
struct shutdown_s shutdown_state
Definition: c_wiz.cpp:44
cleanup
void cleanup(void)
Clean up everything and exit.
Definition: server.cpp:1085
leave
void leave(player *pl, int draw_exit)
Player logs out, or was disconnected.
Definition: server.cpp:1131
do_some_living
void do_some_living(object *op)
Regenerate hp/sp/gr, decreases food.
Definition: player.cpp:3302
object::state
uint8_t state
How the object was last drawn (animation)
Definition: object.h:359
mapstruct::unique
uint32_t unique
If set, this is a per player unique map.
Definition: map.h:333
save_map
int save_map(mapstruct *m, int flag)
Saves a map to file.
Definition: map.cpp:1470
archetype::name
sstring name
More definite name, like "generate_kobold".
Definition: object.h:484
shutdown_s::next_warn
int next_warn
Definition: commands.h:51
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:109
fix_luck
void fix_luck(void)
Fixes luck of players, slowly move it towards 0.
Definition: player.cpp:3936
check_active_maps
void check_active_maps(void)
Finds maps in memory to swap.
Definition: swap.cpp:201
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
commands_clear
void commands_clear()
Clear all registered commands.
Definition: commands.cpp:345
count_players
int count_players(void)
Definition: metaserver.cpp:50
server.h
close_modules
void close_modules()
Clean up all modules which are not disabled.
Definition: init.cpp:87
freearr_x
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.cpp:299
tod.h
player::last_exit
object * last_exit
Last exit used by player or NULL.
Definition: player.h:210
MAP_TIMEOUT
#define MAP_TIMEOUT(m)
Definition: map.h:69
days
static const char * days[]
Ingame days.
Definition: server.cpp:51
TRUE
#define TRUE
Definition: compat.h:11
do_shutdown
static void do_shutdown(void)
Definition: server.cpp:1247
CS_LOGTIME
#define CS_LOGTIME
Definition: config.h:188
cst_lst
CS_Stats cst_lst
Definition: newclient.h:713
mapfile_load
mapstruct * mapfile_load(const char *map, int flags)
Opens the file "filename" and reads information about the map from the given file,...
Definition: map.cpp:1205
FLAG_UNIQUE
#define FLAG_UNIQUE
Item is really unique (UNIQUE_ITEMS)
Definition: define.h:274
object::attacktype
uint32_t attacktype
Bitmask of attacks this object does.
Definition: object.h:352
rv_vector::direction
int direction
General direction to the targer.
Definition: map.h:379
object::temp_animation
const Animations * temp_animation
A temporary animation.
Definition: object.h:431
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:406
RMParms::region
struct region * region
Definition: random_map.h:96
rv_vector::distance
unsigned int distance
Distance, in squares.
Definition: map.h:376
RMParms::Xsize
int Xsize
Definition: random_map.h:74
FORCE
@ FORCE
Definition: object.h:229
knowledge_process_incremental
void knowledge_process_incremental(void)
Incrementally send knowledge information to players, and remove information for players who left.
Definition: knowledge.cpp:1439
object.h
player::ticks_played
uint32_t ticks_played
How many ticks this player has played.
Definition: player.h:224
tick_game_time
void tick_game_time()
Definition: time.cpp:184
events_execute_global_event
void events_execute_global_event(int eventcode,...)
Execute a global event.
Definition: events.cpp:30
RMParms::link_source_map
bool link_source_map
Whether to set the reset group (if not already defined) of the source map for this random map.
Definition: random_map.h:104
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:15
SP_WORD_OF_RECALL
#define SP_WORD_OF_RECALL
Definition: spells.h:92
process_players2
static void process_players2(void)
Do all player-related stuff after objects have been updated.
Definition: server.cpp:876
AUTOSAVE
#define AUTOSAVE
How often (in seconds) the player is saved if he drops things.
Definition: config.h:593
player_update_bg_music
void player_update_bg_music(object *player)
Definition: sounds.cpp:170
unclean_path
static char * unclean_path(const char *src, char *newpath, int size)
Takes a path and replaces all _ with / This basically undoes clean_path().
Definition: server.cpp:350
crypt_string
static char const * crypt_string(char const *str, char const *salt)
Encrypt a string.
Definition: server.cpp:70