summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/files.cc26
-rw-r--r--crawl-ref/source/files.h2
-rw-r--r--crawl-ref/source/initfile.cc71
-rw-r--r--crawl-ref/source/main.cc23
4 files changed, 102 insertions, 20 deletions
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 <string> character name");
- puts(" -species <arg> preselect race (by letter, abbreviation, or name)");
- puts(" -job <arg> preselect class (by letter, abbreviation, or name)");
- puts(" -plain don't use IBM extended characters");
- puts(" -dir <path> crawl directory");
- puts(" -rc <file> init file name");
- puts(" -rcdir <dir> directory that contains (included) rc files");
- puts(" -morgue <dir> directory to save character dumps");
- puts(" -macro <dir> directory to save/find macro.txt");
- puts(" -version Crawl version (and compilation info)");
+ puts(" -help prints this list of options");
+ puts(" -name <string> character name");
+ puts(" -species <arg> preselect race (by letter, abbreviation, or name)");
+ puts(" -job <arg> preselect class (by letter, abbreviation, or name)");
+ puts(" -plain don't use IBM extended characters");
+ puts(" -dir <path> crawl directory");
+ puts(" -rc <file> init file name");
+ puts(" -rcdir <dir> directory that contains (included) rc files");
+ puts(" -morgue <dir> directory to save character dumps");
+ puts(" -macro <dir> directory to save/find macro.txt");
+ puts(" -version Crawl version (and compilation info)");
+ puts(" -save-version <name> 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).");