Browse Source

Implemented simple versioning system for multiplayer

Ivan Savenko 1 year ago
parent
commit
888149c6f6

+ 1 - 0
client/NetPacksLobbyClient.cpp

@@ -43,6 +43,7 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
 	// Check if it's LobbyClientConnected for our client
 	if(pack.uuid == handler.logicConnection->uuid)
 	{
+		handler.logicConnection->setSerializationVersion(pack.version);
 		handler.logicConnection->connectionID = pack.clientId;
 		if(handler.mapToStart)
 		{

+ 1 - 1
lib/mapObjects/CBank.h

@@ -53,7 +53,7 @@ public:
 		h & coastVisitable;
 		if (h.version >= Handler::Version::BANK_UNIT_PLACEMENT)
 			h & regularUnitPlacement;
-		else
+		else if (!h.saving)
 			regularUnitPlacement = false;
 	}
 

+ 14 - 0
lib/networkPacks/PacksForLobby.h

@@ -12,6 +12,7 @@
 #include "StartInfo.h"
 #include "NetPacksBase.h"
 #include "../MetaString.h"
+#include "../serializer/ESerializationVersion.h"
 
 class CServerHandler;
 class CVCMIServer;
@@ -42,6 +43,7 @@ struct DLL_LINKAGE LobbyClientConnected : public CLobbyPackToPropagate
 	// Changed by server before announcing pack
 	int clientId = -1;
 	int hostClientId = -1;
+	ESerializationVersion version = ESerializationVersion::CURRENT;
 
 	void visitTyped(ICPackVisitor & visitor) override;
 
@@ -53,6 +55,18 @@ struct DLL_LINKAGE LobbyClientConnected : public CLobbyPackToPropagate
 
 		h & clientId;
 		h & hostClientId;
+
+		try
+		{
+			if (h.version >= Handler::Version::RELEASE_152)
+				h & version;
+			else
+				version = ESerializationVersion::RELEASE_150;
+		}
+		 catch (const std::runtime_error & e)
+		{
+			version = ESerializationVersion::RELEASE_150;
+		}
 	}
 };
 

+ 1 - 1
lib/serializer/BinarySerializer.h

@@ -115,7 +115,7 @@ public:
 
 	std::map<const void*, ui32> savedPointers;
 
-	const Version version = Version::CURRENT;
+	Version version = Version::CURRENT;
 	bool smartPointerSerialization;
 	bool saving;
 

+ 6 - 0
lib/serializer/Connection.cpp

@@ -173,4 +173,10 @@ void CConnection::enableSmartVectorMemberSerializatoin(CGameState * gs)
 	packReader->addStdVecItems(gs);
 }
 
+void CConnection::setSerializationVersion(ESerializationVersion version)
+{
+	deserializer->version = version;
+	serializer->version = version;
+}
+
 VCMI_LIB_NAMESPACE_END

+ 3 - 0
lib/serializer/Connection.h

@@ -9,6 +9,8 @@
  */
 #pragma once
 
+enum class ESerializationVersion : int32_t;
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 class BinaryDeserializer;
@@ -57,6 +59,7 @@ public:
 	void enterLobbyConnectionMode();
 	void setCallback(IGameCallback * cb);
 	void enterGameplayConnectionMode(CGameState * gs);
+	void setSerializationVersion(ESerializationVersion version);
 };
 
 VCMI_LIB_NAMESPACE_END

+ 5 - 2
lib/serializer/ESerializationVersion.h

@@ -32,6 +32,7 @@ enum class ESerializationVersion : int32_t
 	NONE = 0,
 
 	MINIMAL = 831,
+
 	RELEASE_143, // 832 +text container in campaigns, +starting hero in RMG options
 	HAS_EXTRA_OPTIONS, // 833 +extra options struct as part of startinfo
 	DESTROYED_OBJECTS, // 834 +list of objects destroyed by player
@@ -43,10 +44,12 @@ enum class ESerializationVersion : int32_t
 	ARTIFACT_COSTUMES, // 840 swappable artifacts set added
 
 	RELEASE_150 = ARTIFACT_COSTUMES, // for convenience
+
 	VOTING_SIMTURNS, // 841 - allow modification of simturns duration via vote
+	REMOVE_TEXT_CONTAINER_SIZE_T, // 842 Fixed serialization of size_t from text containers
+	BANK_UNIT_PLACEMENT, // 843 Banks have unit placement flag
 
-	REMOVE_TEXT_CONTAINER_SIZE_T, // Fixed serialization of size_t from text containers
-	BANK_UNIT_PLACEMENT, // 842
+	RELEASE_152 = BANK_UNIT_PLACEMENT,
 
 	CURRENT = BANK_UNIT_PLACEMENT
 };

+ 5 - 0
server/NetPacksLobbyServer.cpp

@@ -46,11 +46,16 @@ void ClientPermissionsCheckerNetPackVisitor::visitLobbyClientConnected(LobbyClie
 
 void ApplyOnServerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
 {
+	auto compatibleVersion = std::min(pack.version, ESerializationVersion::CURRENT);
+	pack.c->setSerializationVersion(compatibleVersion);
+
 	srv.clientConnected(pack.c, pack.names, pack.uuid, pack.mode);
+
 	// Server need to pass some data to newly connected client
 	pack.clientId = pack.c->connectionID;
 	pack.mode = srv.si->mode;
 	pack.hostClientId = srv.hostClientId;
+	pack.version = compatibleVersion;
 
 	result = true;
 }

+ 5 - 0
server/processors/TurnOrderProcessor.h

@@ -113,5 +113,10 @@ public:
 			h & simturnsMinDurationDays;
 			h & simturnsMaxDurationDays;
 		}
+		else if (!h.saving)
+		{
+			simturnsMinDurationDays.reset();
+			simturnsMaxDurationDays.reset();
+		}
 	}
 };