1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +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) else if(current)
{ {
SelectMap sm(*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; *serv << &sm;
UpdateStartOptions uso(sInfo); UpdateStartOptions uso(sInfo);
@ -1148,7 +1144,7 @@ void SelectionTab::parseGames(const std::unordered_set<ResourceID> &files, bool
{ {
try try
{ {
CLoadFile lf(*CResourceHandler::get()->getResourceName(file), minSupportedVersion); CLoadFile lf(*CResourceHandler::get()->getResourceName(file), MINIMAL_SERIALIZATION_VERSION);
lf.checkMagicBytes(SAVEGAME_MAGIC); lf.checkMagicBytes(SAVEGAME_MAGIC);
// ui8 sign[8]; // ui8 sign[8];
// lf >> sign; // 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); throw std::runtime_error("Cannot open server part of " + fname);
{ {
CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion); CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, MINIMAL_SERIALIZATION_VERSION);
loadCommonState(checkingLoader); loadCommonState(checkingLoader);
loader = checkingLoader.decay(); 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) void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
{ {
assert(!serializer.reverseEndianess); assert(!serializer.reverseEndianess);
assert(minimalVersion <= version); assert(minimalVersion <= SERIALIZATION_VERSION);
try try
{ {
@ -55,15 +55,15 @@ void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalV
if(serializer.fileVersion < minimalVersion) if(serializer.fileVersion < minimalVersion)
THROW_FORMAT("Error: too old file format (%s)!", fName); 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; auto versionptr = (char*)&serializer.fileVersion;
std::reverse(versionptr, versionptr + 4); std::reverse(versionptr, versionptr + 4);
logGlobal->warnStream() << "Version number reversed is " << serializer.fileVersion << ", checking..."; 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."; logGlobal->warnStream() << fname << " seems to have different endianness! Entering reversing mode.";
serializer.reverseEndianess = true; 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 ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
s.ptrAllocated(ptr, pid); s.ptrAllocated(ptr, pid);
//T is most derived known type, it's time to call actual serialize //T is most derived known type, it's time to call actual serialize
assert(s.fileVersion != 0);
ptr->serialize(s,s.fileVersion); ptr->serialize(s,s.fileVersion);
return &typeid(T); 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 > 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) void load(T &data)
{ {
if(0) //for testing #989 unsigned length = sizeof(data);
{ char* dataPtr = (char*)&data;
this->read(&data,sizeof(data)); this->read(dataPtr,length);
} if(reverseEndianess)
else 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 > template < typename T, typename std::enable_if < is_serializeable<BinaryDeserializer, T>::value, int >::type = 0 >
void load(T &data) void load(T &data)
{ {
assert( fileVersion != 0 );
////that const cast is evil because it allows to implicitly overwrite const objects when deserializing ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing
typedef typename std::remove_const<T>::type nonConstT; typedef typename std::remove_const<T>::type nonConstT;
nonConstT &hlp = const_cast<nonConstT&>(data); nonConstT &hlp = const_cast<nonConstT&>(data);
@ -521,7 +516,7 @@ public:
std::string fName; std::string fName;
std::unique_ptr<boost::filesystem::ifstream> sfile; 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(); ~CLoadFile();
int read(void * data, unsigned size) override; //throws! 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); THROW_FORMAT("Error: cannot open to write %s!", fname);
sfile->write("VCMI",4); //write magic identifier sfile->write("VCMI",4); //write magic identifier
serializer & version; //write format version serializer & SERIALIZATION_VERSION; //write format version
} }
catch(...) catch(...)
{ {

View File

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

View File

@ -22,7 +22,7 @@ public:
std::unique_ptr<CLoadFile> primaryFile, controlFile; std::unique_ptr<CLoadFile> primaryFile, controlFile;
bool foundDesync; 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! int read( void * data, unsigned size) override; //throws!
void checkMagicBytes(const std::string &text); void checkMagicBytes(const std::string &text);

View File

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

View File

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

View File

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

View File

@ -49,6 +49,9 @@ class DLL_LINKAGE CConnection
void init(); void init();
void reportState(CLogger * out) override; void reportState(CLogger * out) override;
int write(const void * data, unsigned size) override;
int read(void * data, unsigned size) override;
public: public:
BinaryDeserializer iser; BinaryDeserializer iser;
BinarySerializer oser; BinarySerializer oser;
@ -70,8 +73,6 @@ public:
CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name); 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 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(); void close();
bool isOpen() const; bool isOpen() const;
template<class T> template<class T>

View File

@ -464,7 +464,7 @@ void CVCMIServer::loadGame()
c >> clients >> fname; //how many clients should be connected 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); gh.loadCommonState(lf);
lf >> gh; lf >> gh;
} }