2
0
Эх сурвалжийг харах

Fixes zero-initialized fileVersion member in deserializer

Ivan Savenko 9 жил өмнө
parent
commit
256f43f467

+ 1 - 5
client/CPreGame.cpp

@@ -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;

+ 1 - 1
client/Client.cpp

@@ -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();
 		}

+ 4 - 4
lib/serializer/BinaryDeserializer.cpp

@@ -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;

+ 8 - 13
lib/serializer/BinaryDeserializer.h

@@ -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!
 

+ 1 - 1
lib/serializer/BinarySerializer.cpp

@@ -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(...)
 	{

+ 2 - 2
lib/serializer/BinarySerializer.h

@@ -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>

+ 1 - 1
lib/serializer/CLoadIntegrityValidator.h

@@ -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);

+ 1 - 0
lib/serializer/CMemorySerializer.cpp

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

+ 2 - 2
lib/serializer/CSerializer.h

@@ -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;

+ 1 - 0
lib/serializer/Connection.cpp

@@ -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)

+ 3 - 2
lib/serializer/Connection.h

@@ -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>

+ 1 - 1
server/CVCMIServer.cpp

@@ -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;
 	}