Crossfire Server, Trunk  1.75.0
login.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2022 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 <stdlib.h>
22 #include <string.h>
23 #include <sys/stat.h>
24 
25 #include "define.h"
26 #include "loader.h"
27 #include "output_file.h"
28 #include "spells.h"
29 #include "sproto.h"
30 #include "server.h"
31 
32 static void copy_file(const char *filename, FILE *fpout);
33 
41 void emergency_save(int flag) {
42 #ifndef NO_EMERGENCY_SAVE
43  player *pl;
44 
46  LOG(llevError, "Emergency save: ");
47  for (pl = first_player; pl != NULL; pl = pl->next) {
48  if (!pl->ob) {
49  LOG(llevError, "No name, ignoring this.\n");
50  continue;
51  }
52  LOG(llevError, "%s ", pl->ob->name);
54  "Emergency save...");
55 
56  /* If we are not exiting the game (ie, this is sort of a backup save), then
57  * don't change the location back to the village. Note that there are other
58  * options to have backup saves be done at the starting village
59  */
60  if (!flag) {
61  strcpy(pl->maplevel, first_map_path);
62  if (pl->ob->map != NULL)
63  pl->ob->map = NULL;
64  pl->ob->x = -1;
65  pl->ob->y = -1;
66  }
67  if (!save_player(pl->ob, flag)) {
68  LOG(llevError, "(failed) ");
70  "Emergency save failed, checking score...");
71  }
72  hiscore_check(pl->ob, 1);
73  }
74  LOG(llevError, "\n");
75 #else
76  (void)flag;
77  LOG(llevInfo, "Emergency saves disabled, no save attempted\n");
78 #endif
79 }
80 
88 void delete_character(const char *name) {
89  char buf[MAX_BUF];
90 
91  snprintf(buf, sizeof(buf), "%s/%s/%s", settings.localdir, settings.playerdir, name);
92  /* this effectively does an rm -rf on the directory */
94 }
95 
111 int verify_player(const char *name, char *password) {
112  char buf[MAX_BUF];
113  FILE *fp;
114  player *pltmp;
115 
116  if (strpbrk(name, "/.\\") != NULL) {
117  LOG(llevError, "Username contains illegal characters: %s\n", name);
118  return 1;
119  }
120 
121  /* Make sure we don't have a character that has just been loaded into the game with this name.
122  * It is possible for that character to not have been saved yet, and yet a character exists
123  * with that name.
124  * Creating a second character of the same name makes the game *really* confused, so don't
125  * let that happen.
126  *
127  * Neila Hawkins 2021-07-26
128  */
129  for (pltmp = first_player; pltmp != NULL; pltmp = pltmp->next) {
130  if (pltmp->ob->name != NULL && !strcmp(pltmp->ob->name, name)) {
131  // If we find a player already playing with that name, then disallow it.
132  return 2;
133  }
134  }
135 
136  // There is no unsaved player with that name, check the files
137  snprintf(buf, sizeof(buf), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name);
138  if (strlen(buf) >= sizeof(buf)-1) {
139  LOG(llevError, "Username too long: %s\n", name);
140  return 1;
141  }
142 
143  fp = fopen(buf, "r");
144  if (fp == NULL)
145  return 1;
146 
147  /* Read in the file until we find the password line. Our logic could
148  * be a bit better on cleaning up the password from the file, but since
149  * it is written by the program, I think it is fair to assume that the
150  * syntax should be pretty standard.
151  */
152  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
153  if (!strncmp(buf, "password ", 9)) {
154  buf[strlen(buf)-1] = 0; /* remove newline */
155  if (check_password(password, buf+9)) {
156  fclose(fp);
157  return 0;
158  }
159 
160  fclose(fp);
161  return 2;
162  }
163  }
164  LOG(llevDebug, "Could not find a password line in player %s\n", name);
165  fclose(fp);
166  return 1;
167 }
168 
181 int check_name(player *me, const char *name) {
182  if (*name == '\0') {
184  "Your username cannot be blank.");
185  return 0;
186  }
187 
188  if (!playername_ok(name)) {
190  "That name contains illegal characters. Use letters, hyphens and underscores only. Hyphens and underscores are not allowed as the first character.");
191  return 0;
192  }
193  if (strlen(name) >= MAX_NAME) {
195  "That name is too long. (Max length: %d characters)", MAX_NAME);
196  return 0;
197  }
198 
199  return 1;
200 }
201 
209 void destroy_object(object *op) {
210  while (op->inv != NULL)
211  destroy_object(op->inv);
212 
213  if (!QUERY_FLAG(op, FLAG_REMOVED))
214  object_remove(op);
216 }
217 
218 void drop_all_unpaid(object *op) {
219  FOR_INV_PREPARE(op, tmp) {
220  if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
221  object_remove(tmp);
222  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
223  }
224  } FOR_INV_FINISH();
225 }
226 
239 int save_player(object *op, int flag) {
240  FILE *fp;
241  OutputFile of;
242  char filename[MAX_BUF], *tmpfilename;
243  player *pl = op->contr;
244  int i, wiz = QUERY_FLAG(op, FLAG_WIZ);
245  long checksum;
246 #ifdef BACKUP_SAVE_AT_HOME
247  int16_t backup_x, backup_y;
248 #endif
249 
250  PROFILE_BEGIN();
251  if (!op->stats.exp)
252  return 0; /* no experience, no save */
253 
254  flag &= 1;
255 
256  if (!pl->name_changed) {
257  if (!flag) {
259  "Your game is not valid, game not saved.");
260  }
261  return 0;
262  }
263 
264  /* Sanity check - some stuff changes this when player is exiting */
265  if (op->type != PLAYER)
266  return 0;
267 
268  /* Prevent accidental saves if connection is reset after player has
269  * mostly exited.
270  */
271  if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD)
272  return 0;
273 
274  if (flag == 0) {
275  pets_terminate_all(op);
276  drop_all_unpaid(op);
277  }
278 
279  /* Update information on this character. Only do it if it is eligible for
280  * for saving.
281  */
282  if (pl->socket->account_name) {
285  /* Add this character to the account. This really only comes up
286  * for new characters, at which time we want to wait until save -
287  * otherwise there is a good chance that character will be
288  * terminated.
289  */
291  account_link(pl->socket->account_name, pl->ob->name);
292  }
293 
294 
295  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
296  make_path_to_file(filename);
297  fp = tempnam_secure(settings.tmpdir, NULL, &tmpfilename);
298  if (!fp) {
300  "Can't get secure temporary file for save.");
301  LOG(llevDebug, "Can't get secure temporary file for save.\n");
302  return 0;
303  }
304 
305  fprintf(fp, "password %s\n", pl->password);
306  if (settings.set_title == TRUE)
307  if (player_has_own_title(pl))
308  fprintf(fp, "title %s\n", player_get_own_title(pl));
309 
310  fprintf(fp, "gen_hp %d\n", pl->gen_hp);
311  fprintf(fp, "gen_sp %d\n", pl->gen_sp);
312  fprintf(fp, "gen_grace %d\n", pl->gen_grace);
313  fprintf(fp, "listening %d\n", pl->listening);
314  fprintf(fp, "shoottype %d\n", pl->shoottype);
315  fprintf(fp, "bowtype %d\n", pl->bowtype);
316  fprintf(fp, "petmode %d\n", pl->petmode);
317  fprintf(fp, "peaceful %d\n", pl->peaceful);
318  fprintf(fp, "no_shout %d\n", pl->no_shout);
319  fprintf(fp, "digestion %d\n", pl->digestion);
320  fprintf(fp, "pickup %u\n", pl->mode);
321  fprintf(fp, "partial_commands %u\n", pl->partial_commands);
322  /*
323  * outputs_sync and outputs_count are now unused in favor of the facility
324  * being supported on the client instead of in the server, but for now,
325  * set sane values in case an older server is run on a new player file.
326  * Once the server is officially 2.x, this should likely be removed.
327  */
328  fprintf(fp, "outputs_sync %d\n", 16);
329  fprintf(fp, "outputs_count %d\n", 1);
330  /* Match the enumerations but in string form */
331  fprintf(fp, "usekeys %s\n", pl->usekeys == key_inventory ? "key_inventory" : (pl->usekeys == keyrings ? "keyrings" : "containers"));
332  /* Match the enumerations but in string form */
333  fprintf(fp, "unapply %s\n", pl->unapply == unapply_nochoice ? "unapply_nochoice" : (pl->unapply == unapply_never ? "unapply_never" : "unapply_always"));
334  if (pl->unarmed_skill) fprintf(fp, "unarmed_skill %s\n", pl->unarmed_skill);
335 
336 #ifdef BACKUP_SAVE_AT_HOME
337  if (op->map != NULL && flag == 0)
338 #else
339  if (op->map != NULL)
340 #endif
341  fprintf(fp, "map %s\n", op->map->path);
342  else
343  fprintf(fp, "map %s\n", settings.emergency_mapname);
344 
345  fprintf(fp, "savebed_map %s\n", pl->savebed_map);
346  fprintf(fp, "bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y);
347  fprintf(fp, "Str %d\n", pl->orig_stats.Str);
348  fprintf(fp, "Dex %d\n", pl->orig_stats.Dex);
349  fprintf(fp, "Con %d\n", pl->orig_stats.Con);
350  fprintf(fp, "Int %d\n", pl->orig_stats.Int);
351  fprintf(fp, "Pow %d\n", pl->orig_stats.Pow);
352  fprintf(fp, "Wis %d\n", pl->orig_stats.Wis);
353  fprintf(fp, "Cha %d\n", pl->orig_stats.Cha);
354 
355  fprintf(fp, "lev_array %d\n", MIN(op->level, 10));
356  for (i = 1; i <= MIN(op->level, 10) && i <= 10; i++) {
357  fprintf(fp, "%d\n", pl->levhp[i]);
358  fprintf(fp, "%d\n", pl->levsp[i]);
359  fprintf(fp, "%d\n", pl->levgrace[i]);
360  }
361  fprintf(fp, "party_rejoin_mode %d\n", pl->rejoin_party);
362  if (pl->party != NULL) {
363  fprintf(fp, "party_rejoin_name %s\n", pl->party->partyname);
364  fprintf(fp, "party_rejoin_password %s\n", party_get_password(pl->party));
365  }
366  fprintf(fp, "language %s\n", i18n_get_language_code(pl->language));
367  fprintf(fp, "ticks_played %u\n", pl->ticks_played);
368  fprintf(fp, "endplst\n");
369 
371  CLEAR_FLAG(op, FLAG_WIZ);
372 #ifdef BACKUP_SAVE_AT_HOME
373  if (flag) {
374  backup_x = op->x;
375  backup_y = op->y;
376  op->x = -1;
377  op->y = -1;
378  }
379  /* Save objects, but not unpaid objects. Don't remove objects from
380  * inventory.
381  */
382  i = save_object(fp, op, SAVE_FLAG_NO_REMOVE);
383  if (flag) {
384  op->x = backup_x;
385  op->y = backup_y;
386  }
387 #else
388  i = save_object(fp, op, SAVE_FLAG_SAVE_UNPAID|SAVE_FLAG_NO_REMOVE); /* don't check and don't remove */
389 #endif
390 
391  if (wiz)
392  SET_FLAG(op, FLAG_WIZ);
393 
394  if (fclose(fp) != 0 || i != SAVE_ERROR_OK) { /* make sure the write succeeded */
396  "Can't save character!");
397  draw_ext_info_format(NDI_ALL_DMS|NDI_RED, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE, "Save failure for player %s!", op->name);
398  unlink(tmpfilename);
399  free(tmpfilename);
400  return 0;
401  }
402 
404 
405  if (!flag) {
406  // Clear last_skill_ob before removing inventory. This prevents us
407  // from accessing removed skill objects during cleanup.
408  for (int i = 0; i < MAX_SKILLS; i++) {
409  op->contr->last_skill_ob[i] = NULL;
410  }
411 
412  while (op->inv != NULL)
413  destroy_object(op->inv);
414 
415  /* destroying objects will most likely destroy the pointer
416  * in op->contr->ranges[], so clear the range to a safe value.
417  */
418  op->contr->shoottype = range_none;
419  }
420 
421  checksum = 0;
422  fp = of_open(&of, filename);
423  if (fp == NULL) {
425  "Can't open file for save.");
426  unlink(tmpfilename);
427  free(tmpfilename);
428  return 0;
429  }
430  fprintf(fp, "checksum %lx\n", checksum);
431  copy_file(tmpfilename, fp);
432  unlink(tmpfilename);
433  free(tmpfilename);
434  if (!of_close(&of)) {
436  "Can't close file for save.");
437  return 0;
438  }
439 
440  if (!flag)
441  esrv_send_inventory(op, op);
442 
443  if (chmod(filename, SAVE_MODE) != 0) {
444  LOG(llevError, "Could not set permissions on '%s'\n", filename);
445  }
446 
447  /* if this is the first player save, quest or knowledge states can be unsaved */
448  if (!op->contr->has_directory) {
449  op->contr->has_directory = 1;
452  }
453 
454  PROFILE_END(diff, LOG(llevDebug, "Saved player %s (%ld ms)\n", op->name, diff/1000));
455  return 1;
456 }
457 
466 static void copy_file(const char *filename, FILE *fpout) {
467  FILE *fp;
468  char buf[MAX_BUF];
469 
470  fp = fopen(filename, "r");
471  if (fp == NULL) {
472  LOG(llevError, "copy_file failed to open \"%s\", player file(s) may be corrupt.\n", filename);
473  return;
474  }
475  while (fgets(buf, MAX_BUF, fp) != NULL)
476  fputs(buf, fpout);
477  fclose(fp);
478 }
479 
487 static void wrong_password(object *op) {
489  "\nA character with this name already exists. "
490  "Please choose another name, or make sure you entered your "
491  "password correctly.\n");
492 
493  FREE_AND_COPY(op->name, "noname");
494  FREE_AND_COPY(op->name_pl, "noname");
495 
496  op->contr->socket->password_fails++;
499  "You gave an incorrect password too many times, "
500  "you will now be dropped from the server.");
501 
502  LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n",
503  op->contr->socket->host);
504 
505  op->contr->socket->status = Ns_Dead; /* the socket loop should handle the rest for us */
506  } else
507  get_name(op);
508 }
509 
522 void check_login(object *op, const char *password) {
523  FILE *fp;
524  char filename[MAX_BUF];
525  char buf[MAX_BUF], bufall[MAX_BUF];
526  int i, value;
527  uint32_t uvalue;
528  player *pl = op->contr, *pltmp;
529  int correct = 0;
530  time_t elapsed_save_time = 0;
531  struct stat statbuf;
532  char *party_name = NULL, party_password[9];
533 
534  strcpy(pl->maplevel, first_map_path);
535  party_password[0] = 0;
536 
537  /* Check if this matches a connected player, and if yes disconnect old / connect new. */
538  for (pltmp = first_player; pltmp != NULL; pltmp = pltmp->next) {
539  if (pltmp != pl && pltmp->ob->name != NULL && !strcmp(pltmp->ob->name, op->name)) {
540  if (!password || check_password(password, pltmp->password)) {
541  /* We could try and be more clever and re-assign the existing
542  * object to the new player, etc. However, I'm concerned that
543  * there may be a lot of other state that still needs to be sent
544  * in that case (we can't make any assumptions on what the
545  * client knows, as maybe the client crashed), so treating it
546  * as just a normal login is the safest and easiest thing to do.
547  */
548 
549  pltmp->socket->status = Ns_Dead;
550 
551  save_player(pltmp->ob, 0);
552  leave(pltmp, 1);
553  final_free_player(pltmp);
554  break;
555  }
556  if (password) {
557  wrong_password(op);
558  return;
559  }
560  }
561  }
562 
563  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
564 
565  /* If no file, must be a new player, so lets get confirmation of
566  * the password. Return control to the higher level dispatch,
567  * since the rest of this just deals with loading of the file.
568  */
569  fp = fopen(filename, "r");
570  if (fp == NULL) {
571  confirm_password(op);
572  return;
573  }
574  if (fstat(fileno(fp), &statbuf)) {
575  LOG(llevError, "Unable to stat %s?\n", filename);
576  elapsed_save_time = 0;
577  } else {
578  elapsed_save_time = time(NULL)-statbuf.st_mtime;
579  if (elapsed_save_time < 0) {
580  LOG(llevError, "Player file %s was saved in the future? (%ld time)\n", filename, (long)elapsed_save_time);
581  elapsed_save_time = 0;
582  }
583  }
584 
585  if (fgets(bufall, MAX_BUF, fp) != NULL) {
586  if (!strncmp(bufall, "checksum ", 9)) {
587  if ( fgets(bufall, MAX_BUF, fp) == NULL ) {
588  bufall[0]=0; /* should never happen */
589  }
590  }
591  if (sscanf(bufall, "password %s\n", buf)) {
592  /* New password scheme: */
593  correct = password && check_password(password, buf);
594  if (!password) {
595  /* We want to preserve the password. Normally,
596  * pl->password is filled in when user enters
597  * data in the password prompt, but with new login,
598  * there is no password prompt.
599  */
600  strncpy(pl->password, buf, 15);
601  pl->password[15] = 0;
602  }
603  }
604  /* Old password mode removed - I have no idea what it
605  * was, and the current password mechanism has been used
606  * for at least several years.
607  */
608  }
609  if (!correct && password) {
610  wrong_password(op);
611  fclose(fp);
612  return;
613  }
614 
615 #ifdef SAVE_INTERVAL
616  pl->last_save_time = time(NULL);
617 #endif /* SAVE_INTERVAL */
618  pl->party = NULL;
619  if (settings.search_items == TRUE)
620  pl->search_str[0] = '\0';
621  pl->name_changed = 1;
622  pl->orig_stats.Str = 0;
623  pl->orig_stats.Dex = 0;
624  pl->orig_stats.Con = 0;
625  pl->orig_stats.Int = 0;
626  pl->orig_stats.Pow = 0;
627  pl->orig_stats.Wis = 0;
628  pl->orig_stats.Cha = 0;
629  strcpy(pl->savebed_map, first_map_path);
630  pl->bed_x = 0,
631  pl->bed_y = 0;
632  pl->spellparam[0] = '\0';
633 
634  /* Loop through the file, loading the rest of the values */
635  while (fgets(bufall, MAX_BUF, fp) != NULL) {
636  char *val_string, *p;
637 
638  sscanf(bufall, "%s %d\n", buf, &value);
639 
640  val_string = bufall + strlen(buf) +1;
641  p = strchr(val_string, '\n');
642  if (p != NULL)
643  *p = '\0';
644 
645  /* uvalue is an unsigned value. Since at least a
646  * couple different things want an usigned value, cleaner
647  * to just do it once here vs everyplace it may be needed.
648  */
649 
650  uvalue = strtoul(val_string, (char **)NULL, 10);
651 
652  if (!strcmp(buf, "endplst"))
653  break;
654  if (!strcmp(buf, "title") && settings.set_title == TRUE)
655  player_set_own_title(pl, val_string);
656  else if (!strcmp(buf, "unarmed_skill"))
657  pl->unarmed_skill = add_string(val_string);
658  else if (!strcmp(buf, "explore"))
659  ; /* ignore: explore mode has been removed */
660  else if (!strcmp(buf, "gen_hp"))
661  pl->gen_hp = value;
662  else if (!strcmp(buf, "shoottype"))
663  pl->shoottype = (rangetype)value;
664  else if (!strcmp(buf, "bowtype"))
665  pl->bowtype = (bowtype_t)value;
666  else if (!strcmp(buf, "petmode"))
667  pl->petmode = (petmode_t)value;
668  else if (!strcmp(buf, "gen_sp"))
669  pl->gen_sp = value;
670  else if (!strcmp(buf, "gen_grace"))
671  pl->gen_grace = value;
672  else if (!strcmp(buf, "listening"))
673  pl->listening = value;
674  else if (!strcmp(buf, "peaceful"))
675  pl->peaceful = value;
676  else if (!strcmp(buf, "no_shout"))
677  pl->no_shout = value;
678  else if (!strcmp(buf, "digestion"))
679  pl->digestion = value;
680  else if (!strcmp(buf, "pickup")) {
681  pl->mode = uvalue;
682  } else if (!strcmp(buf, "partial_commands")) {
683  pl->partial_commands = uvalue;
684  }
685  else if (!strcmp(buf, "map"))
686  strlcpy(pl->maplevel, val_string, sizeof(pl->maplevel));
687  else if (!strcmp(buf, "savebed_map"))
688  strlcpy(pl->savebed_map, val_string, sizeof(pl->savebed_map));
689  else if (!strcmp(buf, "bed_x"))
690  pl->bed_x = value;
691  else if (!strcmp(buf, "bed_y"))
692  pl->bed_y = value;
693  else if (!strcmp(buf, "Str"))
694  pl->orig_stats.Str = value;
695  else if (!strcmp(buf, "Dex"))
696  pl->orig_stats.Dex = value;
697  else if (!strcmp(buf, "Con"))
698  pl->orig_stats.Con = value;
699  else if (!strcmp(buf, "Int"))
700  pl->orig_stats.Int = value;
701  else if (!strcmp(buf, "Pow"))
702  pl->orig_stats.Pow = value;
703  else if (!strcmp(buf, "Wis"))
704  pl->orig_stats.Wis = value;
705  else if (!strcmp(buf, "Cha"))
706  pl->orig_stats.Cha = value;
707  else if (!strcmp(buf, "usekeys")) {
708  if (!strcmp(val_string, "key_inventory"))
709  pl->usekeys = key_inventory;
710  else if (!strcmp(val_string, "keyrings"))
711  pl->usekeys = keyrings;
712  else if (!strcmp(val_string, "containers"))
713  pl->usekeys = containers;
714  else
715  LOG(llevDebug, "load_player: got unknown usekeys type: %s\n", val_string);
716  } else if (!strcmp(buf, "unapply")) {
717  if (!strcmp(val_string, "unapply_nochoice"))
719  else if (!strcmp(val_string, "unapply_never"))
720  pl->unapply = unapply_never;
721  else if (!strcmp(val_string, "unapply_always"))
722  pl->unapply = unapply_always;
723  else
724  LOG(llevDebug, "load_player: got unknown unapply type: %s\n", val_string);
725  } else if (!strcmp(buf, "lev_array")) {
726  for (i = 1; i <= value; i++) {
727  int j;
728  int count=0;
729 
730  count = fscanf(fp, "%d\n", &j);
731  if ( !count ) j=0; // sanity; should never happen
732  if (j < 3)
733  j = 3;
734  else if (j > 9)
735  j = 9;
736  pl->levhp[i] = j;
737  count = fscanf(fp, "%d\n", &j);
738  if ( !count ) j=0; // sanity; should never happen
739  if (j < 2)
740  j = 2;
741  else if (j > 6)
742  j = 6;
743  pl->levsp[i] = j;
744  count = fscanf(fp, "%d\n", &j);
745  if ( !count ) j=0; // sanity; should never happen
746  if (j < 1)
747  j = 1;
748  else if (j > 3)
749  j = 3;
750  pl->levgrace[i] = j;
751  }
752  } else if (!strcmp(buf, "party_rejoin_mode"))
753  pl->rejoin_party = (enum party_rejoin_mode)value;
754  else if (!strcmp(buf, "party_rejoin_name"))
755  party_name = strdup_local(val_string);
756  else if (!strcmp(buf, "party_rejoin_password")) {
757  strncpy(party_password, val_string, sizeof(party_password));
758  party_password[sizeof(party_password) - 1] = 0;
759  } else if (!strcmp(buf, "language")) {
760  pl->language = i18n_get_language_by_code(val_string);
761  }
762  else if (!strcmp(buf, "ticks_played")) {
763  pl->ticks_played = uvalue;
764  }
765  } /* End of loop loading the character file */
766 
767  /* on first login via account, this player does not exist anyplace -
768  * so don't remove them.
769  */
770  if (!QUERY_FLAG(op, FLAG_REMOVED))
771  object_remove(op);
772  op->speed = 0;
774  /*FIXME dangerous call, object_reset() should be used to init freshly allocated obj struct!*/
775  object_reset(op);
776  op->contr = pl;
777  pl->ob = op;
778  /* this loads the standard objects values. */
779  PROFILE_BEGIN();
780  load_object(fp, op, LO_NEWFILE, 0, false);
781  PROFILE_END(diff, LOG(llevDebug, "Loaded player file for %s (%ld ms)\n", op->name, diff/1000));
782  fclose(fp);
783 
785 
786  pl->is_wraith = object_find_by_name(op, "wraith feed") != NULL;
787  pl->is_old_wraith = object_find_by_name(op, "Wraith_Force") != NULL;
788 
789  LOG(llevInfo, "login: %s from %s\n", op->name, op->contr->socket->host);
790  strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1);
791  pl->title[sizeof(pl->title)-1] = '\0';
792 
793  /* If the map where the person was last saved does not exist,
794  * restart them on their home-savebed. This is good for when
795  * maps change between versions
796  * First, we check for partial path, then check to see if the full
797  * path (for unique player maps)
798  */
799  if (has_been_loaded(pl->maplevel) == NULL
800  && check_path(pl->maplevel, 1) == -1
801  && check_path(pl->maplevel, 0) == -1) {
802  strcpy(pl->maplevel, pl->savebed_map);
803  op->x = pl->bed_x,
804  op->y = pl->bed_y;
805  /* if the map was a shop, the player can have unpaid items, remove them. */
806  remove_unpaid_objects(op, NULL, 1);
807  }
808 
809  /* If player saved beyond some time ago, and the feature is
810  * enabled, put the player back on his savebed map.
811  */
812  if ((settings.reset_loc_time > 0) && (elapsed_save_time > settings.reset_loc_time)) {
813  strcpy(pl->maplevel, pl->savebed_map);
814  op->x = pl->bed_x, op->y = pl->bed_y;
815  /* if the map was a shop, the player can have unpaid items, remove them. */
816  remove_unpaid_objects(op, NULL, 1);
817  }
818 
819  /* make sure he's a player--needed because of class change. */
820  op->type = PLAYER;
822 
823  pl->name_changed = 1;
825 #ifdef AUTOSAVE
826  pl->last_save_tick = pticks;
827 #endif
828  op->carrying = object_sum_weight(op);
829 
830  link_player_skills(op);
831 
832  if (!legal_range(op, op->contr->shoottype))
833  op->contr->shoottype = range_none;
834 
835  /* if it's a dragon player, set the correct title here */
836  if (is_dragon_pl(op) && op->inv != NULL) {
837  object *abil, *skin;
838 
839  abil = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
840  skin = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
841  set_dragon_name(op, abil, skin);
842  }
843 
845  "Welcome Back!");
848  "%s has entered the game.",
849  pl->ob->name);
851 
853  op->contr->socket->update_look = 1;
854  /* If the player should be dead, call kill_player for them
855  * Only check for hp - if player lacks food, let the normal
856  * logic for that to take place. If player is permanently
857  * dead, and not using permadeath mode, the kill_player will
858  * set the play_again flag, so return.
859  */
860  if (op->stats.hp < 0) {
862  "Your character was dead last time you played.");
863  kill_player(op, NULL);
864  if (pl->state != ST_PLAYING)
865  {
866  // Prevent memory leak from strdup-ed party_name.
867  if (party_name)
868  free(party_name);
869  return;
870  }
871  }
872 
873  /* Do this after checking for death - no reason sucking up bandwidth if
874  * the data isn't needed.
875  */
876  esrv_new_player(op->contr, op->weight+op->carrying);
877  /* Need to do these after esvr_new_player, as once the client
878  * sees that, it wipes any info it has about the player.
879  */
880  esrv_add_spells(op->contr, NULL);
881 
882  /* Need to call fix_object now - program modified so that it is not
883  * called during the load process (FLAG_NO_FIX_PLAYER set when
884  * saved)
885  * Moved ahead of the esrv functions, so proper weights will be
886  * sent to the client. Needs to be after esvr_add_spells, otherwise
887  * we'll try to update spells from fix_object.
888  */
889  fix_object(op);
890 
891  pl->has_directory = 1;
892 
893  esrv_send_inventory(op, op);
894  esrv_send_pickup(pl);
897 
899 
900  /* can_use_shield is a new flag. However, the can_use.. seems to largely come
901  * from the class, and not race. I don't see any way to get the class information
902  * to then update this. I don't think this will actually break anything - anyone
903  * that can use armour should be able to use a shield. What this may 'break'
904  * are features new characters get, eg, if someone starts up with a Q, they
905  * should be able to use a shield. However, old Q's won't get that advantage.
906  */
907  if (QUERY_FLAG(op, FLAG_USE_ARMOUR))
909 
910  /* Rejoin party if needed. */
911  if (pl->rejoin_party != party_rejoin_no && party_name != NULL) {
912  partylist *party;
913 
914  party = party_find(party_name);
915  if (!party && pl->rejoin_party == party_rejoin_always) {
916  party = party_form(op, party_name);
917  if (party)
918  party_set_password(party, party_password);
919  }
920  if (party && !pl->party && party_confirm_password(party, party_password)) {
921  party_join(op, party);
922  }
923 
924  if (pl->party)
925  snprintf(buf, MAX_BUF, "Rejoined party %s.", party->partyname);
926  else
927  snprintf(buf, MAX_BUF, "Couldn't rejoin party %s: %s.", party_name, party ? "invalid password." : "no such party.");
929  buf);
930  }
931  free(party_name);
932 }
player::gen_sp
int16_t gen_sp
Bonuses to regeneration speed of sp.
Definition: player.h:127
party_rejoin_no
@ party_rejoin_no
Don't rejoin.
Definition: player.h:99
object::name_pl
sstring name_pl
The plural name of the object.
Definition: object.h:323
player::bed_y
int16_t bed_y
x,y - coordinates of respawn (savebed).
Definition: player.h:111
living::exp
int64_t exp
Experience.
Definition: living.h:47
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:106
output_file.h
global.h
first_player
player * first_player
First player.
Definition: init.cpp:106
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
SAVE_MODE
#define SAVE_MODE
If you have defined SAVE_PLAYER, you might want to change this, too.
Definition: config.h:563
pets_terminate_all
void pets_terminate_all(object *owner)
Removes all pets someone owns.
Definition: pets.cpp:242
MSG_TYPE_COMMAND_SUCCESS
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:534
player::unarmed_skill
const char * unarmed_skill
Prefered skill to use in unarmed combat.
Definition: player.h:221
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
MSG_TYPE_ADMIN_PLAYER
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
Definition: newclient.h:500
player::mode
uint32_t mode
Mode of player for pickup.
Definition: player.h:123
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
of_close
int of_close(OutputFile *of)
Closes an output file.
Definition: output_file.cpp:61
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
player::digestion
int16_t digestion
Any bonuses/penalties to digestion.
Definition: player.h:125
of_open
FILE * of_open(OutputFile *of, const char *fname)
Opens an output file.
Definition: output_file.cpp:30
player
One player.
Definition: player.h:105
strdup_local
#define strdup_local
Definition: compat.h:29
object::inv
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
player::gen_grace
int16_t gen_grace
Bonuses to regeneration speed of grace.
Definition: player.h:129
SAVE_FLAG_NO_REMOVE
#define SAVE_FLAG_NO_REMOVE
If set, objects are not removed while saving.
Definition: map.h:107
first_map_path
char first_map_path[MAX_BUF]
The start-level.
Definition: init.cpp:120
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
player::is_wraith
bool is_wraith
Whether this player is a wraith or not, initialized at load time.
Definition: player.h:227
login_check_shutdown
void login_check_shutdown(object *const op)
Warn op if a server shutdown is scheduled.
Definition: server.cpp:1488
Settings::set_title
uint8_t set_title
Players can set thier title.
Definition: global.h:266
has_been_loaded
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.cpp:79
esrv_new_player
void esrv_new_player(player *pl, uint32_t weight)
Tells the client that here is a player it should start using.
Definition: request.cpp:1008
bowtype_t
bowtype_t
Bow firing mode.
Definition: player.h:41
esrv_send_inventory
void esrv_send_inventory(object *pl, object *op)
Sends inventory of a container.
Definition: item.cpp:316
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
player::bed_x
int16_t bed_x
Definition: player.h:111
party_find
partylist * party_find(const char *partyname)
Find a party by name.
Definition: party.cpp:148
player::no_shout
uint32_t no_shout
if True, player is *not *able to use shout command.
Definition: player.h:148
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
if
if(!(yy_init))
Definition: loader.cpp:36435
living::Dex
int8_t Dex
Definition: living.h:36
object::x
int16_t x
Definition: object.h:335
player::peaceful
uint32_t peaceful
If set, won't attack friendly creatures.
Definition: player.h:146
player::ob
object * ob
The object representing the player.
Definition: player.h:177
copy_file
static void copy_file(const char *filename, FILE *fpout)
Copy a file.
Definition: login.cpp:466
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
esrv_send_pickup
void esrv_send_pickup(player *pl)
Sends the "pickup" state to pl if client wants it requested.
Definition: request.cpp:1880
player::levhp
int8_t levhp[11]
What hp bonus the player gained on that level.
Definition: player.h:186
player_set_own_title
void player_set_own_title(struct player *pl, const char *title)
Sets the custom title.
Definition: player.cpp:272
range_none
@ range_none
No range selected.
Definition: player.h:30
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
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
checksum
static unsigned checksum(const mtar_raw_header_t *rh)
Definition: microtar.cpp:49
MIN
#define MIN(x, y)
Definition: compat.h:21
object_reset
void object_reset(object *op)
Totally resets the specified object, without freeing associated memory.
Definition: object.cpp:919
NDI_ALL_DMS
#define NDI_ALL_DMS
Inform all logged in DMs.
Definition: newclient.h:268
player::partial_commands
uint32_t partial_commands
If 1, then first letters of a command are enough if no ambiguity in name.
Definition: player.h:150
player_has_own_title
int player_has_own_title(const struct player *pl)
Returns whether the player has a custom title.
Definition: player.cpp:247
load_object
int load_object(FILE *fp, object *op, int bufstate, int map_flags, bool artifact_init)
Loads an object from the given file-pointer.
Definition: loader.cpp:38953
player::levsp
int8_t levsp[11]
What sp bonus the player gained on that level.
Definition: player.h:187
player::savebed_map
char savebed_map[MAX_BUF]
Map where player will respawn after death.
Definition: player.h:110
fix_object
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.cpp:1132
PROFILE_BEGIN
#define PROFILE_BEGIN(expr)
Definition: global.h:364
NDI_RED
#define NDI_RED
Definition: newclient.h:249
save_player
int save_player(object *op, int flag)
Saves a player to disk.
Definition: login.cpp:239
account_link
int account_link(const char *account_name, const char *player_name)
Adds a player name to an account.
Definition: account.cpp:444
EVENT_LOGIN
#define EVENT_LOGIN
Player login.
Definition: events.h:57
unapply_always
@ unapply_always
Will unapply whatever is necessary - this goes beyond no choice - if there are multiple ojbect of the...
Definition: player.h:78
LO_NEWFILE
#define LO_NEWFILE
Definition: loader.h:17
esrv_add_spells
void esrv_add_spells(player *pl, object *spell)
This tells the client to add the spell *spell, if spell is NULL, then add all spells in the player's ...
Definition: request.cpp:1994
partylist
One party.
Definition: party.h:10
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:355
object::level
int16_t level
Level of creature or object.
Definition: object.h:361
pticks
uint32_t pticks
Number of ticks since time reset.
Definition: time.cpp:47
buf
StringBuffer * buf
Definition: readable.cpp:1565
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
party_rejoin_always
@ party_rejoin_always
If party doesn't exist, form it.
Definition: player.h:101
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:408
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
socket_struct::update_look
uint32_t update_look
If true, we need to send the look window.
Definition: newserver.h:108
party_join
void party_join(object *op, partylist *party)
Makes a player join a party.
Definition: party.cpp:85
Ns_Dead
@ Ns_Dead
Definition: newserver.h:71
object::carrying
int32_t carrying
How much weight this object contains.
Definition: object.h:377
remove_directory
void remove_directory(const char *path)
This function removes everything in the directory, and the directory itself.
Definition: porting.cpp:117
PROFILE_END
#define PROFILE_END(var, expr)
Definition: global.h:369
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
socket_struct::account_chars
Account_Chars * account_chars
Detailed information on characters on this account.
Definition: newserver.h:131
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
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
object_find_by_name
object * object_find_by_name(const object *who, const char *name)
Finds an object in inventory name.
Definition: object.cpp:3941
final_free_player
void final_free_player(player *pl)
Sends the 'goodbye' command to the player, and closes connection.
Definition: init.cpp:453
party_confirm_password
int party_confirm_password(const partylist *party, const char *password)
Checks whether a given password matches the party's password.
Definition: party.cpp:259
playername_ok
int playername_ok(const char *cp)
Is the player name valid.
Definition: player.cpp:257
i18n_get_language_code
sstring i18n_get_language_code(language_t language)
Return the code of a specified language.
Definition: languages.cpp:86
account_get_account_for_char
const char * account_get_account_for_char(const char *charname)
This looks at all the accounts and sees if charname is associated with any of them.
Definition: account.cpp:579
remove_unpaid_objects
void remove_unpaid_objects(object *op, object *env, int free_items)
This goes throws the inventory and removes unpaid objects, and puts them back in the map (location an...
Definition: player.cpp:3221
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
wrong_password
static void wrong_password(object *op)
Simple function to print errors when password is not correct, and reinitialise the name.
Definition: login.cpp:487
legal_range
int legal_range(object *op, int r)
Check for the validity of a player range.
Definition: c_range.cpp:247
petmode_t
petmode_t
Petmode.
Definition: player.h:57
enter_player_maplevel
void enter_player_maplevel(object *op)
Move a player to its stored map level.
Definition: server.cpp:682
trying_emergency_save
long trying_emergency_save
True when emergency_save() is reached.
Definition: init.cpp:111
verify_player
int verify_player(const char *name, char *password)
This verify that a character of name exits, and that it matches password.
Definition: login.cpp:111
socket_struct::host
char * host
Which host it is connected from (ip address).
Definition: newserver.h:104
delete_character
void delete_character(const char *name)
Totally deletes a character.
Definition: login.cpp:88
socket_struct::account_name
char * account_name
Name of the account logged in on this socket.
Definition: newserver.h:130
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1334
player::levgrace
int8_t levgrace[11]
What grace bonus the player gained on that level.
Definition: player.h:188
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
Definition: global.h:206
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
party_set_password
void party_set_password(partylist *party, const char *password)
Sets a party's password.
Definition: party.cpp:244
FLAG_USE_SHIELD
#define FLAG_USE_SHIELD
Can this creature use a shield?
Definition: define.h:237
leave
void leave(player *pl, int draw_exit)
Player logs out, or was disconnected.
Definition: server.cpp:1303
FOR_INV_FINISH
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:671
MAX_NAME
#define MAX_NAME
Definition: define.h:41
rangetype
rangetype
What range is currently selected by the player.
Definition: player.h:28
player::shoottype
rangetype shoottype
Which range-attack is being used by player.
Definition: player.h:112
sproto.h
MAX_SKILLS
#define MAX_SKILLS
This is the maximum number of skills the game may handle.
Definition: skills.h:70
living::Int
int8_t Int
Definition: living.h:36
partylist::partyname
char * partyname
Party name.
Definition: party.h:14
player::maplevel
char maplevel[MAX_BUF]
On which level is the player?
Definition: player.h:109
party_form
partylist * party_form(object *op, const char *partyname)
Forms the party struct for a party called 'partyname'.
Definition: party.cpp:40
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
key_inventory
@ key_inventory
Only use keys in inventory.
Definition: player.h:66
player::last_skill_ob
object * last_skill_ob[MAX_SKILLS]
Exp objects sent to client.
Definition: player.h:153
Settings::reset_loc_time
int reset_loc_time
Number of seconds to put player back at home.
Definition: global.h:265
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
MSG_TYPE_ADMIN_LOADSAVE
#define MSG_TYPE_ADMIN_LOADSAVE
load/save operations
Definition: newclient.h:503
player::listening
uint8_t listening
Which priority will be used in info_all.
Definition: player.h:133
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
Definition: porting.cpp:222
player::orig_stats
living orig_stats
Permanent real stats of player.
Definition: player.h:167
object::weight
int32_t weight
Attributes of the object.
Definition: object.h:375
player::unapply
unapplymode unapply
Method for auto unapply.
Definition: player.h:121
Settings::playerdir
const char * playerdir
Where the player files are.
Definition: global.h:251
quest_first_player_save
void quest_first_player_save(player *pl)
Ensure the quest state is correctly saved for a player.
Definition: quest.cpp:967
player::search_str
char search_str[MAX_BUF]
Item we are looking for.
Definition: player.h:211
ST_PLAYING
#define ST_PLAYING
Usual state.
Definition: define.h:535
player::gen_hp
int16_t gen_hp
Bonuses to regeneration speed of hp.
Definition: player.h:126
living::Wis
int8_t Wis
Definition: living.h:36
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
FLAG_WIZ
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:231
Settings::emergency_mapname
char * emergency_mapname
Map to return players to in emergency.
Definition: global.h:300
llevInfo
@ llevInfo
Information.
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
destroy_object
void destroy_object(object *op)
Recursively object_free_drop_inventory() op and its inventory.
Definition: login.cpp:209
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
spells.h
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
party_get_password
const char * party_get_password(const partylist *party)
Returns the party's password.
Definition: party.cpp:232
i18n_get_language_by_code
language_t i18n_get_language_by_code(const char *code)
Find the identifier of a language from its code.
Definition: languages.cpp:74
is_dragon_pl
int is_dragon_pl(const object *op)
Checks if player is a dragon.
Definition: player.cpp:122
unapply_nochoice
@ unapply_nochoice
Will unapply objects when there no choice to unapply.
Definition: player.h:76
FLAG_USE_ARMOUR
#define FLAG_USE_ARMOUR
(Monster) can wear armour/shield/helmet
Definition: define.h:295
player::is_old_wraith
bool is_old_wraith
Whether this player is a "old" wraith, initialized at load time and updated when eating.
Definition: player.h:228
check_name
int check_name(player *me, const char *name)
Ensure player's name is valid.
Definition: login.cpp:181
living::Cha
int8_t Cha
Definition: living.h:36
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
MAX_PASSWORD_FAILURES
#define MAX_PASSWORD_FAILURES
How many times we are allowed to give the wrong password before being kicked.
Definition: newserver.h:88
player::language
language_t language
The language the player wishes to use.
Definition: player.h:220
player::state
uint8_t state
Input state of the player (name, password, etc).
Definition: player.h:131
define.h
FLAG_NO_FIX_PLAYER
#define FLAG_NO_FIX_PLAYER
fix_object() won't be called
Definition: define.h:277
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
tempnam_secure
FILE * tempnam_secure(const char *dir, const char *pfx, char **filename)
A replacement for the tempnam_local() function since that one is not very secure.
Definition: porting.cpp:71
check_login
void check_login(object *op, const char *password)
Actually login a player, load from disk and such.
Definition: login.cpp:522
NDI_DK_ORANGE
#define NDI_DK_ORANGE
DarkOrange2.
Definition: newclient.h:252
object_find_by_type_and_arch_name
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Find object in inventory by type and archetype name.
Definition: object.cpp:4262
player::party
partylist * party
Party this player is part of.
Definition: player.h:203
containers
@ containers
Use keys in inventory and active containers.
Definition: player.h:68
keyrings
@ keyrings
Use keys in inventory and active key rings.
Definition: player.h:67
account_char_add
void account_char_add(Account_Chars *chars, player *pl)
This adds a player to the list of accounts.
Definition: account_char.cpp:207
MSG_TYPE_ADMIN_LOGIN
#define MSG_TYPE_ADMIN_LOGIN
login messages/errors
Definition: newclient.h:504
drop_all_unpaid
void drop_all_unpaid(object *op)
Definition: login.cpp:218
SAVE_ERROR_OK
#define SAVE_ERROR_OK
No error.
Definition: map.h:139
loader.h
ST_GET_PARTY_PASSWORD
#define ST_GET_PARTY_PASSWORD
Player tried to join a password-protected party.
Definition: define.h:543
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
player_set_state
void player_set_state(player *pl, uint8_t state)
Set the player's state to the specified one.
Definition: player.cpp:4485
object_sum_weight
signed long object_sum_weight(object *op)
object_sum_weight() is a recursive function which calculates the weight an object is carrying.
Definition: object.cpp:553
FLAG_UNPAID
#define FLAG_UNPAID
Object hasn't been paid for yet.
Definition: define.h:236
player::has_directory
uint32_t has_directory
If 0, the player was not yet saved, its directory doesn't exist.
Definition: player.h:149
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
make_path_to_file
void make_path_to_file(const char *filename)
Checks if any directories in the given path doesn't exist, and creates if necessary.
Definition: porting.cpp:164
player::password
char password[16]
2 (seed) + 11 (crypted) + 1 (EOS) + 2 (safety) = 16
Definition: player.h:193
emergency_save
void emergency_save(int flag)
Save all players.
Definition: login.cpp:41
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:107
socket_struct::password_fails
uint8_t password_fails
How many times the player has failed to give the right password.
Definition: newserver.h:105
knowledge_send_known
void knowledge_send_known(player *pl)
Send initial known knowledge to player, if requested.
Definition: knowledge.cpp:1403
Settings::search_items
uint8_t search_items
Search_items command.
Definition: global.h:268
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
unapply_never
@ unapply_never
Will not unapply objects automatically.
Definition: player.h:77
player::title
char title[BIG_NAME]
Default title, like fighter, wizard, etc.
Definition: player.h:184
me
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various what they and how they effect the player s actions Also in this section are the stat modifiers that specific classes professions bring Player and sps the current and maximum the Current and Maximum The Current Sp can go somewhat negative When Sp is negative not all spells can be and a more negative Sp makes spell casting less likey to succeed can affect Damage and how the characters as well as how often the character can attack this affects the prices when buying and selling items if this drops the player will start losing hit points wd Cleric or Dwarf sm Elf wd Fireborn ft Human ra Mage C Monk me
Definition: stats.txt:102
server.h
Settings::tmpdir
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:256
player_get_own_title
const char * player_get_own_title(const struct player *pl)
Returns the player's own title.
Definition: player.cpp:260
confirm_password
void confirm_password(object *op)
Ask the player to confirm her password during creation.
Definition: player.cpp:1011
player::petmode
petmode_t petmode
Which petmode?
Definition: player.h:115
TRUE
#define TRUE
Definition: compat.h:11
player::spellparam
char spellparam[MAX_BUF]
What param to add to spells.
Definition: player.h:113
link_player_skills
void link_player_skills(object *op)
This function goes through the player inventory and sets up the last_skills[] array in the player obj...
Definition: player.cpp:287
set_dragon_name
void set_dragon_name(object *pl, const object *abil, const object *skin)
Set the new dragon name after gaining levels or changing ability focus (later this can be extended to...
Definition: living.cpp:1688
living::Pow
int8_t Pow
Definition: living.h:36
party_rejoin_mode
party_rejoin_mode
Whether to rejoin party at login or not.
Definition: player.h:98
account_char_save
void account_char_save(Account_Chars *chars)
Saves the character information for the given account.
Definition: account_char.cpp:158
SAVE_FLAG_SAVE_UNPAID
#define SAVE_FLAG_SAVE_UNPAID
If set, unpaid items will be saved.
Definition: map.h:106
player::name_changed
uint32_t name_changed
If true, the player has set a name.
Definition: player.h:145
save_object
int save_object(FILE *fp, object *op, int flag)
Dumps all variables in an object to a file.
Definition: object.cpp:5382
kill_player
void kill_player(object *op, const object *killer)
Handle a player's death.
Definition: player.cpp:3506
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:406
player::bowtype
bowtype_t bowtype
Which firemode?
Definition: player.h:114
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:664
living::hp
int16_t hp
Hit Points.
Definition: living.h:40
FORCE
@ FORCE
Definition: object.h:229
check_path
int check_path(const char *name, int prepend_dir)
This function checks if a file with the given path exists.
Definition: map.cpp:201
player::ticks_played
uint32_t ticks_played
How many ticks this player has played.
Definition: player.h:222
player::usekeys
usekeytype usekeys
Method for finding keys for doors.
Definition: player.h:120
player::rejoin_party
party_rejoin_mode rejoin_party
Whether to rejoin or not party at login.
Definition: player.h:210
events_execute_global_event
void events_execute_global_event(int eventcode,...)
Execute a global event.
Definition: events.cpp:30
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
living::Con
int8_t Con
Definition: living.h:36
quest_send_initial_states
void quest_send_initial_states(player *pl)
Send the current quest states for the specified player, if the client supports those notifications.
Definition: quest.cpp:909
living::Str
int8_t Str
Definition: living.h:36
OutputFile
Definition: output_file.h:41
get_name
void get_name(object *op)
Waiting for the player's name.
Definition: player.cpp:886
knowledge_first_player_save
void knowledge_first_player_save(player *pl)
Ensure the knowledge state is correctly saved for the player.
Definition: knowledge.cpp:1423
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:250