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 
230 int save_player(object *op, int flag) {
231  FILE *fp;
232  OutputFile of;
233  char filename[MAX_BUF], *tmpfilename;
234  player *pl = op->contr;
235  int i, wiz = QUERY_FLAG(op, FLAG_WIZ);
236  long checksum;
237 #ifdef BACKUP_SAVE_AT_HOME
238  int16_t backup_x, backup_y;
239 #endif
240 
241  PROFILE_BEGIN();
242  if (!op->stats.exp)
243  return 0; /* no experience, no save */
244 
245  flag &= 1;
246 
247  if (!pl->name_changed) {
248  if (!flag) {
250  "Your game is not valid, game not saved.");
251  }
252  return 0;
253  }
254 
255  /* Sanity check - some stuff changes this when player is exiting */
256  if (op->type != PLAYER)
257  return 0;
258 
259  /* Prevent accidental saves if connection is reset after player has
260  * mostly exited.
261  */
262  if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD)
263  return 0;
264 
265  if (flag == 0)
266  pets_terminate_all(op);
267 
268  /* Update information on this character. Only do it if it is eligible for
269  * for saving.
270  */
271  if (pl->socket->account_name) {
274  /* Add this character to the account. This really only comes up
275  * for new characters, at which time we want to wait until save -
276  * otherwise there is a good chance that character will be
277  * terminated.
278  */
280  account_link(pl->socket->account_name, pl->ob->name);
281  }
282 
283 
284  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
285  make_path_to_file(filename);
286  fp = tempnam_secure(settings.tmpdir, NULL, &tmpfilename);
287  if (!fp) {
289  "Can't get secure temporary file for save.");
290  LOG(llevDebug, "Can't get secure temporary file for save.\n");
291  return 0;
292  }
293 
294  fprintf(fp, "password %s\n", pl->password);
295  if (settings.set_title == TRUE)
296  if (player_has_own_title(pl))
297  fprintf(fp, "title %s\n", player_get_own_title(pl));
298 
299  fprintf(fp, "gen_hp %d\n", pl->gen_hp);
300  fprintf(fp, "gen_sp %d\n", pl->gen_sp);
301  fprintf(fp, "gen_grace %d\n", pl->gen_grace);
302  fprintf(fp, "listening %d\n", pl->listening);
303  fprintf(fp, "shoottype %d\n", pl->shoottype);
304  fprintf(fp, "bowtype %d\n", pl->bowtype);
305  fprintf(fp, "petmode %d\n", pl->petmode);
306  fprintf(fp, "peaceful %d\n", pl->peaceful);
307  fprintf(fp, "no_shout %d\n", pl->no_shout);
308  fprintf(fp, "digestion %d\n", pl->digestion);
309  fprintf(fp, "pickup %u\n", pl->mode);
310  fprintf(fp, "partial_commands %u\n", pl->partial_commands);
311  /*
312  * outputs_sync and outputs_count are now unused in favor of the facility
313  * being supported on the client instead of in the server, but for now,
314  * set sane values in case an older server is run on a new player file.
315  * Once the server is officially 2.x, this should likely be removed.
316  */
317  fprintf(fp, "outputs_sync %d\n", 16);
318  fprintf(fp, "outputs_count %d\n", 1);
319  /* Match the enumerations but in string form */
320  fprintf(fp, "usekeys %s\n", pl->usekeys == key_inventory ? "key_inventory" : (pl->usekeys == keyrings ? "keyrings" : "containers"));
321  /* Match the enumerations but in string form */
322  fprintf(fp, "unapply %s\n", pl->unapply == unapply_nochoice ? "unapply_nochoice" : (pl->unapply == unapply_never ? "unapply_never" : "unapply_always"));
323  if (pl->unarmed_skill) fprintf(fp, "unarmed_skill %s\n", pl->unarmed_skill);
324 
325 #ifdef BACKUP_SAVE_AT_HOME
326  if (op->map != NULL && flag == 0)
327 #else
328  if (op->map != NULL)
329 #endif
330  fprintf(fp, "map %s\n", op->map->path);
331  else
332  fprintf(fp, "map %s\n", settings.emergency_mapname);
333 
334  fprintf(fp, "savebed_map %s\n", pl->savebed_map);
335  fprintf(fp, "bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y);
336  fprintf(fp, "Str %d\n", pl->orig_stats.Str);
337  fprintf(fp, "Dex %d\n", pl->orig_stats.Dex);
338  fprintf(fp, "Con %d\n", pl->orig_stats.Con);
339  fprintf(fp, "Int %d\n", pl->orig_stats.Int);
340  fprintf(fp, "Pow %d\n", pl->orig_stats.Pow);
341  fprintf(fp, "Wis %d\n", pl->orig_stats.Wis);
342  fprintf(fp, "Cha %d\n", pl->orig_stats.Cha);
343 
344  fprintf(fp, "lev_array %d\n", MIN(op->level, 10));
345  for (i = 1; i <= MIN(op->level, 10) && i <= 10; i++) {
346  fprintf(fp, "%d\n", pl->levhp[i]);
347  fprintf(fp, "%d\n", pl->levsp[i]);
348  fprintf(fp, "%d\n", pl->levgrace[i]);
349  }
350  fprintf(fp, "party_rejoin_mode %d\n", pl->rejoin_party);
351  if (pl->party != NULL) {
352  fprintf(fp, "party_rejoin_name %s\n", pl->party->partyname);
353  fprintf(fp, "party_rejoin_password %s\n", party_get_password(pl->party));
354  }
355  fprintf(fp, "language %s\n", i18n_get_language_code(pl->language));
356  fprintf(fp, "ticks_played %u\n", pl->ticks_played);
357  fprintf(fp, "endplst\n");
358 
360  CLEAR_FLAG(op, FLAG_WIZ);
361 #ifdef BACKUP_SAVE_AT_HOME
362  if (flag) {
363  backup_x = op->x;
364  backup_y = op->y;
365  op->x = -1;
366  op->y = -1;
367  }
368  /* Save objects, but not unpaid objects. Don't remove objects from
369  * inventory.
370  */
371  i = save_object(fp, op, SAVE_FLAG_NO_REMOVE);
372  if (flag) {
373  op->x = backup_x;
374  op->y = backup_y;
375  }
376 #else
377  i = save_object(fp, op, SAVE_FLAG_SAVE_UNPAID|SAVE_FLAG_NO_REMOVE); /* don't check and don't remove */
378 #endif
379 
380  if (wiz)
381  SET_FLAG(op, FLAG_WIZ);
382 
383  if (fclose(fp) != 0 || i != SAVE_ERROR_OK) { /* make sure the write succeeded */
385  "Can't save character!");
386  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);
387  unlink(tmpfilename);
388  free(tmpfilename);
389  return 0;
390  }
391 
393 
394  if (!flag) {
395  // Clear last_skill_ob before removing inventory. This prevents us
396  // from accessing removed skill objects during cleanup.
397  for (int i = 0; i < MAX_SKILLS; i++) {
398  op->contr->last_skill_ob[i] = NULL;
399  }
400 
401  while (op->inv != NULL)
402  destroy_object(op->inv);
403 
404  /* destroying objects will most likely destroy the pointer
405  * in op->contr->ranges[], so clear the range to a safe value.
406  */
407  op->contr->shoottype = range_none;
408  }
409 
410  checksum = 0;
411  fp = of_open(&of, filename);
412  if (fp == NULL) {
414  "Can't open file for save.");
415  unlink(tmpfilename);
416  free(tmpfilename);
417  return 0;
418  }
419  fprintf(fp, "checksum %lx\n", checksum);
420  copy_file(tmpfilename, fp);
421  unlink(tmpfilename);
422  free(tmpfilename);
423  if (!of_close(&of)) {
425  "Can't close file for save.");
426  return 0;
427  }
428 
429  if (!flag)
430  esrv_send_inventory(op, op);
431 
432  if (chmod(filename, SAVE_MODE) != 0) {
433  LOG(llevError, "Could not set permissions on '%s'\n", filename);
434  }
435 
436  /* if this is the first player save, quest or knowledge states can be unsaved */
437  if (!op->contr->has_directory) {
438  op->contr->has_directory = 1;
441  }
442 
443  PROFILE_END(diff, LOG(llevDebug, "Saved player %s (%ld ms)\n", op->name, diff/1000));
444  return 1;
445 }
446 
455 static void copy_file(const char *filename, FILE *fpout) {
456  FILE *fp;
457  char buf[MAX_BUF];
458 
459  fp = fopen(filename, "r");
460  if (fp == NULL) {
461  LOG(llevError, "copy_file failed to open \"%s\", player file(s) may be corrupt.\n", filename);
462  return;
463  }
464  while (fgets(buf, MAX_BUF, fp) != NULL)
465  fputs(buf, fpout);
466  fclose(fp);
467 }
468 
476 static void wrong_password(object *op) {
478  "\nA character with this name already exists. "
479  "Please choose another name, or make sure you entered your "
480  "password correctly.\n");
481 
482  FREE_AND_COPY(op->name, "noname");
483  FREE_AND_COPY(op->name_pl, "noname");
484 
485  op->contr->socket->password_fails++;
488  "You gave an incorrect password too many times, "
489  "you will now be dropped from the server.");
490 
491  LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n",
492  op->contr->socket->host);
493 
494  op->contr->socket->status = Ns_Dead; /* the socket loop should handle the rest for us */
495  } else
496  get_name(op);
497 }
498 
511 void check_login(object *op, const char *password) {
512  FILE *fp;
513  char filename[MAX_BUF];
514  char buf[MAX_BUF], bufall[MAX_BUF];
515  int i, value;
516  uint32_t uvalue;
517  player *pl = op->contr, *pltmp;
518  int correct = 0;
519  time_t elapsed_save_time = 0;
520  struct stat statbuf;
521  char *party_name = NULL, party_password[9];
522 
523  strcpy(pl->maplevel, first_map_path);
524  party_password[0] = 0;
525 
526  /* Check if this matches a connected player, and if yes disconnect old / connect new. */
527  for (pltmp = first_player; pltmp != NULL; pltmp = pltmp->next) {
528  if (pltmp != pl && pltmp->ob->name != NULL && !strcmp(pltmp->ob->name, op->name)) {
529  if (!password || check_password(password, pltmp->password)) {
530  /* We could try and be more clever and re-assign the existing
531  * object to the new player, etc. However, I'm concerned that
532  * there may be a lot of other state that still needs to be sent
533  * in that case (we can't make any assumptions on what the
534  * client knows, as maybe the client crashed), so treating it
535  * as just a normal login is the safest and easiest thing to do.
536  */
537 
538  pltmp->socket->status = Ns_Dead;
539 
540  save_player(pltmp->ob, 0);
541  leave(pltmp, 1);
542  final_free_player(pltmp);
543  break;
544  }
545  if (password) {
546  wrong_password(op);
547  return;
548  }
549  }
550  }
551 
552  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
553 
554  /* If no file, must be a new player, so lets get confirmation of
555  * the password. Return control to the higher level dispatch,
556  * since the rest of this just deals with loading of the file.
557  */
558  fp = fopen(filename, "r");
559  if (fp == NULL) {
560  confirm_password(op);
561  return;
562  }
563  if (fstat(fileno(fp), &statbuf)) {
564  LOG(llevError, "Unable to stat %s?\n", filename);
565  elapsed_save_time = 0;
566  } else {
567  elapsed_save_time = time(NULL)-statbuf.st_mtime;
568  if (elapsed_save_time < 0) {
569  LOG(llevError, "Player file %s was saved in the future? (%ld time)\n", filename, (long)elapsed_save_time);
570  elapsed_save_time = 0;
571  }
572  }
573 
574  if (fgets(bufall, MAX_BUF, fp) != NULL) {
575  if (!strncmp(bufall, "checksum ", 9)) {
576  if ( fgets(bufall, MAX_BUF, fp) == NULL ) {
577  bufall[0]=0; /* should never happen */
578  }
579  }
580  if (sscanf(bufall, "password %s\n", buf)) {
581  /* New password scheme: */
582  correct = password && check_password(password, buf);
583  if (!password) {
584  /* We want to preserve the password. Normally,
585  * pl->password is filled in when user enters
586  * data in the password prompt, but with new login,
587  * there is no password prompt.
588  */
589  strncpy(pl->password, buf, 15);
590  pl->password[15] = 0;
591  }
592  }
593  /* Old password mode removed - I have no idea what it
594  * was, and the current password mechanism has been used
595  * for at least several years.
596  */
597  }
598  if (!correct && password) {
599  wrong_password(op);
600  fclose(fp);
601  return;
602  }
603 
604 #ifdef SAVE_INTERVAL
605  pl->last_save_time = time(NULL);
606 #endif /* SAVE_INTERVAL */
607  pl->party = NULL;
608  if (settings.search_items == TRUE)
609  pl->search_str[0] = '\0';
610  pl->name_changed = 1;
611  pl->orig_stats.Str = 0;
612  pl->orig_stats.Dex = 0;
613  pl->orig_stats.Con = 0;
614  pl->orig_stats.Int = 0;
615  pl->orig_stats.Pow = 0;
616  pl->orig_stats.Wis = 0;
617  pl->orig_stats.Cha = 0;
618  strcpy(pl->savebed_map, first_map_path);
619  pl->bed_x = 0,
620  pl->bed_y = 0;
621  pl->spellparam[0] = '\0';
622 
623  /* Loop through the file, loading the rest of the values */
624  while (fgets(bufall, MAX_BUF, fp) != NULL) {
625  char *val_string, *p;
626 
627  sscanf(bufall, "%s %d\n", buf, &value);
628 
629  val_string = bufall + strlen(buf) +1;
630  p = strchr(val_string, '\n');
631  if (p != NULL)
632  *p = '\0';
633 
634  /* uvalue is an unsigned value. Since at least a
635  * couple different things want an usigned value, cleaner
636  * to just do it once here vs everyplace it may be needed.
637  */
638 
639  uvalue = strtoul(val_string, (char **)NULL, 10);
640 
641  if (!strcmp(buf, "endplst"))
642  break;
643  if (!strcmp(buf, "title") && settings.set_title == TRUE)
644  player_set_own_title(pl, val_string);
645  else if (!strcmp(buf, "unarmed_skill"))
646  pl->unarmed_skill = add_string(val_string);
647  else if (!strcmp(buf, "explore"))
648  ; /* ignore: explore mode has been removed */
649  else if (!strcmp(buf, "gen_hp"))
650  pl->gen_hp = value;
651  else if (!strcmp(buf, "shoottype"))
652  pl->shoottype = (rangetype)value;
653  else if (!strcmp(buf, "bowtype"))
654  pl->bowtype = (bowtype_t)value;
655  else if (!strcmp(buf, "petmode"))
656  pl->petmode = (petmode_t)value;
657  else if (!strcmp(buf, "gen_sp"))
658  pl->gen_sp = value;
659  else if (!strcmp(buf, "gen_grace"))
660  pl->gen_grace = value;
661  else if (!strcmp(buf, "listening"))
662  pl->listening = value;
663  else if (!strcmp(buf, "peaceful"))
664  pl->peaceful = value;
665  else if (!strcmp(buf, "no_shout"))
666  pl->no_shout = value;
667  else if (!strcmp(buf, "digestion"))
668  pl->digestion = value;
669  else if (!strcmp(buf, "pickup")) {
670  pl->mode = uvalue;
671  } else if (!strcmp(buf, "partial_commands")) {
672  pl->partial_commands = uvalue;
673  }
674  else if (!strcmp(buf, "map"))
675  strlcpy(pl->maplevel, val_string, sizeof(pl->maplevel));
676  else if (!strcmp(buf, "savebed_map"))
677  strlcpy(pl->savebed_map, val_string, sizeof(pl->savebed_map));
678  else if (!strcmp(buf, "bed_x"))
679  pl->bed_x = value;
680  else if (!strcmp(buf, "bed_y"))
681  pl->bed_y = value;
682  else if (!strcmp(buf, "Str"))
683  pl->orig_stats.Str = value;
684  else if (!strcmp(buf, "Dex"))
685  pl->orig_stats.Dex = value;
686  else if (!strcmp(buf, "Con"))
687  pl->orig_stats.Con = value;
688  else if (!strcmp(buf, "Int"))
689  pl->orig_stats.Int = value;
690  else if (!strcmp(buf, "Pow"))
691  pl->orig_stats.Pow = value;
692  else if (!strcmp(buf, "Wis"))
693  pl->orig_stats.Wis = value;
694  else if (!strcmp(buf, "Cha"))
695  pl->orig_stats.Cha = value;
696  else if (!strcmp(buf, "usekeys")) {
697  if (!strcmp(val_string, "key_inventory"))
698  pl->usekeys = key_inventory;
699  else if (!strcmp(val_string, "keyrings"))
700  pl->usekeys = keyrings;
701  else if (!strcmp(val_string, "containers"))
702  pl->usekeys = containers;
703  else
704  LOG(llevDebug, "load_player: got unknown usekeys type: %s\n", val_string);
705  } else if (!strcmp(buf, "unapply")) {
706  if (!strcmp(val_string, "unapply_nochoice"))
708  else if (!strcmp(val_string, "unapply_never"))
709  pl->unapply = unapply_never;
710  else if (!strcmp(val_string, "unapply_always"))
711  pl->unapply = unapply_always;
712  else
713  LOG(llevDebug, "load_player: got unknown unapply type: %s\n", val_string);
714  } else if (!strcmp(buf, "lev_array")) {
715  for (i = 1; i <= value; i++) {
716  int j;
717  int count=0;
718 
719  count = fscanf(fp, "%d\n", &j);
720  if ( !count ) j=0; // sanity; should never happen
721  if (j < 3)
722  j = 3;
723  else if (j > 9)
724  j = 9;
725  pl->levhp[i] = j;
726  count = fscanf(fp, "%d\n", &j);
727  if ( !count ) j=0; // sanity; should never happen
728  if (j < 2)
729  j = 2;
730  else if (j > 6)
731  j = 6;
732  pl->levsp[i] = j;
733  count = fscanf(fp, "%d\n", &j);
734  if ( !count ) j=0; // sanity; should never happen
735  if (j < 1)
736  j = 1;
737  else if (j > 3)
738  j = 3;
739  pl->levgrace[i] = j;
740  }
741  } else if (!strcmp(buf, "party_rejoin_mode"))
742  pl->rejoin_party = (enum party_rejoin_mode)value;
743  else if (!strcmp(buf, "party_rejoin_name"))
744  party_name = strdup_local(val_string);
745  else if (!strcmp(buf, "party_rejoin_password")) {
746  strncpy(party_password, val_string, sizeof(party_password));
747  party_password[sizeof(party_password) - 1] = 0;
748  } else if (!strcmp(buf, "language")) {
749  pl->language = i18n_get_language_by_code(val_string);
750  }
751  else if (!strcmp(buf, "ticks_played")) {
752  pl->ticks_played = uvalue;
753  }
754  } /* End of loop loading the character file */
755 
756  /* on first login via account, this player does not exist anyplace -
757  * so don't remove them.
758  */
759  if (!QUERY_FLAG(op, FLAG_REMOVED))
760  object_remove(op);
761  op->speed = 0;
763  /*FIXME dangerous call, object_reset() should be used to init freshly allocated obj struct!*/
764  object_reset(op);
765  op->contr = pl;
766  pl->ob = op;
767  /* this loads the standard objects values. */
768  PROFILE_BEGIN();
769  load_object(fp, op, LO_NEWFILE, 0, false);
770  PROFILE_END(diff, LOG(llevDebug, "Loaded player file for %s (%ld ms)\n", op->name, diff/1000));
771  fclose(fp);
772 
774 
775  pl->is_wraith = object_find_by_name(op, "wraith feed") != NULL;
776  pl->is_old_wraith = object_find_by_name(op, "Wraith_Force") != NULL;
777 
778  LOG(llevInfo, "login: %s from %s\n", op->name, op->contr->socket->host);
779  strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1);
780  pl->title[sizeof(pl->title)-1] = '\0';
781 
782  /* If the map where the person was last saved does not exist,
783  * restart them on their home-savebed. This is good for when
784  * maps change between versions
785  * First, we check for partial path, then check to see if the full
786  * path (for unique player maps)
787  */
788  if (has_been_loaded(pl->maplevel) == NULL
789  && check_path(pl->maplevel, 1) == -1
790  && check_path(pl->maplevel, 0) == -1) {
791  strcpy(pl->maplevel, pl->savebed_map);
792  op->x = pl->bed_x,
793  op->y = pl->bed_y;
794  /* if the map was a shop, the player can have unpaid items, remove them. */
795  remove_unpaid_objects(op, NULL, 1);
796  }
797 
798  /* If player saved beyond some time ago, and the feature is
799  * enabled, put the player back on his savebed map.
800  */
801  if ((settings.reset_loc_time > 0) && (elapsed_save_time > settings.reset_loc_time)) {
802  strcpy(pl->maplevel, pl->savebed_map);
803  op->x = pl->bed_x, op->y = pl->bed_y;
804  /* if the map was a shop, the player can have unpaid items, remove them. */
805  remove_unpaid_objects(op, NULL, 1);
806  }
807 
808  /* make sure he's a player--needed because of class change. */
809  op->type = PLAYER;
811 
812  pl->name_changed = 1;
814 #ifdef AUTOSAVE
815  pl->last_save_tick = pticks;
816 #endif
817  op->carrying = object_sum_weight(op);
818 
819  link_player_skills(op);
820 
821  if (!legal_range(op, op->contr->shoottype))
822  op->contr->shoottype = range_none;
823 
824  /* if it's a dragon player, set the correct title here */
825  if (is_dragon_pl(op) && op->inv != NULL) {
826  object *abil, *skin;
827 
828  abil = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
829  skin = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
830  set_dragon_name(op, abil, skin);
831  }
832 
834  "Welcome Back!");
837  "%s has entered the game.",
838  pl->ob->name);
840 
842  op->contr->socket->update_look = 1;
843  /* If the player should be dead, call kill_player for them
844  * Only check for hp - if player lacks food, let the normal
845  * logic for that to take place. If player is permanently
846  * dead, and not using permadeath mode, the kill_player will
847  * set the play_again flag, so return.
848  */
849  if (op->stats.hp < 0) {
851  "Your character was dead last time you played.");
852  kill_player(op, NULL);
853  if (pl->state != ST_PLAYING)
854  {
855  // Prevent memory leak from strdup-ed party_name.
856  if (party_name)
857  free(party_name);
858  return;
859  }
860  }
861 
862  /* Do this after checking for death - no reason sucking up bandwidth if
863  * the data isn't needed.
864  */
865  esrv_new_player(op->contr, op->weight+op->carrying);
866  /* Need to do these after esvr_new_player, as once the client
867  * sees that, it wipes any info it has about the player.
868  */
869  esrv_add_spells(op->contr, NULL);
870 
871  /* Need to call fix_object now - program modified so that it is not
872  * called during the load process (FLAG_NO_FIX_PLAYER set when
873  * saved)
874  * Moved ahead of the esrv functions, so proper weights will be
875  * sent to the client. Needs to be after esvr_add_spells, otherwise
876  * we'll try to update spells from fix_object.
877  */
878  fix_object(op);
879 
880  pl->has_directory = 1;
881 
882  esrv_send_inventory(op, op);
883  esrv_send_pickup(pl);
886 
888 
889  /* can_use_shield is a new flag. However, the can_use.. seems to largely come
890  * from the class, and not race. I don't see any way to get the class information
891  * to then update this. I don't think this will actually break anything - anyone
892  * that can use armour should be able to use a shield. What this may 'break'
893  * are features new characters get, eg, if someone starts up with a Q, they
894  * should be able to use a shield. However, old Q's won't get that advantage.
895  */
896  if (QUERY_FLAG(op, FLAG_USE_ARMOUR))
898 
899  /* Rejoin party if needed. */
900  if (pl->rejoin_party != party_rejoin_no && party_name != NULL) {
901  partylist *party;
902 
903  party = party_find(party_name);
904  if (!party && pl->rejoin_party == party_rejoin_always) {
905  party = party_form(op, party_name);
906  if (party)
907  party_set_password(party, party_password);
908  }
909  if (party && !pl->party && party_confirm_password(party, party_password)) {
910  party_join(op, party);
911  }
912 
913  if (pl->party)
914  snprintf(buf, MAX_BUF, "Rejoined party %s.", party->partyname);
915  else
916  snprintf(buf, MAX_BUF, "Couldn't rejoin party %s: %s.", party_name, party ? "invalid password." : "no such party.");
918  buf);
919  }
920  free(party_name);
921 }
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
Server 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:225
MSG_TYPE_COMMAND_SUCCESS
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:533
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:499
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:267
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:36428
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:455
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:1835
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:934
NDI_ALL_DMS
#define NDI_ALL_DMS
Inform all logged in DMs.
Definition: newclient.h:267
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:38944
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:371
NDI_RED
#define NDI_RED
Definition: newclient.h:248
save_player
int save_player(object *op, int flag)
Saves a player to disk.
Definition: login.cpp:230
account_link
int account_link(const char *account_name, const char *player_name)
Adds a player name to an account.
Definition: account.cpp:444
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:1949
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:407
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:104
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:67
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:376
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:127
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:1560
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:3956
EVENT_LOGIN
#define EVENT_LOGIN
Player login.
Definition: events.h:44
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:3224
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:476
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:100
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:126
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1349
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
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
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:266
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:502
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:252
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:301
llevInfo
@ llevInfo
Information.
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:265
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:266
socket_struct::status
enum Sock_Status status
Definition: newserver.h:90
MAX_PASSWORD_FAILURES
#define MAX_PASSWORD_FAILURES
How many times we are allowed to give the wrong password before being kicked.
Definition: newserver.h:84
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:511
NDI_DK_ORANGE
#define NDI_DK_ORANGE
DarkOrange2.
Definition: newclient.h:251
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:4277
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:503
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:1833
player_set_state
void player_set_state(player *pl, uint8_t state)
Set the player's state to the specified one.
Definition: player.cpp:4488
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:568
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:101
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:269
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:257
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:1014
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:5397
kill_player
void kill_player(object *op, const object *killer)
Handle a player's death.
Definition: player.cpp:3509
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:405
player::bowtype
bowtype_t bowtype
Which firemode?
Definition: player.h:114
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:889
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:251