Crossfire Server, Trunk  R20513
login.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <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 
31 static void copy_file(const char *filename, FILE *fpout);
32 
40 void emergency_save(int flag) {
41 #ifndef NO_EMERGENCY_SAVE
42  player *pl;
43 
45  LOG(llevError, "Emergency save: ");
46  for (pl = first_player; pl != NULL; pl = pl->next) {
47  if (!pl->ob) {
48  LOG(llevError, "No name, ignoring this.\n");
49  continue;
50  }
51  LOG(llevError, "%s ", pl->ob->name);
53  "Emergency save...");
54 
55  /* If we are not exiting the game (ie, this is sort of a backup save), then
56  * don't change the location back to the village. Note that there are other
57  * options to have backup saves be done at the starting village
58  */
59  if (!flag) {
60  strcpy(pl->maplevel, first_map_path);
61  if (pl->ob->map != NULL)
62  pl->ob->map = NULL;
63  pl->ob->x = -1;
64  pl->ob->y = -1;
65  }
66  if (!save_player(pl->ob, flag)) {
67  LOG(llevError, "(failed) ");
69  "Emergency save failed, checking score...");
70  }
71  hiscore_check(pl->ob, 1);
72  }
73  LOG(llevError, "\n");
74 #else
75  LOG(llevInfo, "Emergency saves disabled, no save attempted\n");
76 #endif
77 }
78 
86 void delete_character(const char *name) {
87  char buf[MAX_BUF];
88 
89  snprintf(buf, sizeof(buf), "%s/%s/%s", settings.localdir, settings.playerdir, name);
90  /* this effectively does an rm -rf on the directory */
91  remove_directory(buf);
92 }
93 
109 int verify_player(const char *name, char *password) {
110  char buf[MAX_BUF];
111  FILE *fp;
112 
113  if (strpbrk(name, "/.\\") != NULL) {
114  LOG(llevError, "Username contains illegal characters: %s\n", name);
115  return 1;
116  }
117 
118  snprintf(buf, sizeof(buf), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name);
119  if (strlen(buf) >= sizeof(buf)-1) {
120  LOG(llevError, "Username too long: %s\n", name);
121  return 1;
122  }
123 
124  fp = fopen(buf, "r");
125  if (fp == NULL)
126  return 1;
127 
128  /* Read in the file until we find the password line. Our logic could
129  * be a bit better on cleaning up the password from the file, but since
130  * it is written by the program, I think it is fair to assume that the
131  * syntax should be pretty standard.
132  */
133  while (fgets(buf, MAX_BUF-1, fp) != NULL) {
134  if (!strncmp(buf, "password ", 9)) {
135  buf[strlen(buf)-1] = 0; /* remove newline */
136  if (check_password(password, buf+9)) {
137  fclose(fp);
138  return 0;
139  }
140 
141  fclose(fp);
142  return 2;
143  }
144  }
145  LOG(llevDebug, "Could not find a password line in player %s\n", name);
146  fclose(fp);
147  return 1;
148 }
149 
162 int check_name(player *me, const char *name) {
163  if (*name == '\0') {
165  "Your username cannot be blank.");
166  return 0;
167  }
168 
169  if (!playername_ok(name)) {
171  "That name contains illegal characters. Use letters, hyphens and underscores only. Hyphens and underscores are not allowed as the first character.");
172  return 0;
173  }
174  if (strlen(name) >= MAX_NAME) {
176  "That name is too long. (Max length: %d characters)", MAX_NAME);
177  return 0;
178  }
179 
180  return 1;
181 }
182 
190 void destroy_object(object *op) {
191  while (op->inv != NULL)
192  destroy_object(op->inv);
193 
194  if (!QUERY_FLAG(op, FLAG_REMOVED))
195  object_remove(op);
197 }
198 
211 int save_player(object *op, int flag) {
212  FILE *fp;
213  OutputFile of;
214  char filename[MAX_BUF], *tmpfilename;
215  object *container = NULL;
216  player *pl = op->contr;
217  int i, wiz = QUERY_FLAG(op, FLAG_WIZ);
218  long checksum;
219 #ifdef BACKUP_SAVE_AT_HOME
220  int16_t backup_x, backup_y;
221 #endif
222 
223  if (!op->stats.exp)
224  return 0; /* no experience, no save */
225 
226  flag &= 1;
227 
228  if (!pl->name_changed || (!flag && !op->stats.exp)) {
229  if (!flag) {
231  "Your game is not valid, game not saved.");
232  }
233  return 0;
234  }
235 
236  /* Sanity check - some stuff changes this when player is exiting */
237  if (op->type != PLAYER)
238  return 0;
239 
240  /* Prevent accidental saves if connection is reset after player has
241  * mostly exited.
242  */
243  if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD)
244  return 0;
245 
246  if (flag == 0)
247  pets_terminate_all(op);
248 
249  /* Update information on this character. Only do it if it is eligible for
250  * for saving.
251  */
253  if (pl->socket.account_name) {
255  /* Add this character to the account. This really only comes up
256  * for new characters, at which time we want to wait until save -
257  * otherwise there is a good chance that character will be
258  * terminated.
259  */
262  }
263 
264 
265  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
266  make_path_to_file(filename);
267  fp = tempnam_secure(settings.tmpdir, NULL, &tmpfilename);
268  if (!fp) {
270  "Can't get secure temporary file for save.");
271  LOG(llevDebug, "Can't get secure temporary file for save.\n");
272  return 0;
273  }
274 
275  /* Eneq(@csd.uu.se): If we have an open container hide it. */
276  if (op->container) {
277  container = op->container;
278  op->container = NULL;
279  }
280 
281  fprintf(fp, "password %s\n", pl->password);
282  if (settings.set_title == TRUE)
283  if (player_has_own_title(pl))
284  fprintf(fp, "title %s\n", player_get_own_title(pl));
285 
286  fprintf(fp, "gen_hp %d\n", pl->gen_hp);
287  fprintf(fp, "gen_sp %d\n", pl->gen_sp);
288  fprintf(fp, "gen_grace %d\n", pl->gen_grace);
289  fprintf(fp, "listening %d\n", pl->listening);
290  fprintf(fp, "shoottype %d\n", pl->shoottype);
291  fprintf(fp, "bowtype %d\n", pl->bowtype);
292  fprintf(fp, "petmode %d\n", pl->petmode);
293  fprintf(fp, "peaceful %d\n", pl->peaceful);
294  fprintf(fp, "no_shout %d\n", pl->no_shout);
295  fprintf(fp, "digestion %d\n", pl->digestion);
296  fprintf(fp, "pickup %u\n", pl->mode);
297  /*
298  * outputs_sync and outputs_count are now unused in favor of the facility
299  * being supported on the client instead of in the server, but for now,
300  * set sane values in case an older server is run on a new player file.
301  * Once the server is officially 2.x, this should likely be removed.
302  */
303  fprintf(fp, "outputs_sync %d\n", 16);
304  fprintf(fp, "outputs_count %d\n", 1);
305  /* Match the enumerations but in string form */
306  fprintf(fp, "usekeys %s\n", pl->usekeys == key_inventory ? "key_inventory" : (pl->usekeys == keyrings ? "keyrings" : "containers"));
307  /* Match the enumerations but in string form */
308  fprintf(fp, "unapply %s\n", pl->unapply == unapply_nochoice ? "unapply_nochoice" : (pl->unapply == unapply_never ? "unapply_never" : "unapply_always"));
309  if (pl->unarmed_skill) fprintf(fp, "unarmed_skill %s\n", pl->unarmed_skill);
310 
311 #ifdef BACKUP_SAVE_AT_HOME
312  if (op->map != NULL && flag == 0)
313 #else
314  if (op->map != NULL)
315 #endif
316  fprintf(fp, "map %s\n", op->map->path);
317  else
318  fprintf(fp, "map %s\n", settings.emergency_mapname);
319 
320  fprintf(fp, "savebed_map %s\n", pl->savebed_map);
321  fprintf(fp, "bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y);
322  fprintf(fp, "Str %d\n", pl->orig_stats.Str);
323  fprintf(fp, "Dex %d\n", pl->orig_stats.Dex);
324  fprintf(fp, "Con %d\n", pl->orig_stats.Con);
325  fprintf(fp, "Int %d\n", pl->orig_stats.Int);
326  fprintf(fp, "Pow %d\n", pl->orig_stats.Pow);
327  fprintf(fp, "Wis %d\n", pl->orig_stats.Wis);
328  fprintf(fp, "Cha %d\n", pl->orig_stats.Cha);
329 
330  fprintf(fp, "lev_array %d\n", MIN(op->level, 10));
331  for (i = 1; i <= MIN(op->level, 10) && i <= 10; i++) {
332  fprintf(fp, "%d\n", pl->levhp[i]);
333  fprintf(fp, "%d\n", pl->levsp[i]);
334  fprintf(fp, "%d\n", pl->levgrace[i]);
335  }
336  fprintf(fp, "party_rejoin_mode %d\n", pl->rejoin_party);
337  if (pl->party != NULL) {
338  fprintf(fp, "party_rejoin_name %s\n", pl->party->partyname);
339  fprintf(fp, "party_rejoin_password %s\n", party_get_password(pl->party));
340  }
341  fprintf(fp, "language %s\n", i18n_get_language_code(pl->language));
342  fprintf(fp, "ticks_played %u\n", pl->ticks_played);
343  fprintf(fp, "endplst\n");
344 
346  CLEAR_FLAG(op, FLAG_WIZ);
347 #ifdef BACKUP_SAVE_AT_HOME
348  if (flag) {
349  backup_x = op->x;
350  backup_y = op->y;
351  op->x = -1;
352  op->y = -1;
353  }
354  /* Save objects, but not unpaid objects. Don't remove objects from
355  * inventory.
356  */
357  i = save_object(fp, op, SAVE_FLAG_NO_REMOVE);
358  if (flag) {
359  op->x = backup_x;
360  op->y = backup_y;
361  }
362 #else
363  i = save_object(fp, op, SAVE_FLAG_SAVE_UNPAID|SAVE_FLAG_NO_REMOVE); /* don't check and don't remove */
364 #endif
365 
366  if (wiz)
367  SET_FLAG(op, FLAG_WIZ);
368 
369  if (fclose(fp) != 0 || i != SAVE_ERROR_OK) { /* make sure the write succeeded */
371  "Can't save character!");
372  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);
373  unlink(tmpfilename);
374  free(tmpfilename);
375  return 0;
376  }
377 
379 
380  if (!flag) {
381  while (op->inv != NULL)
382  destroy_object(op->inv);
383 
384  /* destroying objects will most likely destroy the pointer
385  * in op->contr->ranges[], so clear the range to a safe value.
386  */
387  op->contr->shoottype = range_none;
388  }
389 
390  checksum = 0;
391  fp = of_open(&of, filename);
392  if (fp == NULL) {
394  "Can't open file for save.");
395  unlink(tmpfilename);
396  free(tmpfilename);
397  return 0;
398  }
399  fprintf(fp, "checksum %lx\n", checksum);
400  copy_file(tmpfilename, fp);
401  unlink(tmpfilename);
402  free(tmpfilename);
403  if (!of_close(&of)) {
405  "Can't close file for save.");
406  return 0;
407  }
408 
409  /* Eneq(@csd.uu.se): Reveal the container if we have one. */
410  if (flag && container != NULL)
411  op->container = container;
412 
413  if (!flag)
414  esrv_send_inventory(op, op);
415 
416  if (chmod(filename, SAVE_MODE) != 0) {
417  LOG(llevError, "Could not set permissions on '%s'\n", filename);
418  }
419 
420  /* if this is the first player save, quest or knowledge states can be unsaved */
421  if (!op->contr->has_directory) {
422  op->contr->has_directory = 1;
425  }
426 
427  return 1;
428 }
429 
438 static void copy_file(const char *filename, FILE *fpout) {
439  FILE *fp;
440  char buf[MAX_BUF];
441 
442  fp = fopen(filename, "r");
443  if (fp == NULL) {
444  LOG(llevError, "copy_file failed to open \"%s\", player file(s) may be corrupt.\n", filename);
445  return;
446  }
447  while (fgets(buf, MAX_BUF, fp) != NULL)
448  fputs(buf, fpout);
449  fclose(fp);
450 }
451 
459 static void wrong_password(object *op) {
461  "\nA character with this name already exists. "
462  "Please choose another name, or make sure you entered your "
463  "password correctly.\n");
464 
465  FREE_AND_COPY(op->name, "noname");
466  FREE_AND_COPY(op->name_pl, "noname");
467 
468  op->contr->socket.password_fails++;
471  "You gave an incorrect password too many times, "
472  "you will now be dropped from the server.");
473 
474  LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n",
475  op->contr->socket.host);
476 
477  op->contr->socket.status = Ns_Dead; /* the socket loop should handle the rest for us */
478  } else
479  get_name(op);
480 }
481 
494 void check_login(object *op, int check_pass) {
495  FILE *fp;
496  char filename[MAX_BUF];
497  char buf[MAX_BUF], bufall[MAX_BUF];
498  int i, value;
499  uint32_t uvalue;
500  player *pl = op->contr, *pltmp;
501  int correct = 0;
502  time_t elapsed_save_time = 0;
503  struct stat statbuf;
504  char *party_name = NULL, party_password[9];
505 
506  strcpy(pl->maplevel, first_map_path);
507  party_password[0] = 0;
508 
509  /* Check if this matches a connected player, and if yes disconnect old / connect new. */
510  for (pltmp = first_player; pltmp != NULL; pltmp = pltmp->next) {
511  if (pltmp != pl && pltmp->ob->name != NULL && !strcmp(pltmp->ob->name, op->name)) {
512  if (!check_pass || check_password(pl->write_buf+1, pltmp->password)) {
513  /* We could try and be more clever and re-assign the existing
514  * object to the new player, etc. However, I'm concerned that
515  * there may be a lot of other state that still needs to be sent
516  * in that case (we can't make any assumptions on what the
517  * client knows, as maybe the client crashed), so treating it
518  * as just a normal login is the safest and easiest thing to do.
519  */
520 
521  pltmp->socket.status = Ns_Dead;
522 
523  save_player(pltmp->ob, 0);
524  leave(pltmp, 1);
525  final_free_player(pltmp);
526  break;
527  }
528  if (check_pass) {
529  wrong_password(op);
530  return;
531  }
532  }
533  }
534 
535  snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
536 
537  /* If no file, must be a new player, so lets get confirmation of
538  * the password. Return control to the higher level dispatch,
539  * since the rest of this just deals with loading of the file.
540  */
541  fp = fopen(filename, "r");
542  if (fp == NULL) {
543  confirm_password(op);
544  return;
545  }
546  if (fstat(fileno(fp), &statbuf)) {
547  LOG(llevError, "Unable to stat %s?\n", filename);
548  elapsed_save_time = 0;
549  } else {
550  elapsed_save_time = time(NULL)-statbuf.st_mtime;
551  if (elapsed_save_time < 0) {
552  LOG(llevError, "Player file %s was saved in the future? (%ld time)\n", filename, (long)elapsed_save_time);
553  elapsed_save_time = 0;
554  }
555  }
556 
557  if (fgets(bufall, MAX_BUF, fp) != NULL) {
558  if (!strncmp(bufall, "checksum ", 9)) {
559  (void)fgets(bufall, MAX_BUF, fp);
560  }
561  if (sscanf(bufall, "password %s\n", buf)) {
562  /* New password scheme: */
563  correct = check_password(pl->write_buf+1, buf);
564  if (!check_pass) {
565  /* We want to preserve the password. Normally,
566  * pl->password is filled in when user enters
567  * data in the password prompt, but with new login,
568  * there is no password prompt.
569  */
570  strncpy(pl->password, buf, 15);
571  pl->password[15] = 0;
572  }
573  }
574  /* Old password mode removed - I have no idea what it
575  * was, and the current password mechanism has been used
576  * for at least several years.
577  */
578  }
579  if (!correct && check_pass) {
580  wrong_password(op);
581  fclose(fp);
582  return;
583  }
584 
585 #ifdef SAVE_INTERVAL
586  pl->last_save_time = time(NULL);
587 #endif /* SAVE_INTERVAL */
588  pl->party = NULL;
589  if (settings.search_items == TRUE)
590  pl->search_str[0] = '\0';
591  pl->name_changed = 1;
592  pl->orig_stats.Str = 0;
593  pl->orig_stats.Dex = 0;
594  pl->orig_stats.Con = 0;
595  pl->orig_stats.Int = 0;
596  pl->orig_stats.Pow = 0;
597  pl->orig_stats.Wis = 0;
598  pl->orig_stats.Cha = 0;
599  strcpy(pl->savebed_map, first_map_path);
600  pl->bed_x = 0,
601  pl->bed_y = 0;
602  pl->spellparam[0] = '\0';
603 
604  /* Loop through the file, loading the rest of the values */
605  while (fgets(bufall, MAX_BUF, fp) != NULL) {
606  char *val_string, *p;
607 
608  sscanf(bufall, "%s %d\n", buf, &value);
609 
610  val_string = bufall + strlen(buf) +1;
611  p = strchr(val_string, '\n');
612  if (p != NULL)
613  *p = '\0';
614 
615  /* uvalue is an unsigned value. Since at least a
616  * couple different things want an usigned value, cleaner
617  * to just do it once here vs everyplace it may be needed.
618  */
619 
620  uvalue = strtoul(val_string, (char **)NULL, 10);
621 
622  if (!strcmp(buf, "endplst"))
623  break;
624  if (!strcmp(buf, "title") && settings.set_title == TRUE)
625  player_set_own_title(pl, val_string);
626  else if (!strcmp(buf, "unarmed_skill"))
627  pl->unarmed_skill = add_string(val_string);
628  else if (!strcmp(buf, "explore"))
629  ; /* ignore: explore mode has been removed */
630  else if (!strcmp(buf, "gen_hp"))
631  pl->gen_hp = value;
632  else if (!strcmp(buf, "shoottype"))
633  pl->shoottype = (rangetype)value;
634  else if (!strcmp(buf, "bowtype"))
635  pl->bowtype = (bowtype_t)value;
636  else if (!strcmp(buf, "petmode"))
637  pl->petmode = (petmode_t)value;
638  else if (!strcmp(buf, "gen_sp"))
639  pl->gen_sp = value;
640  else if (!strcmp(buf, "gen_grace"))
641  pl->gen_grace = value;
642  else if (!strcmp(buf, "listening"))
643  pl->listening = value;
644  else if (!strcmp(buf, "peaceful"))
645  pl->peaceful = value;
646  else if (!strcmp(buf, "no_shout"))
647  pl->no_shout = value;
648  else if (!strcmp(buf, "digestion"))
649  pl->digestion = value;
650  else if (!strcmp(buf, "pickup")) {
651  pl->mode = uvalue;
652  }
653  else if (!strcmp(buf, "map"))
654  snprintf(pl->maplevel, sizeof(pl->maplevel), "%s", val_string);
655  else if (!strcmp(buf, "savebed_map"))
656  snprintf(pl->savebed_map, sizeof(pl->savebed_map), "%s", val_string);
657  else if (!strcmp(buf, "bed_x"))
658  pl->bed_x = value;
659  else if (!strcmp(buf, "bed_y"))
660  pl->bed_y = value;
661  else if (!strcmp(buf, "Str"))
662  pl->orig_stats.Str = value;
663  else if (!strcmp(buf, "Dex"))
664  pl->orig_stats.Dex = value;
665  else if (!strcmp(buf, "Con"))
666  pl->orig_stats.Con = value;
667  else if (!strcmp(buf, "Int"))
668  pl->orig_stats.Int = value;
669  else if (!strcmp(buf, "Pow"))
670  pl->orig_stats.Pow = value;
671  else if (!strcmp(buf, "Wis"))
672  pl->orig_stats.Wis = value;
673  else if (!strcmp(buf, "Cha"))
674  pl->orig_stats.Cha = value;
675  else if (!strcmp(buf, "usekeys")) {
676  if (!strcmp(val_string, "key_inventory"))
677  pl->usekeys = key_inventory;
678  else if (!strcmp(val_string, "keyrings"))
679  pl->usekeys = keyrings;
680  else if (!strcmp(val_string, "containers"))
681  pl->usekeys = containers;
682  else
683  LOG(llevDebug, "load_player: got unknown usekeys type: %s\n", val_string);
684  } else if (!strcmp(buf, "unapply")) {
685  if (!strcmp(val_string, "unapply_nochoice"))
687  else if (!strcmp(val_string, "unapply_never"))
688  pl->unapply = unapply_never;
689  else if (!strcmp(val_string, "unapply_always"))
690  pl->unapply = unapply_always;
691  else
692  LOG(llevDebug, "load_player: got unknown unapply type: %s\n", val_string);
693  } else if (!strcmp(buf, "lev_array")) {
694  for (i = 1; i <= value; i++) {
695  int j;
696 
697  fscanf(fp, "%d\n", &j);
698  if (j < 3)
699  j = 3;
700  else if (j > 9)
701  j = 9;
702  pl->levhp[i] = j;
703  fscanf(fp, "%d\n", &j);
704  if (j < 2)
705  j = 2;
706  else if (j > 6)
707  j = 6;
708  pl->levsp[i] = j;
709  fscanf(fp, "%d\n", &j);
710  if (j < 1)
711  j = 1;
712  else if (j > 3)
713  j = 3;
714  pl->levgrace[i] = j;
715  }
716  } else if (!strcmp(buf, "party_rejoin_mode"))
717  pl->rejoin_party = (enum party_rejoin_mode)value;
718  else if (!strcmp(buf, "party_rejoin_name"))
719  party_name = strdup_local(val_string);
720  else if (!strcmp(buf, "party_rejoin_password")) {
721  strncpy(party_password, val_string, sizeof(party_password));
722  party_password[sizeof(party_password) - 1] = 0;
723  } else if (!strcmp(buf, "language")) {
724  pl->language = i18n_get_language_by_code(val_string);
725  }
726  else if (!strcmp(buf, "ticks_played")) {
727  pl->ticks_played = uvalue;
728  }
729  } /* End of loop loading the character file */
730 
731  /* on first login via account, this player does not exist anyplace -
732  * so don't remove them.
733  */
734  if (!QUERY_FLAG(op, FLAG_REMOVED))
735  object_remove(op);
736  op->speed = 0;
738  /*FIXME dangerous call, object_reset() should be used to init freshly allocated obj struct!*/
739  object_reset(op);
740  op->contr = pl;
741  pl->ob = op;
742  /* this loads the standard objects values. */
743  load_object(fp, op, LO_NEWFILE, 0);
744  fclose(fp);
745 
747 
748  strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1);
749  pl->title[sizeof(pl->title)-1] = '\0';
750 
751  /* If the map where the person was last saved does not exist,
752  * restart them on their home-savebed. This is good for when
753  * maps change between versions
754  * First, we check for partial path, then check to see if the full
755  * path (for unique player maps)
756  */
757  if (has_been_loaded(pl->maplevel) == NULL
758  && check_path(pl->maplevel, 1) == -1
759  && check_path(pl->maplevel, 0) == -1) {
760  strcpy(pl->maplevel, pl->savebed_map);
761  op->x = pl->bed_x,
762  op->y = pl->bed_y;
763  /* if the map was a shop, the player can have unpaid items, remove them. */
764  remove_unpaid_objects(op, NULL, 1);
765  }
766 
767  /* If player saved beyond some time ago, and the feature is
768  * enabled, put the player back on his savebed map.
769  */
770  if ((settings.reset_loc_time > 0) && (elapsed_save_time > settings.reset_loc_time)) {
771  strcpy(pl->maplevel, pl->savebed_map);
772  op->x = pl->bed_x, op->y = pl->bed_y;
773  /* if the map was a shop, the player can have unpaid items, remove them. */
774  remove_unpaid_objects(op, NULL, 1);
775  }
776 
777  /* make sure he's a player--needed because of class change. */
778  op->type = PLAYER;
780 
781  pl->name_changed = 1;
783 #ifdef AUTOSAVE
784  pl->last_save_tick = pticks;
785 #endif
786  op->carrying = object_sum_weight(op);
787 
788  link_player_skills(op);
789 
790  if (!legal_range(op, op->contr->shoottype))
791  op->contr->shoottype = range_none;
792 
793  /* if it's a dragon player, set the correct title here */
794  if (is_dragon_pl(op) && op->inv != NULL) {
795  object *abil, *skin;
796 
797  abil = object_find_by_type_and_arch_name(op, FORCE, "dragon_ability_force");
798  skin = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
799  set_dragon_name(op, abil, skin);
800  }
801 
803  "Welcome Back!");
806  "%s has entered the game.",
807  pl->ob->name);
808 
809  /* Lauwenmark : Here we handle the LOGIN global event */
811  op->contr->socket.update_look = 1;
812  /* If the player should be dead, call kill_player for them
813  * Only check for hp - if player lacks food, let the normal
814  * logic for that to take place. If player is permanently
815  * dead, and not using permadeath mode, the kill_player will
816  * set the play_again flag, so return.
817  */
818  if (op->stats.hp < 0) {
820  "Your character was dead last time you played.");
821  kill_player(op, NULL);
822  if (pl->state != ST_PLAYING)
823  return;
824  }
825  LOG(llevInfo, "login: %s from %s\n", op->name, op->contr->socket.host);
826 
827  /* Do this after checking for death - no reason sucking up bandwidth if
828  * the data isn't needed.
829  */
830  esrv_new_player(op->contr, op->weight+op->carrying);
831  /* Need to do these after esvr_new_player, as once the client
832  * sees that, it wipes any info it has about the player.
833  */
834  esrv_add_spells(op->contr, NULL);
835 
836  /* Need to call fix_object now - program modified so that it is not
837  * called during the load process (FLAG_NO_FIX_PLAYER set when
838  * saved)
839  * Moved ahead of the esrv functions, so proper weights will be
840  * sent to the client. Needs to be after esvr_add_spells, otherwise
841  * we'll try to update spells from fix_object.
842  */
843  fix_object(op);
844 
845  pl->has_directory = 1;
846 
847  esrv_send_inventory(op, op);
848  esrv_send_pickup(pl);
851 
853 
854  /* can_use_shield is a new flag. However, the can_use.. seems to largely come
855  * from the class, and not race. I don't see any way to get the class information
856  * to then update this. I don't think this will actually break anything - anyone
857  * that can use armour should be able to use a shield. What this may 'break'
858  * are features new characters get, eg, if someone starts up with a Q, they
859  * should be able to use a shield. However, old Q's won't get that advantage.
860  */
861  if (QUERY_FLAG(op, FLAG_USE_ARMOUR))
863 
864  /* Rejoin party if needed. */
865  if (pl->rejoin_party != party_rejoin_no && party_name != NULL) {
866  partylist *party;
867 
868  party = party_find(party_name);
869  if (!party && pl->rejoin_party == party_rejoin_always) {
870  party = party_form(op, party_name);
871  if (party)
872  party_set_password(party, party_password);
873  }
874  if (party && !pl->party && party_confirm_password(party, party_password)) {
875  party_join(op, party);
876  }
877 
878  if (pl->party)
879  snprintf(buf, MAX_BUF, "Rejoined party %s.", party->partyname);
880  else
881  snprintf(buf, MAX_BUF, "Couldn't rejoin party %s: %s.", party_name, party ? "invalid password." : "no such party.");
883  buf);
884  }
885  free(party_name);
886 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
int check_name(player *me, const char *name)
Ensure player&#39;s name is valid.
Definition: login.c:162
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
Will unapply whatever is necessary - this goes beyond no choice - if there are multiple ojbect of the...
Definition: player.h:65
int8_t Int
Definition: living.h:35
One player.
Definition: player.h:92
Use keys in inventory and active containers.
Definition: player.h:55
#define MSG_TYPE_ADMIN_LOGIN
login messages/errors
Definition: newclient.h:478
#define ST_GET_PARTY_PASSWORD
Player tried to join a password-protected party.
Definition: define.h:585
Spell-related defines: spellpath, subtypes, ...
int16_t gen_hp
Bonuses to regeneration speed of hp.
Definition: player.h:113
Information.
Definition: logger.h:12
void leave(player *pl, int draw_exit)
Player logs out, or was disconnected.
Definition: server.c:1180
#define SAVE_ERROR_OK
No error.
Definition: map.h:143
void delete_character(const char *name)
Totally deletes a character.
Definition: login.c:86
char * account_name
Name of the account logged in on this socket.
Definition: newserver.h:138
#define SET_FLAG(xyz, p)
Definition: define.h:223
int i18n_get_language_by_code(const char *code)
Find the identifier of a language from its code.
Definition: languages.c:110
#define NDI_ALL
Inform all players of this message.
Definition: newclient.h:246
int16_t bed_x
Definition: player.h:98
bool check_password(const char *typed, const char *crypted)
Hash a password and compare it to the stored version.
Definition: server.c:100
char title[BIG_NAME]
Default title, like fighter, wizard, etc.
Definition: player.h:165
void make_path_to_file(const char *filename)
Checks if any directories in the given path doesn&#39;t exist, and creates if necessary.
Definition: porting.c:312
char spellparam[MAX_BUF]
What param to add to spells.
Definition: player.h:100
uint32_t name_changed
If true, the player has set a name.
Definition: player.h:130
#define FLAG_USE_ARMOUR
(Monster) can wear armour/shield/helmet
Definition: define.h:296
#define strdup_local
Definition: compat.h:25
void check_login(object *op, int check_pass)
Actually login a player, load from disk and such.
Definition: login.c:494
void remove_directory(const char *path)
This function removes everything in the directory, and the directory itself.
Definition: porting.c:154
One party.
Definition: party.h:10
struct obj * container
Current container being used.
Definition: object.h:291
#define EVENT_LOGIN
Player login.
Definition: plugin.h:88
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
uint32_t has_directory
If 0, the player was not yet saved, its directory doesn&#39;t exist.
Definition: player.h:134
No range selected.
Definition: player.h:17
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.c:561
void party_set_password(partylist *party, const char *password)
Sets a party&#39;s password.
Definition: party.c:275
int save_player(object *op, int flag)
Saves a player to disk.
Definition: login.c:211
int16_t gen_grace
Bonuses to regeneration speed of grace.
Definition: player.h:116
#define FLAG_NO_FIX_PLAYER
fix_object() won&#39;t be called
Definition: define.h:277
const char * playerdir
Where the player files are.
Definition: global.h:246
signed long object_sum_weight(object *op)
object_sum_weight() is a recursive function which calculates the weight an object is carrying...
Definition: object.c:311
void enter_player_maplevel(object *op)
Move a player to its stored map level.
Definition: server.c:651
uint32_t pticks
?
Definition: time.c:45
int8_t levsp[11]
What sp bonus the player gained on that level.
Definition: player.h:168
object clone
An object from which to do object_copy()
Definition: object.h:470
socket_struct socket
Socket information for this player.
Definition: player.h:94
rangetype shoottype
Which range-attack is being used by player.
Definition: player.h:99
void esrv_send_inventory(object *pl, object *op)
Sends inventory of a container.
Definition: item.c:307
const char * party_get_password(const partylist *party)
Returns the party&#39;s password.
Definition: party.c:263
int64_t exp
Experience.
Definition: living.h:46
#define MSG_TYPE_ADMIN_LOADSAVE
load/save operations
Definition: newclient.h:477
int language
The language the player wishes to use.
Definition: player.h:201
enum Sock_Status status
Definition: newserver.h:100
#define TRUE
Definition: compat.h:10
int legal_range(object *op, int r)
Check for the validity of a player range.
Definition: c_range.c:264
Use keys in inventory and active key rings.
Definition: player.h:54
Global type definitions and header inclusions.
char * partyname
Party name.
Definition: party.h:14
void pets_terminate_all(object *owner)
Removes all pets someone owns.
Definition: pets.c:231
Will not unapply objects automatically.
Definition: player.h:64
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
#define ST_PLAYING
Usual state.
Definition: define.h:577
char savebed_map[MAX_BUF]
Map where player will respawn after death.
Definition: player.h:97
#define NDI_DK_ORANGE
DarkOrange2.
Definition: newclient.h:227
#define MAX_PASSWORD_FAILURES
How many times we are allowed to give the wrong password before being kicked.
Definition: newserver.h:94
char * host
Which host it is connected from (ip address).
Definition: newserver.h:110
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&#39;s ...
Definition: request.c:1738
#define MIN(x, y)
Definition: compat.h:17
int8_t Con
Definition: living.h:35
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
int16_t hp
Hit Points.
Definition: living.h:39
static void wrong_password(object *op)
Simple function to print errors when password is not correct, and reinitialise the name...
Definition: login.c:459
partylist * party
Party this player is part of.
Definition: player.h:186
void get_name(object *op)
Waiting for the player&#39;s name.
Definition: player.c:854
uint32_t no_shout
if True, player is *not *able to use shout command.
Definition: player.h:133
uint32_t ticks_played
How many ticks this player has played.
Definition: player.h:203
const char * player_get_own_title(const struct pl *pl)
Returns the player&#39;s own title.
Definition: player.c:252
int player_has_own_title(const struct pl *pl)
Returns whether the player has a custom title.
Definition: player.c:239
#define SAVE_FLAG_SAVE_UNPAID
If set, unpaid items will be saved.
Definition: map.h:110
uint32_t update_look
If true, we need to send the look window.
Definition: newserver.h:115
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
party_rejoin_mode
Whether to rejoin party at login or not.
Definition: player.h:85
int16_t y
Position in the map for this object.
Definition: object.h:326
void esrv_new_player(player *pl, uint32_t weight)
Tells the client that here is a player it should start using.
Definition: request.c:856
#define NDI_RED
Definition: newclient.h:224
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:379
void kill_player(object *op, const object *killer)
Handle a player&#39;s death.
Definition: player.c:3465
Account_Char * account_chars
Detailed information on characters on this account.
Definition: newserver.h:139
const char * name_pl
The plural name of the object.
Definition: object.h:315
void player_set_own_title(struct pl *pl, const char *title)
Sets the custom title.
Definition: player.c:264
unapplymode unapply
Method for auto unapply.
Definition: player.h:108
int16_t gen_sp
Bonuses to regeneration speed of sp.
Definition: player.h:114
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:510
If party doesn&#39;t exist, form it.
Definition: player.h:88
Defines for loader.l / loader.c.
signed short int16_t
Definition: win32.h:160
uint8_t search_items
Search_items command.
Definition: global.h:265
enum _petmode petmode_t
Petmode.
#define LO_NEWFILE
Definition: loader.h:17
int32_t weight
Attributes of the object.
Definition: object.h:365
#define NDI_ALL_DMS
Inform all logged in DMs.
Definition: newclient.h:247
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:253
int8_t Wis
Definition: living.h:35
#define FLAG_USE_SHIELD
Can this creature use a shield?
Definition: define.h:237
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
Definition: newclient.h:474
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
int is_dragon_pl(const object *op)
Checks if player is a dragon.
Definition: player.c:114
char search_str[MAX_BUF]
Item we are looking for.
Definition: player.h:192
#define snprintf
Definition: win32.h:46
void player_set_state(player *pl, uint8_t state)
Set the player&#39;s state to the specified one.
Definition: player.c:4457
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.c:108
int of_close(OutputFile *of)
Closes an output file.
Definition: output_file.c:61
int32_t carrying
How much weight this object contains.
Definition: object.h:367
const char * name
The name of the object, obviously...
Definition: object.h:311
int16_t bed_y
x,y - coordinates of respawn (savebed).
Definition: player.h:98
living orig_stats
Permanent real stats of player.
Definition: player.h:148
int save_object(FILE *fp, object *op, int flag)
Dumps all variables in an object to a file.
Definition: object.c:5186
int execute_global_event(int eventcode,...)
Definition: main.c:369
uint8_t state
Input state of the player (name, password, etc).
Definition: player.h:118
void object_reset(object *op)
Sets to 0 vital variables in an object.
Definition: object.c:704
uint8_t listening
Which priority will be used in info_all.
Definition: player.h:120
void confirm_password(object *op)
Ask the player to confirm her password during creation.
Definition: player.c:980
int8_t Cha
Definition: living.h:35
void hiscore_check(object *op, int quiet)
Checks if player should enter the hiscore, and if so writes her into the list.
Definition: hiscore.c:302
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
partylist * party_find(const char *partyname)
Find a party by name.
Definition: party.c:147
Don&#39;t rejoin.
Definition: player.h:86
float speed
The overall speed of this object.
Definition: object.h:328
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
party_rejoin_mode rejoin_party
Whether to rejoin or not party at login.
Definition: player.h:191
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:231
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
#define MSG_TYPE_ADMIN
Definition: newclient.h:377
uint32_t peaceful
If set, won&#39;t attack friendly creatures.
Definition: player.h:131
enum _bowtype bowtype_t
Bow firing mode.
int16_t x
Definition: object.h:326
void quest_send_initial_states(player *pl)
Send the current quest states for the specified player, if the client supports those notifications...
Definition: quest.c:1346
void knowledge_first_player_save(player *pl)
Ensure the knowledge state is correctly saved for the player.
Definition: knowledge.c:1431
int8_t levhp[11]
What hp bonus the player gained on that level.
Definition: player.h:167
int8_t Str
Definition: living.h:35
#define SAVE_FLAG_NO_REMOVE
If set, objects are not removed while saving.
Definition: map.h:111
Account_Char * account_char_add(Account_Char *chars, player *pl)
This adds a player to the list of accounts.
Definition: account_char.c:192
object * ob
The object representing the player.
Definition: player.h:158
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.c:3221
unsigned int uint32_t
Definition: win32.h:162
See Player.
Definition: object.h:107
uint8_t password_fails
How many times the player has failed to give the right password.
Definition: newserver.h:112
bowtype_t bowtype
Which firemode?
Definition: player.h:101
void knowledge_send_known(player *pl)
Send initial known knowledge to player, if requested.
Definition: knowledge.c:1411
int account_link(const char *account_name, const char *player_name)
Adds a player name to an account.
Definition: account.c:460
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
Definition: global.h:213
const char * localdir
Read/write data files.
Definition: global.h:245
char password[16]
2 (seed) + 11 (crypted) + 1 (EOS) + 2 (safety) = 16
Definition: player.h:176
living stats
Str, Con, Dex, etc.
Definition: object.h:368
int load_object(FILE *fp, object *op, int bufstate, int map_flags)
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.c:79
int8_t Dex
Definition: living.h:35
struct archt * arch
Pointer to archetype.
Definition: object.h:412
sstring i18n_get_language_code(int language)
Return the code of a specified language.
Definition: languages.c:122
Only for debugging purposes.
Definition: logger.h:13
void account_char_save(const char *account, Account_Char *chars)
Saves the character information for the given account.
Definition: account_char.c:145
#define unlink(__a)
Definition: win32.h:56
void quest_first_player_save(player *pl)
Ensure the quest state is correctly saved for a player.
Definition: quest.c:1407
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
uint32_t mode
Mode of player for pickup.
Definition: player.h:110
struct Settings settings
Server settings.
Definition: init.c:40
int verify_player(const char *name, char *password)
This verify that a character of name exits, and that it matches password.
Definition: login.c:109
EXTERN long trying_emergency_save
True when emergency_save() is reached.
Definition: global.h:135
FILE * of_open(OutputFile *of, const char *fname)
Opens an output file.
Definition: output_file.c:30
#define SAVE_MODE
If you have defined SAVE_PLAYER, you might want to change this, too.
Definition: config.h:616
rangetype
What range is currently selected by the player.
Definition: player.h:15
void party_join(object *op, partylist *party)
Makes a player join a party.
Definition: party.c:84
Functions for creating text output files.
EXTERN char first_map_path[MAX_BUF]
The start-level.
Definition: global.h:153
void destroy_object(object *op)
Recursively object_free_drop_inventory() op and its inventory.
Definition: login.c:190
int party_confirm_password(const partylist *party, const char *password)
Checks whether a given password matches the party&#39;s password.
Definition: party.c:290
void emergency_save(int flag)
Save all players.
Definition: login.c:40
sstring add_string(const char *str)
This will add &#39;str&#39; to the hash table.
Definition: shstr.c:124
EXTERN player * first_player
First player.
Definition: global.h:117
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: skill_util.c:112
int playername_ok(const char *cp)
Is the player name valid.
Definition: player.c:252
struct pl * next
Pointer to next player, NULL if this is last.
Definition: player.h:93
int check_path(const char *name, int prepend_dir)
This function checks if a file with the given path exists.
Definition: map.c:203
int reset_loc_time
Number of seconds to put player back at home.
Definition: global.h:262
void esrv_send_pickup(player *pl)
Sends the "pickup" state to pl if client wants it requested.
Definition: request.c:1625
Will unapply objects when there no choice to unapply.
Definition: player.h:63
int8_t Pow
Definition: living.h:35
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
petmode_t petmode
Which petmode?
Definition: player.h:102
uint8_t set_title
Players can set thier title.
Definition: global.h:263
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
void final_free_player(player *pl)
Sends the &#39;goodbye&#39; command to the player, and closes connection.
Definition: init.c:444
char maplevel[MAX_BUF]
On which level is the player?
Definition: player.h:96
usekeytype usekeys
Method for finding keys for doors.
Definition: player.h:107
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
#define MAX_NAME
Definition: define.h:41
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.c:1629
Only use keys in inventory.
Definition: player.h:53
char * emergency_mapname
Map to return players to in emergency.
Definition: global.h:297
partylist * party_form(object *op, const char *partyname)
Forms the party struct for a party called &#39;partyname&#39;.
Definition: party.c:40
char write_buf[MAX_BUF]
Holds arbitrary input from client.
Definition: player.h:174
int8_t levgrace[11]
What grace bonus the player gained on that level.
Definition: player.h:169
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.c:4168
const char * unarmed_skill
Prefered skill to use in unarmed combat.
Definition: player.h:202
int16_t level
Level of creature or object.
Definition: object.h:351
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.c:1120
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
int16_t digestion
Any bonuses/penalties to digestion.
Definition: player.h:112
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.c:1654
static void copy_file(const char *filename, FILE *fpout)
Copy a file.
Definition: login.c:438
Core defines: object types, flags, etc.
Definition: object.h:224