1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Fixes zero-initialized fileVersion member in deserializer

This commit is contained in:
Ivan Savenko 2016-10-29 19:52:19 +03:00
parent ba5ad286cd
commit 256f43f467
12 changed files with 26 additions and 32 deletions

View File

@ -724,10 +724,6 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
else if(current)
{
SelectMap sm(*current);
// FIXME: Super dirty hack to avoid crash on multiplayer game start.
// There is some issues with TriggeredEvent serialization that cause it.
// We'll look into them once refactored serializer fixed and merged
sm.mapInfo->mapHeader->triggeredEvents.clear();
*serv << &sm;
UpdateStartOptions uso(sInfo);
@ -1148,7 +1144,7 @@ void SelectionTab::parseGames(const std::unordered_set<ResourceID> &files, bool
{
try
{
CLoadFile lf(*CResourceHandler::get()->getResourceName(file), minSupportedVersion);
CLoadFile lf(*CResourceHandler::get()->getResourceName(file), MINIMAL_SERIALIZATION_VERSION);
lf.checkMagicBytes(SAVEGAME_MAGIC);
// ui8 sign[8];
// lf >> sign;

View File

@ -291,7 +291,7 @@ void CClient::loadGame(const std::string & fname, const bool server, const std::
throw std::runtime_error("Cannot open server part of " + fname);
{
CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion);
CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, MINIMAL_SERIALIZATION_VERSION);
loadCommonState(checkingLoader);
loader = checkingLoader.decay();
}

View File

@ -34,7 +34,7 @@ int CLoadFile::read(void * data, unsigned size)
void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
{
assert(!serializer.reverseEndianess);
assert(minimalVersion <= version);
assert(minimalVersion <= SERIALIZATION_VERSION);
try
{
@ -55,15 +55,15 @@ void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalV
if(serializer.fileVersion < minimalVersion)
THROW_FORMAT("Error: too old file format (%s)!", fName);
if(serializer.fileVersion > version)
if(serializer.fileVersion > SERIALIZATION_VERSION )
{
logGlobal->warnStream() << boost::format("Warning format version mismatch: found %d when current is %d! (file %s)\n") % serializer.fileVersion % version % fName;
logGlobal->warnStream() << boost::format("Warning format version mismatch: found %d when current is %d! (file %s)\n") % serializer.fileVersion % SERIALIZATION_VERSION % fName;
auto versionptr = (char*)&serializer.fileVersion;
std::reverse(versionptr, versionptr + 4);
logGlobal->warnStream() << "Version number reversed is " << serializer.fileVersion << ", checking...";
if(serializer.fileVersion == version)
if(serializer.fileVersion == SERIALIZATION_VERSION)
{
logGlobal->warnStream() << fname << " seems to have different endianness! Entering reversing mode.";
serializer.reverseEndianess = true;

View File

@ -148,6 +148,7 @@ class DLL_LINKAGE BinaryDeserializer : public CLoaderBase
ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
s.ptrAllocated(ptr, pid);
//T is most derived known type, it's time to call actual serialize
assert(s.fileVersion != 0);
ptr->serialize(s,s.fileVersion);
return &typeid(T);
}
@ -185,23 +186,17 @@ public:
template < class T, typename std::enable_if < std::is_fundamental<T>::value && !std::is_same<T, bool>::value, int >::type = 0 >
void load(T &data)
{
if(0) //for testing #989
{
this->read(&data,sizeof(data));
}
else
{
unsigned length = sizeof(data);
char* dataPtr = (char*)&data;
this->read(dataPtr,length);
if(reverseEndianess)
std::reverse(dataPtr, dataPtr + length);
}
unsigned length = sizeof(data);
char* dataPtr = (char*)&data;
this->read(dataPtr,length);
if(reverseEndianess)
std::reverse(dataPtr, dataPtr + length);
}
template < typename T, typename std::enable_if < is_serializeable<BinaryDeserializer, T>::value, int >::type = 0 >
void load(T &data)
{
assert( fileVersion != 0 );
////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
typedef typename std::remove_const<T>::type nonConstT;
nonConstT &hlp = const_cast<nonConstT&>(data);
@ -521,7 +516,7 @@ public:
std::string fName;
std::unique_ptr<boost::filesystem::ifstream> sfile;
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = version); //throws!
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION ); //throws!
~CLoadFile();
int read(void * data, unsigned size) override; //throws!

View File

@ -43,7 +43,7 @@ void CSaveFile::openNextFile(const boost::filesystem::path &fname)
THROW_FORMAT("Error: cannot open to write %s!", fname);
sfile->write("VCMI",4); //write magic identifier
serializer & version; //write format version
serializer & SERIALIZATION_VERSION; //write format version
}
catch(...)
{

View File

@ -102,7 +102,7 @@ class DLL_LINKAGE BinarySerializer : public CSaverBase
const T *ptr = static_cast<const T*>(data);
//T is most derived known type, it's time to call actual serialize
const_cast<T*>(ptr)->serialize(s,version);
const_cast<T*>(ptr)->serialize(s, SERIALIZATION_VERSION);
}
};
@ -235,7 +235,7 @@ public:
template < typename T, typename std::enable_if < is_serializeable<BinarySerializer, T>::value, int >::type = 0 >
void save(const T &data)
{
const_cast<T&>(data).serialize(*this,version);
const_cast<T&>(data).serialize(*this, SERIALIZATION_VERSION);
}
template <typename T>

View File

@ -22,7 +22,7 @@ public:
std::unique_ptr<CLoadFile> primaryFile, controlFile;
bool foundDesync;
CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion = version); //throws!
CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion = SERIALIZATION_VERSION); //throws!
int read( void * data, unsigned size) override; //throws!
void checkMagicBytes(const std::string &text);

View File

@ -36,5 +36,6 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this)
readPos = 0;
registerTypes(iser);
registerTypes(oser);
iser.fileVersion = SERIALIZATION_VERSION;
}

View File

@ -14,8 +14,8 @@
#include "../ConstTransitivePtr.h"
#include "../GameConstants.h"
const ui32 version = 761;
const ui32 minSupportedVersion = 753;
const ui32 SERIALIZATION_VERSION = 761;
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
const std::string SAVEGAME_MAGIC = "VCMISVG";
class CHero;

View File

@ -58,6 +58,7 @@ void CConnection::init()
receivedStop = sendStop = false;
static int cid = 1;
connectionID = cid++;
iser.fileVersion = SERIALIZATION_VERSION;
}
CConnection::CConnection(std::string host, std::string port, std::string Name)

View File

@ -49,6 +49,9 @@ class DLL_LINKAGE CConnection
void init();
void reportState(CLogger * out) override;
int write(const void * data, unsigned size) override;
int read(void * data, unsigned size) override;
public:
BinaryDeserializer iser;
BinarySerializer oser;
@ -70,8 +73,6 @@ public:
CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name);
CConnection(TSocket * Socket, std::string Name); //use immediately after accepting connection into socket
int write(const void * data, unsigned size) override;
int read(void * data, unsigned size) override;
void close();
bool isOpen() const;
template<class T>

View File

@ -464,7 +464,7 @@ void CVCMIServer::loadGame()
c >> clients >> fname; //how many clients should be connected
{
CLoadFile lf(*CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)), minSupportedVersion);
CLoadFile lf(*CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::SERVER_SAVEGAME)), MINIMAL_SERIALIZATION_VERSION);
gh.loadCommonState(lf);
lf >> gh;
}