mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-11-04 06:32:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1977 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1977 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "ReplicaManager2.h"
 | 
						|
#include "MessageIdentifiers.h"
 | 
						|
#include "RakAssert.h"
 | 
						|
#include "RakPeerInterface.h"
 | 
						|
#include "NetworkIDManager.h"
 | 
						|
 | 
						|
using namespace RakNet;
 | 
						|
 | 
						|
unsigned char Replica2::clientSharedID=0;
 | 
						|
Replica2* Replica2::clientPtrArray[256];
 | 
						|
 | 
						|
 | 
						|
#ifdef _MSC_VER
 | 
						|
#pragma warning( push )
 | 
						|
#endif
 | 
						|
 | 
						|
bool SerializationContext::IsSerializationCommand(SerializationType r)
 | 
						|
{
 | 
						|
	return r>=SEND_SERIALIZATION_GENERIC_TO_SYSTEM && r<=RELAY_SERIALIZATION_TO_SYSTEMS;
 | 
						|
}
 | 
						|
bool SerializationContext::IsDownloadCommand(SerializationType r)
 | 
						|
{
 | 
						|
	return r>=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM && r<=SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
 | 
						|
}
 | 
						|
bool SerializationContext::IsDestructionCommand(SerializationType r)
 | 
						|
{
 | 
						|
	return r>=SEND_DESTRUCTION_GENERIC_TO_SYSTEM && r<=RELAY_DESTRUCTION_TO_SYSTEMS;
 | 
						|
}
 | 
						|
bool SerializationContext::IsConstructionCommand(SerializationType r)
 | 
						|
{
 | 
						|
	return r>=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM && r<=SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT;
 | 
						|
}
 | 
						|
bool SerializationContext::IsVisibilityCommand(SerializationType r)
 | 
						|
{
 | 
						|
	return r>=SEND_VISIBILITY_TRUE_TO_SYSTEM && r<=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
 | 
						|
}
 | 
						|
bool SerializationContext::IsVisible(SerializationType r)
 | 
						|
{
 | 
						|
	return r==SEND_VISIBILITY_TRUE_TO_SYSTEM || r==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM || r==RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
 | 
						|
}
 | 
						|
 | 
						|
