/* * Attempt to Load a "savefile" * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; byte savefile_game; cptr what = "generic"; /* Paranoia */ turn = 0; p_ptr->p_turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; load_player_ghost_file(); /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fff = file_open(savefile, MODE_READ, -1); if (fff) fd = 0; else fd = -1; /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) { /* Give a message */ msg_print("Savefile does not exist."); message_flush(); /* Allow this */ return (TRUE); } /* Close the file */ file_close(fff); /* Okay */ if (!err) { /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fff = file_open(savefile, MODE_READ, -1); if (fff) { fd = 0; } else fd = -1; /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; } /* Process file */ if (!err) { /* Read the first four bytes */ if (!file_read(fff, (char*)(vvv), 4)) err = -1; /* What */ if (err) what = "Cannot read savefile"; rd_byte(&savefile_game); /* Close the file */ file_close(fff); } /* Process file */ if (!err) { /* Extract version */ sf_major = vvv[0]; sf_minor = vvv[1]; sf_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH)) { err = -1; what = "Savefile is too old"; } else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1)) { err = -1; what = "Savefile is from the future"; } else if (game_mode != savefile_game) { err = -1; if (game_mode == GAME_NPPMORIA) what = "Not a NPPMoria savefile"; else if (game_mode == GAME_NPPANGBAND) what = "Not a NPPAngband savefile"; else what = "Unknown savefile type"; } else { /* Attempt to load */ err = rd_savefile(); /* Message (below) */ if (err) what = "Cannot parse savefile"; } } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = "Broken savefile"; } /* Okay */ if (!err) { /* Give a conversion warning */ if ((version_major != sf_major) || (version_minor != sf_minor) || (version_patch != sf_patch)) { /* Message */ msg_format("Converted a %d.%d.%d savefile.", sf_major, sf_minor, sf_patch); message_flush(); } /* Player is dead */ if (p_ptr->is_dead) { /*note, add or_true to the arg wixard if statement to resurrect character*/ /* Cheat death (unless the character retired) */ if (arg_wizard) { /*heal the player*/ hp_player(2000); /* Forget death */ p_ptr->is_dead = FALSE; /* A character was loaded */ character_loaded = TRUE; /* Done */ return (TRUE); } /* Forget death */ p_ptr->is_dead = FALSE; /* Count lives */ sf_lives++; /* Forget turns */ turn = 0; p_ptr->p_turn = 0; /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof(p_ptr->died_from)); } /* Success */ return (TRUE); } /* Message */ msg_format("Error (%s) reading %d.%d.%d savefile.", what, sf_major, sf_minor, sf_patch); message_flush(); /* Oops */ return (FALSE); }
/* * Attempt to Load a "savefile" * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; #ifdef VERIFY_TIMESTAMP struct stat statbuf; #endif /* VERIFY_TIMESTAMP */ cptr what = "generic"; /* Paranoia */ turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) { /* Give a message */ msg_print("Savefile does not exist."); message_flush(); /* Allow this */ return (TRUE); } /* Close the file */ fd_close(fd); #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (!err) { FILE *fkk; char temp[1024]; /* Extract name of lock file */ strcpy(temp, savefile); strcat(temp, ".lok"); /* Grab permissions */ safe_setuid_grab(); /* Check for lock */ fkk = my_fopen(temp, "r"); /* Drop permissions */ safe_setuid_drop(); /* Oops, lock exists */ if (fkk) { /* Close the file */ my_fclose(fkk); /* Message */ msg_print("Savefile is currently in use."); message_flush(); /* Oops */ return (FALSE); } /* Grab permissions */ safe_setuid_grab(); /* Create a lock file */ fkk = my_fopen(temp, "w"); /* Drop permissions */ safe_setuid_drop(); /* Dump a line of info */ fprintf(fkk, "Lock file for savefile '%s'\n", savefile); /* Close the lock file */ my_fclose(fkk); } #endif /* VERIFY_SAVEFILE */ /* Okay */ if (!err) { /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; } /* Process file */ if (!err) { #ifdef VERIFY_TIMESTAMP /* Grab permissions */ safe_setuid_grab(); /* Get the timestamp */ (void)fstat(fd, &statbuf); /* Drop permissions */ safe_setuid_drop(); #endif /* VERIFY_TIMESTAMP */ /* Read the first four bytes */ if (fd_read(fd, (char*)(vvv), sizeof(vvv))) err = -1; /* What */ if (err) what = "Cannot read savefile"; /* Close the file */ fd_close(fd); } /* Process file */ if (!err) { /* Extract version */ sf_major = vvv[0]; sf_minor = vvv[1]; sf_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH)) { err = -1; what = "Savefile is too old"; } else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1)) { err = -1; what = "Savefile is from the future"; } else { /* Attempt to load */ err = rd_savefile(); /* Message (below) */ if (err) what = "Cannot parse savefile"; } } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = "Broken savefile"; } #ifdef VERIFY_TIMESTAMP /* Verify timestamp */ if (!err && !arg_wizard) { /* Hack -- Verify the timestamp */ if (sf_when > (statbuf.st_ctime + 100) || sf_when < (statbuf.st_ctime - 100)) { /* Message */ what = "Invalid timestamp"; /* Oops */ err = -1; } } #endif /* VERIFY_TIMESTAMP */ /* Okay */ if (!err) { /* Give a conversion warning */ if ((version_major != sf_major) || (version_minor != sf_minor) || (version_patch != sf_patch)) { /* Message */ msg_format("Converted a %d.%d.%d savefile.", sf_major, sf_minor, sf_patch); message_flush(); } /* Player is dead */ if (p_ptr->is_dead) { /* Forget death */ p_ptr->is_dead = FALSE; /* Cheat death */ if (arg_wizard) { /* A character was loaded */ character_loaded = TRUE; /* Done */ return (TRUE); } /* Count lives */ sf_lives++; /* Forget turns */ turn = old_turn = 0; /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ strcpy(p_ptr->died_from, "(alive and well)"); } /* Success */ return (TRUE); } #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (TRUE) { char temp[1024]; /* Extract name of lock file */ strcpy(temp, savefile); strcat(temp, ".lok"); /* Grab permissions */ safe_setuid_grab(); /* Remove lock */ fd_kill(temp); /* Drop permissions */ safe_setuid_drop(); } #endif /* VERIFY_SAVEFILE */ /* Message */ msg_format("Error (%s) reading %d.%d.%d savefile.", what, sf_major, sf_minor, sf_patch); message_flush(); /* Oops */ return (FALSE); }
/* * Attempt to Load a "savefile" * * On multi-user systems, you may only "read" a savefile if you will be * allowed to "write" it later, this prevents painful situations in which * the player loads a savefile belonging to someone else, and then is not * allowed to save his game when he quits. * * We return "TRUE" if the savefile was usable, and we set the global * flag "character_loaded" if a real, living, character was loaded. * * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ bool load_player(void) { int fd = -1; errr err = 0; byte vvv[4]; #ifdef VERIFY_TIMESTAMP struct stat statbuf; #endif /* VERIFY_TIMESTAMP */ cptr what = "generic"; /* Paranoia */ turn = 0; /* Paranoia */ p_ptr->is_dead = FALSE; // Set a flag to show that we are restoring a game p_ptr->restoring = TRUE; /* Allow empty savefile name */ if (!savefile[0]) return (TRUE); /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) { /* Give a message */ msg_format("Savefile \"%s\" does not exist.", savefile); message_flush(); /* Allow this */ p_ptr->restoring = FALSE; return (FALSE);//// } /* Close the file */ fd_close(fd); #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (!err) { FILE *fkk; char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Check for lock */ fkk = my_fopen(temp, "r"); /* Drop permissions */ safe_setuid_drop(); /* Oops, lock exists */ if (fkk) { /* Close the file */ my_fclose(fkk); /* Message */ msg_print("Savefile is currently in use."); message_flush(); /* Oops */ return (FALSE); } /* Grab permissions */ safe_setuid_grab(); /* Create a lock file */ fkk = my_fopen(temp, "w"); /* Drop permissions */ safe_setuid_drop(); /* Dump a line of info */ fprintf(fkk, "Lock file for savefile '%s'\n", savefile); /* Close the lock file */ my_fclose(fkk); } #endif /* VERIFY_SAVEFILE */ /* Okay */ if (!err) { /* Grab permissions */ safe_setuid_grab(); /* Open the savefile */ fd = fd_open(savefile, O_RDONLY); /* Drop permissions */ safe_setuid_drop(); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; } /* Process file */ if (!err) { #ifdef VERIFY_TIMESTAMP /* Grab permissions */ safe_setuid_grab(); /* Get the timestamp */ (void)fstat(fd, &statbuf); /* Drop permissions */ safe_setuid_drop(); #endif /* VERIFY_TIMESTAMP */ /* Read the first four bytes */ if (fd_read(fd, (char*)(vvv), sizeof(vvv))) err = -1; /* What */ if (err) what = "Cannot read savefile"; /* Close the file */ fd_close(fd); } /* Process file */ if (!err) { /* Extract version */ sf_major = vvv[0]; sf_minor = vvv[1]; sf_patch = vvv[2]; sf_extra = vvv[3]; /* Clear screen */ Term_clear(); if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH)) { err = -1; what = "Savefile is too old"; } else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1)) { err = -1; what = "Savefile is from the future"; } else { /* Attempt to load */ err = rd_savefile(); /* Message (below) */ if (err) what = "Cannot parse savefile"; } } /* Paranoia */ if (!err) { /* Invalid turn */ if (!turn) err = -1; /* Message (below) */ if (err) what = "Broken savefile"; } #ifdef VERIFY_TIMESTAMP /* Verify timestamp */ if (!err && !arg_wizard) { /* Hack -- Verify the timestamp */ if (sf_when > (statbuf.st_ctime + 100) || sf_when < (statbuf.st_ctime - 100)) { /* Message */ what = "Invalid timestamp"; /* Oops */ err = -1; } } #endif /* VERIFY_TIMESTAMP */ /* Okay */ if (!err) { /* Give a conversion warning */ if ((version_major != sf_major) || (version_minor != sf_minor) || (version_patch != sf_patch)) { /* Message */ msg_format("Converted a %d.%d.%d savefile.", sf_major, sf_minor, sf_patch); message_flush(); } // if Morgoth has lost his crown... if ((&a_info[ART_MORGOTH_3])->cur_num == 1) { // lower Morgoth's protection, remove his light source, increase his will and perception (&r_info[R_IDX_MORGOTH])->pd -= 1; (&r_info[R_IDX_MORGOTH])->light = 0; (&r_info[R_IDX_MORGOTH])->wil += 5; (&r_info[R_IDX_MORGOTH])->per += 5; } /* Player is dead */ if (p_ptr->is_dead) { /* Cheat death (unless the character retired) */ if (arg_wizard) { /*heal the player*/ hp_player(100, TRUE, TRUE); /* Forget death */ p_ptr->is_dead = FALSE; /* A character was loaded */ character_loaded = TRUE; // put the character somewhere sensible p_ptr->depth = min_depth(); // Mark savefile p_ptr->noscore |= 0x0001; /* Done */ return (TRUE); } /* Forget death */ p_ptr->is_dead = FALSE; /* Count lives */ sf_lives++; /* Forget turns */ turn = 0; playerturn = 0; /* A dead character was loaded */ character_loaded_dead = TRUE;//// /* Done */ return (TRUE); } /* A character was loaded */ character_loaded = TRUE; /* Still alive */ if (p_ptr->chp >= 0) { /* Reset cause of death */ my_strcpy(p_ptr->died_from, "(alive and well)", sizeof (p_ptr->died_from)); } // count the artefacts seen for the player p_ptr->artefacts = artefact_count(); /* Success */ return (TRUE); } #ifdef VERIFY_SAVEFILE /* Verify savefile usage */ if (TRUE) { char temp[1024]; /* Extract name of lock file */ my_strcpy(temp, savefile, sizeof(temp)); my_strcat(temp, ".lok", sizeof(temp)); /* Grab permissions */ safe_setuid_grab(); /* Remove lock */ fd_kill(temp); /* Drop permissions */ safe_setuid_drop(); } #endif /* VERIFY_SAVEFILE */ /* Message */ msg_format("Error (%s) reading %d.%d.%d savefile.", what, sf_major, sf_minor, sf_patch); message_flush(); /* Oops */ return (FALSE); }