add new minimumVersion setting in saves, can restrict the smallest version of TPT that is able to open the save. Uses major/minor version for this

Also add RESTRICTVERSION macro to help when adding restrictions later
Also show errors when opening broken stamps now too
This commit is contained in:
jacob1 2015-10-02 21:25:15 -04:00
parent 1bd861719f
commit 63843c2bd7
5 changed files with 73 additions and 9 deletions

View File

@ -1094,6 +1094,7 @@ SaveFile * Client::GetStamp(std::string stampID)
catch (ParseException & e)
{
std::cerr << "Client: Invalid stamp file, " << stampID << " " << std::string(e.what()) << std::endl;
file->SetLoadingError(e.what());
}
}
return file;

View File

@ -466,7 +466,7 @@ void GameSave::readOPS(char * data, int dataLength)
if (savedVersion > SAVE_VERSION)
{
fromNewerVersion = true;
throw ParseException(ParseException::WrongVersion, "Save from newer version");
//throw ParseException(ParseException::WrongVersion, "Save from newer version");
}
//Incompatible cell size
@ -721,6 +721,37 @@ void GameSave::readOPS(char * data, int dataLength)
}
}
}
else if (!strcmp(bson_iterator_key(&iter), "minimumVersion"))
{
if (bson_iterator_type(&iter) == BSON_OBJECT)
{
int major = INT_MAX, minor = INT_MAX;
bson_iterator subiter;
bson_iterator_subiterator(&iter, &subiter);
while (bson_iterator_next(&subiter))
{
if (bson_iterator_type(&subiter) == BSON_INT)
{
if (!strcmp(bson_iterator_key(&subiter), "major"))
major = bson_iterator_int(&subiter);
else if (!strcmp(bson_iterator_key(&subiter), "minor"))
minor = bson_iterator_int(&subiter);
else
fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter));
}
}
if (major > SAVE_VERSION || (major == SAVE_VERSION && minor > MINOR_VERSION))
{
std::stringstream errorMessage;
errorMessage << "Save from a newer version: Requires version " << major << "." << minor;
throw ParseException(ParseException::WrongVersion, errorMessage.str());
}
}
else
{
fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter));
}
}
}
//Read wall and fan data
@ -1783,6 +1814,12 @@ void GameSave::readPSv(char * data, int dataLength)
}
}
// restrict the minimum version this save can be opened with
#define RESTRICTVERSION(major, minor) if ((major) > minimumMajorVersion || (((major) == minimumMajorVersion && (minor) > minimumMinorVersion))) {\
minimumMajorVersion = major;\
minimumMinorVersion = minor;\
}
char * GameSave::serialiseOPS(unsigned int & dataLength)
{
//Particle *particles = sim->parts;
@ -1794,6 +1831,10 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
int blockX, blockY, blockW, blockH, fullX, fullY, fullW, fullH;
int x, y, i, wallDataFound = 0;
int posCount, signsCount;
// minimum version this save is compatible with
// when building, this number may be increased depending on what elements are used
// or what properties are detected
int minimumMajorVersion = 90, minimumMinorVersion = 2;
bson b;
std::fill(elementCount, elementCount+PT_NUM, 0);
@ -2117,6 +2158,10 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
bson_append_string(&b, "platform", IDENT_PLATFORM);
bson_append_string(&b, "builtType", IDENT_BUILD);
bson_append_finish_object(&b);
bson_append_start_object(&b, "minimumVersion");
bson_append_int(&b, "major", minimumMajorVersion);
bson_append_int(&b, "minor", minimumMinorVersion);
bson_append_finish_object(&b);
bson_append_bool(&b, "waterEEnabled", waterEEnabled);

View File

@ -7,11 +7,12 @@ SaveFile::SaveFile(SaveFile & save):
thumbnail(NULL),
gameSave(NULL),
filename(save.filename),
displayName(save.displayName)
displayName(save.displayName),
loadingError(save.loadingError)
{
if(save.gameSave)
if (save.gameSave)
gameSave = new GameSave(*save.gameSave);
if(save.thumbnail)
if (save.thumbnail)
thumbnail = new Thumbnail(*save.thumbnail);
}
@ -29,7 +30,8 @@ SaveFile::SaveFile(std::string filename):
thumbnail(NULL),
gameSave(NULL),
filename(filename),
displayName(filename)
displayName(filename),
loadingError("")
{
}
@ -64,6 +66,16 @@ void SaveFile::SetDisplayName(std::string displayName)
this->displayName = displayName;
}
std::string SaveFile::GetError()
{
return loadingError;
}
void SaveFile::SetLoadingError(std::string error)
{
loadingError = error;
}
SaveFile::~SaveFile() {
delete gameSave;
delete thumbnail;

View File

@ -19,6 +19,8 @@ public:
void SetDisplayName(std::string displayName);
std::string GetName();
void SetFileName(std::string fileName);
std::string GetError();
void SetLoadingError(std::string error);
virtual ~SaveFile();
private:
@ -26,6 +28,7 @@ private:
GameSave * gameSave;
std::string filename;
std::string displayName;
std::string loadingError;
};
#endif /* SAVEFILE_H_ */

View File

@ -110,11 +110,14 @@ public:
StampsCallback(GameController * cc_) { cc = cc_; }
virtual void ControllerExit()
{
if(cc->localBrowser->GetSave())
SaveFile *file = cc->localBrowser->GetSave();
if (file)
{
if (cc->localBrowser->GetMoveToFront())
Client::Ref().MoveStampToFront(cc->localBrowser->GetSave()->GetName());
cc->LoadStamp(cc->localBrowser->GetSave()->GetGameSave());
if (file->GetError().length())
new ErrorMessage("Error loading stamp", file->GetError());
else if (cc->localBrowser->GetMoveToFront())
Client::Ref().MoveStampToFront(file->GetName());
cc->LoadStamp(file->GetGameSave());
}
}
};