int ReplicaManager2::Replica2CompByNetworkID( const NetworkID &key, RakNet::Replica2 * const &data )
 | 
						|
{
 | 
						|
	if (key < data->GetNetworkID())
 | 
						|
		return -1;
 | 
						|
	if (key == data->GetNetworkID())
 | 
						|
		return 0;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
int ReplicaManager2::Replica2ObjectComp( RakNet::Replica2 * const &key, RakNet::Replica2 * const &data )
 | 
						|
{
 | 
						|
	if (key->GetAllocationNumber()<data->GetAllocationNumber())
 | 
						|
		return -1;
 | 
						|
	if (key->GetAllocationNumber()==data->GetAllocationNumber())
 | 
						|
		return 0;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
int ReplicaManager2::Connection_RM2CompBySystemAddress( const SystemAddress &key, RakNet::Connection_RM2 * const &data )
 | 
						|
{
 | 
						|
	if (key < data->GetSystemAddress())
 | 
						|
		return -1;
 | 
						|
	if (key == data->GetSystemAddress())
 | 
						|
		return 0;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
ReplicaManager2::ReplicaManager2()
 | 
						|
{
 | 
						|
	connectionFactoryInterface=0;
 | 
						|
	defaultOrderingChannel=0;
 | 
						|
	defaultPacketPriority=HIGH_PRIORITY;
 | 
						|
	defaultPacketReliablity=RELIABLE_ORDERED;
 | 
						|
	autoUpdateConstruction=true;
 | 
						|
	autoUpdateVisibility=true;
 | 
						|
	autoAddNewConnections=true;
 | 
						|
	doReplicaAutoUpdate=true;
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress>::IMPLEMENT_DEFAULT_COMPARISON();
 | 
						|
}
 | 
						|
ReplicaManager2::~ReplicaManager2()
 | 
						|
{
 | 
						|
}
 | 
						|
void ReplicaManager2::SendConstruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
 | 
						|
						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
 | 
						|
						unsigned char localClientId, SerializationType type, 
 | 
						|
						PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	if (replica==0)
 | 
						|
		return;
 | 
						|
 | 
						|
	// Why would you request an object you already have?
 | 
						|
	if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID && replica->QueryIsConstructionAuthority()==false)
 | 
						|
		return;
 | 
						|
 | 
						|
	RakAssert(replica->QueryConstruction(0)!=BQR_NEVER);
 | 
						|
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection;
 | 
						|
 | 
						|
	// Add to list of replicas if not already there
 | 
						|
	bool newReference;
 | 
						|
	Reference(replica, &newReference);
 | 
						|
	
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	WriteHeader(&bs, ID_REPLICA_MANAGER_CONSTRUCTION, timestamp);
 | 
						|
	bs.Write((unsigned char) type);
 | 
						|
	bs.Write(replica->GetNetworkID());
 | 
						|
	bs.Write(localClientId);
 | 
						|
	
 | 
						|
	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
 | 
						|
	{
 | 
						|
		connection = AutoCreateConnection(recipient, &newConnection);
 | 
						|
		if (connection==0)
 | 
						|
			return;
 | 
						|
 | 
						|
		if (newConnection)
 | 
						|
		{
 | 
						|
			// If a new connection, the replica was constructed automatically anyway
 | 
						|
			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
 | 
						|
			return;
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		// Lookup connection by target. If does not exist, create
 | 
						|
		
 | 
						|
		AddConstructionReference(connection, replica);
 | 
						|
		if (sendMessage)
 | 
						|
		{
 | 
						|
			// Send the packet
 | 
						|
			Send(&bs, recipient, priority, reliability, orderingChannel);
 | 
						|
 | 
						|
			if (newReference && replica->QueryVisibility(connection)==BQR_ALWAYS)
 | 
						|
			{
 | 
						|
//				SerializationContext sc;
 | 
						|
//				sc.recipientAddress=recipient;
 | 
						|
//				sc.timestamp=timestamp;
 | 
						|
//				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
//				sc.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
 | 
						|
				replica->SendSerialize(recipient, SEND_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
 | 
						|
		CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
 | 
						|
		WriteExclusionList(&bs, exclusionList);
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		unsigned i;
 | 
						|
		for (i=0; i < culledOutput.Size(); i++)
 | 
						|
		{
 | 
						|
			connection=culledOutput[i];
 | 
						|
			AddConstructionReference(connection, replica);
 | 
						|
 | 
						|
			if (sendMessage)
 | 
						|
				Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
 | 
						|
			if (newReference && replica->QueryIsSerializationAuthority() && replica->QueryVisibility(connection)==BQR_ALWAYS)
 | 
						|
			{
 | 
						|
//				SerializationContext sc;
 | 
						|
//				sc.recipientAddress=connection->GetSystemAddress();
 | 
						|
//				sc.timestamp=0;
 | 
						|
//				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
//				sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
 | 
						|
				replica->SendSerialize(connection->GetSystemAddress(), BROADCAST_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}	
 | 
						|
}
 | 
						|
 | 
						|
void ReplicaManager2::SendDestruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
 | 
						|
						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
 | 
						|
						SerializationType type, 
 | 
						|
						PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	if (replica==0)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (replica->QueryIsDestructionAuthority()==false)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
 | 
						|
	{
 | 
						|
		bool newConnection;
 | 
						|
 | 
						|
		// Lookup connection by target. If does not exist, create
 | 
						|
		Connection_RM2* connection = AutoCreateConnection(recipient, &newConnection);
 | 
						|
		if (connection==0)
 | 
						|
			return;
 | 
						|
 | 
						|
		// Have this system stop referencing the replica object
 | 
						|
		connection->Deref(replica);
 | 
						|
 | 
						|
		if (newConnection)
 | 
						|
		{
 | 
						|
			// If a new connection, the object didn't exist anyway
 | 
						|
			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (sendMessage && replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID)
 | 
						|
	{
 | 
						|
		// Send the packet
 | 
						|
		RakNet::BitStream bs;
 | 
						|
		WriteHeader(&bs, ID_REPLICA_MANAGER_DESTRUCTION, timestamp);
 | 
						|
		bs.Write((unsigned char) type);
 | 
						|
		bs.Write(replica->GetNetworkID());
 | 
						|
		
 | 
						|
		if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
 | 
						|
		{
 | 
						|
			if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
 | 
						|
				return;
 | 
						|
			bs.Write(replicaData);
 | 
						|
 | 
						|
			Send(&bs, recipient, priority, reliability, orderingChannel);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
 | 
						|
			GetConnectionsWithReplicaConstructed(replica, output);
 | 
						|
			CullByAndAddToExclusionList(output, culledOutput, exclusionList);
 | 
						|
			WriteExclusionList(&bs, exclusionList);
 | 
						|
			bs.Write(replicaData);
 | 
						|
 | 
						|
			unsigned i;
 | 
						|
			for (i=0; i < output.Size(); i++)
 | 
						|
				Send(&bs, output[i]->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ReplicaManager2::SendSerialize(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
 | 
						|
						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
 | 
						|
						SerializationType type, 
 | 
						|
						 PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	if (replica==0)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (replica->QueryIsSerializationAuthority()==false)
 | 
						|
		return;
 | 
						|
 | 
						|
	// Add to list of replicas if not already there
 | 
						|
	bool newReference;
 | 
						|
	Reference(replica, &newReference);
 | 
						|
 | 
						|
	if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		replica->BroadcastConstruction();
 | 
						|
	}
 | 
						|
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection;
 | 
						|
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	WriteHeader(&bs, ID_REPLICA_MANAGER_SERIALIZE, timestamp);
 | 
						|
	bs.Write((unsigned char) type);
 | 
						|
	bs.Write(replica->GetNetworkID());
 | 
						|
 | 
						|
	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
 | 
						|
	{
 | 
						|
		connection = AutoCreateConnection(recipient, &newConnection);
 | 
						|
		if (connection==0)
 | 
						|
			return;
 | 
						|
		if (newConnection)
 | 
						|
			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
 | 
						|
		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
 | 
						|
			return;
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		// Send the packet
 | 
						|
		Send(&bs, recipient, priority, reliability, orderingChannel);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
 | 
						|
		GetConnectionsWithSerializeVisibility(replica, output);
 | 
						|
 | 
						|
		CullByAndAddToExclusionList(output, culledOutput, exclusionList);
 | 
						|
		WriteExclusionList(&bs, exclusionList);
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		unsigned i;
 | 
						|
		for (i=0; i < culledOutput.Size(); i++)
 | 
						|
		{
 | 
						|
			connection=culledOutput[i];	
 | 
						|
			Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
		}
 | 
						|
	}	
 | 
						|
}
 | 
						|
void ReplicaManager2::SendVisibility(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
 | 
						|
							 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
 | 
						|
							 SerializationType type, 
 | 
						|
							 PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	if (replica==0)
 | 
						|
		return;
 | 
						|
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection;
 | 
						|
 | 
						|
	if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
 | 
						|
		return;
 | 
						|
 | 
						|
	// Add to list of replicas if not already there
 | 
						|
	bool newReference;
 | 
						|
	Reference(replica, &newReference);
 | 
						|
 | 
						|
	if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		replica->BroadcastConstruction();
 | 
						|
	}
 | 
						|
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	WriteHeader(&bs, ID_REPLICA_MANAGER_SCOPE_CHANGE, timestamp);
 | 
						|
	bs.Write((unsigned char) type);
 | 
						|
	bs.Write(replica->GetNetworkID());
 | 
						|
 | 
						|
	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
 | 
						|
	{
 | 
						|
		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
 | 
						|
			return;
 | 
						|
 | 
						|
		connection = AutoCreateConnection(recipient, &newConnection);
 | 
						|
		if (connection==0)
 | 
						|
			return;
 | 
						|
		if (newConnection)
 | 
						|
			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		if (SerializationContext::IsVisibilityCommand(type))
 | 
						|
		{
 | 
						|
			if (SerializationContext::IsVisible(type))
 | 
						|
				AddVisibilityReference(connection, replica);
 | 
						|
			else
 | 
						|
				RemoveVisibilityReference(connection, replica);
 | 
						|
		}
 | 
						|
		// Send the packet
 | 
						|
		Send(&bs, recipient, priority, reliability, orderingChannel);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
 | 
						|
		CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
 | 
						|
		WriteExclusionList(&bs, exclusionList);
 | 
						|
		bs.Write(replicaData);
 | 
						|
 | 
						|
		unsigned i;
 | 
						|
		for (i=0; i < culledOutput.Size(); i++)
 | 
						|
		{
 | 
						|
			connection=culledOutput[i];
 | 
						|
			if (SerializationContext::IsVisible(type))
 | 
						|
				AddVisibilityReference(connection, replica);
 | 
						|
			else
 | 
						|
				RemoveVisibilityReference(connection, replica);
 | 
						|
			Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
		}
 | 
						|
	}	
 | 
						|
}
 | 
						|
void ReplicaManager2::Dereference(Replica2 *replica)
 | 
						|
{
 | 
						|
	unsigned i;
 | 
						|
	if (replica==0)
 | 
						|
		return;
 | 
						|
 | 
						|
	for (i=0; i < connectionList.Size(); i++)
 | 
						|
	{
 | 
						|
		connectionList[i]->lastConstructionList.RemoveIfExists(replica);
 | 
						|
		connectionList[i]->lastSerializationList.RemoveIfExists(replica);
 | 
						|
	}
 | 
						|
 | 
						|
	for (i=0; i < fullReplicaUnorderedList.Size(); i++)
 | 
						|
	{
 | 
						|
		if (fullReplicaUnorderedList[i]==replica)
 | 
						|
		{
 | 
						|
			fullReplicaUnorderedList.RemoveAtIndex(i);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	fullReplicaOrderedList.RemoveIfExists(replica);
 | 
						|
	alwaysDoConstructReplicaOrderedList.RemoveIfExists(replica);
 | 
						|
	alwaysDoSerializeReplicaOrderedList.RemoveIfExists(replica);
 | 
						|
	variableConstructReplicaOrderedList.RemoveIfExists(replica);
 | 
						|
	variableSerializeReplicaOrderedList.RemoveIfExists(replica);
 | 
						|
}
 | 
						|
void ReplicaManager2::Update(RakPeerInterface *peer)
 | 
						|
{
 | 
						|
	(void) peer;
 | 
						|
 | 
						|
	unsigned i;
 | 
						|
 | 
						|
	if (autoUpdateConstruction || autoUpdateVisibility)
 | 
						|
	{
 | 
						|
		for (i=0; i < connectionList.Size(); i++)
 | 
						|
		{
 | 
						|
			if (autoUpdateConstruction)
 | 
						|
				connectionList[i]->SetConstructionByReplicaQuery(this);
 | 
						|
			if (autoUpdateVisibility)
 | 
						|
				connectionList[i]->SetVisibilityByReplicaQuery(this);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (doReplicaAutoUpdate)
 | 
						|
	{
 | 
						|
		RakNetTime currentTime = RakNet::GetTime();
 | 
						|
		for (i=0; i < fullReplicaUnorderedList.Size(); i++)
 | 
						|
		{
 | 
						|
			fullReplicaUnorderedList[i]->ElapseAutoSerializeTimers(currentTime-lastUpdateTime,false);
 | 
						|
		}
 | 
						|
		lastUpdateTime=currentTime;
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
unsigned ReplicaManager2::GetReplicaCount(void) const
 | 
						|
{
 | 
						|
	return fullReplicaUnorderedList.Size();
 | 
						|
}
 | 
						|
Replica2 *ReplicaManager2::GetReplicaAtIndex(unsigned index)
 | 
						|
{
 | 
						|
	return fullReplicaUnorderedList[index];
 | 
						|
}
 | 
						|
void ReplicaManager2::SetAutoAddNewConnections(bool autoDownload)
 | 
						|
{
 | 
						|
	autoAddNewConnections=autoDownload;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetDoReplicaAutoSerializeUpdate(bool autoUpdate)
 | 
						|
{
 | 
						|
	doReplicaAutoUpdate=autoUpdate;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetConnectionFactory(Connection_RM2Factory *factory)
 | 
						|
{
 | 
						|
	RakAssert(factory);
 | 
						|
	connectionFactoryInterface=factory;
 | 
						|
}
 | 
						|
unsigned ReplicaManager2::GetConnectionCount(void) const
 | 
						|
{
 | 
						|
	return connectionList.Size();
 | 
						|
}
 | 
						|
Connection_RM2* ReplicaManager2::GetConnectionAtIndex(unsigned index) const
 | 
						|
{
 | 
						|
	return connectionList[index];
 | 
						|
}
 | 
						|
Connection_RM2* ReplicaManager2::GetConnectionBySystemAddress(SystemAddress systemAddress) const
 | 
						|
{
 | 
						|
	bool objectExists;
 | 
						|
	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
 | 
						|
	if (objectExists)
 | 
						|
		return connectionList[index];
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
unsigned int ReplicaManager2::GetConnectionIndexBySystemAddress(SystemAddress systemAddress) const
 | 
						|
{
 | 
						|
	bool objectExists;
 | 
						|
	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
 | 
						|
	if (objectExists)
 | 
						|
		return index;
 | 
						|
	return (unsigned int) -1;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetDefaultOrderingChannel(char def)
 | 
						|
{
 | 
						|
	defaultOrderingChannel=def;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetDefaultPacketPriority(PacketPriority def)
 | 
						|
{
 | 
						|
	defaultPacketPriority=def;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetDefaultPacketReliability(PacketReliability def)
 | 
						|
{
 | 
						|
	defaultPacketReliablity=def;
 | 
						|
}
 | 
						|
void ReplicaManager2::SetAutoUpdateScope(bool construction, bool visibility)
 | 
						|
{
 | 
						|
	autoUpdateConstruction=construction;
 | 
						|
	autoUpdateVisibility=visibility;
 | 
						|
}
 | 
						|
void ReplicaManager2::RecalculateVisibility(Replica2 *replica)
 | 
						|
{
 | 
						|
	Dereference(replica);
 | 
						|
	bool newReference;
 | 
						|
	Reference(replica, &newReference);
 | 
						|
 | 
						|
	if (replica->QueryConstruction(0)==BQR_NEVER && autoUpdateConstruction)
 | 
						|
	{
 | 
						|
		// Destroy on all systems
 | 
						|
		replica->SendDestruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_DESTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
 | 
						|
	}
 | 
						|
	if (replica->QueryConstruction(0)==BQR_ALWAYS && autoUpdateConstruction)
 | 
						|
	{
 | 
						|
		// Create on all systems
 | 
						|
		replica->SendConstruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_CONSTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
 | 
						|
	}
 | 
						|
	if (replica->QueryVisibility(0)==BQR_ALWAYS && autoUpdateVisibility)
 | 
						|
	{
 | 
						|
		// Set visibility and creation on all systems
 | 
						|
		replica->SendVisibility(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
 | 
						|
		replica->SendSerialize(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
 | 
						|
	}
 | 
						|
}
 | 
						|
void ReplicaManager2::GetConnectionsWithReplicaConstructed(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
 | 
						|
{
 | 
						|
	BooleanQueryResult res;
 | 
						|
	res = replica->QueryConstruction(0);
 | 
						|
	if (res==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		output=connectionList;
 | 
						|
	}
 | 
						|
	else if (res!=BQR_NEVER)
 | 
						|
	{
 | 
						|
		unsigned i;
 | 
						|
		for (i=0; i < connectionList.Size(); i++)
 | 
						|
		{
 | 
						|
			if (connectionList[i]->lastConstructionList.HasData(replica))
 | 
						|
				output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
void ReplicaManager2::GetConnectionsWithSerializeVisibility(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
 | 
						|
{
 | 
						|
	BooleanQueryResult res;
 | 
						|
	res = replica->QueryVisibility(0);
 | 
						|
	if (res==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		GetConnectionsWithReplicaConstructed(replica, output);
 | 
						|
	}
 | 
						|
	else if (res!=BQR_NEVER)
 | 
						|
	{
 | 
						|
		unsigned i;
 | 
						|
		for (i=0; i < connectionList.Size(); i++)
 | 
						|
		{
 | 
						|
			if (connectionList[i]->lastSerializationList.HasData(replica))
 | 
						|
				output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
RakPeerInterface *ReplicaManager2::GetRakPeer(void) const
 | 
						|
{
 | 
						|
	return rakPeer;
 | 
						|
}
 | 
						|
Connection_RM2* ReplicaManager2::AutoCreateConnection(SystemAddress systemAddress, bool *newConnection)
 | 
						|
{
 | 
						|
	if (autoAddNewConnections)
 | 
						|
		return CreateConnectionIfDoesNotExist(systemAddress, newConnection);
 | 
						|
	else
 | 
						|
	{
 | 
						|
		bool objectExists;
 | 
						|
		unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
 | 
						|
		*newConnection=false;
 | 
						|
		if (objectExists==false)
 | 
						|
		{
 | 
						|
			return 0;
 | 
						|
		}
 | 
						|
		return connectionList[index];
 | 
						|
	}
 | 
						|
}
 | 
						|
Connection_RM2* ReplicaManager2::CreateConnectionIfDoesNotExist(SystemAddress systemAddress, bool *newConnection)
 | 
						|
{
 | 
						|
	bool objectExists;
 | 
						|
	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
 | 
						|
	if (objectExists==false)
 | 
						|
	{
 | 
						|
		// If it crashes here, you need to call SetConnection_RM2Factory
 | 
						|
		Connection_RM2 *connection = connectionFactoryInterface->AllocConnection();
 | 
						|
		connection->SetSystemAddress(systemAddress);
 | 
						|
		connectionList.Insert(systemAddress, connection, false);
 | 
						|
		*newConnection=true;
 | 
						|
		return connection;
 | 
						|
	}
 | 
						|
	*newConnection=false;
 | 
						|
	return connectionList[index];
 | 
						|
}
 | 
						|
bool ReplicaManager2::AddNewConnection(SystemAddress systemAddress)
 | 
						|
{
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection = CreateConnectionIfDoesNotExist(systemAddress, &newConnection);
 | 
						|
	if (newConnection)
 | 
						|
		DownloadToNewConnection(connection, 0, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
	return newConnection;
 | 
						|
}
 | 
						|
bool ReplicaManager2::RemoveConnection(SystemAddress systemAddress)
 | 
						|
{
 | 
						|
	unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
 | 
						|
	if (index!=(unsigned int) -1)
 | 
						|
	{
 | 
						|
		connectionFactoryInterface->DeallocConnection(connectionList[index]);
 | 
						|
		connectionList.RemoveAtIndex(index);
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
bool ReplicaManager2::HasConnection(SystemAddress systemAddress)
 | 
						|
{
 | 
						|
	unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
 | 
						|
	return index!=(unsigned int) -1;
 | 
						|
}
 | 
						|
void ReplicaManager2::Reference(Replica2* replica, bool *newReference)
 | 
						|
{
 | 
						|
	replica->SetReplicaManager(this);
 | 
						|
 | 
						|
	bool objectExists;
 | 
						|
	unsigned index = fullReplicaOrderedList.GetIndexFromKey(replica,&objectExists);
 | 
						|
	if (objectExists==false)
 | 
						|
	{
 | 
						|
		fullReplicaUnorderedList.Insert(replica);
 | 
						|
		fullReplicaOrderedList.InsertAtIndex(replica, index);
 | 
						|
 | 
						|
		BooleanQueryResult queryResult;
 | 
						|
		queryResult = replica->QueryConstruction(0);
 | 
						|
		if (queryResult==BQR_ALWAYS)
 | 
						|
			alwaysDoConstructReplicaOrderedList.Insert(replica,replica, false);
 | 
						|
		else if (queryResult!=BQR_NEVER)
 | 
						|
			variableConstructReplicaOrderedList.Insert(replica,replica, false);
 | 
						|
		queryResult = replica->QueryVisibility(0);
 | 
						|
		if (queryResult==BQR_ALWAYS)
 | 
						|
			alwaysDoSerializeReplicaOrderedList.Insert(replica,replica, false);
 | 
						|
		else if (queryResult!=BQR_NEVER)
 | 
						|
			variableSerializeReplicaOrderedList.Insert(replica,replica, false);
 | 
						|
 | 
						|
		*newReference=true;
 | 
						|
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	*newReference=false;
 | 
						|
}
 | 
						|
void ReplicaManager2::AddConstructionReference(Connection_RM2* connection, Replica2* replica)
 | 
						|
{
 | 
						|
	if (replica->QueryIsConstructionAuthority() && replica->QueryConstruction(0)!=BQR_ALWAYS && replica->QueryConstruction(0)!=BQR_NEVER)
 | 
						|
		connection->lastConstructionList.Insert(replica, replica, false);
 | 
						|
}
 | 
						|
void ReplicaManager2::AddVisibilityReference(Connection_RM2* connection, Replica2* replica)
 | 
						|
{
 | 
						|
	if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
 | 
						|
		connection->lastSerializationList.Insert(replica, replica, false);
 | 
						|
}
 | 
						|
void ReplicaManager2::RemoveVisibilityReference(Connection_RM2* connection, Replica2* replica)
 | 
						|
{
 | 
						|
	if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
 | 
						|
		connection->lastSerializationList.RemoveIfExists(replica);
 | 
						|
}
 | 
						|
void ReplicaManager2::WriteHeader(RakNet::BitStream *bs, MessageID type, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	if (timestamp!=0)
 | 
						|
	{
 | 
						|
		bs->Write((MessageID)ID_TIMESTAMP);
 | 
						|
		bs->Write(timestamp);
 | 
						|
	}
 | 
						|
	bs->Write(type);
 | 
						|
}
 | 
						|
void ReplicaManager2::OnCloseConnection(RakPeerInterface *peer, SystemAddress systemAddress)
 | 
						|
{
 | 
						|
	(void) peer;
 | 
						|
 | 
						|
	RemoveConnection(systemAddress);
 | 
						|
}
 | 
						|
void ReplicaManager2::OnShutdown(RakPeerInterface *peer)
 | 
						|
{
 | 
						|
	(void) peer;
 | 
						|
	Clear();
 | 
						|
}
 | 
						|
void ReplicaManager2::OnAttach(RakPeerInterface *peer)
 | 
						|
{
 | 
						|
	rakPeer=peer;
 | 
						|
	lastUpdateTime=RakNet::GetTime();
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnReceive(RakPeerInterface *peer, Packet *packet)
 | 
						|
{
 | 
						|
	RakNetTime timestamp=0;
 | 
						|
	unsigned char packetIdentifier, packetDataOffset;
 | 
						|
	if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
 | 
						|
	{
 | 
						|
		if ( packet->length > sizeof( unsigned char ) + sizeof( RakNetTime ) )
 | 
						|
		{
 | 
						|
			packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( RakNetTime ) ];
 | 
						|
			// Required for proper endian swapping
 | 
						|
			RakNet::BitStream tsBs(packet->data+sizeof(MessageID),packet->length-1,false);
 | 
						|
			tsBs.Read(timestamp);
 | 
						|
			packetDataOffset=sizeof( unsigned char )*2 + sizeof( RakNetTime );
 | 
						|
		}
 | 
						|
		else
 | 
						|
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		packetIdentifier = ( unsigned char ) packet->data[ 0 ];
 | 
						|
		packetDataOffset=sizeof( unsigned char );
 | 
						|
	}
 | 
						|
 | 
						|
	switch (packetIdentifier)
 | 
						|
	{
 | 
						|
	case ID_NEW_INCOMING_CONNECTION:
 | 
						|
	case ID_CONNECTION_REQUEST_ACCEPTED:
 | 
						|
		if (autoAddNewConnections)
 | 
						|
			AddNewConnection(packet->systemAddress);
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	case ID_DISCONNECTION_NOTIFICATION:
 | 
						|
	case ID_CONNECTION_LOST:
 | 
						|
		OnCloseConnection(peer, packet->systemAddress);
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	case ID_REPLICA_MANAGER_DOWNLOAD_STARTED:
 | 
						|
		return OnDownloadStarted(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
 | 
						|
		return OnDownloadComplete(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	case ID_REPLICA_MANAGER_CONSTRUCTION:
 | 
						|
		return OnConstruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	case ID_REPLICA_MANAGER_DESTRUCTION:
 | 
						|
		return OnDestruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	case ID_REPLICA_MANAGER_SCOPE_CHANGE:
 | 
						|
		return OnVisibilityChange(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	case ID_REPLICA_MANAGER_SERIALIZE:
 | 
						|
		return OnSerialize(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
 | 
						|
	}
 | 
						|
 | 
						|
	return RR_CONTINUE_PROCESSING;
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnDownloadStarted(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
 | 
						|
	if (connection==0)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	SerializationType serializationType;
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	connection->DeserializeDownloadStarted(&incomingBitstream, sender, this, timestamp, serializationType);
 | 
						|
 | 
						|
	if (newConnection)
 | 
						|
		DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnDownloadComplete(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
 | 
						|
	if (connection==0)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	SerializationType serializationType;
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	connection->DeserializeDownloadComplete(&incomingBitstream, sender, this, timestamp, serializationType);
 | 
						|
 | 
						|
	if (newConnection)
 | 
						|
		DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
 | 
						|
PluginReceiveResult ReplicaManager2::OnConstruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
 | 
						|
	if (connection==0)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	SerializationType serializationType;
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	NetworkID networkId=UNASSIGNED_NETWORK_ID;
 | 
						|
	unsigned char localClientId=255;
 | 
						|
	bool success;
 | 
						|
	incomingBitstream.Read(networkId);
 | 
						|
	success=incomingBitstream.Read(localClientId);
 | 
						|
	RakAssert(success);
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	ReadExclusionList(&incomingBitstream, exclusionList);
 | 
						|
	exclusionList.Insert(sender,sender, false);
 | 
						|
 | 
						|
	Replica2* replica;
 | 
						|
	replica = connection->ReceiveConstruct(&incomingBitstream, networkId, sender, localClientId, serializationType, this, timestamp,exclusionList);
 | 
						|
	if (replica)
 | 
						|
	{
 | 
						|
		// Register this object on this connection
 | 
						|
		AddConstructionReference(connection, replica);
 | 
						|
	}
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnDestruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	if (HasConnection(sender)==false)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	SerializationType serializationType;
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	NetworkID networkId;
 | 
						|
	incomingBitstream.Read(networkId);
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	ReadExclusionList(&incomingBitstream, exclusionList);
 | 
						|
	exclusionList.Insert(sender,sender, false);
 | 
						|
	Replica2 * replica = rakPeer->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2*>( networkId );
 | 
						|
	if (replica)
 | 
						|
	{
 | 
						|
		// Verify that this is a registered object, so it actually is a Replica2
 | 
						|
		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
 | 
						|
		{
 | 
						|
			// This object is not registered
 | 
						|
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
		}
 | 
						|
 | 
						|
		replica->ReceiveDestruction(sender, &incomingBitstream, serializationType, timestamp,exclusionList );
 | 
						|
	}
 | 
						|
	// else this object is unknown
 | 
						|
 | 
						|
	
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnVisibilityChange(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	bool newConnection;
 | 
						|
	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
 | 
						|
	if (connection==0)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	SerializationType serializationType;
 | 
						|
	
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	NetworkID networkId;
 | 
						|
	incomingBitstream.Read(networkId);
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	ReadExclusionList(&incomingBitstream, exclusionList);
 | 
						|
	exclusionList.Insert(sender,sender, false);
 | 
						|
	
 | 
						|
	Replica2 *replica = rakPeer->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
 | 
						|
	if (replica)
 | 
						|
	{
 | 
						|
		// Verify that this is a registered object, so it actually is a Replica2
 | 
						|
		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
 | 
						|
		{
 | 
						|
			RakAssert(0);
 | 
						|
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
		}
 | 
						|
 | 
						|
		replica->ReceiveVisibility(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
 | 
						|
 | 
						|
		AddConstructionReference(connection, replica);
 | 
						|
 | 
						|
		// Update the last known visibility list
 | 
						|
		if (SerializationContext::IsVisibilityCommand(serializationType))
 | 
						|
		{
 | 
						|
			if (SerializationContext::IsVisible(serializationType))
 | 
						|
				AddVisibilityReference(connection, replica);
 | 
						|
			else
 | 
						|
				RemoveVisibilityReference(connection, replica);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
PluginReceiveResult ReplicaManager2::OnSerialize(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
 | 
						|
	Connection_RM2* connection = GetConnectionBySystemAddress(sender);
 | 
						|
	if (connection==0)
 | 
						|
		return RR_CONTINUE_PROCESSING;
 | 
						|
	SerializationType serializationType;
 | 
						|
	unsigned char c;
 | 
						|
	incomingBitstream.Read(c);
 | 
						|
	serializationType=(SerializationType) c;
 | 
						|
	NetworkID networkId;
 | 
						|
	incomingBitstream.Read(networkId);
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	ReadExclusionList(&incomingBitstream, exclusionList);
 | 
						|
	exclusionList.Insert(sender,sender, false);
 | 
						|
 | 
						|
	Replica2 *replica = rakPeer->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
 | 
						|
	if (replica)
 | 
						|
	{
 | 
						|
		// Verify that this is a registered object, so it actually is a Replica2
 | 
						|
		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
 | 
						|
		{
 | 
						|
			RakAssert(0);
 | 
						|
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
		}
 | 
						|
 | 
						|
		exclusionList.Insert(sender,sender, false);
 | 
						|
 | 
						|
		replica->ReceiveSerialize(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
 | 
						|
 | 
						|
		AddConstructionReference(connection, replica);
 | 
						|
	}
 | 
						|
	return RR_STOP_PROCESSING_AND_DEALLOCATE;
 | 
						|
}
 | 
						|
bool ReplicaManager2::AddToAndWriteExclusionList(SystemAddress recipient, RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	if (exclusionList.HasData(recipient))
 | 
						|
		return false;
 | 
						|
	exclusionList.Insert(recipient,recipient,true);
 | 
						|
	WriteExclusionList(bs,exclusionList);
 | 
						|
	return true;
 | 
						|
}
 | 
						|
void ReplicaManager2::WriteExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	bs->WriteCompressed(exclusionList.Size());
 | 
						|
	for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionList.Size(); exclusionListIndex++ )
 | 
						|
		bs->Write(exclusionList[exclusionListIndex]);
 | 
						|
}
 | 
						|
 | 
						|
void ReplicaManager2::CullByAndAddToExclusionList(
 | 
						|
								 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &inputList,
 | 
						|
								 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &culledOutput,
 | 
						|
								 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	Connection_RM2* connection;
 | 
						|
	unsigned i;
 | 
						|
	unsigned exclusionListIndex=0;
 | 
						|
	for (i=0; i < inputList.Size(); i++)
 | 
						|
	{
 | 
						|
		connection=inputList[i];
 | 
						|
		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < connection->GetSystemAddress())
 | 
						|
			exclusionListIndex++;
 | 
						|
		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==connection->GetSystemAddress())
 | 
						|
		{
 | 
						|
			exclusionListIndex++;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		culledOutput.InsertAtEnd(connection);
 | 
						|
	}
 | 
						|
 | 
						|
	for (i=0; i < culledOutput.Size(); i++)
 | 
						|
		exclusionList.Insert(culledOutput[i]->GetSystemAddress(),culledOutput[i]->GetSystemAddress(),true);
 | 
						|
}
 | 
						|
void ReplicaManager2::ReadExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	unsigned int exclusionListSize;
 | 
						|
	bs->ReadCompressed(exclusionListSize);
 | 
						|
	for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionListSize; exclusionListIndex++)
 | 
						|
	{
 | 
						|
		SystemAddress systemToExclude;
 | 
						|
		bs->Read(systemToExclude);
 | 
						|
		exclusionList.InsertAtEnd(systemToExclude);
 | 
						|
	}
 | 
						|
}
 | 
						|
void ReplicaManager2::Send(RakNet::BitStream *bs, SystemAddress recipient, PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	if (priority==NUMBER_OF_PRIORITIES)
 | 
						|
		priority=defaultPacketPriority;
 | 
						|
	if (reliability==NUMBER_OF_RELIABILITIES)
 | 
						|
		reliability=defaultPacketReliablity;
 | 
						|
	if (orderingChannel==-1)
 | 
						|
		orderingChannel=defaultOrderingChannel;
 | 
						|
	rakPeer->Send(bs, priority,reliability,orderingChannel,recipient,false);
 | 
						|
}
 | 
						|
void ReplicaManager2::Clear(void)
 | 
						|
{
 | 
						|
	fullReplicaUnorderedList.Clear();
 | 
						|
	fullReplicaOrderedList.Clear();
 | 
						|
	alwaysDoConstructReplicaOrderedList.Clear();
 | 
						|
	alwaysDoSerializeReplicaOrderedList.Clear();
 | 
						|
	variableConstructReplicaOrderedList.Clear();
 | 
						|
	variableSerializeReplicaOrderedList.Clear();
 | 
						|
	unsigned i;
 | 
						|
	for (i=0; i < connectionList.Size(); i++)
 | 
						|
		connectionFactoryInterface->DeallocConnection(connectionList[i]);
 | 
						|
	connectionList.Clear();
 | 
						|
}
 | 
						|
void ReplicaManager2::DownloadToNewConnection(Connection_RM2* connection, RakNetTime timestamp, PacketPriority priority, PacketReliability reliability, char orderingChannel)
 | 
						|
{
 | 
						|
	unsigned int i;
 | 
						|
	RakNet::BitStream bs, bs2;
 | 
						|
	BooleanQueryResult bqr;
 | 
						|
	SystemAddress systemAddress = connection->GetSystemAddress();
 | 
						|
	SerializationContext serializationContext;
 | 
						|
	serializationContext.recipientAddress=systemAddress;
 | 
						|
	serializationContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
	serializationContext.serializationType=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
 | 
						|
	serializationContext.timestamp=0;
 | 
						|
 | 
						|
	// bs2 is so SerializeDownloadStarted can change the timestamp
 | 
						|
	connection->SerializeDownloadStarted(&bs2, this, &serializationContext);
 | 
						|
	WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_STARTED, timestamp);
 | 
						|
	bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
 | 
						|
	bs.Write(&bs2);
 | 
						|
	Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
 | 
						|
	// Construct all objects before serializing them. This way the recipient will have valid NetworkID references.
 | 
						|
	// Send all objects that always exist
 | 
						|
	for (i=0; i < fullReplicaUnorderedList.Size(); i++)
 | 
						|
	{
 | 
						|
		if (fullReplicaUnorderedList[i]->QueryIsConstructionAuthority())
 | 
						|
		{
 | 
						|
			bqr=fullReplicaUnorderedList[i]->QueryConstruction(connection);
 | 
						|
			if (bqr==BQR_ALWAYS || bqr==BQR_YES)
 | 
						|
				fullReplicaUnorderedList[i]->SendConstruction(systemAddress, SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
 | 
						|
			// Remember for this particular connection that we already sent this update to this system
 | 
						|
			if (bqr==BQR_YES)
 | 
						|
				AddConstructionReference(connection, fullReplicaUnorderedList[i]);
 | 
						|
		}			
 | 
						|
	}
 | 
						|
 | 
						|
	bool notVisible;
 | 
						|
 | 
						|
	// Send all objects that are always visible
 | 
						|
	for (i=0; i < fullReplicaUnorderedList.Size(); i++)
 | 
						|
	{
 | 
						|
		notVisible=false;
 | 
						|
		if (fullReplicaUnorderedList[i]->QueryIsVisibilityAuthority())
 | 
						|
		{
 | 
						|
			bqr=fullReplicaUnorderedList[i]->QueryVisibility(connection);
 | 
						|
			if (bqr==BQR_ALWAYS || bqr==BQR_YES)
 | 
						|
			{
 | 
						|
				fullReplicaUnorderedList[i]->SendVisibility(systemAddress, SEND_VISIBILITY_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
 | 
						|
				// Remember for this particular connection that we already sent this update to this system
 | 
						|
				if (bqr==BQR_YES)
 | 
						|
					AddVisibilityReference(connection, fullReplicaUnorderedList[i]);
 | 
						|
			}
 | 
						|
			else
 | 
						|
				notVisible=true;
 | 
						|
		}
 | 
						|
 | 
						|
		if (fullReplicaUnorderedList[i]->QueryIsSerializationAuthority() && notVisible==false)
 | 
						|
			fullReplicaUnorderedList[i]->SendSerialize(systemAddress, SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
 | 
						|
	}
 | 
						|
 | 
						|
	bs.Reset();
 | 
						|
	// bs2 is so SerializeDownloadComplete can change the timestamp
 | 
						|
	connection->SerializeDownloadComplete(&bs2, this,&serializationContext);
 | 
						|
	WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE, timestamp);
 | 
						|
	bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
 | 
						|
	bs.Write(&bs2);
 | 
						|
	Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
 | 
						|
}
 | 
						|
Replica2::Replica2()
 | 
						|
{
 | 
						|
	rm2=0; hasClientID=false;
 | 
						|
 | 
						|
	DataStructures::Map<SerializationType, AutoSerializeEvent*>::IMPLEMENT_DEFAULT_COMPARISON();
 | 
						|
}
 | 
						|
Replica2::~Replica2()
 | 
						|
{
 | 
						|
	rm2->Dereference(this);
 | 
						|
	if (hasClientID)
 | 
						|
		clientPtrArray[clientID]=0;
 | 
						|
	ClearAutoSerializeTimers();
 | 
						|
}
 | 
						|
 | 
						|
void Replica2::SetReplicaManager(ReplicaManager2* rm)
 | 
						|
{
 | 
						|
	rm2=rm;
 | 
						|
	if (GetNetworkIDManager()==0)
 | 
						|
		SetNetworkIDManager(rm->GetRakPeer()->GetNetworkIDManager());
 | 
						|
}
 | 
						|
ReplicaManager2* Replica2::GetReplicaManager(void) const
 | 
						|
{
 | 
						|
	return rm2;
 | 
						|
}
 | 
						|
bool Replica2::SerializeDestruction(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationContext;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
bool Replica2::Serialize(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationContext;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
bool Replica2::SerializeVisibility(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationContext;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
void Replica2::DeserializeDestruction(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationType;
 | 
						|
	(void) sender;
 | 
						|
	(void) timestamp;
 | 
						|
 | 
						|
}
 | 
						|
void Replica2::Deserialize(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationType;
 | 
						|
	(void) sender;
 | 
						|
	(void) timestamp;
 | 
						|
}
 | 
						|
void Replica2::DeserializeVisibility(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	(void) bitStream;
 | 
						|
	(void) serializationType;
 | 
						|
	(void) sender;
 | 
						|
	(void) timestamp;
 | 
						|
}
 | 
						|
void Replica2::SendConstruction(SystemAddress recipientAddress, SerializationType serializationType)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext;
 | 
						|
 | 
						|
	if (serializationType==UNDEFINED_REASON)
 | 
						|
	{
 | 
						|
		if (QueryIsConstructionAuthority()==false)
 | 
						|
			defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
 | 
						|
		else
 | 
						|
			defaultContext.serializationType=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM;
 | 
						|
	}
 | 
						|
	else
 | 
						|
		defaultContext.serializationType=serializationType;
 | 
						|
 | 
						|
	defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
	defaultContext.recipientAddress=recipientAddress;
 | 
						|
	defaultContext.timestamp=0;
 | 
						|
 | 
						|
	unsigned char localId;
 | 
						|
	if (QueryIsConstructionAuthority()==false)
 | 
						|
		localId=Replica2::clientSharedID++;
 | 
						|
	else
 | 
						|
		localId=0;
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	if (SerializeConstruction(&bs, &defaultContext))
 | 
						|
		rm2->SendConstruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,localId,defaultContext.serializationType);
 | 
						|
}
 | 
						|
void Replica2::SendDestruction(SystemAddress recipientAddress, SerializationType serializationType)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
 | 
						|
 | 
						|
	if (serializationType==UNDEFINED_REASON)
 | 
						|
		defaultContext.serializationType=SEND_DESTRUCTION_GENERIC_TO_SYSTEM;
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	if (SerializeDestruction(&bs, &defaultContext))
 | 
						|
		rm2->SendDestruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,defaultContext.serializationType);
 | 
						|
}
 | 
						|
void Replica2::SendSerialize(SystemAddress recipientAddress, SerializationType serializationType)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
 | 
						|
 | 
						|
	if (serializationType==UNDEFINED_REASON)
 | 
						|
		defaultContext.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
 | 
						|
 | 
						|
	if (Serialize(&bs, &defaultContext))
 | 
						|
	{
 | 
						|
		DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
		rm2->SendSerialize(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::SendVisibility(SystemAddress recipientAddress, SerializationType serializationType)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
 | 
						|
 | 
						|
	if (serializationType==UNDEFINED_REASON)
 | 
						|
		defaultContext.serializationType=SEND_VISIBILITY_TRUE_TO_SYSTEM;
 | 
						|
 | 
						|
	if (SerializeVisibility(&bs, &defaultContext))
 | 
						|
	{
 | 
						|
		DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
		rm2->SendVisibility(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::BroadcastSerialize(SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
 | 
						|
	SerializationContext *usedContext;
 | 
						|
	if (serializationContext)
 | 
						|
		usedContext=serializationContext;
 | 
						|
	else
 | 
						|
		usedContext=&defaultContext;
 | 
						|
 | 
						|
	bool newReference;
 | 
						|
	rm2->Reference(this, &newReference);
 | 
						|
 | 
						|
	// If this is a new object, then before sending serialization we should send construction to all systems
 | 
						|
	if (newReference && QueryConstruction(0)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		BroadcastConstruction();
 | 
						|
	}
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
 | 
						|
	{
 | 
						|
		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
 | 
						|
		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
 | 
						|
			continue;
 | 
						|
		bs.Reset();
 | 
						|
		if (Serialize(&bs, usedContext)==false)
 | 
						|
			continue;
 | 
						|
		exclusionList.Clear();
 | 
						|
		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
 | 
						|
		{
 | 
						|
			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
 | 
						|
				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress());
 | 
						|
		}
 | 
						|
		rm2->SendSerialize(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void Replica2::ReceiveSerialize(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
 | 
						|
{
 | 
						|
	// Force all autoserialize timers to go off early, so any variable changes from the Deserialize event do not themselves trigger an autoserialize event
 | 
						|
	ForceElapseAllAutoserializeTimers(false);
 | 
						|
 | 
						|
	// Deserialize the new data
 | 
						|
	Deserialize(serializedObject, serializationType, sender, timestamp);
 | 
						|
 | 
						|
	// Update last values for all autoserialize timers
 | 
						|
	ForceElapseAllAutoserializeTimers(true);
 | 
						|
 | 
						|
	SerializationContext serializationContext;
 | 
						|
	serializationContext.serializationType=RELAY_SERIALIZATION_TO_SYSTEMS;
 | 
						|
	serializationContext.timestamp=timestamp;
 | 
						|
	serializationContext.relaySourceAddress=sender;
 | 
						|
 | 
						|
 | 
						|
	BooleanQueryResult bqr;
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	unsigned exclusionListIndex=0;
 | 
						|
	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
 | 
						|
	{
 | 
						|
		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
 | 
						|
		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
 | 
						|
			exclusionListIndex++;
 | 
						|
		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
 | 
						|
		{
 | 
						|
			exclusionListIndex++;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
 | 
						|
		// Don't relay serializations if this object should not be visible
 | 
						|
		bqr=QueryVisibility(rm2->connectionList[i]);
 | 
						|
		if (bqr==BQR_NEVER || bqr==BQR_NO)
 | 
						|
			continue;
 | 
						|
 | 
						|
		bs.Reset();
 | 
						|
		if (Serialize(&bs, &serializationContext)==false)
 | 
						|
			continue;
 | 
						|
		rm2->SendSerialize(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void Replica2::BroadcastConstruction(SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
 | 
						|
	SerializationContext *usedContext;
 | 
						|
	if (serializationContext)
 | 
						|
		usedContext=serializationContext;
 | 
						|
	else
 | 
						|
	{
 | 
						|
		usedContext=&defaultContext;
 | 
						|
		if (QueryIsConstructionAuthority()==false)
 | 
						|
			defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
 | 
						|
	}	
 | 
						|
 | 
						|
	bool newReference;
 | 
						|
	rm2->Reference(this, &newReference);
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
 | 
						|
	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
 | 
						|
	{
 | 
						|
		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
 | 
						|
		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
 | 
						|
			continue;
 | 
						|
		bs.Reset();
 | 
						|
		if (SerializeConstruction(&bs, usedContext)==false)
 | 
						|
			continue;
 | 
						|
		unsigned char localId;
 | 
						|
		if (QueryIsConstructionAuthority()==false)
 | 
						|
		{
 | 
						|
			clientPtrArray[Replica2::clientSharedID]=this;
 | 
						|
			localId=Replica2::clientSharedID++;
 | 
						|
		}
 | 
						|
		else
 | 
						|
			localId=0;
 | 
						|
		exclusionList.Clear();
 | 
						|
		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
 | 
						|
		{
 | 
						|
			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
 | 
						|
				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress());
 | 
						|
		}
 | 
						|
		rm2->SendConstruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList, localId, usedContext->serializationType);
 | 
						|
	}
 | 
						|
 | 
						|
	// If this is a new object, then after sending construction we should send visibility and serialization if it is always visible or serialized
 | 
						|
	if (newReference)
 | 
						|
	{
 | 
						|
		bool notVisible=false;
 | 
						|
		BooleanQueryResult bqr;
 | 
						|
		bqr=QueryVisibility(0);
 | 
						|
 | 
						|
		if (bqr==BQR_ALWAYS)
 | 
						|
			BroadcastVisibility(true);
 | 
						|
		else if (bqr==BQR_NEVER)
 | 
						|
			notVisible=true;
 | 
						|
 | 
						|
		if (notVisible==false)
 | 
						|
			BroadcastSerialize();
 | 
						|
	}
 | 
						|
}
 | 
						|
Replica2 * Replica2::ReceiveConstructionReply(SystemAddress sender, BitStream *replicaData, bool constructionAllowed)
 | 
						|
{
 | 
						|
	(void) replicaData;
 | 
						|
	(void) sender;
 | 
						|
 | 
						|
	if (constructionAllowed==false)
 | 
						|
	{
 | 
						|
		delete this;
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return this;
 | 
						|
}
 | 
						|
 | 
						|
void Replica2::BroadcastDestruction(SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext(BROADCAST_DESTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS, 0);
 | 
						|
	SerializationContext *usedContext;
 | 
						|
	if (serializationContext)
 | 
						|
		usedContext=serializationContext;
 | 
						|
	else
 | 
						|
		usedContext=&defaultContext;
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	rm2->CullByAndAddToExclusionList(rm2->connectionList, culledOutput, exclusionList);
 | 
						|
 | 
						|
	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
 | 
						|
	{
 | 
						|
		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
 | 
						|
		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
 | 
						|
			continue;
 | 
						|
		bs.Reset();
 | 
						|
		if (SerializeDestruction(&bs, usedContext)==false)
 | 
						|
			continue;
 | 
						|
		exclusionList.Clear();
 | 
						|
		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
 | 
						|
		{
 | 
						|
			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
 | 
						|
				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress());
 | 
						|
		}
 | 
						|
		rm2->SendDestruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList,usedContext->serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::BroadcastVisibility(bool isVisible, SerializationContext *serializationContext)
 | 
						|
{
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	SerializationContext defaultContext;
 | 
						|
	SerializationContext *usedContext;
 | 
						|
 | 
						|
	if (serializationContext)
 | 
						|
	{
 | 
						|
		usedContext=serializationContext;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (isVisible)
 | 
						|
			defaultContext.serializationType=BROADCAST_VISIBILITY_TRUE_TO_SYSTEM;
 | 
						|
		else
 | 
						|
			defaultContext.serializationType=BROADCAST_VISIBILITY_FALSE_TO_SYSTEM;
 | 
						|
		defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
		defaultContext.timestamp=0;
 | 
						|
		usedContext=&defaultContext;
 | 
						|
	}
 | 
						|
 | 
						|
	if ((QueryVisibility(0)==BQR_ALWAYS && isVisible==false) ||
 | 
						|
		(QueryVisibility(0)==BQR_NEVER && isVisible==true))
 | 
						|
	{
 | 
						|
		// This doesn't make sense
 | 
						|
		RakAssert(0);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	bool newReference;
 | 
						|
	rm2->Reference(this, &newReference);
 | 
						|
 | 
						|
	// If this is a new object, then before sending visibility we should send construction to all systems
 | 
						|
	if (newReference && QueryConstruction(0)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		BroadcastConstruction();
 | 
						|
	}
 | 
						|
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
 | 
						|
	{
 | 
						|
		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
 | 
						|
		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
 | 
						|
			continue;
 | 
						|
		bs.Reset();
 | 
						|
		if (SerializeVisibility(&bs, usedContext)==false)
 | 
						|
			continue;
 | 
						|
		exclusionList.Clear();
 | 
						|
		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
 | 
						|
		{
 | 
						|
			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
 | 
						|
				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress());
 | 
						|
		}
 | 
						|
		rm2->SendVisibility(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
 | 
						|
	}
 | 
						|
 | 
						|
	if (newReference && QueryVisibility(0)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		BroadcastSerialize();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void Replica2::ReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
 | 
						|
{
 | 
						|
	DeserializeDestruction(serializedObject, serializationType, sender, timestamp);
 | 
						|
 | 
						|
	SerializationContext serializationContext;
 | 
						|
	serializationContext.serializationType=RELAY_DESTRUCTION_TO_SYSTEMS;
 | 
						|
	serializationContext.relaySourceAddress=sender;
 | 
						|
	serializationContext.timestamp=0;
 | 
						|
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	unsigned exclusionListIndex=0;
 | 
						|
	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
 | 
						|
	{
 | 
						|
		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
 | 
						|
 | 
						|
		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
 | 
						|
			exclusionListIndex++;
 | 
						|
		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
 | 
						|
		{
 | 
						|
			exclusionListIndex++;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
 | 
						|
		bs.Reset();
 | 
						|
		if (SerializeDestruction(&bs, &serializationContext)==false)
 | 
						|
			continue;
 | 
						|
		rm2->SendDestruction(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList,serializationContext.serializationType);
 | 
						|
	}
 | 
						|
 | 
						|
	DeleteOnReceiveDestruction(sender, serializedObject, serializationType, timestamp, exclusionList);
 | 
						|
}
 | 
						|
void Replica2::DeleteOnReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
 | 
						|
{
 | 
						|
	(void) sender;
 | 
						|
	(void) serializedObject;
 | 
						|
	(void) serializationType;
 | 
						|
	(void) timestamp;
 | 
						|
	(void) exclusionList;
 | 
						|
	delete this;
 | 
						|
}
 | 
						|
void Replica2::ReceiveVisibility(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	DeserializeVisibility(serializedObject, serializationType, sender, timestamp);
 | 
						|
 | 
						|
	SerializationContext serializationContext;
 | 
						|
	if (serializationType==SEND_VISIBILITY_TRUE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM)
 | 
						|
		serializationContext.serializationType=RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
 | 
						|
	else if (serializationType==SEND_VISIBILITY_FALSE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_FALSE_TO_SYSTEM)
 | 
						|
		serializationContext.serializationType=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
 | 
						|
	else
 | 
						|
		serializationContext.serializationType=serializationType;
 | 
						|
	serializationContext.timestamp=timestamp;
 | 
						|
	serializationContext.relaySourceAddress=sender;
 | 
						|
 | 
						|
	RakNet::BitStream bs;
 | 
						|
	unsigned exclusionListIndex=0;
 | 
						|
	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
 | 
						|
	{
 | 
						|
		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
 | 
						|
 | 
						|
		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
 | 
						|
			exclusionListIndex++;
 | 
						|
		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
 | 
						|
		{
 | 
						|
			exclusionListIndex++;
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
 | 
						|
		bs.Reset();
 | 
						|
		if (SerializeVisibility(&bs, &serializationContext)==false)
 | 
						|
			continue;
 | 
						|
		rm2->SendVisibility(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
 | 
						|
	}
 | 
						|
}
 | 
						|
BooleanQueryResult Replica2::QueryConstruction(Connection_RM2 *connection)
 | 
						|
{
 | 
						|
	(void) connection;
 | 
						|
 | 
						|
	return BQR_ALWAYS;
 | 
						|
}
 | 
						|
BooleanQueryResult Replica2::QueryVisibility(Connection_RM2 *connection)
 | 
						|
{
 | 
						|
	(void) connection;
 | 
						|
 | 
						|
	return BQR_ALWAYS;
 | 
						|
}
 | 
						|
bool Replica2::QueryIsConstructionAuthority(void) const
 | 
						|
{
 | 
						|
	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
 | 
						|
}
 | 
						|
bool Replica2::QueryIsDestructionAuthority(void) const
 | 
						|
{
 | 
						|
	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
 | 
						|
}
 | 
						|
bool Replica2::QueryIsVisibilityAuthority(void) const
 | 
						|
{
 | 
						|
	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
 | 
						|
}
 | 
						|
bool Replica2::QueryIsSerializationAuthority(void) const
 | 
						|
{
 | 
						|
	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
 | 
						|
}
 | 
						|
bool Replica2::AllowRemoteConstruction(SystemAddress sender, RakNet::BitStream *replicaData, SerializationType type, RakNetTime timestamp)
 | 
						|
{
 | 
						|
	(void) sender;
 | 
						|
	(void) replicaData;
 | 
						|
	(void) type;
 | 
						|
	(void) timestamp;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
void Replica2::ForceElapseAllAutoserializeTimers(bool resynchOnly)
 | 
						|
{
 | 
						|
	ElapseAutoSerializeTimers(99999999, resynchOnly);
 | 
						|
}
 | 
						|
void Replica2::ElapseAutoSerializeTimers(RakNetTime timeElapsed, bool resynchOnly)
 | 
						|
{
 | 
						|
	AutoSerializeEvent* ase;
 | 
						|
	unsigned i;
 | 
						|
	for (i=0; i < autoSerializeTimers.Size(); i++)
 | 
						|
	{
 | 
						|
		ase = autoSerializeTimers[i];
 | 
						|
		if (ase->remainingCountdown>timeElapsed)
 | 
						|
		{
 | 
						|
			ase->remainingCountdown-=timeElapsed;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			ase->remainingCountdown=ase->initialCountdown;
 | 
						|
 | 
						|
			RakNet::BitStream *lastWrite, *newWrite;
 | 
						|
			if (ase->writeToResult1)
 | 
						|
			{
 | 
						|
				newWrite=&ase->lastAutoSerializeResult1;
 | 
						|
				lastWrite=&ase->lastAutoSerializeResult2;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				newWrite=&ase->lastAutoSerializeResult2;
 | 
						|
				lastWrite=&ase->lastAutoSerializeResult1;
 | 
						|
			}
 | 
						|
			newWrite->Reset();
 | 
						|
			OnAutoSerializeTimerElapsed(ase->serializationType,newWrite,lastWrite,ase->remainingCountdown, resynchOnly);
 | 
						|
			ase->writeToResult1=!ase->writeToResult1;
 | 
						|
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::OnAutoSerializeTimerElapsed(SerializationType serializationType, RakNet::BitStream *output, RakNet::BitStream *lastOutput, RakNetTime lastAutoSerializeCountdown, bool resynchOnly)
 | 
						|
{
 | 
						|
	(void) lastAutoSerializeCountdown;
 | 
						|
 | 
						|
	SerializationContext context;
 | 
						|
	if (resynchOnly)
 | 
						|
		context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
 | 
						|
	else
 | 
						|
		context.serializationType=serializationType;
 | 
						|
	context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
	context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
	context.timestamp=0;
 | 
						|
	if (Serialize(output, &context))
 | 
						|
	{
 | 
						|
		if (resynchOnly==false &&
 | 
						|
			output->GetNumberOfBitsUsed()>0 &&
 | 
						|
			(output->GetNumberOfBitsUsed()!=lastOutput->GetNumberOfBitsUsed() ||
 | 
						|
			memcmp(output->GetData(), lastOutput->GetData(), (size_t) output->GetNumberOfBytesUsed())!=0))
 | 
						|
		{
 | 
						|
			BroadcastAutoSerialize(&context, output);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::BroadcastAutoSerialize(SerializationContext *serializationContext, RakNet::BitStream *serializedObject)
 | 
						|
{
 | 
						|
	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
 | 
						|
	rm2->SendSerialize(this,serializedObject,UNASSIGNED_SYSTEM_ADDRESS, serializationContext->timestamp, exclusionList, BROADCAST_AUTO_SERIALIZE_TO_SYSTEM);
 | 
						|
}
 | 
						|
void Replica2::AddAutoSerializeTimer(RakNetTime interval, SerializationType serializationType, RakNetTime countdown )
 | 
						|
{
 | 
						|
	if (countdown==(RakNetTime)-1)
 | 
						|
		countdown=interval;
 | 
						|
	if (autoSerializeTimers.Has(serializationType))
 | 
						|
	{
 | 
						|
		AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
 | 
						|
		if (interval==0)
 | 
						|
		{
 | 
						|
			// Elapse this timer immediately, then go back to initialCountdown
 | 
						|
			ase->remainingCountdown=ase->initialCountdown;
 | 
						|
 | 
						|
			RakNet::BitStream *lastWrite, *newWrite;
 | 
						|
			if (ase->writeToResult1)
 | 
						|
			{
 | 
						|
				newWrite=&ase->lastAutoSerializeResult1;
 | 
						|
				lastWrite=&ase->lastAutoSerializeResult2;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				newWrite=&ase->lastAutoSerializeResult2;
 | 
						|
				lastWrite=&ase->lastAutoSerializeResult1;
 | 
						|
			}
 | 
						|
			newWrite->Reset();
 | 
						|
 | 
						|
			OnAutoSerializeTimerElapsed(serializationType,newWrite,lastWrite,ase->initialCountdown, false);
 | 
						|
 | 
						|
			ase->remainingCountdown=ase->initialCountdown;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			ase->initialCountdown=interval;
 | 
						|
			ase->remainingCountdown=countdown;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{		
 | 
						|
		AutoSerializeEvent *ase = new AutoSerializeEvent;
 | 
						|
		ase->serializationType=serializationType;
 | 
						|
		ase->initialCountdown=interval;
 | 
						|
		ase->remainingCountdown=countdown;
 | 
						|
		ase->writeToResult1=true;
 | 
						|
 | 
						|
		SerializationContext context;
 | 
						|
		context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
 | 
						|
		context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
		context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
		context.timestamp=0;
 | 
						|
		Serialize(&ase->lastAutoSerializeResult2, &context);
 | 
						|
 | 
						|
		autoSerializeTimers.Set(serializationType,ase);
 | 
						|
	}
 | 
						|
}
 | 
						|
RakNetTime Replica2::GetTimeToNextAutoSerialize(SerializationType serializationType)
 | 
						|
{
 | 
						|
	if (autoSerializeTimers.Has(serializationType))
 | 
						|
	{
 | 
						|
		AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
 | 
						|
		return ase->remainingCountdown;
 | 
						|
	}
 | 
						|
	return (RakNetTime)-1;
 | 
						|
}
 | 
						|
void Replica2::CancelAutoSerializeTimer(SerializationType serializationType)
 | 
						|
{
 | 
						|
	unsigned i=0;
 | 
						|
	while (i < autoSerializeTimers.Size())
 | 
						|
	{
 | 
						|
		if (autoSerializeTimers[i]->serializationType==serializationType)
 | 
						|
		{
 | 
						|
			delete autoSerializeTimers[i];
 | 
						|
			autoSerializeTimers.RemoveAtIndex(i);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			i++;
 | 
						|
	}
 | 
						|
}
 | 
						|
void Replica2::ClearAutoSerializeTimers(void)
 | 
						|
{
 | 
						|
	unsigned i;
 | 
						|
	for (i=0; i < autoSerializeTimers.Size(); i++)
 | 
						|
		delete autoSerializeTimers[i];
 | 
						|
	autoSerializeTimers.Clear();
 | 
						|
}
 | 
						|
Connection_RM2::Connection_RM2()
 | 
						|
{
 | 
						|
}
 | 
						|
Connection_RM2::~Connection_RM2()
 | 
						|
{
 | 
						|
}
 | 
						|
void Connection_RM2::SetConstructionByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> ¤tVisibility, ReplicaManager2 *replicaManager)
 | 
						|
{
 | 
						|
	(void) replicaManager;
 | 
						|
 | 
						|
	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentConstructionList, exclusiveToLastConstructionList;
 | 
						|
	CalculateListExclusivity(currentVisibility, lastConstructionList, exclusiveToCurrentConstructionList, exclusiveToLastConstructionList);
 | 
						|
 | 
						|
	unsigned i;
 | 
						|
	for (i=0; i < exclusiveToCurrentConstructionList.Size(); i++)
 | 
						|
	{
 | 
						|
		// Construct
 | 
						|
		if (exclusiveToCurrentConstructionList[i]->QueryIsConstructionAuthority())
 | 
						|
		{
 | 
						|
			exclusiveToCurrentConstructionList[i]->SendConstruction(systemAddress);
 | 
						|
		//	lastConstructionList.Insert(exclusiveToCurrentConstructionList[i],exclusiveToCurrentConstructionList[i],true);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	for (i=0; i < exclusiveToLastConstructionList.Size(); i++)
 | 
						|
	{
 | 
						|
		// Destruction
 | 
						|
		if (exclusiveToLastConstructionList[i]->QueryIsDestructionAuthority())
 | 
						|
		{
 | 
						|
			exclusiveToLastConstructionList[i]->SendDestruction(systemAddress);
 | 
						|
			lastConstructionList.RemoveIfExists(exclusiveToLastConstructionList[i]);
 | 
						|
			lastSerializationList.RemoveIfExists(exclusiveToLastConstructionList[i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
void Connection_RM2::SetVisibilityByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> ¤tVisibility, ReplicaManager2 *replicaManager)
 | 
						|
{
 | 
						|
	(void) replicaManager;
 | 
						|
 | 
						|
	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentSerializationList, exclusiveToLastSerializationList;
 | 
						|
	CalculateListExclusivity(currentVisibility, lastSerializationList, exclusiveToCurrentSerializationList, exclusiveToLastSerializationList);
 | 
						|
 | 
						|
	unsigned i;
 | 
						|
	for (i=0; i < exclusiveToCurrentSerializationList.Size(); i++)
 | 
						|
	{
 | 
						|
		// In scope
 | 
						|
		if (exclusiveToCurrentSerializationList[i]->QueryIsVisibilityAuthority())
 | 
						|
		{
 | 
						|
			exclusiveToCurrentSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_TRUE_TO_SYSTEM);
 | 
						|
			exclusiveToCurrentSerializationList[i]->SendSerialize(systemAddress);
 | 
						|
		//	lastSerializationList.Insert(exclusiveToCurrentSerializationList[i],exclusiveToCurrentSerializationList[i], true);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	for (i=0; i < exclusiveToLastSerializationList.Size(); i++)
 | 
						|
	{
 | 
						|
		// Out of scope
 | 
						|
		if (exclusiveToLastSerializationList[i]->QueryIsVisibilityAuthority())
 | 
						|
		{
 | 
						|
			exclusiveToLastSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_FALSE_TO_SYSTEM);
 | 
						|
			lastSerializationList.RemoveIfExists(exclusiveToLastSerializationList[i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
void Connection_RM2::CalculateListExclusivity(
 | 
						|
							  const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listOne,
 | 
						|
							  const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listTwo,
 | 
						|
							  DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListOne, 
 | 
						|
							  DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListTwo
 | 
						|
							  ) const
 | 
						|
{
 | 
						|
	int res;
 | 
						|
	unsigned listOneIndex=0, listTwoIndex=0;
 | 
						|
 | 
						|
	while (listOneIndex<listOne.Size() && listTwoIndex < listTwo.Size())
 | 
						|
	{
 | 
						|
		res = ReplicaManager2::Replica2ObjectComp(listOne[listOneIndex],listTwo[listTwoIndex]);
 | 
						|
		if (res<0)
 | 
						|
		{
 | 
						|
			exclusiveToListOne.InsertAtEnd(listOne[listOneIndex]);
 | 
						|
			listOneIndex++;
 | 
						|
		}
 | 
						|
		else if (res>0)
 | 
						|
		{
 | 
						|
			exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex]);
 | 
						|
			listTwoIndex++;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			listOneIndex++;
 | 
						|
			listTwoIndex++;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	while (listOneIndex<listOne.Size())
 | 
						|
	{
 | 
						|
		exclusiveToListOne.InsertAtEnd(listOne[listOneIndex]);
 | 
						|
		listOneIndex++;
 | 
						|
	}
 | 
						|
 | 
						|
	while (listTwoIndex<listTwo.Size())
 | 
						|
	{
 | 
						|
		exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex]);
 | 
						|
		listTwoIndex++;
 | 
						|
	}
 | 
						|
}
 | 
						|
void Connection_RM2::SetConstructionByReplicaQuery(ReplicaManager2 *replicaManager)
 | 
						|
{
 | 
						|
	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> constructedObjects;
 | 
						|
 | 
						|
	unsigned i;
 | 
						|
	BooleanQueryResult res;
 | 
						|
	for (i=0; i < replicaManager->variableConstructReplicaOrderedList.Size(); i++)
 | 
						|
	{
 | 
						|
		if (replicaManager->variableConstructReplicaOrderedList[i]->QueryIsConstructionAuthority())
 | 
						|
		{
 | 
						|
			res = replicaManager->variableConstructReplicaOrderedList[i]->QueryConstruction(this);
 | 
						|
			if (res==BQR_YES)
 | 
						|
				constructedObjects.InsertAtEnd(replicaManager->variableConstructReplicaOrderedList[i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	SetConstructionByList(constructedObjects, replicaManager);
 | 
						|
}
 | 
						|
void Connection_RM2::SetVisibilityByReplicaQuery(ReplicaManager2 *replicaManager)
 | 
						|
{
 | 
						|
	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> currentVisibility;
 | 
						|
 | 
						|
	unsigned i;
 | 
						|
	BooleanQueryResult res;
 | 
						|
	for (i=0; i < replicaManager->variableSerializeReplicaOrderedList.Size(); i++)
 | 
						|
	{
 | 
						|
		if (replicaManager->variableSerializeReplicaOrderedList[i]->QueryIsVisibilityAuthority())
 | 
						|
		{
 | 
						|
			res = replicaManager->variableSerializeReplicaOrderedList[i]->QueryVisibility(this);
 | 
						|
			if (res==BQR_YES)
 | 
						|
				currentVisibility.InsertAtEnd(replicaManager->variableSerializeReplicaOrderedList[i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	SetVisibilityByList(currentVisibility, replicaManager);
 | 
						|
}
 | 
						|
void Connection_RM2::SerializeDownloadStarted(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
 | 
						|
	(void) objectData;
 | 
						|
	(void) replicaManager;
 | 
						|
	(void) serializationContext;
 | 
						|
}
 | 
						|
void Connection_RM2::SerializeDownloadComplete(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
 | 
						|
	(void) objectData;
 | 
						|
	(void) replicaManager;
 | 
						|
	(void) serializationContext;
 | 
						|
}
 | 
						|
void Connection_RM2::DeserializeDownloadStarted(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
 | 
						|
	(void) objectData;
 | 
						|
	(void) sender;
 | 
						|
	(void) replicaManager;
 | 
						|
	(void) timestamp;
 | 
						|
	(void) replicaManager;
 | 
						|
	(void) serializationType;
 | 
						|
}
 | 
						|
void Connection_RM2::DeserializeDownloadComplete(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
 | 
						|
	(void) objectData;
 | 
						|
	(void) sender;
 | 
						|
	(void) replicaManager;
 | 
						|
	(void) timestamp;
 | 
						|
	(void) serializationType;
 | 
						|
}
 | 
						|
Replica2 * Connection_RM2::ReceiveConstruct(RakNet::BitStream *replicaData, NetworkID networkId, SystemAddress sender, unsigned char localClientId, SerializationType type,
 | 
						|
					ReplicaManager2 *replicaManager, RakNetTime timestamp,
 | 
						|
					DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
 | 
						|
{
 | 
						|
	Replica2 *obj=0;
 | 
						|
 | 
						|
	bool newReference=false;
 | 
						|
	if (type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT || type==SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT)
 | 
						|
	{
 | 
						|
		obj = Replica2::clientPtrArray[localClientId];
 | 
						|
		if (obj)
 | 
						|
		{
 | 
						|
			obj = obj->ReceiveConstructionReply(sender, replicaData, type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
 | 
						|
			obj->SetNetworkID(networkId);
 | 
						|
			replicaManager->Reference(obj, &newReference);
 | 
						|
			replicaManager->AddConstructionReference(this,obj);
 | 
						|
 | 
						|
			// The object could not be serialized before because it didn't have a NetworkID. So serialize it now.
 | 
						|
			if (obj->QueryIsSerializationAuthority() && (obj->QueryVisibility(this)==BQR_ALWAYS || obj->QueryVisibility(this)==BQR_YES))
 | 
						|
			{
 | 
						|
				SerializationContext sc;
 | 
						|
				sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
				sc.timestamp=timestamp;
 | 
						|
				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
				sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
 | 
						|
				obj->BroadcastSerialize(&sc);
 | 
						|
 | 
						|
				replicaManager->AddVisibilityReference(this,obj);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		// Create locally, relay, send back reply
 | 
						|
		bool collision = replicaManager->GetRakPeer()->GetNetworkIDManager()->GET_OBJECT_FROM_ID<NetworkIDObject*>( networkId )!=0;
 | 
						|
		obj = Construct(replicaData, sender, type, replicaManager, timestamp, networkId, collision);
 | 
						|
		if (obj)
 | 
						|
		{
 | 
						|
			replicaManager->Reference(obj, &newReference);
 | 
						|
 | 
						|
			if (obj->AllowRemoteConstruction(sender, replicaData, type, timestamp)==false)
 | 
						|
			{
 | 
						|
				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
 | 
						|
					obj->SendConstruction(sender, SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT);
 | 
						|
				delete obj;
 | 
						|
				obj=0;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				if (networkId!=UNASSIGNED_NETWORK_ID)
 | 
						|
					obj->SetNetworkID(networkId);
 | 
						|
 | 
						|
				SerializationContext serializationContext;
 | 
						|
				serializationContext.relaySourceAddress=sender;
 | 
						|
				serializationContext.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
 | 
						|
				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
 | 
						|
					serializationContext.serializationType=BROADCAST_CONSTRUCTION_REQUEST_ACCEPTED_TO_SYSTEM;
 | 
						|
				else 
 | 
						|
					serializationContext.serializationType=BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM;
 | 
						|
				exclusionList.Insert(sender,sender,false);
 | 
						|
 | 
						|
				RakNet::BitStream bs;
 | 
						|
				unsigned exclusionListIndex=0;
 | 
						|
				for (unsigned i=0; i < replicaManager->connectionList.Size(); i++)
 | 
						|
				{
 | 
						|
					serializationContext.recipientAddress=replicaManager->connectionList[i]->GetSystemAddress();
 | 
						|
 | 
						|
					while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
 | 
						|
						exclusionListIndex++;
 | 
						|
					if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
 | 
						|
					{
 | 
						|
						exclusionListIndex++;
 | 
						|
						continue;
 | 
						|
					}
 | 
						|
 | 
						|
					bs.Reset();
 | 
						|
					if (obj->SerializeConstruction(&bs, &serializationContext)==false)
 | 
						|
						continue;
 | 
						|
					unsigned char localId;
 | 
						|
					if (obj->QueryIsConstructionAuthority()==false)
 | 
						|
						localId=Replica2::clientSharedID++;
 | 
						|
					else
 | 
						|
						localId=0;
 | 
						|
					replicaManager->SendConstruction(obj,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList, localId, serializationContext.serializationType);
 | 
						|
				}
 | 
						|
 | 
						|
				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
 | 
						|
				{
 | 
						|
					DataStructures::OrderedList<SystemAddress,SystemAddress> emptyList;
 | 
						|
					replicaManager->SendConstruction(obj, &bs, sender, timestamp, true,
 | 
						|
						emptyList, localClientId, SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (obj && newReference && obj->QueryIsSerializationAuthority() && obj->QueryVisibility(this)==BQR_ALWAYS)
 | 
						|
	{
 | 
						|
		SerializationContext sc;
 | 
						|
		sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
		sc.timestamp=timestamp;
 | 
						|
		sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
 | 
						|
		sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
 | 
						|
		obj->BroadcastSerialize(&sc);
 | 
						|
	}
 | 
						|
 | 
						|
	return obj;
 | 
						|
}
 | 
						|
void Connection_RM2::SetSystemAddress(SystemAddress sa)
 | 
						|
{
 | 
						|
	systemAddress=sa;
 | 
						|
}
 | 
						|
SystemAddress Connection_RM2::GetSystemAddress(void) const
 | 
						|
{
 | 
						|
	return systemAddress;
 | 
						|
}
 | 
						|
 | 
						|
void Connection_RM2::Deref(Replica2* replica)
 | 
						|
{
 | 
						|
	lastConstructionList.RemoveIfExists(replica);
 | 
						|
	lastSerializationList.RemoveIfExists(replica);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef _MSC_VER
 | 
						|
#pragma warning( pop )
 | 
						|
#endif
 |