diff options
Diffstat (limited to 'crawl-ref/source/files.cc')
-rw-r--r-- | crawl-ref/source/files.cc | 204 |
1 files changed, 67 insertions, 137 deletions
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index c1ffa33500..41ceddfe99 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -107,16 +107,22 @@ #endif #endif -void save_level(int level_saved, level_area_type lt, - branch_type where_were_you); +static void save_level(int level_saved, level_area_type lt, + branch_type where_were_you); -#define GHOST_MINOR_VERSION 1 -#define LEVEL_MINOR_VERSION 1 +static bool _get_and_validate_version(FILE *restoreFile, char& major, char& minor, + std::string* reason=0); -// 1: starting version -// 2: append piety_hysteresis to TAG_YOU -// 3: add quiver info. -#define YOU_MINOR_VERSION 3 + +static bool determine_ghost_version( FILE *ghostFile, + char &majorVersion, char &minorVersion ); + +static void restore_ghost_version( FILE *ghostFile, char major, char minor ); + +static void restore_tagged_file( FILE *restoreFile, int fileType, + char minorVersion ); + +static void load_ghost(); const short GHOST_SIGNATURE = short( 0xDC55 ); @@ -136,29 +142,6 @@ static void redraw_all(void) REDRAW_LINE_1_MASK | REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK; } -static bool determine_version( FILE *restoreFile, - char &majorVersion, char &minorVersion ); - -static void restore_version( FILE *restoreFile, - char majorVersion, char minorVersion ); - -static bool determine_level_version( FILE *levelFile, - char &majorVersion, char &minorVersion ); - -static void restore_level_version( FILE *levelFile, - char majorVersion, char minorVersion ); - -static bool determine_ghost_version( FILE *ghostFile, - char &majorVersion, char &minorVersion ); - -static void restore_ghost_version( FILE *ghostFile, - char majorVersion, char minorVersion ); - -static void restore_tagged_file( FILE *restoreFile, int fileType, - char minorVersion ); - -static void load_ghost(); - static std::string uid_as_string() { #ifdef MULTIUSER @@ -207,11 +190,10 @@ player_save_info read_character_info(const std::string &savefile) if (!charf) return fromfile; - char majorVersion = 0; - char minorVersion = 0; + char majorVersion; + char minorVersion; - if (determine_version(charf, majorVersion, minorVersion) - && majorVersion == SAVE_MAJOR_VERSION) + if (_get_and_validate_version(charf, majorVersion, minorVersion)) { // backup before we clobber "you" const player backup(you); @@ -647,7 +629,7 @@ std::string make_filename( const char *prefix, int level, branch_type where, isGhost ); } -static void write_version( FILE *dataFile, int majorVersion, int minorVersion, +static void _write_version( FILE *dataFile, int majorVersion, int minorVersion, bool extended_version ) { // write version @@ -675,21 +657,23 @@ static void write_version( FILE *dataFile, int majorVersion, int minorVersion, } } -static void write_tagged_file( FILE *dataFile, char majorVersion, - char minorVersion, int fileType, - bool extended_version = false ) +static void _write_tagged_file( FILE *outf, int fileType, + bool extended_version = false ) { // find all relevant tags char tags[NUM_TAGS]; tag_set_expected(tags, fileType); - write_version( dataFile, majorVersion, minorVersion, extended_version ); + _write_version( outf, TAG_MAJOR_VERSION, TAG_MINOR_VERSION, + extended_version ); // all other tags for (int i = 1; i < NUM_TAGS; i++) { if (tags[i] == 1) - tag_write((tag_type)i, dataFile); + { + tag_write((tag_type)i, outf); + } } } @@ -701,14 +685,10 @@ bool travel_load_map( branch_type branch, int absdepth ) if (!levelFile) return false; - // BEGIN -- must load the old level : pre-load tasks - - // LOAD various tags char majorVersion; char minorVersion; - if (!determine_level_version( levelFile, majorVersion, minorVersion ) - || majorVersion != SAVE_MAJOR_VERSION) + if (!_get_and_validate_version( levelFile, majorVersion, minorVersion )) { fclose(levelFile); return false; @@ -1051,15 +1031,17 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, // BEGIN -- must load the old level : pre-load tasks // LOAD various tags - char majorVersion = 0; - char minorVersion = 0; + char majorVersion; + char minorVersion; - if (!determine_level_version( levelFile, majorVersion, minorVersion )) + std::string reason; + if (!_get_and_validate_version( levelFile, majorVersion, minorVersion, &reason )) { - end(-1, false, "\nLevel file appears to be invalid.\n"); + end(-1, false, "\nLevel file is invalid. %s\n", + reason.c_str()); } - restore_level_version( levelFile, majorVersion, minorVersion ); + restore_tagged_file(levelFile, TAGTYPE_LEVEL, minorVersion); // sanity check - EOF if (!feof( levelFile )) @@ -1232,8 +1214,7 @@ void save_level(int level_saved, level_area_type old_ltype, // nail all items to the ground fix_item_coordinates(); - write_tagged_file( saveFile, SAVE_MAJOR_VERSION, - LEVEL_MINOR_VERSION, TAGTYPE_LEVEL ); + _write_tagged_file( saveFile, TAGTYPE_LEVEL ); fclose(saveFile); @@ -1314,8 +1295,7 @@ void save_game(bool leave_game, const char *farewellmsg) if (!charf) end(-1, true, "Unable to open \"%s\" for writing!\n", charFile.c_str()); - write_tagged_file( charf, SAVE_MAJOR_VERSION, - YOU_MINOR_VERSION, TAGTYPE_PLAYER ); + _write_tagged_file( charf, TAGTYPE_PLAYER ); fclose(charf); DO_CHMOD_PRIVATE(charFile.c_str()); @@ -1386,8 +1366,7 @@ void load_ghost(void) return; } - if (majorVersion != SAVE_MAJOR_VERSION - || minorVersion != GHOST_MINOR_VERSION) + if (majorVersion != TAG_MAJOR_VERSION || minorVersion > TAG_MINOR_VERSION) { fclose(gfile); @@ -1439,13 +1418,13 @@ void restore_game(void) if (!charf ) end(-1, true, "Unable to open %s for reading!\n", charFile.c_str() ); - char majorVersion = 0; - char minorVersion = 0; - - if (!determine_version(charf, majorVersion, minorVersion)) - end(-1, false, "\nSavefile appears to be invalid.\n"); + char majorVersion; + char minorVersion; + std::string reason; + if (!_get_and_validate_version(charf, majorVersion, minorVersion, &reason)) + end(-1, false, "\nSave file is invalid. %s\n", reason.c_str()); - restore_version(charf, majorVersion, minorVersion); + restore_tagged_file(charf, TAGTYPE_PLAYER, minorVersion); // sanity check - EOF if (!feof(charf)) @@ -1602,46 +1581,39 @@ bool apply_to_all_dungeons(bool (*applicator)()) return success; } -static bool determine_version( FILE *restoreFile, - char &majorVersion, char &minorVersion ) +static bool _get_and_validate_version(FILE *restoreFile, char &major, char &minor, + std::string* reason) { + std::string dummy; + if (reason == 0) reason = &dummy; + // read first two bytes. char buf[2]; if (read2(restoreFile, buf, 2) != 2) + { + major = minor = -1; + *reason = "File is corrupt."; return false; // empty file? + } - // otherwise, read version and validate. - majorVersion = buf[0]; - minorVersion = buf[1]; - - if (majorVersion == SAVE_MAJOR_VERSION) - return true; - - return false; // if it's not 0, no idea -} + major = buf[0]; + minor = buf[1]; -static void restore_version( FILE *restoreFile, - char majorVersion, char minorVersion ) -{ - // assuming the following check can be removed once we can read all - // savefile versions. - if (majorVersion != SAVE_MAJOR_VERSION) + if (major != TAG_MAJOR_VERSION) { - end(-1, false, "\nSorry, this release cannot read a v%d.%d savefile.\n", - majorVersion, minorVersion); + *reason = make_stringf("Major version mismatch: %d (want %d).", major, TAG_MAJOR_VERSION); + return false; } - switch(majorVersion) + if (minor > TAG_MINOR_VERSION) { - case SAVE_MAJOR_VERSION: - restore_tagged_file(restoreFile, TAGTYPE_PLAYER, minorVersion); - break; - default: - break; + *reason = make_stringf("Minor version mismatch: %d (want <= %d).", minor, TAG_MINOR_VERSION); + return false; } + + return true; } -// generic v4 restore function static void restore_tagged_file( FILE *restoreFile, int fileType, char minorVersion ) { @@ -1665,46 +1637,6 @@ static void restore_tagged_file( FILE *restoreFile, int fileType, tag_missing(i, minorVersion); } -static bool determine_level_version( FILE *levelFile, - char &majorVersion, char &minorVersion ) -{ - // read first two bytes. - char buf[2]; - if (read2(levelFile, buf, 2) != 2) - return false; // empty file? - - // otherwise, read version and validate. - majorVersion = buf[0]; - minorVersion = buf[1]; - - if (majorVersion == SAVE_MAJOR_VERSION) - return true; - - return false; // if its not SAVE_MAJOR_VERSION, no idea -} - -static void restore_level_version( FILE *levelFile, - char majorVersion, char minorVersion ) -{ - // assuming the following check can be removed once we can read all - // savefile versions. - if (majorVersion != SAVE_MAJOR_VERSION) - { - end(-1, false, - "\nSorry, this release cannot read a v%d.%d level file.\n", - majorVersion, minorVersion); - } - - switch(majorVersion) - { - case SAVE_MAJOR_VERSION: - restore_tagged_file(levelFile, TAGTYPE_LEVEL, minorVersion); - break; - default: - break; - } -} - static bool determine_ghost_version( FILE *ghostFile, char &majorVersion, char &minorVersion ) { @@ -1722,15 +1654,15 @@ static bool determine_ghost_version( FILE *ghostFile, if (unmarshallShort(inf) != GHOST_SIGNATURE) return (false); - if (majorVersion == SAVE_MAJOR_VERSION - && minorVersion <= GHOST_MINOR_VERSION) + if (majorVersion == TAG_MAJOR_VERSION + && minorVersion <= TAG_MINOR_VERSION) { // Discard three more 32-bit words of padding. inf.read(NULL, 3*4); return !feof(ghostFile); } - return false; // if its not SAVE_MAJOR_VERSION, no idea! + return false; // if its not TAG_MAJOR_VERSION, no idea! } static void restore_ghost_version( FILE *ghostFile, @@ -1738,7 +1670,7 @@ static void restore_ghost_version( FILE *ghostFile, { switch(majorVersion) { - case SAVE_MAJOR_VERSION: + case TAG_MAJOR_VERSION: restore_tagged_file(ghostFile, TAGTYPE_GHOST, minorVersion); break; default: @@ -1776,9 +1708,7 @@ void save_ghost( bool force ) return; } - write_tagged_file( gfile, SAVE_MAJOR_VERSION, - GHOST_MINOR_VERSION, TAGTYPE_GHOST, - true ); + _write_tagged_file( gfile, TAGTYPE_GHOST, true ); lk_close(gfile, "wb", cha_fil); @@ -1789,7 +1719,7 @@ void save_ghost( bool force ) DO_CHMOD_PRIVATE(cha_fil.c_str()); } // end save_ghost() - +// XXX: remove? void generate_random_demon() { int rdem = 0; |