Ejemplo n.º 1
0
void SyncManagerImpl::OnIdentityInfoReceived(const NetworkConnectionPtr& connection, NetworkInMessage& msg)
{
	size_t connectionIndex;
	if (GetIndexOfConnection(connection, connectionIndex))
	{
#if defined(SYNC_DEBUG)
		LogInfo("Sync: Received Handshake");
#endif

		RemoteSyncPeer& remotePeer = m_remoteHosts[connectionIndex];
		remotePeer.m_authorityLevel = static_cast<AuthorityLevel>(msg.ReadByte());
		remotePeer.m_systemID = msg.ReadInt32();
		remotePeer.m_userName = msg.ReadStdString();
		remotePeer.m_userID = msg.ReadInt32();


		// Verify that this systemID is not already in use by another machine.  If so, force a disconnection
		// rather than risk data corruption, because GUIDS are based on SystemIDs
		bool duplicateSystemIDFound = (m_syncContext->GetLocalSystemID() == remotePeer.m_systemID);
		if (!duplicateSystemIDFound)
		{
			for (size_t i = 0; i < m_remoteHosts.size(); ++i)
			{
				if (i == connectionIndex) continue;

				if (m_remoteHosts[i].m_systemID == remotePeer.m_systemID)
				{
					duplicateSystemIDFound = true;
					break;
				}
			}
		}
		
		// The sync system will break down if two machines of equal authority level connect.  
		// So verify that they are different levels, or else disconnect
		bool authLevelsMatch = (remotePeer.m_authorityLevel == m_syncContext->GetAuthorityLevel());

		if (duplicateSystemIDFound || authLevelsMatch)
		{	
			// We're registered to receive disconnect callbacks, so we know that SyncManagerImpl::OnDisconnected()
			// will be called as a result of calling this. 
			if (authLevelsMatch)
			{
				LogError("Two machines with equal authority levels have connected: breaking the connection to avoid sync data corruption");
			}
			else
			{
				LogError("Duplicate system ID detected: breaking the connection to avoid sync data corruption");
			}
			XTASSERT(!duplicateSystemIDFound);
			connection->Disconnect();
		}

		// We should not be receiving a handshake message more than once
		XTASSERT(remotePeer.m_bHandshakeComplete == false);

		remotePeer.m_bHandshakeComplete = true;
	}
}
Ejemplo n.º 2
0
void SyncManagerImpl::OnMessageReceived(const NetworkConnectionPtr& connection, NetworkInMessage& msg)
{
	SyncMessages messageType = (SyncMessages)msg.ReadByte();
	switch (messageType)
	{
	case IdentityInfo:
		OnIdentityInfoReceived(connection, msg);
		break;

	case SyncChanges:
		OnSyncChangeReceived(connection, msg);
		break;
	}
}
Ejemplo n.º 3
0
void SyncManagerImpl::OnSyncChangeReceived(const NetworkConnectionPtr& connection, NetworkInMessage& msg)
{
#if defined(SYNC_DEBUG)
	LogInfo("%s ReceivedSyncPacket", m_syncContext->GetLocalUser()->GetName().GetString().c_str());
#endif

	size_t connectionIndex;
	if (GetIndexOfConnection(connection, connectionIndex))
	{
		RemoteSyncPeer& remotePeer = m_remoteHosts[connectionIndex];

		if (XTVERIFY(remotePeer.m_bHandshakeComplete))
		{
			XTASSERT(remotePeer.m_systemID != kUnknownSystemID);

			// Read out the number of ops sent in this message
			int32 numOps = msg.ReadInt32();

			// Read out each of the ops
			for (int32 i = 0; i < numOps; ++i)
			{
				VersionedOp incomingVersionedOp;

				// Read the state that the remote machine was in before the op was applied
				incomingVersionedOp.m_state.m_opsSent = msg.ReadInt32();
				incomingVersionedOp.m_state.m_opsReceived = msg.ReadInt32();

				// Read the type of the op
				Operation::Type opType = (Operation::Type)msg.ReadByte();

				// Create an op of the appropriate type
				OperationPtr incomingOp = m_syncContext->GetOpFactory().Make(opType, remotePeer.m_authorityLevel);

				// Read the op data
				incomingOp->Deserialize(msg);

				incomingVersionedOp.m_op = incomingOp;

				// Add it to the list of incoming ops
				remotePeer.m_incoming.push_back(incomingVersionedOp);
			}
		}
	}
}
Ejemplo n.º 4
0
void CreateOperation::Deserialize(NetworkInMessage& msg)
{
	m_elementType	= (ElementType)msg.ReadByte();
	m_name			= msg.ReadString();
	m_elementGuid	= msg.ReadInt64();
	m_parentGuid	= msg.ReadInt64();
	m_startingValue.Deserialize(msg);

	// Read the number of ancestors
	uint32 numAncestors = msg.ReadUInt32();
	m_hierarchy.reserve(numAncestors);

	// Read the GUIDs of the ancestors
	for (uint32 i = 0; i < numAncestors; ++i)
	{
		m_hierarchy.push_back(msg.ReadInt64());
	}

	// NOTE: authority level is NOT included in the op when serialized; it changes as the op is sent around the network
}