42 static void copy_file(
const char *filename, FILE *fpout);
52 #ifndef NO_EMERGENCY_SAVE
64 "Emergency save...", NULL);
72 if (pl->
ob->
map != NULL)
80 "Emergency save failed, checking score...", NULL);
86 LOG(
llevInfo,
"Emergency saves disabled, no save attempted\n");
125 if (strpbrk(name,
"/.\\") != NULL) {
126 LOG(
llevError,
"Username contains illegal characters: %s\n", name);
131 if (strlen(buf) >=
sizeof(buf)-1) {
144 while (fgets(buf,
MAX_BUF-1, fp) != NULL) {
145 if (!strncmp(buf,
"password ", 9)) {
146 buf[strlen(buf)-1] = 0;
156 LOG(
llevDebug,
"Could not find a password line in player %s\n", name);
176 "Your username cannot be blank.", NULL);
182 "That name contains illegal characters. Use letters, hyphens and underscores only. Hyphens and underscores are not allowed as the first character.", NULL);
187 "That name is too long. (Max length: %d characters)", NULL,
MAX_NAME);
203 while ((tmp = op->
inv))
226 object *tmp, *container = NULL;
230 #ifdef BACKUP_SAVE_AT_HOME
231 sint16 backup_x, backup_y;
242 "Your game is not valid, game not saved.", NULL);
265 "Can't get secure temporary file for save.", NULL);
266 LOG(
llevDebug,
"Can't get secure temporary file for save.\n");
276 fprintf(fp,
"password %s\n", pl->
password);
279 fprintf(fp,
"title %s\n", pl->
own_title);
281 fprintf(fp,
"explore %d\n", pl->
explore);
282 fprintf(fp,
"gen_hp %d\n", pl->
gen_hp);
283 fprintf(fp,
"gen_sp %d\n", pl->
gen_sp);
284 fprintf(fp,
"gen_grace %d\n", pl->
gen_grace);
285 fprintf(fp,
"listening %d\n", pl->
listening);
286 fprintf(fp,
"shoottype %d\n", pl->
shoottype);
287 fprintf(fp,
"bowtype %d\n", pl->
bowtype);
288 fprintf(fp,
"petmode %d\n", pl->
petmode);
289 fprintf(fp,
"peaceful %d\n", pl->
peaceful);
290 fprintf(fp,
"no_shout %d\n", pl->
no_shout);
291 fprintf(fp,
"digestion %d\n", pl->
digestion);
292 fprintf(fp,
"pickup %u\n", pl->
mode);
300 #ifdef BACKUP_SAVE_AT_HOME
301 if (op->
map != NULL && flag == 0)
305 fprintf(fp,
"map %s\n", op->
map->
path);
310 fprintf(fp,
"bed_x %d\nbed_y %d\n", pl->
bed_x, pl->
bed_y);
311 fprintf(fp,
"weapon_sp %f\n", pl->
weapon_sp);
320 fprintf(fp,
"lev_array %d\n",
MIN(op->
level, 10));
321 for (i = 1; i <= pl->
last_level && i <= 10; i++) {
322 fprintf(fp,
"%d\n", pl->
levhp[i]);
323 fprintf(fp,
"%d\n", pl->
levsp[i]);
324 fprintf(fp,
"%d\n", pl->
levgrace[i]);
326 fprintf(fp,
"party_rejoin_mode %d\n", pl->
rejoin_party);
327 if (pl->
party != NULL) {
329 fprintf(fp,
"party_rejoin_password %s\n", pl->
party->
passwd);
331 fprintf(fp,
"language %d\n", pl->
language);
332 fprintf(fp,
"endplst\n");
336 #ifdef BACKUP_SAVE_AT_HOME
360 "Can't save character!", NULL);
370 while ((tmp = op->
inv))
380 snprintf(backupfile,
sizeof(backupfile),
"%s.tmp", filename);
381 rename(filename, backupfile);
382 fp = fopen(filename,
"w");
385 "Can't open file for save.", NULL);
390 fprintf(fp,
"checksum %lx\n", checksum);
394 if (fclose(fp) == EOF) {
396 "Can't close file for save.", NULL);
397 rename(backupfile, filename);
403 if (flag && container != NULL)
421 static void copy_file(
const char *filename, FILE *fpout) {
425 if ((fp = fopen(filename,
"r")) == NULL) {
426 LOG(
llevError,
"copy_file failed to open \"%s\", player file(s) may be corrupt.\n", filename);
429 while (fgets(buf,
MAX_BUF, fp) != NULL)
443 "\nA character with this name already exists. "
444 "Please choose another name, or make sure you entered your "
445 "password correctly.\n",
454 "You gave an incorrect password too many times, "
455 "you will now be dropped from the server.",
458 LOG(
llevInfo,
"A player connecting from %s has been dropped for password failure\n",
481 time_t elapsed_save_time = 0;
483 char *party_name = NULL, party_password[9];
486 party_password[0] = 0;
490 if (pltmp != pl && pltmp->
ob->
name != NULL && !strcmp(pltmp->ob->name, op->
name)) {
501 pltmp->socket.status =
Ns_Dead;
531 if (fstat(fileno(fp), &statbuf)) {
533 elapsed_save_time = 0;
535 elapsed_save_time = time(NULL)-statbuf.st_mtime;
536 if (elapsed_save_time < 0) {
537 LOG(
llevError,
"Player file %s was saved in the future? (%d time)\n", filename, elapsed_save_time);
538 elapsed_save_time = 0;
542 if (fgets(bufall,
MAX_BUF, fp) != NULL) {
543 if (!strncmp(bufall,
"checksum ", 9)) {
544 checksum =
strtol(bufall+9, (
char **)NULL, 16);
545 (void)fgets(bufall,
MAX_BUF, fp);
547 if (sscanf(bufall,
"password %s\n", buf)) {
563 pl->last_save_time = time(NULL);
582 while (fgets(bufall,
MAX_BUF, fp) != NULL) {
583 sscanf(bufall,
"%s %d\n", buf, &value);
584 if (!strcmp(buf,
"endplst"))
587 sscanf(bufall,
"title %[^\n]", pl->
own_title);
588 else if (!strcmp(buf,
"explore"))
590 else if (!strcmp(buf,
"gen_hp"))
592 else if (!strcmp(buf,
"shoottype"))
594 else if (!strcmp(buf,
"bowtype"))
596 else if (!strcmp(buf,
"petmode"))
598 else if (!strcmp(buf,
"gen_sp"))
600 else if (!strcmp(buf,
"gen_grace"))
602 else if (!strcmp(buf,
"listening"))
604 else if (!strcmp(buf,
"peaceful"))
606 else if (!strcmp(buf,
"no_shout"))
608 else if (!strcmp(buf,
"digestion"))
610 else if (!strcmp(buf,
"pickup"))
612 else if (!strcmp(buf,
"outputs_sync"))
614 else if (!strcmp(buf,
"outputs_count"))
616 else if (!strcmp(buf,
"map"))
617 sscanf(bufall,
"map %s", pl->
maplevel);
618 else if (!strcmp(buf,
"savebed_map"))
620 else if (!strcmp(buf,
"bed_x"))
622 else if (!strcmp(buf,
"bed_y"))
624 else if (!strcmp(buf,
"weapon_sp"))
625 sscanf(buf,
"weapon_sp %f", &pl->
weapon_sp);
626 else if (!strcmp(buf,
"Str"))
628 else if (!strcmp(buf,
"Dex"))
630 else if (!strcmp(buf,
"Con"))
632 else if (!strcmp(buf,
"Int"))
634 else if (!strcmp(buf,
"Pow"))
636 else if (!strcmp(buf,
"Wis"))
638 else if (!strcmp(buf,
"Cha"))
640 else if (!strcmp(buf,
"usekeys")) {
641 if (!strcmp(bufall+8,
"key_inventory\n"))
643 else if (!strcmp(bufall+8,
"keyrings\n"))
645 else if (!strcmp(bufall+8,
"containers\n"))
648 LOG(
llevDebug,
"load_player: got unknown usekeys type: %s\n", bufall+8);
649 }
else if (!strcmp(buf,
"unapply")) {
650 if (!strcmp(bufall+8,
"unapply_nochoice\n"))
652 else if (!strcmp(bufall+8,
"unapply_never\n"))
654 else if (!strcmp(bufall+8,
"unapply_always\n"))
657 LOG(
llevDebug,
"load_player: got unknown unapply type: %s\n", bufall+8);
658 }
else if (!strcmp(buf,
"lev_array")) {
659 for (i = 1; i <= value; i++) {
662 fscanf(fp,
"%d\n", &j);
664 fscanf(fp,
"%d\n", &j);
666 fscanf(fp,
"%d\n", &j);
669 }
else if (!strcmp(buf,
"party_rejoin_mode")) {
671 }
else if (!strcmp(buf,
"party_rejoin_name")) {
672 party_name =
strdup_local(bufall+strlen(
"party_rejoin_name")+1);
673 if (party_name && strlen(party_name) > 0)
674 party_name[strlen(party_name)-1] =
'\0';
675 }
else if (!strcmp(buf,
"party_rejoin_password")) {
678 snprintf(party_password,
sizeof(party_password),
"%s", bufall+strlen(
"party_rejoin_password")+1);
679 len = strlen(party_password);
683 if (len > 0 && len < 8)
684 party_password[len-1] =
'\0';
685 }
else if (!strcmp(buf,
"language")) {
741 pl->last_save_tick =
pticks;
752 object *tmp, *abil = NULL, *skin = NULL;
754 for (tmp = op->
inv; tmp != NULL; tmp = tmp->
below) {
756 if (strcmp(tmp->
arch->
name,
"dragon_ability_force") == 0)
758 else if (strcmp(tmp->
arch->
name,
"dragon_skin_force") == 0)
766 "Welcome Back!", NULL);
769 "%s has entered the game.",
770 "%s has entered the game.",
784 "Your character was dead last your played.",
830 if (strcmp(party_name, party->
partyname) == 0)
837 if (party && strcmp(party->
passwd, party_password) == 0) {
846 snprintf(buf,
MAX_BUF,
"Couldn't rejoined party %s: %s.", party_name, party ?
"invalid password." :
"no such party.");
int check_name(player *me, const char *name)
int check_password(char *typed, char *crypted)
#define ST_GET_PARTY_PASSWORD
void enter_exit(object *op, object *exit_ob)
void esrv_new_player(player *pl, uint32 weight)
void leave(player *pl, int draw_exit)
void delete_character(const char *name)
long strtol(register char *str, char **ptr, register int base)
void make_path_to_file(const char *filename)
void remove_directory(const char *path)
int save_player(object *op, int flag)
#define FLAG_NO_FIX_PLAYER
#define MSG_TYPE_COMMAND_SUCCESS
#define MSG_TYPE_ADMIN_PLAYER
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
void esrv_send_inventory(object *pl, object *op)
void close_and_delete(FILE *fp, int compressed)
signed long sum_weight(object *op)
int legal_range(object *op, int r)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
void terminate_all_pets(object *owner)
char savebed_map[MAX_BUF]
#define MAX_PASSWORD_FAILURES
void esrv_add_spells(player *pl, object *spell)
static void wrong_password(object *op)
void get_name(object *op)
#define SAVE_FLAG_SAVE_UNPAID
void remove_ob(object *op)
struct party_struct * next
int is_dragon_pl(const object *op)
FILE * tempnam_secure(const char *dir, const char *pfx, char **filename)
int execute_global_event(int eventcode,...)
void confirm_password(object *op)
void check_score(object *op, int quiet)
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
char * strdup_local(const char *str)
party_rejoin_mode rejoin_party
int save_object(FILE *fp, object *op, int flag)
#define SAVE_FLAG_NO_REMOVE
void remove_unpaid_objects(object *op, object *env, int free_items)
int snprintf(char *dest, int max, const char *format,...)
partylist * get_firstparty(void)
#define FREE_AND_COPY(sv, nv)
partylist * form_party(object *op, const char *params)
int load_object(FILE *fp, object *op, int bufstate, int map_flags)
void reset_object(object *op)
int verify_player(const char *name, char *password)
EXTERN long trying_emergency_save
EXTERN char first_map_path[MAX_BUF]
void destroy_object(object *op)
void update_ob_speed(object *op)
void emergency_save(int flag)
EXTERN player * first_player
void link_player_skills(object *op)
void send_party_message(object *op, char *msg)
int playername_ok(const char *cp)
int check_path(const char *name, int prepend_dir)
void esrv_send_pickup(player *pl)
void final_free_player(player *pl)
void check_login(object *op)
void LOG(LogLevel logLevel, const char *format,...)
void kill_player(object *op)
void set_dragon_name(object *pl, const object *abil, const object *skin)
#define MSG_TYPE_ADMIN_LOADSAVE
void free_object(object *ob)
#define MSG_TYPE_ADMIN_LOGIN
void fix_object(object *op)
FILE * open_and_uncompress(const char *name, int flag, int *compressed)
static void copy_file(const char *filename, FILE *fpout)