浏览代码

Merge pull request #4339 from IvanSavenko/artifact_crash_fix

Fixed crash on deserialization of new artifacts (and possibly some other objects)
Ivan Savenko 1 年之前
父节点
当前提交
7fe9c473b4

+ 1 - 1
lib/bonuses/Bonus.h

@@ -53,7 +53,7 @@ public:
 	JsonNode toJsonNode() const;
 };
 
-#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
+#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.loadingGamestate) deserializationFix();
 
 /// Struct for handling bonuses of several types. Can be transferred to any hero
 struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>, public Serializeable

+ 4 - 0
lib/networkPacks/PacksForLobby.h

@@ -155,9 +155,13 @@ struct DLL_LINKAGE LobbyStartGame : public CLobbyPackToPropagate
 
 	template <typename Handler> void serialize(Handler &h)
 	{
+		if (!h.saving)
+			h.loadingGamestate = true;
 		h & clientId;
 		h & initializedStartInfo;
 		h & initializedGameState;
+		if (!h.saving)
+			h.loadingGamestate = false;
 	}
 };
 

+ 0 - 2
lib/serializer/BinaryDeserializer.cpp

@@ -15,9 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 BinaryDeserializer::BinaryDeserializer(IBinaryReader * r): CLoaderBase(r)
 {
-	saving = false;
 	version = Version::NONE;
-	smartPointerSerialization = true;
 	reverseEndianness = false;
 
 	registerTypes(*this);

+ 5 - 4
lib/serializer/BinaryDeserializer.h

@@ -165,8 +165,9 @@ public:
 	std::map<uint32_t, Serializeable*> loadedPointers;
 	std::map<const Serializeable*, std::shared_ptr<Serializeable>> loadedSharedPointers;
 	IGameCallback * cb = nullptr;
-	bool smartPointerSerialization;
-	bool saving;
+	static constexpr bool trackSerializedPointers = true;
+	static constexpr bool saving = false;
+	bool loadingGamestate = false;
 
 	bool hasFeature(Version what) const
 	{
@@ -342,7 +343,7 @@ public:
 		}
 
 		uint32_t pid = 0xffffffff; //pointer id (or maybe rather pointee id)
-		if(smartPointerSerialization)
+		if(trackSerializedPointers)
 		{
 			load( pid ); //get the id
 			auto i = loadedPointers.find(pid); //lookup
@@ -383,7 +384,7 @@ public:
 	template <typename T>
 	void ptrAllocated(T *ptr, uint32_t pid)
 	{
-		if(smartPointerSerialization && pid != 0xffffffff)
+		if(trackSerializedPointers && pid != 0xffffffff)
 			loadedPointers[pid] = const_cast<Serializeable*>(dynamic_cast<const Serializeable*>(ptr)); //add loaded pointer to our lookup map; cast is to avoid errors with const T* pt
 	}
 

+ 0 - 2
lib/serializer/BinarySerializer.cpp

@@ -15,8 +15,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 BinarySerializer::BinarySerializer(IBinaryWriter * w): CSaverBase(w)
 {
-	saving=true;
-	smartPointerSerialization = true;
 	registerTypes(*this);
 }
 

+ 4 - 3
lib/serializer/BinarySerializer.h

@@ -118,8 +118,9 @@ public:
 	std::map<const Serializeable*, uint32_t> savedPointers;
 
 	Version version = Version::CURRENT;
-	bool smartPointerSerialization;
-	bool saving;
+	static constexpr bool trackSerializedPointers = true;
+	static constexpr bool saving = true;
+	bool loadingGamestate = false;
 
 	bool hasFeature(Version what) const
 	{
@@ -257,7 +258,7 @@ public:
 				return;
 		}
 
-		if(smartPointerSerialization)
+		if(trackSerializedPointers)
 		{
 			// We might have an object that has multiple inheritance and store it via the non-first base pointer.
 			// Therefore, all pointers need to be normalized to the actual object address.

+ 1 - 0
lib/serializer/CLoadFile.cpp

@@ -29,6 +29,7 @@ int CLoadFile::read(std::byte * data, unsigned size)
 
 void CLoadFile::openNextFile(const boost::filesystem::path & fname, ESerializationVersion minimalVersion)
 {
+	serializer.loadingGamestate = true;
 	assert(!serializer.reverseEndianness);
 	assert(minimalVersion <= ESerializationVersion::CURRENT);
 

+ 0 - 12
lib/serializer/Connection.cpp

@@ -151,18 +151,6 @@ void CConnection::enterGameplayConnectionMode(CGameState * gs)
 	enableSmartVectorMemberSerializatoin(gs);
 }
 
-void CConnection::disableSmartPointerSerialization()
-{
-	deserializer->smartPointerSerialization = false;
-	serializer->smartPointerSerialization = false;
-}
-
-void CConnection::enableSmartPointerSerialization()
-{
-	deserializer->smartPointerSerialization = true;
-	serializer->smartPointerSerialization = true;
-}
-
 void CConnection::disableSmartVectorMemberSerialization()
 {
 	packReader->smartVectorMembersSerialization = false;

+ 0 - 2
lib/serializer/Connection.h

@@ -38,8 +38,6 @@ class DLL_LINKAGE CConnection : boost::noncopyable
 
 	void disableStackSendingByID();
 	void enableStackSendingByID();
-	void disableSmartPointerSerialization();
-	void enableSmartPointerSerialization();
 	void disableSmartVectorMemberSerialization();
 	void enableSmartVectorMemberSerializatoin(CGameState * gs);