From 37c0c9ef3041be75b689e53b0a4f7d597971ecf7 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 22 Nov 2009 14:13:50 -0600 Subject: add a --save-version option for checking a player's save file version --- crawl-ref/source/files.cc | 26 +++++++++++----- crawl-ref/source/files.h | 2 ++ crawl-ref/source/initfile.cc | 71 +++++++++++++++++++++++++++++++++++++++++++- crawl-ref/source/main.cc | 23 +++++++------- 4 files changed, 102 insertions(+), 20 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 7836f63a1b..87f3984fb5 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -2149,26 +2149,36 @@ bool apply_to_all_dungeons(bool (*applicator)()) return (success); } -static bool _get_and_validate_version(FILE *restoreFile, char &major, - char &minor, std::string* reason) +bool get_save_version(FILE *file, char &major, char &minor) { - std::string dummy; - if (reason == 0) - reason = &dummy; - // Read first two bytes. char buf[2]; - if (read2(restoreFile, buf, 2) != 2) + if (read2(file, buf, 2) != 2) { // Empty file? major = minor = -1; - *reason = "File is corrupt."; return (false); } major = buf[0]; minor = buf[1]; + return (true); +} + +static bool _get_and_validate_version(FILE *restoreFile, char &major, + char &minor, std::string* reason) +{ + std::string dummy; + if (reason == 0) + reason = &dummy; + + if (!get_save_version(restoreFile, major, minor)) + { + *reason = "File is corrupt."; + return (false); + } + if (major != TAG_MAJOR_VERSION) { *reason = make_stringf("Major version mismatch: %d (want %d).", diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h index d81e23240e..fa30603f60 100644 --- a/crawl-ref/source/files.h +++ b/crawl-ref/source/files.h @@ -91,6 +91,8 @@ void save_game(bool leave_game, const char *bye = NULL); // Save game without exiting (used when changing levels). void save_game_state(); +bool get_save_version(FILE *file, char &major, char &minor); + void restore_game(void); bool apply_to_all_dungeons(bool (*applicator)()); diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 9fdbf2a886..22a19a20ca 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -3474,6 +3474,7 @@ enum commandline_option_type { CLO_BUILDDB, CLO_HELP, CLO_VERSION, + CLO_SAVE_VERSION, CLO_EXTRA_OPT_FIRST, CLO_EXTRA_OPT_LAST, @@ -3483,7 +3484,7 @@ enum commandline_option_type { static const char *cmd_ops[] = { "scores", "name", "species", "job", "plain", "dir", "rc", "rcdir", "tscores", "vscores", "scorefile", "morgue", "macro", - "mapstat", "arena", "test", "builddb", "help", "version", + "mapstat", "arena", "test", "builddb", "help", "version", "save-version", "extra-opt-first", "extra-opt-last", }; @@ -3524,6 +3525,66 @@ static void _print_version() printf("%s", compilation_info().c_str()); } +static void _print_save_version(char *name) +{ + std::string basename = get_savedir_filename(name, "", ""); + std::string filename = basename + ".sav"; + +#ifdef LOAD_UNPACKAGE_CMD + std::string zipfile = basename + PACKAGE_SUFFIX; + FILE *handle = fopen(zipfile.c_str(), "rb+"); + if (handle == NULL) + { + fprintf(stderr, "Unable to open %s for reading!\n", zipfile.c_str()); + return; + } + else + { + fclose(handle); + + // Create command. + char cmd_buff[1024]; + + std::string zipname = basename; + std::string directory = get_savedir(); + std::string savefile = filename; + savefile.erase(0, savefile.rfind(FILE_SEPARATOR) + 1); + + escape_path_spaces(zipname); + escape_path_spaces(directory); + escape_path_spaces(savefile); + snprintf( cmd_buff, sizeof(cmd_buff), UNPACK_SPECIFIC_FILE_CMD, + zipname.c_str(), + directory.c_str(), + savefile.c_str() ); + + if (system( cmd_buff ) != 0) + { + fprintf(stderr, "Warning: Zip command (UNPACK_SPECIFIC_FILE_CMD) " + "returned non-zero value!" EOL ); + } + } +#endif + + FILE *charf = fopen(filename.c_str(), "rb"); + if (!charf) { + fprintf(stderr, "Unable to open %s for reading!\n", filename.c_str()); + return; + } + + char major, minor; + if (!get_save_version(charf, major, minor)) { + fprintf(stderr, "Save file is invalid.\n"); + } + else { + printf("Save file version for %s is %d.%d\n", name, major, minor); + } + +#ifdef LOAD_UNPACKAGE_CMD + unlink(filename.c_str()); +#endif +} + static bool _check_extra_opt(char* _opt) { std::string opt(_opt); @@ -3817,6 +3878,14 @@ bool parse_args( int argc, char **argv, bool rc_only ) _print_version(); end(0); + case CLO_SAVE_VERSION: + // Always parse. + if (!next_is_param) + return (false); + + _print_save_version(next_arg); + end(0); + case CLO_EXTRA_OPT_FIRST: if (!next_is_param) return (false); diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc index 508bab53ce..275c660f20 100644 --- a/crawl-ref/source/main.cc +++ b/crawl-ref/source/main.cc @@ -312,17 +312,18 @@ int main( int argc, char *argv[] ) static void _show_commandline_options_help() { puts("Command line options:"); - puts(" -help prints this list of options"); - puts(" -name character name"); - puts(" -species preselect race (by letter, abbreviation, or name)"); - puts(" -job preselect class (by letter, abbreviation, or name)"); - puts(" -plain don't use IBM extended characters"); - puts(" -dir crawl directory"); - puts(" -rc init file name"); - puts(" -rcdir directory that contains (included) rc files"); - puts(" -morgue directory to save character dumps"); - puts(" -macro directory to save/find macro.txt"); - puts(" -version Crawl version (and compilation info)"); + puts(" -help prints this list of options"); + puts(" -name character name"); + puts(" -species preselect race (by letter, abbreviation, or name)"); + puts(" -job preselect class (by letter, abbreviation, or name)"); + puts(" -plain don't use IBM extended characters"); + puts(" -dir crawl directory"); + puts(" -rc init file name"); + puts(" -rcdir directory that contains (included) rc files"); + puts(" -morgue directory to save character dumps"); + puts(" -macro directory to save/find macro.txt"); + puts(" -version Crawl version (and compilation info)"); + puts(" -save-version Save file version for the given player"); puts(""); puts("Command line options override init file options, which override"); puts("environment options (CRAWL_NAME, CRAWL_DIR, CRAWL_RC)."); -- cgit v1.2.3-54-g00ecf