00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <global.h>
00035 #ifndef __CEXTRACT__
00036 #include <sproto.h>
00037 #endif
00038 #include <spells.h>
00039 #include <loader.h>
00040 #include <define.h>
00041
00042 static void copy_file(const char *filename, FILE *fpout);
00043
00051 void emergency_save(int flag) {
00052 #ifndef NO_EMERGENCY_SAVE
00053 player *pl;
00054
00055 trying_emergency_save = 1;
00056 LOG(llevError, "Emergency save: ");
00057 for (pl = first_player; pl != NULL; pl = pl->next) {
00058 if (!pl->ob) {
00059 LOG(llevError, "No name, ignoring this.\n");
00060 continue;
00061 }
00062 LOG(llevError, "%s ", pl->ob->name);
00063 draw_ext_info(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00064 "Emergency save...", NULL);
00065
00066
00067
00068
00069
00070 if (!flag) {
00071 strcpy(pl->maplevel, first_map_path);
00072 if (pl->ob->map != NULL)
00073 pl->ob->map = NULL;
00074 pl->ob->x = -1;
00075 pl->ob->y = -1;
00076 }
00077 if (!save_player(pl->ob, flag)) {
00078 LOG(llevError, "(failed) ");
00079 draw_ext_info(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00080 "Emergency save failed, checking score...", NULL);
00081 }
00082 check_score(pl->ob, 1);
00083 }
00084 LOG(llevError, "\n");
00085 #else
00086 LOG(llevInfo, "Emergency saves disabled, no save attempted\n");
00087 #endif
00088 }
00089
00097 void delete_character(const char *name) {
00098 char buf[MAX_BUF];
00099
00100 snprintf(buf, sizeof(buf), "%s/%s/%s", settings.localdir, settings.playerdir, name);
00101
00102 remove_directory(buf);
00103 }
00104
00120 int verify_player(const char *name, char *password) {
00121 char buf[MAX_BUF];
00122 int comp;
00123 FILE *fp;
00124
00125 if (strpbrk(name, "/.\\") != NULL) {
00126 LOG(llevError, "Username contains illegal characters: %s\n", name);
00127 return 1;
00128 }
00129
00130 snprintf(buf, sizeof(buf), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, name, name);
00131 if (strlen(buf) >= sizeof(buf)-1) {
00132 LOG(llevError, "Username too long: %s\n", name);
00133 return 1;
00134 }
00135
00136 if ((fp = open_and_uncompress(buf, 0, &comp)) == NULL)
00137 return 1;
00138
00139
00140
00141
00142
00143
00144 while (fgets(buf, MAX_BUF-1, fp) != NULL) {
00145 if (!strncmp(buf, "password ", 9)) {
00146 buf[strlen(buf)-1] = 0;
00147 if (check_password(password, buf+9)) {
00148 close_and_delete(fp, comp);
00149 return 0;
00150 } else {
00151 close_and_delete(fp, comp);
00152 return 2;
00153 }
00154 }
00155 }
00156 LOG(llevDebug, "Could not find a password line in player %s\n", name);
00157 close_and_delete(fp, comp);
00158 return 1;
00159 }
00160
00173 int check_name(player *me, const char *name) {
00174 if (*name == '\0') {
00175 draw_ext_info(NDI_UNIQUE, 0, me->ob, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00176 "Your username cannot be blank.", NULL);
00177 return 0;
00178 }
00179
00180 if (!playername_ok(name)) {
00181 draw_ext_info(NDI_UNIQUE, 0, me->ob, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00182 "That name contains illegal characters. Use letters, hyphens and underscores only. Hyphens and underscores are not allowed as the first character.", NULL);
00183 return 0;
00184 }
00185 if (strlen(name) >= MAX_NAME) {
00186 draw_ext_info_format(NDI_UNIQUE, 0, me->ob, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00187 "That name is too long. (Max length: %d characters)", NULL, MAX_NAME);
00188 return 0;
00189 }
00190
00191 return 1;
00192 }
00193
00201 void destroy_object(object *op) {
00202 object *tmp;
00203 while ((tmp = op->inv))
00204 destroy_object(tmp);
00205
00206 if (!QUERY_FLAG(op, FLAG_REMOVED))
00207 remove_ob(op);
00208 free_object(op);
00209 }
00210
00223 int save_player(object *op, int flag) {
00224 FILE *fp;
00225 char filename[MAX_BUF], *tmpfilename, backupfile[MAX_BUF];
00226 object *tmp, *container = NULL;
00227 player *pl = op->contr;
00228 int i, wiz = QUERY_FLAG(op, FLAG_WIZ);
00229 long checksum;
00230 #ifdef BACKUP_SAVE_AT_HOME
00231 sint16 backup_x, backup_y;
00232 #endif
00233
00234 if (!op->stats.exp)
00235 return 0;
00236
00237 flag &= 1;
00238
00239 if (!pl->name_changed||(!flag&&!op->stats.exp)) {
00240 if (!flag) {
00241 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00242 "Your game is not valid, game not saved.", NULL);
00243 }
00244 return 0;
00245 }
00246
00247
00248 if (op->type != PLAYER)
00249 return 0;
00250
00251
00252
00253
00254 if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD)
00255 return 0;
00256
00257 if (flag == 0)
00258 terminate_all_pets(op);
00259
00260 snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
00261 make_path_to_file(filename);
00262 fp = tempnam_secure(settings.tmpdir, NULL, &tmpfilename);
00263 if (!fp) {
00264 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00265 "Can't get secure temporary file for save.", NULL);
00266 LOG(llevDebug, "Can't get secure temporary file for save.\n");
00267 return 0;
00268 }
00269
00270
00271 if (op->container) {
00272 container = op->container;
00273 op->container = NULL;
00274 }
00275
00276 fprintf(fp, "password %s\n", pl->password);
00277 if (settings.set_title == TRUE)
00278 if (pl->own_title[0] != '\0')
00279 fprintf(fp, "title %s\n", pl->own_title);
00280
00281 fprintf(fp, "explore %d\n", pl->explore);
00282 fprintf(fp, "gen_hp %d\n", pl->gen_hp);
00283 fprintf(fp, "gen_sp %d\n", pl->gen_sp);
00284 fprintf(fp, "gen_grace %d\n", pl->gen_grace);
00285 fprintf(fp, "listening %d\n", pl->listening);
00286 fprintf(fp, "shoottype %d\n", pl->shoottype);
00287 fprintf(fp, "bowtype %d\n", pl->bowtype);
00288 fprintf(fp, "petmode %d\n", pl->petmode);
00289 fprintf(fp, "peaceful %d\n", pl->peaceful);
00290 fprintf(fp, "no_shout %d\n", pl->no_shout);
00291 fprintf(fp, "digestion %d\n", pl->digestion);
00292 fprintf(fp, "pickup %u\n", pl->mode);
00293 fprintf(fp, "outputs_sync %d\n", pl->outputs_sync);
00294 fprintf(fp, "outputs_count %d\n", pl->outputs_count);
00295
00296 fprintf(fp, "usekeys %s\n", pl->usekeys == key_inventory ? "key_inventory" : (pl->usekeys == keyrings ? "keyrings" : "containers"));
00297
00298 fprintf(fp, "unapply %s\n", pl->unapply == unapply_nochoice ? "unapply_nochoice" : (pl->unapply == unapply_never ? "unapply_never" : "unapply_always"));
00299
00300 #ifdef BACKUP_SAVE_AT_HOME
00301 if (op->map != NULL && flag == 0)
00302 #else
00303 if (op->map != NULL)
00304 #endif
00305 fprintf(fp, "map %s\n", op->map->path);
00306 else
00307 fprintf(fp, "map %s\n", settings.emergency_mapname);
00308
00309 fprintf(fp, "savebed_map %s\n", pl->savebed_map);
00310 fprintf(fp, "bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y);
00311 fprintf(fp, "weapon_sp %f\n", pl->weapon_sp);
00312 fprintf(fp, "Str %d\n", pl->orig_stats.Str);
00313 fprintf(fp, "Dex %d\n", pl->orig_stats.Dex);
00314 fprintf(fp, "Con %d\n", pl->orig_stats.Con);
00315 fprintf(fp, "Int %d\n", pl->orig_stats.Int);
00316 fprintf(fp, "Pow %d\n", pl->orig_stats.Pow);
00317 fprintf(fp, "Wis %d\n", pl->orig_stats.Wis);
00318 fprintf(fp, "Cha %d\n", pl->orig_stats.Cha);
00319
00320 fprintf(fp, "lev_array %d\n", MIN(op->level, 10));
00321 for (i = 1; i <= pl->last_level && i <= 10; i++) {
00322 fprintf(fp, "%d\n", pl->levhp[i]);
00323 fprintf(fp, "%d\n", pl->levsp[i]);
00324 fprintf(fp, "%d\n", pl->levgrace[i]);
00325 }
00326 fprintf(fp, "party_rejoin_mode %d\n", pl->rejoin_party);
00327 if (pl->party != NULL) {
00328 fprintf(fp, "party_rejoin_name %s\n", pl->party->partyname);
00329 fprintf(fp, "party_rejoin_password %s\n", pl->party->passwd);
00330 }
00331 fprintf(fp, "language %d\n", pl->language);
00332 fprintf(fp, "endplst\n");
00333
00334 SET_FLAG(op, FLAG_NO_FIX_PLAYER);
00335 CLEAR_FLAG(op, FLAG_WIZ);
00336 #ifdef BACKUP_SAVE_AT_HOME
00337 if (flag) {
00338 backup_x = op->x;
00339 backup_y = op->y;
00340 op->x = -1;
00341 op->y = -1;
00342 }
00343
00344
00345
00346 i = save_object(fp, op, SAVE_FLAG_NO_REMOVE);
00347 if (flag) {
00348 op->x = backup_x;
00349 op->y = backup_y;
00350 }
00351 #else
00352 i = save_object(fp, op, SAVE_FLAG_SAVE_UNPAID|SAVE_FLAG_NO_REMOVE);
00353 #endif
00354
00355 if (wiz)
00356 SET_FLAG(op, FLAG_WIZ);
00357
00358 if (fclose(fp) != 0 || i != SAVE_ERROR_OK) {
00359 draw_ext_info(NDI_UNIQUE|NDI_RED, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00360 "Can't save character!", NULL);
00361 draw_ext_info_format(NDI_ALL_DMS|NDI_RED, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE, "Save failure for player %s!", NULL, op->name);
00362 unlink(tmpfilename);
00363 free(tmpfilename);
00364 return 0;
00365 }
00366
00367 CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
00368
00369 if (!flag) {
00370 while ((tmp = op->inv))
00371 destroy_object(tmp);
00372
00373
00374
00375
00376 op->contr->shoottype = range_none;
00377 }
00378
00379 checksum = 0;
00380 snprintf(backupfile, sizeof(backupfile), "%s.tmp", filename);
00381 rename(filename, backupfile);
00382 fp = fopen(filename, "w");
00383 if (!fp) {
00384 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00385 "Can't open file for save.", NULL);
00386 unlink(tmpfilename);
00387 free(tmpfilename);
00388 return 0;
00389 }
00390 fprintf(fp, "checksum %lx\n", checksum);
00391 copy_file(tmpfilename, fp);
00392 unlink(tmpfilename);
00393 free(tmpfilename);
00394 if (fclose(fp) == EOF) {
00395 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE,
00396 "Can't close file for save.", NULL);
00397 rename(backupfile, filename);
00398 return 0;
00399 } else
00400 unlink(backupfile);
00401
00402
00403 if (flag && container != NULL)
00404 op->container = container;
00405
00406 if (!flag)
00407 esrv_send_inventory(op, op);
00408
00409 chmod(filename, SAVE_MODE);
00410 return 1;
00411 }
00412
00421 static void copy_file(const char *filename, FILE *fpout) {
00422 FILE *fp;
00423 char buf[MAX_BUF];
00424
00425 if ((fp = fopen(filename, "r")) == NULL) {
00426 LOG(llevError, "copy_file failed to open \"%s\", player file(s) may be corrupt.\n", filename);
00427 return;
00428 }
00429 while (fgets(buf, MAX_BUF, fp) != NULL)
00430 fputs(buf, fpout);
00431 fclose(fp);
00432 }
00433
00441 static void wrong_password(object *op) {
00442 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00443 "\nA character with this name already exists. "
00444 "Please choose another name, or make sure you entered your "
00445 "password correctly.\n",
00446 NULL);
00447
00448 FREE_AND_COPY(op->name, "noname");
00449 FREE_AND_COPY(op->name_pl, "noname");
00450
00451 op->contr->socket.password_fails++;
00452 if (op->contr->socket.password_fails >= MAX_PASSWORD_FAILURES) {
00453 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00454 "You gave an incorrect password too many times, "
00455 "you will now be dropped from the server.",
00456 NULL);
00457
00458 LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n",
00459 op->contr->socket.host);
00460
00461 op->contr->socket.status = Ns_Dead;
00462 } else
00463 get_name(op);
00464 }
00465
00473 void check_login(object *op) {
00474 FILE *fp;
00475 char filename[MAX_BUF];
00476 char buf[MAX_BUF], bufall[MAX_BUF];
00477 int i, value, comp;
00478 long checksum = 0;
00479 player *pl = op->contr, *pltmp;
00480 int correct = 0;
00481 time_t elapsed_save_time = 0;
00482 struct stat statbuf;
00483 char *party_name = NULL, party_password[9];
00484
00485 strcpy(pl->maplevel, first_map_path);
00486 party_password[0] = 0;
00487
00488
00489 for (pltmp = first_player; pltmp != NULL; pltmp = pltmp->next) {
00490 if (pltmp != pl && pltmp->ob->name != NULL && !strcmp(pltmp->ob->name, op->name)) {
00491 if (check_password(pl->write_buf+1, pltmp->password)) {
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 pltmp->socket.status = Ns_Dead;
00502
00503 save_player(pltmp->ob, 0);
00504 if (!QUERY_FLAG(pltmp->ob, FLAG_REMOVED)) {
00505
00506
00507
00508 terminate_all_pets(pltmp->ob);
00509 remove_ob(pltmp->ob);
00510 }
00511 leave(pltmp, 1);
00512 final_free_player(pltmp);
00513 break;
00514 } else {
00515 wrong_password(op);
00516 return;
00517 }
00518 }
00519 }
00520
00521 snprintf(filename, sizeof(filename), "%s/%s/%s/%s.pl", settings.localdir, settings.playerdir, op->name, op->name);
00522
00523
00524
00525
00526
00527 if ((fp = open_and_uncompress(filename, 1, &comp)) == NULL) {
00528 confirm_password(op);
00529 return;
00530 }
00531 if (fstat(fileno(fp), &statbuf)) {
00532 LOG(llevError, "Unable to stat %s?\n", filename);
00533 elapsed_save_time = 0;
00534 } else {
00535 elapsed_save_time = time(NULL)-statbuf.st_mtime;
00536 if (elapsed_save_time < 0) {
00537 LOG(llevError, "Player file %s was saved in the future? (%d time)\n", filename, elapsed_save_time);
00538 elapsed_save_time = 0;
00539 }
00540 }
00541
00542 if (fgets(bufall, MAX_BUF, fp) != NULL) {
00543 if (!strncmp(bufall, "checksum ", 9)) {
00544 checksum = strtol(bufall+9, (char **)NULL, 16);
00545 (void)fgets(bufall, MAX_BUF, fp);
00546 }
00547 if (sscanf(bufall, "password %s\n", buf)) {
00548
00549 correct = check_password(pl->write_buf+1, buf);
00550 }
00551
00552
00553
00554
00555 }
00556 if (!correct) {
00557 wrong_password(op);
00558 fclose(fp);
00559 return;
00560 }
00561
00562 #ifdef SAVE_INTERVAL
00563 pl->last_save_time = time(NULL);
00564 #endif
00565 pl->party = NULL;
00566 if (settings.search_items == TRUE)
00567 pl->search_str[0] = '\0';
00568 pl->name_changed = 1;
00569 pl->orig_stats.Str = 0;
00570 pl->orig_stats.Dex = 0;
00571 pl->orig_stats.Con = 0;
00572 pl->orig_stats.Int = 0;
00573 pl->orig_stats.Pow = 0;
00574 pl->orig_stats.Wis = 0;
00575 pl->orig_stats.Cha = 0;
00576 strcpy(pl->savebed_map, first_map_path);
00577 pl->bed_x = 0,
00578 pl->bed_y = 0;
00579 pl->spellparam[0] = '\0';
00580
00581
00582 while (fgets(bufall, MAX_BUF, fp) != NULL) {
00583 sscanf(bufall, "%s %d\n", buf, &value);
00584 if (!strcmp(buf, "endplst"))
00585 break;
00586 else if (!strcmp(buf, "title") && settings.set_title == TRUE)
00587 sscanf(bufall, "title %[^\n]", pl->own_title);
00588 else if (!strcmp(buf, "explore"))
00589 pl->explore = value;
00590 else if (!strcmp(buf, "gen_hp"))
00591 pl->gen_hp = value;
00592 else if (!strcmp(buf, "shoottype"))
00593 pl->shoottype = (rangetype)value;
00594 else if (!strcmp(buf, "bowtype"))
00595 pl->bowtype = (bowtype_t)value;
00596 else if (!strcmp(buf, "petmode"))
00597 pl->petmode = (petmode_t)value;
00598 else if (!strcmp(buf, "gen_sp"))
00599 pl->gen_sp = value;
00600 else if (!strcmp(buf, "gen_grace"))
00601 pl->gen_grace = value;
00602 else if (!strcmp(buf, "listening"))
00603 pl->listening = value;
00604 else if (!strcmp(buf, "peaceful"))
00605 pl->peaceful = value;
00606 else if (!strcmp(buf, "no_shout"))
00607 pl->no_shout = value;
00608 else if (!strcmp(buf, "digestion"))
00609 pl->digestion = value;
00610 else if (!strcmp(buf, "pickup"))
00611 pl->mode = value;
00612 else if (!strcmp(buf, "outputs_sync"))
00613 pl->outputs_sync = value;
00614 else if (!strcmp(buf, "outputs_count"))
00615 pl->outputs_count = value;
00616 else if (!strcmp(buf, "map"))
00617 sscanf(bufall, "map %s", pl->maplevel);
00618 else if (!strcmp(buf, "savebed_map"))
00619 sscanf(bufall, "savebed_map %s", pl->savebed_map);
00620 else if (!strcmp(buf, "bed_x"))
00621 pl->bed_x = value;
00622 else if (!strcmp(buf, "bed_y"))
00623 pl->bed_y = value;
00624 else if (!strcmp(buf,"weapon_sp"))
00625 sscanf(buf, "weapon_sp %f", &pl->weapon_sp);
00626 else if (!strcmp(buf, "Str"))
00627 pl->orig_stats.Str = value;
00628 else if (!strcmp(buf, "Dex"))
00629 pl->orig_stats.Dex = value;
00630 else if (!strcmp(buf, "Con"))
00631 pl->orig_stats.Con = value;
00632 else if (!strcmp(buf, "Int"))
00633 pl->orig_stats.Int = value;
00634 else if (!strcmp(buf, "Pow"))
00635 pl->orig_stats.Pow = value;
00636 else if (!strcmp(buf, "Wis"))
00637 pl->orig_stats.Wis = value;
00638 else if (!strcmp(buf, "Cha"))
00639 pl->orig_stats.Cha = value;
00640 else if (!strcmp(buf, "usekeys")) {
00641 if (!strcmp(bufall+8, "key_inventory\n"))
00642 pl->usekeys = key_inventory;
00643 else if (!strcmp(bufall+8, "keyrings\n"))
00644 pl->usekeys = keyrings;
00645 else if (!strcmp(bufall+8, "containers\n"))
00646 pl->usekeys = containers;
00647 else
00648 LOG(llevDebug, "load_player: got unknown usekeys type: %s\n", bufall+8);
00649 } else if (!strcmp(buf, "unapply")) {
00650 if (!strcmp(bufall+8, "unapply_nochoice\n"))
00651 pl->unapply = unapply_nochoice;
00652 else if (!strcmp(bufall+8, "unapply_never\n"))
00653 pl->unapply = unapply_never;
00654 else if (!strcmp(bufall+8, "unapply_always\n"))
00655 pl->unapply = unapply_always;
00656 else
00657 LOG(llevDebug, "load_player: got unknown unapply type: %s\n", bufall+8);
00658 } else if (!strcmp(buf, "lev_array")) {
00659 for (i = 1; i <= value; i++) {
00660 int j;
00661
00662 fscanf(fp, "%d\n", &j);
00663 pl->levhp[i] = j;
00664 fscanf(fp, "%d\n", &j);
00665 pl->levsp[i] = j;
00666 fscanf(fp, "%d\n", &j);
00667 pl->levgrace[i] = j;
00668 }
00669 } else if (!strcmp(buf, "party_rejoin_mode")) {
00670 pl->rejoin_party = value;
00671 } else if (!strcmp(buf, "party_rejoin_name")) {
00672 party_name = strdup_local(bufall+strlen("party_rejoin_name")+1);
00673 if (party_name && strlen(party_name) > 0)
00674 party_name[strlen(party_name)-1] = '\0';
00675 } else if (!strcmp(buf, "party_rejoin_password")) {
00676 size_t len;
00677
00678 snprintf(party_password, sizeof(party_password), "%s", bufall+strlen("party_rejoin_password")+1);
00679 len = strlen(party_password);
00680
00681
00682
00683 if (len > 0 && len < 8)
00684 party_password[len-1] = '\0';
00685 } else if (!strcmp(buf, "language")) {
00686 if (value < 0 || value >= NUM_LANGUAGES)
00687 value = 0;
00688 pl->language = value;
00689 }
00690 }
00691 remove_ob(op);
00692 op->speed = 0;
00693 update_ob_speed(op);
00694
00695 reset_object(op);
00696 op->contr = pl;
00697 pl->ob = op;
00698
00699 load_object(fp, op, LO_NEWFILE, 0);
00700 close_and_delete(fp, comp);
00701
00702 CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
00703
00704 strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1);
00705 pl->title[sizeof(pl->title)-1] = '\0';
00706
00707
00708
00709
00710
00711
00712
00713 if (check_path(pl->maplevel, 1) == -1) {
00714 if (check_path(pl->maplevel, 0) == -1) {
00715 strcpy(pl->maplevel, pl->savebed_map);
00716 op->x = pl->bed_x,
00717 op->y = pl->bed_y;
00718
00719 remove_unpaid_objects(op, NULL, 1);
00720 }
00721 }
00722
00723
00724
00725
00726 if ((settings.reset_loc_time > 0) && (elapsed_save_time > settings.reset_loc_time)) {
00727 strcpy(pl->maplevel, pl->savebed_map);
00728 op->x = pl->bed_x, op->y = pl->bed_y;
00729
00730 remove_unpaid_objects(op, NULL, 1);
00731 }
00732
00733
00734 op->type = PLAYER;
00735
00736 enter_exit(op, NULL);
00737
00738 pl->name_changed = 1;
00739 pl->state = ST_PLAYING;
00740 #ifdef AUTOSAVE
00741 pl->last_save_tick = pticks;
00742 #endif
00743 op->carrying = sum_weight(op);
00744
00745 link_player_skills(op);
00746
00747 if (!legal_range(op, op->contr->shoottype))
00748 op->contr->shoottype = range_none;
00749
00750
00751 if (is_dragon_pl(op) && op->inv != NULL) {
00752 object *tmp, *abil = NULL, *skin = NULL;
00753
00754 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) {
00755 if (tmp->type == FORCE) {
00756 if (strcmp(tmp->arch->name, "dragon_ability_force") == 0)
00757 abil = tmp;
00758 else if (strcmp(tmp->arch->name, "dragon_skin_force") == 0)
00759 skin = tmp;
00760 }
00761 }
00762 set_dragon_name(op, abil, skin);
00763 }
00764
00765 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00766 "Welcome Back!", NULL);
00767 draw_ext_info_format(NDI_UNIQUE|NDI_ALL|NDI_DK_ORANGE, 5, NULL,
00768 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_PLAYER,
00769 "%s has entered the game.",
00770 "%s has entered the game.",
00771 pl->ob->name);
00772
00773
00774 execute_global_event(EVENT_LOGIN, pl, pl->socket.host);
00775 op->contr->socket.update_look = 1;
00776
00777
00778
00779
00780
00781
00782 if (op->stats.hp < 0) {
00783 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOGIN,
00784 "Your character was dead last your played.",
00785 NULL);
00786 kill_player(op);
00787 if (pl->state != ST_PLAYING)
00788 return;
00789 }
00790 LOG(llevInfo, "LOGIN: Player named %s from ip %s\n", op->name,
00791 op->contr->socket.host);
00792
00793
00794
00795
00796 esrv_new_player(op->contr, op->weight+op->carrying);
00797
00798
00799
00800 esrv_add_spells(op->contr, NULL);
00801
00802
00803
00804
00805
00806
00807
00808
00809 fix_object(op);
00810
00811 esrv_send_inventory(op, op);
00812 esrv_send_pickup(pl);
00813
00814 CLEAR_FLAG(op, FLAG_FRIENDLY);
00815
00816
00817
00818
00819
00820
00821
00822
00823 if (QUERY_FLAG(op, FLAG_USE_ARMOUR))
00824 SET_FLAG(op, FLAG_USE_SHIELD);
00825
00826
00827 if (pl->rejoin_party != party_rejoin_no && party_name != NULL) {
00828 partylist *party;
00829 for (party = get_firstparty(); party; party = party->next) {
00830 if (strcmp(party_name, party->partyname) == 0)
00831 break;
00832 }
00833 if (!party && pl->rejoin_party == party_rejoin_always) {
00834 party = form_party(op, party_name);
00835 snprintf(party->passwd, sizeof(party->passwd), "%s", party_password);
00836 }
00837 if (party && strcmp(party->passwd, party_password) == 0) {
00838 pl->party = party;
00839 snprintf(buf, MAX_BUF, "%s joins party %s", op->name, party->partyname);
00840 send_party_message(op, buf);
00841 }
00842
00843 if (pl->party)
00844 snprintf(buf, MAX_BUF, "Rejoined party %s.", party->partyname);
00845 else
00846 snprintf(buf, MAX_BUF, "Couldn't rejoined party %s: %s.", party_name, party ? "invalid password." : "no such party.");
00847 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00848 buf, NULL);
00849 }
00850 if (party_name)
00851 free(party_name);
00852
00853 return;
00854 }