1 #include "NativeFeatureIncludes.h"
2 #if _RAKNET_SUPPORT_ReplicaManager2==1
3 
4 #include "ReplicaManager2.h"
5 #include "MessageIdentifiers.h"
6 #include "RakAssert.h"
7 #include "RakPeerInterface.h"
8 #include "NetworkIDManager.h"
9 
10 using namespace RakNet;
11 
12 unsigned char Replica2::clientSharedID=0;
13 Replica2* Replica2::clientPtrArray[256];
14 
15 
16 #ifdef _MSC_VER
17 #pragma warning( push )
18 #endif
19 
IsSerializationCommand(SerializationType r)20 bool SerializationContext::IsSerializationCommand(SerializationType r)
21 {
22 	return r>=SEND_SERIALIZATION_GENERIC_TO_SYSTEM && r<=RELAY_SERIALIZATION_TO_SYSTEMS;
23 }
IsDownloadCommand(SerializationType r)24 bool SerializationContext::IsDownloadCommand(SerializationType r)
25 {
26 	return r>=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM && r<=SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
27 }
IsDestructionCommand(SerializationType r)28 bool SerializationContext::IsDestructionCommand(SerializationType r)
29 {
30 	return r>=SEND_DESTRUCTION_GENERIC_TO_SYSTEM && r<=RELAY_DESTRUCTION_TO_SYSTEMS;
31 }
IsConstructionCommand(SerializationType r)32 bool SerializationContext::IsConstructionCommand(SerializationType r)
33 {
34 	return r>=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM && r<=SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT;
35 }
IsVisibilityCommand(SerializationType r)36 bool SerializationContext::IsVisibilityCommand(SerializationType r)
37 {
38 	return r>=SEND_VISIBILITY_TRUE_TO_SYSTEM && r<=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
39 }
IsVisible(SerializationType r)40 bool SerializationContext::IsVisible(SerializationType r)
41 {
42 	return r==SEND_VISIBILITY_TRUE_TO_SYSTEM || r==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM || r==RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
43 }
44 
Replica2CompByNetworkID(const NetworkID & key,RakNet::Replica2 * const & data)45 int ReplicaManager2::Replica2CompByNetworkID( const NetworkID &key, RakNet::Replica2 * const &data )
46 {
47 	if (key < data->GetNetworkID())
48 		return -1;
49 	if (key == data->GetNetworkID())
50 		return 0;
51 	return 1;
52 }
53 
Replica2ObjectComp(RakNet::Replica2 * const & key,RakNet::Replica2 * const & data)54 int ReplicaManager2::Replica2ObjectComp( RakNet::Replica2 * const &key, RakNet::Replica2 * const &data )
55 {
56 	if (key->GetAllocationNumber()<data->GetAllocationNumber())
57 		return -1;
58 	if (key->GetAllocationNumber()==data->GetAllocationNumber())
59 		return 0;
60 	return 1;
61 }
62 
Connection_RM2CompBySystemAddress(const SystemAddress & key,RakNet::Connection_RM2 * const & data)63 int ReplicaManager2::Connection_RM2CompBySystemAddress( const SystemAddress &key, RakNet::Connection_RM2 * const &data )
64 {
65 	if (key < data->GetSystemAddress())
66 		return -1;
67 	if (key == data->GetSystemAddress())
68 		return 0;
69 	return 1;
70 }
71 
ReplicaManager2()72 ReplicaManager2::ReplicaManager2()
73 {
74 	connectionFactoryInterface=0;
75 	defaultOrderingChannel=0;
76 	defaultPacketPriority=HIGH_PRIORITY;
77 	defaultPacketReliablity=RELIABLE_ORDERED;
78 	autoUpdateConstruction=true;
79 	autoUpdateVisibility=true;
80 	autoAddNewConnections=true;
81 	doReplicaAutoUpdate=true;
82 	DataStructures::OrderedList<SystemAddress,SystemAddress>::IMPLEMENT_DEFAULT_COMPARISON();
83 }
~ReplicaManager2()84 ReplicaManager2::~ReplicaManager2()
85 {
86 }
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)87 void ReplicaManager2::SendConstruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
88 						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
89 						unsigned char localClientId, SerializationType type,
90 						PacketPriority priority, PacketReliability reliability, char orderingChannel)
91 {
92 	if (replica==0)
93 		return;
94 
95 	// Why would you request an object you already have?
96 	if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID && replica->QueryIsConstructionAuthority()==false)
97 		return;
98 
99 	if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
100 		return;
101 
102 	RakAssert(replica->QueryConstruction(0)!=BQR_NEVER);
103 
104 	bool newConnection;
105 	Connection_RM2* connection;
106 
107 	// Add to list of replicas if not already there
108 	bool newReference;
109 	Reference(replica, &newReference);
110 
111 	RakNet::BitStream bs;
112 	WriteHeader(&bs, ID_REPLICA_MANAGER_CONSTRUCTION, timestamp);
113 	bs.Write((unsigned char) type);
114 	bs.Write(replica->GetNetworkID());
115 	bs.Write(localClientId);
116 
117 	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
118 	{
119 		connection = AutoCreateConnection(recipient, &newConnection);
120 		if (connection==0)
121 			return;
122 
123 		if (newConnection)
124 		{
125 			// If a new connection, the replica was constructed automatically anyway
126 			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
127 			return;
128 		}
129 
130 		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
131 			return;
132 		bs.AlignWriteToByteBoundary();
133 		bs.Write(replicaData);
134 
135 		// Lookup connection by target. If does not exist, create
136 
137 		AddConstructionReference(connection, replica);
138 		if (sendMessage)
139 		{
140 			// Send the packet
141 			Send(&bs, recipient, priority, reliability, orderingChannel);
142 
143 			if (newReference && replica->QueryVisibility(connection)==BQR_ALWAYS)
144 			{
145 //				SerializationContext sc;
146 //				sc.recipientAddress=recipient;
147 //				sc.timestamp=timestamp;
148 //				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
149 //				sc.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
150 				replica->SendSerialize(recipient, SEND_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
151 			}
152 		}
153 	}
154 	else
155 	{
156 		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
157 		CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
158 		WriteExclusionList(&bs, exclusionList);
159 		bs.AlignWriteToByteBoundary();
160 		bs.Write(replicaData);
161 
162 		unsigned i;
163 		for (i=0; i < culledOutput.Size(); i++)
164 		{
165 			connection=culledOutput[i];
166 			AddConstructionReference(connection, replica);
167 
168 			if (sendMessage)
169 				Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
170 
171 			if (newReference && replica->QueryIsSerializationAuthority() && replica->QueryVisibility(connection)==BQR_ALWAYS)
172 			{
173 //				SerializationContext sc;
174 //				sc.recipientAddress=connection->GetSystemAddress();
175 //				sc.timestamp=0;
176 //				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
177 //				sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
178 				replica->SendSerialize(connection->GetSystemAddress(), BROADCAST_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
179 			}
180 		}
181 	}
182 }
183 
SendDestruction(Replica2 * replica,BitStream * replicaData,SystemAddress recipient,RakNetTime timestamp,bool sendMessage,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList,SerializationType type,PacketPriority priority,PacketReliability reliability,char orderingChannel)184 void ReplicaManager2::SendDestruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
185 						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
186 						SerializationType type,
187 						PacketPriority priority, PacketReliability reliability, char orderingChannel)
188 {
189 	if (replica==0)
190 		return;
191 
192 	if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
193 		return;
194 
195 	if (replica->QueryIsDestructionAuthority()==false)
196 		return;
197 
198 	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
199 	{
200 		bool newConnection;
201 
202 		// Lookup connection by target. If does not exist, create
203 		Connection_RM2* connection = AutoCreateConnection(recipient, &newConnection);
204 		if (connection==0)
205 			return;
206 
207 		// Have this system stop referencing the replica object
208 		connection->Deref(replica);
209 
210 		if (newConnection)
211 		{
212 			// If a new connection, the object didn't exist anyway
213 			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
214 			return;
215 		}
216 	}
217 
218 	if (sendMessage && replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID)
219 	{
220 		// Send the packet
221 		RakNet::BitStream bs;
222 		WriteHeader(&bs, ID_REPLICA_MANAGER_DESTRUCTION, timestamp);
223 		bs.Write((unsigned char) type);
224 		bs.Write(replica->GetNetworkID());
225 
226 		if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
227 		{
228 			if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
229 				return;
230 			bs.AlignWriteToByteBoundary();
231 			bs.Write(replicaData);
232 
233 			Send(&bs, recipient, priority, reliability, orderingChannel);
234 		}
235 		else
236 		{
237 			DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
238 			GetConnectionsWithReplicaConstructed(replica, output);
239 			CullByAndAddToExclusionList(output, culledOutput, exclusionList);
240 			WriteExclusionList(&bs, exclusionList);
241 			bs.AlignWriteToByteBoundary();
242 			bs.Write(replicaData);
243 
244 			unsigned i;
245 			for (i=0; i < output.Size(); i++)
246 				Send(&bs, output[i]->GetSystemAddress(), priority, reliability, orderingChannel);
247 		}
248 	}
249 }
250 
SendSerialize(Replica2 * replica,BitStream * replicaData,SystemAddress recipient,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList,SerializationType type,PacketPriority priority,PacketReliability reliability,char orderingChannel)251 void ReplicaManager2::SendSerialize(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
252 						DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
253 						SerializationType type,
254 						 PacketPriority priority, PacketReliability reliability, char orderingChannel)
255 {
256 	if (replica==0)
257 		return;
258 
259 	if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
260 		return;
261 
262 	if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
263 		return;
264 
265 	if (replica->QueryIsSerializationAuthority()==false)
266 		return;
267 
268 	// Add to list of replicas if not already there
269 	bool newReference;
270 	Reference(replica, &newReference);
271 
272 	if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
273 	{
274 		replica->BroadcastConstruction();
275 	}
276 
277 	bool newConnection;
278 	Connection_RM2* connection;
279 
280 	RakNet::BitStream bs;
281 	WriteHeader(&bs, ID_REPLICA_MANAGER_SERIALIZE, timestamp);
282 	bs.Write((unsigned char) type);
283 	bs.Write(replica->GetNetworkID());
284 
285 	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
286 	{
287 		connection = AutoCreateConnection(recipient, &newConnection);
288 		if (connection==0)
289 			return;
290 		if (newConnection)
291 			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
292 
293 		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
294 			return;
295 		bs.AlignWriteToByteBoundary();
296 		bs.Write(replicaData);
297 
298 		// Send the packet
299 		Send(&bs, recipient, priority, reliability, orderingChannel);
300 	}
301 	else
302 	{
303 		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
304 		GetConnectionsWithSerializeVisibility(replica, output);
305 
306 		CullByAndAddToExclusionList(output, culledOutput, exclusionList);
307 		WriteExclusionList(&bs, exclusionList);
308 		bs.AlignWriteToByteBoundary();
309 		bs.Write(replicaData);
310 
311 		unsigned i;
312 		for (i=0; i < culledOutput.Size(); i++)
313 		{
314 			connection=culledOutput[i];
315 			Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
316 		}
317 	}
318 }
SendVisibility(Replica2 * replica,BitStream * replicaData,SystemAddress recipient,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList,SerializationType type,PacketPriority priority,PacketReliability reliability,char orderingChannel)319 void ReplicaManager2::SendVisibility(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
320 							 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
321 							 SerializationType type,
322 							 PacketPriority priority, PacketReliability reliability, char orderingChannel)
323 {
324 	if (replica==0)
325 		return;
326 
327 	bool newConnection;
328 	Connection_RM2* connection;
329 
330 	if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
331 		return;
332 
333 	if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
334 		return;
335 
336 	// Add to list of replicas if not already there
337 	bool newReference;
338 	Reference(replica, &newReference);
339 
340 	if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
341 	{
342 		replica->BroadcastConstruction();
343 	}
344 
345 	RakNet::BitStream bs;
346 	WriteHeader(&bs, ID_REPLICA_MANAGER_SCOPE_CHANGE, timestamp);
347 	bs.Write((unsigned char) type);
348 	bs.Write(replica->GetNetworkID());
349 
350 	if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
351 	{
352 		if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
353 			return;
354 
355 		connection = AutoCreateConnection(recipient, &newConnection);
356 		if (connection==0)
357 			return;
358 		if (newConnection)
359 			DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
360 
361 		bs.AlignWriteToByteBoundary();
362 		bs.Write(replicaData);
363 
364 		if (SerializationContext::IsVisibilityCommand(type))
365 		{
366 			if (SerializationContext::IsVisible(type))
367 				AddVisibilityReference(connection, replica);
368 			else
369 				RemoveVisibilityReference(connection, replica);
370 		}
371 		// Send the packet
372 		Send(&bs, recipient, priority, reliability, orderingChannel);
373 	}
374 	else
375 	{
376 		DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
377 		CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
378 		WriteExclusionList(&bs, exclusionList);
379 		bs.AlignWriteToByteBoundary();
380 		bs.Write(replicaData);
381 
382 		unsigned i;
383 		for (i=0; i < culledOutput.Size(); i++)
384 		{
385 			connection=culledOutput[i];
386 			if (SerializationContext::IsVisible(type))
387 				AddVisibilityReference(connection, replica);
388 			else
389 				RemoveVisibilityReference(connection, replica);
390 			Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
391 		}
392 	}
393 }
Dereference(Replica2 * replica)394 void ReplicaManager2::Dereference(Replica2 *replica)
395 {
396 	unsigned i;
397 	if (replica==0)
398 		return;
399 
400 	for (i=0; i < connectionList.Size(); i++)
401 	{
402 		connectionList[i]->lastConstructionList.RemoveIfExists(replica);
403 		connectionList[i]->lastSerializationList.RemoveIfExists(replica);
404 	}
405 
406 	for (i=0; i < fullReplicaUnorderedList.Size(); i++)
407 	{
408 		if (fullReplicaUnorderedList[i]==replica)
409 		{
410 			fullReplicaUnorderedList.RemoveAtIndex(i);
411 			break;
412 		}
413 	}
414 
415 	fullReplicaOrderedList.RemoveIfExists(replica);
416 	alwaysDoConstructReplicaOrderedList.RemoveIfExists(replica);
417 	alwaysDoSerializeReplicaOrderedList.RemoveIfExists(replica);
418 	variableConstructReplicaOrderedList.RemoveIfExists(replica);
419 	variableSerializeReplicaOrderedList.RemoveIfExists(replica);
420 }
Update(void)421 void ReplicaManager2::Update(void)
422 {
423 	unsigned i;
424 
425 	if (autoUpdateConstruction || autoUpdateVisibility)
426 	{
427 		for (i=0; i < connectionList.Size(); i++)
428 		{
429 			if (autoUpdateConstruction)
430 				connectionList[i]->SetConstructionByReplicaQuery(this);
431 			if (autoUpdateVisibility)
432 				connectionList[i]->SetVisibilityByReplicaQuery(this);
433 		}
434 	}
435 
436 	if (doReplicaAutoUpdate)
437 	{
438 		RakNetTime currentTime = RakNet::GetTime();
439 		for (i=0; i < fullReplicaUnorderedList.Size(); i++)
440 		{
441 			fullReplicaUnorderedList[i]->ElapseAutoSerializeTimers(currentTime-lastUpdateTime,false);
442 		}
443 		lastUpdateTime=currentTime;
444 	}
445 
446 }
GetReplicaCount(void) const447 unsigned ReplicaManager2::GetReplicaCount(void) const
448 {
449 	return fullReplicaUnorderedList.Size();
450 }
GetReplicaAtIndex(unsigned index)451 Replica2 *ReplicaManager2::GetReplicaAtIndex(unsigned index)
452 {
453 	return fullReplicaUnorderedList[index];
454 }
SetAutoAddNewConnections(bool autoDownload)455 void ReplicaManager2::SetAutoAddNewConnections(bool autoDownload)
456 {
457 	autoAddNewConnections=autoDownload;
458 }
SetDoReplicaAutoSerializeUpdate(bool autoUpdate)459 void ReplicaManager2::SetDoReplicaAutoSerializeUpdate(bool autoUpdate)
460 {
461 	doReplicaAutoUpdate=autoUpdate;
462 }
SetConnectionFactory(Connection_RM2Factory * factory)463 void ReplicaManager2::SetConnectionFactory(Connection_RM2Factory *factory)
464 {
465 	RakAssert(factory);
466 	connectionFactoryInterface=factory;
467 }
GetConnectionCount(void) const468 unsigned ReplicaManager2::GetConnectionCount(void) const
469 {
470 	return connectionList.Size();
471 }
GetConnectionAtIndex(unsigned index) const472 Connection_RM2* ReplicaManager2::GetConnectionAtIndex(unsigned index) const
473 {
474 	return connectionList[index];
475 }
GetConnectionBySystemAddress(SystemAddress systemAddress) const476 Connection_RM2* ReplicaManager2::GetConnectionBySystemAddress(SystemAddress systemAddress) const
477 {
478 	bool objectExists;
479 	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
480 	if (objectExists)
481 		return connectionList[index];
482 	return 0;
483 }
GetConnectionIndexBySystemAddress(SystemAddress systemAddress) const484 unsigned int ReplicaManager2::GetConnectionIndexBySystemAddress(SystemAddress systemAddress) const
485 {
486 	bool objectExists;
487 	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
488 	if (objectExists)
489 		return index;
490 	return (unsigned int) -1;
491 }
SetDefaultOrderingChannel(char def)492 void ReplicaManager2::SetDefaultOrderingChannel(char def)
493 {
494 	defaultOrderingChannel=def;
495 }
SetDefaultPacketPriority(PacketPriority def)496 void ReplicaManager2::SetDefaultPacketPriority(PacketPriority def)
497 {
498 	defaultPacketPriority=def;
499 }
SetDefaultPacketReliability(PacketReliability def)500 void ReplicaManager2::SetDefaultPacketReliability(PacketReliability def)
501 {
502 	defaultPacketReliablity=def;
503 }
SetAutoUpdateScope(bool construction,bool visibility)504 void ReplicaManager2::SetAutoUpdateScope(bool construction, bool visibility)
505 {
506 	autoUpdateConstruction=construction;
507 	autoUpdateVisibility=visibility;
508 }
RecalculateVisibility(Replica2 * replica)509 void ReplicaManager2::RecalculateVisibility(Replica2 *replica)
510 {
511 	Dereference(replica);
512 	bool newReference;
513 	Reference(replica, &newReference);
514 
515 	if (replica->QueryConstruction(0)==BQR_NEVER && autoUpdateConstruction)
516 	{
517 		// Destroy on all systems
518 		replica->SendDestruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_DESTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
519 	}
520 	if (replica->QueryConstruction(0)==BQR_ALWAYS && autoUpdateConstruction)
521 	{
522 		// Create on all systems
523 		replica->SendConstruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_CONSTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
524 	}
525 	if (replica->QueryVisibility(0)==BQR_ALWAYS && autoUpdateVisibility)
526 	{
527 		// Set visibility and creation on all systems
528 		replica->SendVisibility(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
529 		replica->SendSerialize(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
530 	}
531 }
GetConnectionsWithReplicaConstructed(Replica2 * replica,DataStructures::OrderedList<SystemAddress,Connection_RM2 *,ReplicaManager2::Connection_RM2CompBySystemAddress> & output)532 void ReplicaManager2::GetConnectionsWithReplicaConstructed(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
533 {
534 	BooleanQueryResult res;
535 	res = replica->QueryConstruction(0);
536 	if (res==BQR_ALWAYS)
537 	{
538 		output=connectionList;
539 	}
540 	else if (res!=BQR_NEVER)
541 	{
542 		unsigned i;
543 		for (i=0; i < connectionList.Size(); i++)
544 		{
545 			if (connectionList[i]->lastConstructionList.HasData(replica))
546 				output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false, __FILE__,__LINE__);
547 		}
548 	}
549 }
GetConnectionsWithSerializeVisibility(Replica2 * replica,DataStructures::OrderedList<SystemAddress,Connection_RM2 *,ReplicaManager2::Connection_RM2CompBySystemAddress> & output)550 void ReplicaManager2::GetConnectionsWithSerializeVisibility(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
551 {
552 	BooleanQueryResult res;
553 	res = replica->QueryVisibility(0);
554 	if (res==BQR_ALWAYS)
555 	{
556 		GetConnectionsWithReplicaConstructed(replica, output);
557 	}
558 	else if (res!=BQR_NEVER)
559 	{
560 		unsigned i;
561 		for (i=0; i < connectionList.Size(); i++)
562 		{
563 			if (connectionList[i]->lastSerializationList.HasData(replica))
564 				output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false, __FILE__,__LINE__);
565 		}
566 	}
567 }
GetRakPeer(void) const568 RakPeerInterface *ReplicaManager2::GetRakPeer(void) const
569 {
570 	return rakPeerInterface;
571 }
AutoCreateConnection(SystemAddress systemAddress,bool * newConnection)572 Connection_RM2* ReplicaManager2::AutoCreateConnection(SystemAddress systemAddress, bool *newConnection)
573 {
574 	if (autoAddNewConnections)
575 		return CreateConnectionIfDoesNotExist(systemAddress, newConnection);
576 	else
577 	{
578 		bool objectExists;
579 		unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
580 		*newConnection=false;
581 		if (objectExists==false)
582 		{
583 			return 0;
584 		}
585 		return connectionList[index];
586 	}
587 }
CreateConnectionIfDoesNotExist(SystemAddress systemAddress,bool * newConnection)588 Connection_RM2* ReplicaManager2::CreateConnectionIfDoesNotExist(SystemAddress systemAddress, bool *newConnection)
589 {
590 	bool objectExists;
591 	unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
592 	if (objectExists==false)
593 	{
594 		// If it crashes here, you need to call SetConnection_RM2Factory
595 		Connection_RM2 *connection = connectionFactoryInterface->AllocConnection();
596 		connection->SetSystemAddress(systemAddress);
597 		connection->SetGuid(rakPeerInterface->GetGuidFromSystemAddress(systemAddress));
598 		connectionList.Insert(systemAddress, connection, false, __FILE__,__LINE__);
599 		*newConnection=true;
600 		return connection;
601 	}
602 	*newConnection=false;
603 	return connectionList[index];
604 }
AddNewConnection(SystemAddress systemAddress)605 bool ReplicaManager2::AddNewConnection(SystemAddress systemAddress)
606 {
607 	bool newConnection;
608 	Connection_RM2* connection = CreateConnectionIfDoesNotExist(systemAddress, &newConnection);
609 	if (newConnection)
610 		DownloadToNewConnection(connection, 0, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
611 	return newConnection;
612 }
RemoveConnection(SystemAddress systemAddress)613 bool ReplicaManager2::RemoveConnection(SystemAddress systemAddress)
614 {
615 	unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
616 	if (index!=(unsigned int) -1)
617 	{
618 		connectionFactoryInterface->DeallocConnection(connectionList[index]);
619 		connectionList.RemoveAtIndex(index);
620 		return true;
621 	}
622 	return false;
623 }
HasConnection(SystemAddress systemAddress)624 bool ReplicaManager2::HasConnection(SystemAddress systemAddress)
625 {
626 	unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
627 	return index!=(unsigned int) -1;
628 }
Reference(Replica2 * replica,bool * newReference)629 void ReplicaManager2::Reference(Replica2* replica, bool *newReference)
630 {
631 	replica->SetReplicaManager(this);
632 
633 	bool objectExists;
634 	unsigned index = fullReplicaOrderedList.GetIndexFromKey(replica,&objectExists);
635 	if (objectExists==false)
636 	{
637 		fullReplicaUnorderedList.Insert(replica, __FILE__, __LINE__);
638 		fullReplicaOrderedList.InsertAtIndex(replica, index, __FILE__,__LINE__);
639 
640 		BooleanQueryResult queryResult;
641 		queryResult = replica->QueryConstruction(0);
642 		if (queryResult==BQR_ALWAYS)
643 			alwaysDoConstructReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
644 		else if (queryResult!=BQR_NEVER)
645 			variableConstructReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
646 		queryResult = replica->QueryVisibility(0);
647 		if (queryResult==BQR_ALWAYS)
648 			alwaysDoSerializeReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
649 		else if (queryResult!=BQR_NEVER)
650 			variableSerializeReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
651 
652 		if (newReference)
653 			*newReference=true;
654 
655 		return;
656 	}
657 	if (newReference)
658 		*newReference=false;
659 }
AddConstructionReference(Connection_RM2 * connection,Replica2 * replica)660 void ReplicaManager2::AddConstructionReference(Connection_RM2* connection, Replica2* replica)
661 {
662 	if (replica->QueryIsConstructionAuthority() && replica->QueryConstruction(0)!=BQR_ALWAYS && replica->QueryConstruction(0)!=BQR_NEVER)
663 		connection->lastConstructionList.Insert(replica, replica, false, __FILE__,__LINE__);
664 }
AddVisibilityReference(Connection_RM2 * connection,Replica2 * replica)665 void ReplicaManager2::AddVisibilityReference(Connection_RM2* connection, Replica2* replica)
666 {
667 	if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
668 		connection->lastSerializationList.Insert(replica, replica, false, __FILE__,__LINE__);
669 }
RemoveVisibilityReference(Connection_RM2 * connection,Replica2 * replica)670 void ReplicaManager2::RemoveVisibilityReference(Connection_RM2* connection, Replica2* replica)
671 {
672 	if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
673 		connection->lastSerializationList.RemoveIfExists(replica);
674 }
WriteHeader(RakNet::BitStream * bs,MessageID type,RakNetTime timestamp)675 void ReplicaManager2::WriteHeader(RakNet::BitStream *bs, MessageID type, RakNetTime timestamp)
676 {
677 	if (timestamp!=0)
678 	{
679 		bs->Write((MessageID)ID_TIMESTAMP);
680 		bs->Write(timestamp);
681 	}
682 	bs->Write(type);
683 }
OnClosedConnection(SystemAddress systemAddress,RakNetGUID rakNetGUID,PI2_LostConnectionReason lostConnectionReason)684 void ReplicaManager2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
685 {
686 	(void) systemAddress;
687 	(void) rakNetGUID;
688 	(void) lostConnectionReason;
689 
690 	RemoveConnection(systemAddress);
691 }
OnRakPeerShutdown(void)692 void ReplicaManager2::OnRakPeerShutdown(void)
693 {
694 	Clear();
695 }
OnAttach(void)696 void ReplicaManager2::OnAttach(void)
697 {
698 	lastUpdateTime=RakNet::GetTime();
699 }
OnNewConnection(SystemAddress systemAddress,RakNetGUID rakNetGUID,bool isIncoming)700 void ReplicaManager2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
701 {
702 	(void) systemAddress;
703 	(void) rakNetGUID;
704 	(void) isIncoming;
705 
706 	if (autoAddNewConnections)
707 		AddNewConnection(systemAddress);
708 }
OnReceive(Packet * packet)709 PluginReceiveResult ReplicaManager2::OnReceive(Packet *packet)
710 {
711 	RakNetTime timestamp=0;
712 	unsigned char packetIdentifier, packetDataOffset;
713 	if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
714 	{
715 		if ( packet->length > sizeof( unsigned char ) + sizeof( RakNetTime ) )
716 		{
717 			packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( RakNetTime ) ];
718 			// Required for proper endian swapping
719 			RakNet::BitStream tsBs(packet->data+sizeof(MessageID),packet->length-1,false);
720 			tsBs.Read(timestamp);
721 			packetDataOffset=sizeof( unsigned char )*2 + sizeof( RakNetTime );
722 		}
723 		else
724 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
725 	}
726 	else
727 	{
728 		packetIdentifier = ( unsigned char ) packet->data[ 0 ];
729 		packetDataOffset=sizeof( unsigned char );
730 	}
731 
732 	switch (packetIdentifier)
733 	{
734 	case ID_REPLICA_MANAGER_DOWNLOAD_STARTED:
735 		return OnDownloadStarted(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
736 	case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
737 		return OnDownloadComplete(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
738 	case ID_REPLICA_MANAGER_CONSTRUCTION:
739 		return OnConstruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
740 	case ID_REPLICA_MANAGER_DESTRUCTION:
741 		return OnDestruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
742 	case ID_REPLICA_MANAGER_SCOPE_CHANGE:
743 		return OnVisibilityChange(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
744 	case ID_REPLICA_MANAGER_SERIALIZE:
745 		return OnSerialize(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
746 	}
747 
748 	return RR_CONTINUE_PROCESSING;
749 }
OnDownloadStarted(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)750 PluginReceiveResult ReplicaManager2::OnDownloadStarted(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
751 {
752 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
753 	bool newConnection;
754 	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
755 	if (connection==0)
756 		return RR_CONTINUE_PROCESSING;
757 	SerializationType serializationType;
758 	unsigned char c;
759 	incomingBitstream.Read(c);
760 	serializationType=(SerializationType) c;
761 	incomingBitstream.AlignReadToByteBoundary();
762 	connection->DeserializeDownloadStarted(&incomingBitstream, sender, this, timestamp, serializationType);
763 
764 	if (newConnection)
765 		DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
766 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
767 }
OnDownloadComplete(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)768 PluginReceiveResult ReplicaManager2::OnDownloadComplete(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
769 {
770 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
771 	bool newConnection;
772 	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
773 	if (connection==0)
774 		return RR_CONTINUE_PROCESSING;
775 	SerializationType serializationType;
776 	unsigned char c;
777 	incomingBitstream.Read(c);
778 	serializationType=(SerializationType) c;
779 	incomingBitstream.AlignReadToByteBoundary();
780 	connection->DeserializeDownloadComplete(&incomingBitstream, sender, this, timestamp, serializationType);
781 
782 	if (newConnection)
783 		DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
784 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
785 }
786 
OnConstruction(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)787 PluginReceiveResult ReplicaManager2::OnConstruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
788 {
789 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
790 	bool newConnection;
791 	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
792 	if (connection==0)
793 		return RR_CONTINUE_PROCESSING;
794 	SerializationType serializationType;
795 	unsigned char c;
796 	incomingBitstream.Read(c);
797 	serializationType=(SerializationType) c;
798 	NetworkID networkId=UNASSIGNED_NETWORK_ID;
799 	unsigned char localClientId=255;
800 	bool success;
801 	incomingBitstream.Read(networkId);
802 	success=incomingBitstream.Read(localClientId);
803 	RakAssert(success);
804 
805 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
806 	ReadExclusionList(&incomingBitstream, exclusionList);
807 	exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
808 
809 	Replica2* replica;
810 	// The prefix misaligns the data from the send, which is a problem if the user uses aligned data
811 	incomingBitstream.AlignReadToByteBoundary();
812 	replica = connection->ReceiveConstruct(&incomingBitstream, networkId, sender, localClientId, serializationType, this, timestamp,exclusionList);
813 	if (replica)
814 	{
815 		// Register this object on this connection
816 		AddConstructionReference(connection, replica);
817 	}
818 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
819 }
OnDestruction(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)820 PluginReceiveResult ReplicaManager2::OnDestruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
821 {
822 	if (HasConnection(sender)==false)
823 		return RR_CONTINUE_PROCESSING;
824 
825 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
826 	SerializationType serializationType;
827 	unsigned char c;
828 	incomingBitstream.Read(c);
829 	serializationType=(SerializationType) c;
830 	NetworkID networkId;
831 	incomingBitstream.Read(networkId);
832 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
833 	ReadExclusionList(&incomingBitstream, exclusionList);
834 	exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
835 	Replica2 * replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2*>( networkId );
836 	if (replica)
837 	{
838 		// Verify that this is a registered object, so it actually is a Replica2
839 		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
840 		{
841 			// This object is not registered
842 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
843 		}
844 
845 		// The prefix misaligns the data from the send, which is a problem if the user uses aligned data
846 		incomingBitstream.AlignReadToByteBoundary();
847 		replica->ReceiveDestruction(sender, &incomingBitstream, serializationType, timestamp,exclusionList );
848 	}
849 	// else this object is unknown
850 
851 
852 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
853 }
OnVisibilityChange(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)854 PluginReceiveResult ReplicaManager2::OnVisibilityChange(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
855 {
856 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
857 	bool newConnection;
858 	Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
859 	if (connection==0)
860 		return RR_CONTINUE_PROCESSING;
861 	SerializationType serializationType;
862 
863 	unsigned char c;
864 	incomingBitstream.Read(c);
865 	serializationType=(SerializationType) c;
866 	NetworkID networkId;
867 	incomingBitstream.Read(networkId);
868 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
869 	ReadExclusionList(&incomingBitstream, exclusionList);
870 	exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
871 
872 	Replica2 *replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
873 	if (replica)
874 	{
875 		// Verify that this is a registered object, so it actually is a Replica2
876 		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
877 		{
878 			RakAssert(0);
879 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
880 		}
881 
882 		// The prefix misaligns the data from the send, which is a problem if the user uses aligned data
883 		incomingBitstream.AlignReadToByteBoundary();
884 		replica->ReceiveVisibility(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
885 
886 		AddConstructionReference(connection, replica);
887 
888 		// Update the last known visibility list
889 		if (SerializationContext::IsVisibilityCommand(serializationType))
890 		{
891 			if (SerializationContext::IsVisible(serializationType))
892 				AddVisibilityReference(connection, replica);
893 			else
894 				RemoveVisibilityReference(connection, replica);
895 		}
896 	}
897 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
898 }
OnSerialize(unsigned char * packetData,int packetDataLength,SystemAddress sender,RakNetTime timestamp)899 PluginReceiveResult ReplicaManager2::OnSerialize(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
900 {
901 	RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
902 	Connection_RM2* connection = GetConnectionBySystemAddress(sender);
903 	if (connection==0)
904 		return RR_CONTINUE_PROCESSING;
905 	SerializationType serializationType;
906 	unsigned char c;
907 	incomingBitstream.Read(c);
908 	serializationType=(SerializationType) c;
909 	NetworkID networkId;
910 	incomingBitstream.Read(networkId);
911 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
912 	ReadExclusionList(&incomingBitstream, exclusionList);
913 	exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
914 
915 	Replica2 *replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
916 	if (replica)
917 	{
918 		// Verify that this is a registered object, so it actually is a Replica2
919 		if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
920 		{
921 			RakAssert(0);
922 			return RR_STOP_PROCESSING_AND_DEALLOCATE;
923 		}
924 
925 		exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
926 
927 		// The prefix misaligns the data from the send, which is a problem if the user uses aligned data
928 		incomingBitstream.AlignReadToByteBoundary();
929 		replica->ReceiveSerialize(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
930 
931 		AddConstructionReference(connection, replica);
932 	}
933 	return RR_STOP_PROCESSING_AND_DEALLOCATE;
934 }
AddToAndWriteExclusionList(SystemAddress recipient,RakNet::BitStream * bs,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)935 bool ReplicaManager2::AddToAndWriteExclusionList(SystemAddress recipient, RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
936 {
937 	if (exclusionList.HasData(recipient))
938 		return false;
939 	exclusionList.Insert(recipient,recipient,true, __FILE__,__LINE__);
940 	WriteExclusionList(bs,exclusionList);
941 	return true;
942 }
WriteExclusionList(RakNet::BitStream * bs,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)943 void ReplicaManager2::WriteExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
944 {
945 	bs->WriteCompressed(exclusionList.Size());
946 	for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionList.Size(); exclusionListIndex++ )
947 		bs->Write(exclusionList[exclusionListIndex]);
948 }
949 
CullByAndAddToExclusionList(DataStructures::OrderedList<SystemAddress,Connection_RM2 *,ReplicaManager2::Connection_RM2CompBySystemAddress> & inputList,DataStructures::OrderedList<SystemAddress,Connection_RM2 *,ReplicaManager2::Connection_RM2CompBySystemAddress> & culledOutput,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)950 void ReplicaManager2::CullByAndAddToExclusionList(
951 								 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &inputList,
952 								 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &culledOutput,
953 								 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
954 {
955 	Connection_RM2* connection;
956 	unsigned i;
957 	unsigned exclusionListIndex=0;
958 	for (i=0; i < inputList.Size(); i++)
959 	{
960 		connection=inputList[i];
961 		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < connection->GetSystemAddress())
962 			exclusionListIndex++;
963 		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==connection->GetSystemAddress())
964 		{
965 			exclusionListIndex++;
966 			continue;
967 		}
968 		culledOutput.InsertAtEnd(connection, __FILE__,__LINE__);
969 	}
970 
971 	for (i=0; i < culledOutput.Size(); i++)
972 		exclusionList.Insert(culledOutput[i]->GetSystemAddress(),culledOutput[i]->GetSystemAddress(),true, __FILE__,__LINE__);
973 }
ReadExclusionList(RakNet::BitStream * bs,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)974 void ReplicaManager2::ReadExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
975 {
976 	unsigned int exclusionListSize;
977 	bs->ReadCompressed(exclusionListSize);
978 	for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionListSize; exclusionListIndex++)
979 	{
980 		SystemAddress systemToExclude;
981 		bs->Read(systemToExclude);
982 		exclusionList.InsertAtEnd(systemToExclude, __FILE__,__LINE__);
983 	}
984 }
Send(RakNet::BitStream * bs,SystemAddress recipient,PacketPriority priority,PacketReliability reliability,char orderingChannel)985 void ReplicaManager2::Send(RakNet::BitStream *bs, SystemAddress recipient, PacketPriority priority, PacketReliability reliability, char orderingChannel)
986 {
987 	if (priority==NUMBER_OF_PRIORITIES)
988 		priority=defaultPacketPriority;
989 	if (reliability==NUMBER_OF_RELIABILITIES)
990 		reliability=defaultPacketReliablity;
991 	if (orderingChannel==-1)
992 		orderingChannel=defaultOrderingChannel;
993 	SendUnified(bs, priority,reliability,orderingChannel,recipient,false);
994 }
Clear(void)995 void ReplicaManager2::Clear(void)
996 {
997 	fullReplicaUnorderedList.Clear(false, __FILE__, __LINE__);
998 	fullReplicaOrderedList.Clear(false, __FILE__, __LINE__);
999 	alwaysDoConstructReplicaOrderedList.Clear(false, __FILE__, __LINE__);
1000 	alwaysDoSerializeReplicaOrderedList.Clear(false, __FILE__, __LINE__);
1001 	variableConstructReplicaOrderedList.Clear(false, __FILE__, __LINE__);
1002 	variableSerializeReplicaOrderedList.Clear(false, __FILE__, __LINE__);
1003 	unsigned i;
1004 	for (i=0; i < connectionList.Size(); i++)
1005 		connectionFactoryInterface->DeallocConnection(connectionList[i]);
1006 	connectionList.Clear(false, __FILE__, __LINE__);
1007 }
DownloadToNewConnection(Connection_RM2 * connection,RakNetTime timestamp,PacketPriority priority,PacketReliability reliability,char orderingChannel)1008 void ReplicaManager2::DownloadToNewConnection(Connection_RM2* connection, RakNetTime timestamp, PacketPriority priority, PacketReliability reliability, char orderingChannel)
1009 {
1010 	unsigned int i;
1011 	RakNet::BitStream bs, bs2;
1012 	BooleanQueryResult bqr;
1013 	SystemAddress systemAddress = connection->GetSystemAddress();
1014 	SerializationContext serializationContext;
1015 	serializationContext.recipientAddress=systemAddress;
1016 	serializationContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1017 	serializationContext.serializationType=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
1018 	serializationContext.timestamp=0;
1019 
1020 	// bs2 is so SerializeDownloadStarted can change the timestamp
1021 	bs2.AlignWriteToByteBoundary();
1022 	connection->SerializeDownloadStarted(&bs2, this, &serializationContext);
1023 	WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_STARTED, timestamp);
1024 	bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
1025 	bs.Write(&bs2);
1026 	Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
1027 
1028 	DataStructures::List<Replica2*> initialDownloadList;
1029 	DataStructures::List<Replica2*> culledDownloadList;
1030 	connection->SortInitialDownload(fullReplicaUnorderedList, initialDownloadList);
1031 
1032 	// Construct all objects before serializing them. This way the recipient will have valid NetworkID references.
1033 	// Send all objects that always exist
1034 	for (i=0; i < initialDownloadList.Size(); i++)
1035 	{
1036 		if (initialDownloadList[i]->QueryIsConstructionAuthority())
1037 		{
1038 			bqr=initialDownloadList[i]->QueryConstruction(connection);
1039 			if (bqr==BQR_ALWAYS || bqr==BQR_YES)
1040 			{
1041 				initialDownloadList[i]->SendConstruction(systemAddress, SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
1042 				culledDownloadList.Insert(initialDownloadList[i], __FILE__, __LINE__ );
1043 			}
1044 			// Remember for this particular connection that we already sent this update to this system
1045 			if (bqr==BQR_YES)
1046 				AddConstructionReference(connection, initialDownloadList[i]);
1047 		}
1048 	}
1049 
1050 	bool notVisible;
1051 
1052 	// Send all objects that are always visible
1053 	for (i=0; i < culledDownloadList.Size(); i++)
1054 	{
1055 		notVisible=false;
1056 		if (culledDownloadList[i]->QueryIsVisibilityAuthority())
1057 		{
1058 			bqr=culledDownloadList[i]->QueryVisibility(connection);
1059 			if (bqr==BQR_ALWAYS || bqr==BQR_YES)
1060 			{
1061 				culledDownloadList[i]->SendVisibility(systemAddress, SEND_VISIBILITY_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
1062 				// Remember for this particular connection that we already sent this update to this system
1063 				if (bqr==BQR_YES)
1064 					AddVisibilityReference(connection, culledDownloadList[i]);
1065 			}
1066 			else
1067 				notVisible=true;
1068 		}
1069 
1070 		if (culledDownloadList[i]->QueryIsSerializationAuthority() && notVisible==false)
1071 			culledDownloadList[i]->SendSerialize(systemAddress, SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
1072 	}
1073 
1074 	bs.Reset();
1075 	// bs2 is so SerializeDownloadComplete can change the timestamp
1076 	bs2.AlignWriteToByteBoundary();
1077 	connection->SerializeDownloadComplete(&bs2, this,&serializationContext);
1078 	WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE, timestamp);
1079 	bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
1080 	bs.Write(&bs2);
1081 	Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
1082 }
Replica2()1083 Replica2::Replica2()
1084 {
1085 	rm2=0;
1086 	hasClientID=false;
1087 
1088 	DataStructures::Map<SerializationType, AutoSerializeEvent*>::IMPLEMENT_DEFAULT_COMPARISON();
1089 }
~Replica2()1090 Replica2::~Replica2()
1091 {
1092 	DereferenceFromDestruction();
1093 }
1094 
SetReplicaManager(ReplicaManager2 * rm)1095 void Replica2::SetReplicaManager(ReplicaManager2* rm)
1096 {
1097 	rm2=rm;
1098 	if (GetNetworkIDManager()==0)
1099 		SetNetworkIDManager(rm->GetRakPeer()->GetNetworkIDManager());
1100 }
GetReplicaManager(void) const1101 ReplicaManager2* Replica2::GetReplicaManager(void) const
1102 {
1103 	return rm2;
1104 }
SerializeDestruction(RakNet::BitStream * bitStream,SerializationContext * serializationContext)1105 bool Replica2::SerializeDestruction(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
1106 {
1107 	(void) bitStream;
1108 	(void) serializationContext;
1109 
1110 	return true;
1111 }
Serialize(RakNet::BitStream * bitStream,SerializationContext * serializationContext)1112 bool Replica2::Serialize(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
1113 {
1114 	(void) bitStream;
1115 	(void) serializationContext;
1116 
1117 	return true;
1118 }
SerializeVisibility(RakNet::BitStream * bitStream,SerializationContext * serializationContext)1119 bool Replica2::SerializeVisibility(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
1120 {
1121 	(void) bitStream;
1122 	(void) serializationContext;
1123 
1124 	return true;
1125 }
DeserializeDestruction(RakNet::BitStream * bitStream,SerializationType serializationType,SystemAddress sender,RakNetTime timestamp)1126 void Replica2::DeserializeDestruction(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
1127 {
1128 	(void) bitStream;
1129 	(void) serializationType;
1130 	(void) sender;
1131 	(void) timestamp;
1132 
1133 }
Deserialize(RakNet::BitStream * bitStream,SerializationType serializationType,SystemAddress sender,RakNetTime timestamp)1134 void Replica2::Deserialize(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
1135 {
1136 	(void) bitStream;
1137 	(void) serializationType;
1138 	(void) sender;
1139 	(void) timestamp;
1140 }
DeserializeVisibility(RakNet::BitStream * bitStream,SerializationType serializationType,SystemAddress sender,RakNetTime timestamp)1141 void Replica2::DeserializeVisibility(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
1142 {
1143 	(void) bitStream;
1144 	(void) serializationType;
1145 	(void) sender;
1146 	(void) timestamp;
1147 }
SendConstruction(SystemAddress recipientAddress,SerializationType serializationType)1148 void Replica2::SendConstruction(SystemAddress recipientAddress, SerializationType serializationType)
1149 {
1150 	RakNet::BitStream bs;
1151 	SerializationContext defaultContext;
1152 
1153 	if (serializationType==UNDEFINED_REASON)
1154 	{
1155 		if (QueryIsConstructionAuthority()==false)
1156 			defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
1157 		else
1158 			defaultContext.serializationType=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM;
1159 	}
1160 	else
1161 		defaultContext.serializationType=serializationType;
1162 
1163 	defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1164 	defaultContext.recipientAddress=recipientAddress;
1165 	defaultContext.timestamp=0;
1166 
1167 	unsigned char localId;
1168 	if (QueryIsConstructionAuthority()==false)
1169 	{
1170 		clientPtrArray[Replica2::clientSharedID]=this;
1171 		localId=Replica2::clientSharedID++;
1172 	}
1173 	else
1174 		localId=0;
1175 
1176 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1177 	// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
1178 	bs.AlignWriteToByteBoundary();
1179 	if (SerializeConstruction(&bs, &defaultContext))
1180 		rm2->SendConstruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,localId,defaultContext.serializationType);
1181 }
SendDestruction(SystemAddress recipientAddress,SerializationType serializationType)1182 void Replica2::SendDestruction(SystemAddress recipientAddress, SerializationType serializationType)
1183 {
1184 	RakNet::BitStream bs;
1185 	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
1186 
1187 	if (serializationType==UNDEFINED_REASON)
1188 		defaultContext.serializationType=SEND_DESTRUCTION_GENERIC_TO_SYSTEM;
1189 
1190 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1191 	// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
1192 	bs.AlignWriteToByteBoundary();
1193 	if (SerializeDestruction(&bs, &defaultContext))
1194 		rm2->SendDestruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,defaultContext.serializationType);
1195 }
SendSerialize(SystemAddress recipientAddress,SerializationType serializationType)1196 void Replica2::SendSerialize(SystemAddress recipientAddress, SerializationType serializationType)
1197 {
1198 	RakNet::BitStream bs;
1199 	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
1200 
1201 	if (serializationType==UNDEFINED_REASON)
1202 		defaultContext.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
1203 
1204 	// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
1205 	bs.AlignWriteToByteBoundary();
1206 	if (Serialize(&bs, &defaultContext))
1207 	{
1208 		DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1209 		rm2->SendSerialize(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
1210 	}
1211 }
SendVisibility(SystemAddress recipientAddress,SerializationType serializationType)1212 void Replica2::SendVisibility(SystemAddress recipientAddress, SerializationType serializationType)
1213 {
1214 	RakNet::BitStream bs;
1215 	SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
1216 
1217 	if (serializationType==UNDEFINED_REASON)
1218 		defaultContext.serializationType=SEND_VISIBILITY_TRUE_TO_SYSTEM;
1219 
1220 	// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
1221 	bs.AlignWriteToByteBoundary();
1222 	if (SerializeVisibility(&bs, &defaultContext))
1223 	{
1224 		DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1225 		rm2->SendVisibility(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
1226 	}
1227 }
BroadcastSerialize(SerializationContext * serializationContext)1228 void Replica2::BroadcastSerialize(SerializationContext *serializationContext)
1229 {
1230 	RakNet::BitStream bs;
1231 	SerializationContext defaultContext(BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
1232 	SerializationContext *usedContext;
1233 	if (serializationContext)
1234 		usedContext=serializationContext;
1235 	else
1236 		usedContext=&defaultContext;
1237 
1238 	bool newReference;
1239 	rm2->Reference(this, &newReference);
1240 
1241 	// If this is a new object, then before sending serialization we should send construction to all systems
1242 	if (newReference && QueryConstruction(0)==BQR_ALWAYS)
1243 	{
1244 		BroadcastConstruction();
1245 	}
1246 
1247 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1248 	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
1249 	{
1250 		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
1251 		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
1252 			continue;
1253 		bs.Reset();
1254 		// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
1255 		bs.AlignWriteToByteBoundary();
1256 		if (Serialize(&bs, usedContext)==false)
1257 			continue;
1258 		exclusionList.Clear(false, __FILE__, __LINE__);
1259 		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
1260 		{
1261 			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
1262 				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
1263 		}
1264 		rm2->SendSerialize(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
1265 	}
1266 }
1267 
ReceiveSerialize(SystemAddress sender,RakNet::BitStream * serializedObject,SerializationType serializationType,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)1268 void Replica2::ReceiveSerialize(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
1269 {
1270 	// Force all autoserialize timers to go off early, so any variable changes from the Deserialize event do not themselves trigger an autoserialize event
1271 	ForceElapseAllAutoserializeTimers(false);
1272 
1273 	// Deserialize the new data
1274 	Deserialize(serializedObject, serializationType, sender, timestamp);
1275 
1276 	// Update last values for all autoserialize timers
1277 	ForceElapseAllAutoserializeTimers(true);
1278 
1279 	SerializationContext serializationContext;
1280 	serializationContext.serializationType=RELAY_SERIALIZATION_TO_SYSTEMS;
1281 	serializationContext.timestamp=timestamp;
1282 	serializationContext.relaySourceAddress=sender;
1283 
1284 
1285 	BooleanQueryResult bqr;
1286 	RakNet::BitStream bs;
1287 	unsigned exclusionListIndex=0;
1288 	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
1289 	{
1290 		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
1291 		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
1292 			exclusionListIndex++;
1293 		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
1294 		{
1295 			exclusionListIndex++;
1296 			continue;
1297 		}
1298 
1299 		// Don't relay serializations if this object should not be visible
1300 		bqr=QueryVisibility(rm2->connectionList[i]);
1301 		if (bqr==BQR_NEVER || bqr==BQR_NO)
1302 			continue;
1303 
1304 		bs.Reset();
1305 		if (Serialize(&bs, &serializationContext)==false)
1306 			continue;
1307 		rm2->SendSerialize(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
1308 	}
1309 }
1310 
BroadcastConstruction(SerializationContext * serializationContext)1311 void Replica2::BroadcastConstruction(SerializationContext *serializationContext)
1312 {
1313 	RakNet::BitStream bs;
1314 	SerializationContext defaultContext(BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
1315 	SerializationContext *usedContext;
1316 	if (serializationContext)
1317 		usedContext=serializationContext;
1318 	else
1319 	{
1320 		usedContext=&defaultContext;
1321 		if (QueryIsConstructionAuthority()==false)
1322 			defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
1323 	}
1324 
1325 	bool newReference;
1326 	rm2->Reference(this, &newReference);
1327 
1328 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1329 
1330 	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
1331 	{
1332 		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
1333 		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
1334 			continue;
1335 		bs.Reset();
1336 		if (SerializeConstruction(&bs, usedContext)==false)
1337 			continue;
1338 		unsigned char localId;
1339 		if (QueryIsConstructionAuthority()==false)
1340 		{
1341 			clientPtrArray[Replica2::clientSharedID]=this;
1342 			localId=Replica2::clientSharedID++;
1343 		}
1344 		else
1345 			localId=0;
1346 		exclusionList.Clear(false, __FILE__, __LINE__);
1347 		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
1348 		{
1349 			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
1350 				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
1351 		}
1352 		rm2->SendConstruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList, localId, usedContext->serializationType);
1353 	}
1354 
1355 
1356 	bool notVisible=false;
1357 	BooleanQueryResult bqr;
1358 	bqr=QueryVisibility(0);
1359 
1360 	if (bqr==BQR_ALWAYS)
1361 		BroadcastVisibility(true);
1362 	else if (bqr==BQR_NEVER)
1363 		notVisible=true;
1364 
1365 	if (notVisible==false)
1366 		BroadcastSerialize();
1367 }
ReceiveConstructionReply(SystemAddress sender,BitStream * replicaData,bool constructionAllowed)1368 Replica2 * Replica2::ReceiveConstructionReply(SystemAddress sender, BitStream *replicaData, bool constructionAllowed)
1369 {
1370 	(void) replicaData;
1371 	(void) sender;
1372 
1373 	if (constructionAllowed==false)
1374 	{
1375 		//RakNet::OP_DELETE(this, __FILE__, __LINE__);
1376 		delete this;
1377 		return 0;
1378 	}
1379 
1380 	return this;
1381 }
DereferenceFromDestruction(void)1382 void Replica2::DereferenceFromDestruction(void)
1383 {
1384 	if (rm2)
1385 		rm2->Dereference(this);
1386 	if (hasClientID)
1387 		clientPtrArray[clientID]=0;
1388 	ClearAutoSerializeTimers();
1389 }
BroadcastDestruction(SerializationContext * serializationContext)1390 void Replica2::BroadcastDestruction(SerializationContext *serializationContext)
1391 {
1392 	RakNet::BitStream bs;
1393 	SerializationContext defaultContext(BROADCAST_DESTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS, 0);
1394 	SerializationContext *usedContext;
1395 	if (serializationContext)
1396 		usedContext=serializationContext;
1397 	else
1398 		usedContext=&defaultContext;
1399 
1400 	DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
1401 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1402 	rm2->CullByAndAddToExclusionList(rm2->connectionList, culledOutput, exclusionList);
1403 
1404 	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
1405 	{
1406 		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
1407 		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
1408 			continue;
1409 		bs.Reset();
1410 		if (SerializeDestruction(&bs, usedContext)==false)
1411 			continue;
1412 		exclusionList.Clear(false, __FILE__, __LINE__);
1413 		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
1414 		{
1415 			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
1416 				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
1417 		}
1418 		rm2->SendDestruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList,usedContext->serializationType);
1419 	}
1420 }
BroadcastVisibility(bool isVisible,SerializationContext * serializationContext)1421 void Replica2::BroadcastVisibility(bool isVisible, SerializationContext *serializationContext)
1422 {
1423 	RakNet::BitStream bs;
1424 	SerializationContext defaultContext;
1425 	SerializationContext *usedContext;
1426 
1427 	if (serializationContext)
1428 	{
1429 		usedContext=serializationContext;
1430 	}
1431 	else
1432 	{
1433 		if (isVisible)
1434 			defaultContext.serializationType=BROADCAST_VISIBILITY_TRUE_TO_SYSTEM;
1435 		else
1436 			defaultContext.serializationType=BROADCAST_VISIBILITY_FALSE_TO_SYSTEM;
1437 		defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1438 		defaultContext.timestamp=0;
1439 		usedContext=&defaultContext;
1440 	}
1441 
1442 	if ((QueryVisibility(0)==BQR_ALWAYS && isVisible==false) ||
1443 		(QueryVisibility(0)==BQR_NEVER && isVisible==true))
1444 	{
1445 		// This doesn't make sense
1446 		RakAssert(0);
1447 		return;
1448 	}
1449 
1450 	bool newReference;
1451 	rm2->Reference(this, &newReference);
1452 
1453 	// If this is a new object, then before sending visibility we should send construction to all systems
1454 	if (newReference && QueryConstruction(0)==BQR_ALWAYS)
1455 	{
1456 		BroadcastConstruction();
1457 	}
1458 
1459 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1460 	for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
1461 	{
1462 		usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
1463 		if (usedContext->relaySourceAddress==usedContext->recipientAddress)
1464 			continue;
1465 		bs.Reset();
1466 		if (SerializeVisibility(&bs, usedContext)==false)
1467 			continue;
1468 		exclusionList.Clear(false, __FILE__, __LINE__);
1469 		for (unsigned j=0; j < rm2->connectionList.Size(); j++)
1470 		{
1471 			if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
1472 				exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
1473 		}
1474 		rm2->SendVisibility(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
1475 	}
1476 
1477 	if (newReference && QueryVisibility(0)==BQR_ALWAYS)
1478 	{
1479 		BroadcastSerialize();
1480 	}
1481 }
1482 
ReceiveDestruction(SystemAddress sender,RakNet::BitStream * serializedObject,SerializationType serializationType,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)1483 void Replica2::ReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
1484 {
1485 	DeserializeDestruction(serializedObject, serializationType, sender, timestamp);
1486 
1487 	SerializationContext serializationContext;
1488 	serializationContext.serializationType=RELAY_DESTRUCTION_TO_SYSTEMS;
1489 	serializationContext.relaySourceAddress=sender;
1490 	serializationContext.timestamp=0;
1491 
1492 	RakNet::BitStream bs;
1493 	unsigned exclusionListIndex=0;
1494 	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
1495 	{
1496 		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
1497 
1498 		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
1499 			exclusionListIndex++;
1500 		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
1501 		{
1502 			exclusionListIndex++;
1503 			continue;
1504 		}
1505 
1506 		bs.Reset();
1507 		if (SerializeDestruction(&bs, &serializationContext)==false)
1508 			continue;
1509 		rm2->SendDestruction(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList,serializationContext.serializationType);
1510 	}
1511 
1512 	DeleteOnReceiveDestruction(sender, serializedObject, serializationType, timestamp, exclusionList);
1513 }
DeleteOnReceiveDestruction(SystemAddress sender,RakNet::BitStream * serializedObject,SerializationType serializationType,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)1514 void Replica2::DeleteOnReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
1515 {
1516 	(void) sender;
1517 	(void) serializedObject;
1518 	(void) serializationType;
1519 	(void) timestamp;
1520 	(void) exclusionList;
1521 	//RakNet::OP_DELETE(this, __FILE__, __LINE__);
1522 	delete this;
1523 }
ReceiveVisibility(SystemAddress sender,RakNet::BitStream * serializedObject,SerializationType serializationType,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)1524 void Replica2::ReceiveVisibility(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
1525 {
1526 	DeserializeVisibility(serializedObject, serializationType, sender, timestamp);
1527 
1528 	SerializationContext serializationContext;
1529 	if (serializationType==SEND_VISIBILITY_TRUE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM)
1530 		serializationContext.serializationType=RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
1531 	else if (serializationType==SEND_VISIBILITY_FALSE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_FALSE_TO_SYSTEM)
1532 		serializationContext.serializationType=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
1533 	else
1534 		serializationContext.serializationType=serializationType;
1535 	serializationContext.timestamp=timestamp;
1536 	serializationContext.relaySourceAddress=sender;
1537 
1538 	RakNet::BitStream bs;
1539 	unsigned exclusionListIndex=0;
1540 	for (unsigned i=0; i < rm2->connectionList.Size(); i++)
1541 	{
1542 		serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
1543 
1544 		while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
1545 			exclusionListIndex++;
1546 		if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
1547 		{
1548 			exclusionListIndex++;
1549 			continue;
1550 		}
1551 
1552 		bs.Reset();
1553 		if (SerializeVisibility(&bs, &serializationContext)==false)
1554 			continue;
1555 		rm2->SendVisibility(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
1556 	}
1557 }
QueryConstruction(Connection_RM2 * connection)1558 BooleanQueryResult Replica2::QueryConstruction(Connection_RM2 *connection)
1559 {
1560 	(void) connection;
1561 
1562 	return BQR_ALWAYS;
1563 }
QueryVisibility(Connection_RM2 * connection)1564 BooleanQueryResult Replica2::QueryVisibility(Connection_RM2 *connection)
1565 {
1566 	(void) connection;
1567 
1568 	return BQR_ALWAYS;
1569 }
QueryIsConstructionAuthority(void) const1570 bool Replica2::QueryIsConstructionAuthority(void) const
1571 {
1572 	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
1573 }
QueryIsDestructionAuthority(void) const1574 bool Replica2::QueryIsDestructionAuthority(void) const
1575 {
1576 	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
1577 }
QueryIsVisibilityAuthority(void) const1578 bool Replica2::QueryIsVisibilityAuthority(void) const
1579 {
1580 	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
1581 }
QueryIsSerializationAuthority(void) const1582 bool Replica2::QueryIsSerializationAuthority(void) const
1583 {
1584 	return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
1585 }
AllowRemoteConstruction(SystemAddress sender,RakNet::BitStream * replicaData,SerializationType type,RakNetTime timestamp)1586 bool Replica2::AllowRemoteConstruction(SystemAddress sender, RakNet::BitStream *replicaData, SerializationType type, RakNetTime timestamp)
1587 {
1588 	(void) sender;
1589 	(void) replicaData;
1590 	(void) type;
1591 	(void) timestamp;
1592 
1593 	return true;
1594 }
ForceElapseAllAutoserializeTimers(bool resynchOnly)1595 void Replica2::ForceElapseAllAutoserializeTimers(bool resynchOnly)
1596 {
1597 	ElapseAutoSerializeTimers(99999999, resynchOnly);
1598 }
OnConstructionComplete(RakNet::BitStream * replicaData,SystemAddress sender,SerializationType type,ReplicaManager2 * replicaManager,RakNetTime timestamp,NetworkID networkId,bool networkIDCollision)1599 void Replica2::OnConstructionComplete(RakNet::BitStream *replicaData, SystemAddress sender, SerializationType type, ReplicaManager2 *replicaManager, RakNetTime timestamp, NetworkID networkId, bool networkIDCollision)
1600 {
1601 	(void) replicaData;
1602 	(void) sender;
1603 	(void) type;
1604 	(void) replicaManager;
1605 	(void) timestamp;
1606 	(void) networkId;
1607 	(void) networkIDCollision;
1608 }
ElapseAutoSerializeTimers(RakNetTime timeElapsed,bool resynchOnly)1609 void Replica2::ElapseAutoSerializeTimers(RakNetTime timeElapsed, bool resynchOnly)
1610 {
1611 	AutoSerializeEvent* ase;
1612 	unsigned i;
1613 	for (i=0; i < autoSerializeTimers.Size(); i++)
1614 	{
1615 		ase = autoSerializeTimers[i];
1616 		if (ase->remainingCountdown>timeElapsed)
1617 		{
1618 			ase->remainingCountdown-=timeElapsed;
1619 		}
1620 		else
1621 		{
1622 			ase->remainingCountdown=ase->initialCountdown;
1623 
1624 			RakNet::BitStream *lastWrite, *newWrite;
1625 			if (ase->writeToResult1)
1626 			{
1627 				newWrite=&ase->lastAutoSerializeResult1;
1628 				lastWrite=&ase->lastAutoSerializeResult2;
1629 			}
1630 			else
1631 			{
1632 				newWrite=&ase->lastAutoSerializeResult2;
1633 				lastWrite=&ase->lastAutoSerializeResult1;
1634 			}
1635 			newWrite->Reset();
1636 			OnAutoSerializeTimerElapsed(ase->serializationType,newWrite,lastWrite,ase->remainingCountdown, resynchOnly);
1637 			ase->writeToResult1=!ase->writeToResult1;
1638 
1639 		}
1640 	}
1641 }
OnAutoSerializeTimerElapsed(SerializationType serializationType,RakNet::BitStream * output,RakNet::BitStream * lastOutput,RakNetTime lastAutoSerializeCountdown,bool resynchOnly)1642 void Replica2::OnAutoSerializeTimerElapsed(SerializationType serializationType, RakNet::BitStream *output, RakNet::BitStream *lastOutput, RakNetTime lastAutoSerializeCountdown, bool resynchOnly)
1643 {
1644 	(void) lastAutoSerializeCountdown;
1645 
1646 	SerializationContext context;
1647 	if (resynchOnly)
1648 		context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
1649 	else
1650 		context.serializationType=serializationType;
1651 	context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1652 	context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
1653 	context.timestamp=0;
1654 	if (Serialize(output, &context))
1655 	{
1656 		if (resynchOnly==false &&
1657 			output->GetNumberOfBitsUsed()>0 &&
1658 			(output->GetNumberOfBitsUsed()!=lastOutput->GetNumberOfBitsUsed() ||
1659 			memcmp(output->GetData(), lastOutput->GetData(), (size_t) output->GetNumberOfBytesUsed())!=0))
1660 		{
1661 			BroadcastAutoSerialize(&context, output);
1662 		}
1663 	}
1664 }
BroadcastAutoSerialize(SerializationContext * serializationContext,RakNet::BitStream * serializedObject)1665 void Replica2::BroadcastAutoSerialize(SerializationContext *serializationContext, RakNet::BitStream *serializedObject)
1666 {
1667 	DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
1668 	rm2->SendSerialize(this,serializedObject,UNASSIGNED_SYSTEM_ADDRESS, serializationContext->timestamp, exclusionList, BROADCAST_AUTO_SERIALIZE_TO_SYSTEM);
1669 }
AddAutoSerializeTimer(RakNetTime interval,SerializationType serializationType,RakNetTime countdown)1670 void Replica2::AddAutoSerializeTimer(RakNetTime interval, SerializationType serializationType, RakNetTime countdown )
1671 {
1672 	if (countdown==(RakNetTime)-1)
1673 		countdown=interval;
1674 	if (autoSerializeTimers.Has(serializationType))
1675 	{
1676 		AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
1677 		if (interval==0)
1678 		{
1679 			// Elapse this timer immediately, then go back to initialCountdown
1680 			ase->remainingCountdown=ase->initialCountdown;
1681 
1682 			RakNet::BitStream *lastWrite, *newWrite;
1683 			if (ase->writeToResult1)
1684 			{
1685 				newWrite=&ase->lastAutoSerializeResult1;
1686 				lastWrite=&ase->lastAutoSerializeResult2;
1687 			}
1688 			else
1689 			{
1690 				newWrite=&ase->lastAutoSerializeResult2;
1691 				lastWrite=&ase->lastAutoSerializeResult1;
1692 			}
1693 			newWrite->Reset();
1694 
1695 			OnAutoSerializeTimerElapsed(serializationType,newWrite,lastWrite,ase->initialCountdown, false);
1696 
1697 			ase->remainingCountdown=ase->initialCountdown;
1698 		}
1699 		else
1700 		{
1701 			ase->initialCountdown=interval;
1702 			ase->remainingCountdown=countdown;
1703 		}
1704 	}
1705 	else
1706 	{
1707 		AutoSerializeEvent *ase = RakNet::OP_NEW<AutoSerializeEvent>( __FILE__, __LINE__ );
1708 		ase->serializationType=serializationType;
1709 		ase->initialCountdown=interval;
1710 		ase->remainingCountdown=countdown;
1711 		ase->writeToResult1=true;
1712 
1713 		SerializationContext context;
1714 		context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
1715 		context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1716 		context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
1717 		context.timestamp=0;
1718 		Serialize(&ase->lastAutoSerializeResult2, &context);
1719 
1720 		autoSerializeTimers.Set(serializationType,ase);
1721 	}
1722 }
GetTimeToNextAutoSerialize(SerializationType serializationType)1723 RakNetTime Replica2::GetTimeToNextAutoSerialize(SerializationType serializationType)
1724 {
1725 	if (autoSerializeTimers.Has(serializationType))
1726 	{
1727 		AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
1728 		return ase->remainingCountdown;
1729 	}
1730 	return (RakNetTime)-1;
1731 }
CancelAutoSerializeTimer(SerializationType serializationType)1732 void Replica2::CancelAutoSerializeTimer(SerializationType serializationType)
1733 {
1734 	unsigned i=0;
1735 	while (i < autoSerializeTimers.Size())
1736 	{
1737 		if (autoSerializeTimers[i]->serializationType==serializationType)
1738 		{
1739 			RakNet::OP_DELETE(autoSerializeTimers[i], __FILE__, __LINE__);
1740 			autoSerializeTimers.RemoveAtIndex(i);
1741 		}
1742 		else
1743 			i++;
1744 	}
1745 }
ClearAutoSerializeTimers(void)1746 void Replica2::ClearAutoSerializeTimers(void)
1747 {
1748 	unsigned i;
1749 	for (i=0; i < autoSerializeTimers.Size(); i++)
1750 		RakNet::OP_DELETE(autoSerializeTimers[i], __FILE__, __LINE__);
1751 	autoSerializeTimers.Clear();
1752 }
Connection_RM2()1753 Connection_RM2::Connection_RM2()
1754 {
1755 	rakNetGuid=UNASSIGNED_RAKNET_GUID;
1756 	systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
1757 }
~Connection_RM2()1758 Connection_RM2::~Connection_RM2()
1759 {
1760 }
SetConstructionByList(DataStructures::OrderedList<Replica2 *,Replica2 *,ReplicaManager2::Replica2ObjectComp> & currentVisibility,ReplicaManager2 * replicaManager)1761 void Connection_RM2::SetConstructionByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &currentVisibility, ReplicaManager2 *replicaManager)
1762 {
1763 	(void) replicaManager;
1764 
1765 	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentConstructionList, exclusiveToLastConstructionList;
1766 	CalculateListExclusivity(currentVisibility, lastConstructionList, exclusiveToCurrentConstructionList, exclusiveToLastConstructionList);
1767 
1768 	unsigned i;
1769 	for (i=0; i < exclusiveToCurrentConstructionList.Size(); i++)
1770 	{
1771 		// Construct
1772 		if (exclusiveToCurrentConstructionList[i]->QueryIsConstructionAuthority())
1773 		{
1774 			exclusiveToCurrentConstructionList[i]->SendConstruction(systemAddress);
1775 		//	lastConstructionList.Insert(exclusiveToCurrentConstructionList[i],exclusiveToCurrentConstructionList[i],true);
1776 		}
1777 	}
1778 
1779 	for (i=0; i < exclusiveToLastConstructionList.Size(); i++)
1780 	{
1781 		// Destruction
1782 		if (exclusiveToLastConstructionList[i]->QueryIsDestructionAuthority())
1783 		{
1784 			exclusiveToLastConstructionList[i]->SendDestruction(systemAddress);
1785 			lastConstructionList.RemoveIfExists(exclusiveToLastConstructionList[i]);
1786 			lastSerializationList.RemoveIfExists(exclusiveToLastConstructionList[i]);
1787 		}
1788 	}
1789 }
SetVisibilityByList(DataStructures::OrderedList<Replica2 *,Replica2 *,ReplicaManager2::Replica2ObjectComp> & currentVisibility,ReplicaManager2 * replicaManager)1790 void Connection_RM2::SetVisibilityByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &currentVisibility, ReplicaManager2 *replicaManager)
1791 {
1792 	(void) replicaManager;
1793 
1794 	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentSerializationList, exclusiveToLastSerializationList;
1795 	CalculateListExclusivity(currentVisibility, lastSerializationList, exclusiveToCurrentSerializationList, exclusiveToLastSerializationList);
1796 
1797 	unsigned i;
1798 	for (i=0; i < exclusiveToCurrentSerializationList.Size(); i++)
1799 	{
1800 		// In scope
1801 		if (exclusiveToCurrentSerializationList[i]->QueryIsVisibilityAuthority())
1802 		{
1803 			exclusiveToCurrentSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_TRUE_TO_SYSTEM);
1804 			exclusiveToCurrentSerializationList[i]->SendSerialize(systemAddress);
1805 		//	lastSerializationList.Insert(exclusiveToCurrentSerializationList[i],exclusiveToCurrentSerializationList[i], true);
1806 		}
1807 	}
1808 
1809 	for (i=0; i < exclusiveToLastSerializationList.Size(); i++)
1810 	{
1811 		// Out of scope
1812 		if (exclusiveToLastSerializationList[i]->QueryIsVisibilityAuthority())
1813 		{
1814 			exclusiveToLastSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_FALSE_TO_SYSTEM);
1815 			lastSerializationList.RemoveIfExists(exclusiveToLastSerializationList[i]);
1816 		}
1817 	}
1818 }
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) const1819 void Connection_RM2::CalculateListExclusivity(
1820 							  const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listOne,
1821 							  const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listTwo,
1822 							  DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListOne,
1823 							  DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListTwo
1824 							  ) const
1825 {
1826 	int res;
1827 	unsigned listOneIndex=0, listTwoIndex=0;
1828 
1829 	while (listOneIndex<listOne.Size() && listTwoIndex < listTwo.Size())
1830 	{
1831 		res = ReplicaManager2::Replica2ObjectComp(listOne[listOneIndex],listTwo[listTwoIndex]);
1832 		if (res<0)
1833 		{
1834 			exclusiveToListOne.InsertAtEnd(listOne[listOneIndex], __FILE__,__LINE__);
1835 			listOneIndex++;
1836 		}
1837 		else if (res>0)
1838 		{
1839 			exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex], __FILE__,__LINE__);
1840 			listTwoIndex++;
1841 		}
1842 		else
1843 		{
1844 			listOneIndex++;
1845 			listTwoIndex++;
1846 		}
1847 	}
1848 
1849 	while (listOneIndex<listOne.Size())
1850 	{
1851 		exclusiveToListOne.InsertAtEnd(listOne[listOneIndex], __FILE__,__LINE__);
1852 		listOneIndex++;
1853 	}
1854 
1855 	while (listTwoIndex<listTwo.Size())
1856 	{
1857 		exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex], __FILE__,__LINE__);
1858 		listTwoIndex++;
1859 	}
1860 }
SetConstructionByReplicaQuery(ReplicaManager2 * replicaManager)1861 void Connection_RM2::SetConstructionByReplicaQuery(ReplicaManager2 *replicaManager)
1862 {
1863 	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> constructedObjects;
1864 
1865 	unsigned i;
1866 	BooleanQueryResult res;
1867 	for (i=0; i < replicaManager->variableConstructReplicaOrderedList.Size(); i++)
1868 	{
1869 		if (replicaManager->variableConstructReplicaOrderedList[i]->QueryIsConstructionAuthority())
1870 		{
1871 			res = replicaManager->variableConstructReplicaOrderedList[i]->QueryConstruction(this);
1872 			if (res==BQR_YES || res==BQR_ALWAYS) // TODO - optimize ALWAYS here
1873 				constructedObjects.InsertAtEnd(replicaManager->variableConstructReplicaOrderedList[i], __FILE__,__LINE__);
1874 		}
1875 	}
1876 
1877 	SetConstructionByList(constructedObjects, replicaManager);
1878 }
SetVisibilityByReplicaQuery(ReplicaManager2 * replicaManager)1879 void Connection_RM2::SetVisibilityByReplicaQuery(ReplicaManager2 *replicaManager)
1880 {
1881 	DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> currentVisibility;
1882 
1883 	unsigned i;
1884 	BooleanQueryResult res;
1885 	for (i=0; i < replicaManager->variableSerializeReplicaOrderedList.Size(); i++)
1886 	{
1887 		if (replicaManager->variableSerializeReplicaOrderedList[i]->QueryIsVisibilityAuthority())
1888 		{
1889 			res = replicaManager->variableSerializeReplicaOrderedList[i]->QueryVisibility(this);
1890 			if (res==BQR_YES || res==BQR_ALWAYS) // TODO - optimize ALWAYS here
1891 				currentVisibility.InsertAtEnd(replicaManager->variableSerializeReplicaOrderedList[i], __FILE__,__LINE__);
1892 		}
1893 	}
1894 
1895 	SetVisibilityByList(currentVisibility, replicaManager);
1896 }
SortInitialDownload(const DataStructures::List<Replica2 * > & orderedDownloadList,DataStructures::List<Replica2 * > & initialDownloadList)1897 void Connection_RM2::SortInitialDownload( const DataStructures::List<Replica2*> &orderedDownloadList, DataStructures::List<Replica2*> &initialDownloadList ) {
1898 		initialDownloadList = orderedDownloadList;
1899 }
SerializeDownloadStarted(RakNet::BitStream * objectData,ReplicaManager2 * replicaManager,SerializationContext * serializationContext)1900 void Connection_RM2::SerializeDownloadStarted(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
1901 	(void) objectData;
1902 	(void) replicaManager;
1903 	(void) serializationContext;
1904 }
SerializeDownloadComplete(RakNet::BitStream * objectData,ReplicaManager2 * replicaManager,SerializationContext * serializationContext)1905 void Connection_RM2::SerializeDownloadComplete(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
1906 	(void) objectData;
1907 	(void) replicaManager;
1908 	(void) serializationContext;
1909 }
DeserializeDownloadStarted(RakNet::BitStream * objectData,SystemAddress sender,ReplicaManager2 * replicaManager,RakNetTime timestamp,SerializationType serializationType)1910 void Connection_RM2::DeserializeDownloadStarted(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
1911 	(void) objectData;
1912 	(void) sender;
1913 	(void) replicaManager;
1914 	(void) timestamp;
1915 	(void) replicaManager;
1916 	(void) serializationType;
1917 }
DeserializeDownloadComplete(RakNet::BitStream * objectData,SystemAddress sender,ReplicaManager2 * replicaManager,RakNetTime timestamp,SerializationType serializationType)1918 void Connection_RM2::DeserializeDownloadComplete(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
1919 	(void) objectData;
1920 	(void) sender;
1921 	(void) replicaManager;
1922 	(void) timestamp;
1923 	(void) serializationType;
1924 }
ReceiveConstruct(RakNet::BitStream * replicaData,NetworkID networkId,SystemAddress sender,unsigned char localClientId,SerializationType type,ReplicaManager2 * replicaManager,RakNetTime timestamp,DataStructures::OrderedList<SystemAddress,SystemAddress> & exclusionList)1925 Replica2 * Connection_RM2::ReceiveConstruct(RakNet::BitStream *replicaData, NetworkID networkId, SystemAddress sender, unsigned char localClientId, SerializationType type,
1926 					ReplicaManager2 *replicaManager, RakNetTime timestamp,
1927 					DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
1928 {
1929 	Replica2 *obj=0;
1930 
1931 	bool newReference=false;
1932 	if (type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT || type==SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT)
1933 	{
1934 		obj = Replica2::clientPtrArray[localClientId];
1935 		if (obj)
1936 		{
1937 			// The prefix misaligns the data from the send, which is a problem if the user uses aligned data
1938 			replicaData->AlignReadToByteBoundary();
1939 			obj = obj->ReceiveConstructionReply(sender, replicaData, type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
1940 			obj->SetNetworkID(networkId);
1941 			replicaManager->Reference(obj, &newReference);
1942 			replicaManager->AddConstructionReference(this,obj);
1943 
1944 			// The object could not be serialized before because it didn't have a NetworkID. So serialize it now.
1945 			if (obj->QueryIsSerializationAuthority() && (obj->QueryVisibility(this)==BQR_ALWAYS || obj->QueryVisibility(this)==BQR_YES))
1946 			{
1947 				SerializationContext sc;
1948 				sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
1949 				sc.timestamp=timestamp;
1950 				sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
1951 				sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
1952 				obj->BroadcastSerialize(&sc);
1953 
1954 				replicaManager->AddVisibilityReference(this,obj);
1955 			}
1956 		}
1957 	}
1958 	else
1959 	{
1960 		// Create locally send back reply
1961 		bool collision = replicaManager->GetRakPeer()->GetNetworkIDManager()->GET_OBJECT_FROM_ID<NetworkIDObject*>( networkId )!=0;
1962 		replicaData->AlignReadToByteBoundary();
1963 		obj = Construct(replicaData, sender, type, replicaManager, timestamp, networkId, collision);
1964 		if (obj)
1965 		{
1966 			replicaManager->Reference(obj, &newReference);
1967 
1968 			if (obj->AllowRemoteConstruction(sender, replicaData, type, timestamp)==false)
1969 			{
1970 				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
1971 					obj->SendConstruction(sender, SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT);
1972 				//RakNet::OP_DELETE(obj, __FILE__, __LINE__);
1973 				delete obj;
1974 				obj=0;
1975 			}
1976 			else
1977 			{
1978 				if (networkId!=UNASSIGNED_NETWORK_ID)
1979 					obj->SetNetworkID(networkId);
1980 
1981 				RakNet::BitStream bs;
1982 				SerializationContext serializationContext;
1983 				serializationContext.relaySourceAddress=sender;
1984 				serializationContext.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
1985 
1986 				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
1987 					serializationContext.serializationType=BROADCAST_CONSTRUCTION_REQUEST_ACCEPTED_TO_SYSTEM;
1988 				else
1989 					serializationContext.serializationType=BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM;
1990 				exclusionList.Insert(sender,sender,false, __FILE__,__LINE__);
1991 
1992 				unsigned exclusionListIndex=0;
1993 				for (unsigned i=0; i < replicaManager->connectionList.Size(); i++)
1994 				{
1995 					serializationContext.recipientAddress=replicaManager->connectionList[i]->GetSystemAddress();
1996 
1997 					while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
1998 						exclusionListIndex++;
1999 					if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
2000 					{
2001 						exclusionListIndex++;
2002 						continue;
2003 					}
2004 
2005 					BooleanQueryResult queryConstruction = obj->QueryConstruction(0);
2006 					if ( (queryConstruction==BQR_ALWAYS || queryConstruction==BQR_NEVER) &&
2007 						replicaManager->autoUpdateConstruction )
2008 					{
2009 						// Relay autoUpdateConstruction is on, and the construction is not variable
2010 						bs.Reset();
2011 						if (obj->SerializeConstruction(&bs, &serializationContext)==false)
2012 							continue;
2013 						unsigned char localId;
2014 						if (obj->QueryIsConstructionAuthority()==false)
2015 							localId=Replica2::clientSharedID++;
2016 						else
2017 							localId=0;
2018 						replicaManager->SendConstruction(obj,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList, localId, serializationContext.serializationType);
2019 					}
2020 				}
2021 
2022 				if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
2023 				{
2024 					DataStructures::OrderedList<SystemAddress,SystemAddress> emptyList;
2025 					// // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
2026 					bs.AlignWriteToByteBoundary();
2027 					replicaManager->SendConstruction(obj, &bs, sender, timestamp, true,
2028 						emptyList, localClientId, SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
2029 				}
2030 
2031 				replicaData->AlignReadToByteBoundary();
2032 				obj->OnConstructionComplete(replicaData, sender, type, replicaManager, timestamp, networkId, collision);
2033 			}
2034 		}
2035 	}
2036 
2037 	if (obj && newReference && obj->QueryIsSerializationAuthority() && obj->QueryVisibility(this)==BQR_ALWAYS)
2038 	{
2039 		SerializationContext sc;
2040 		sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
2041 		sc.timestamp=timestamp;
2042 		sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
2043 		sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
2044 		obj->BroadcastSerialize(&sc);
2045 	}
2046 
2047 	return obj;
2048 }
SetSystemAddress(SystemAddress sa)2049 void Connection_RM2::SetSystemAddress(SystemAddress sa)
2050 {
2051 	systemAddress=sa;
2052 }
GetSystemAddress(void) const2053 SystemAddress Connection_RM2::GetSystemAddress(void) const
2054 {
2055 	return systemAddress;
2056 }
SetGuid(RakNetGUID guid)2057 void Connection_RM2::SetGuid(RakNetGUID guid)
2058 {
2059 	rakNetGuid=guid;
2060 }
GetGuid(void) const2061 RakNetGUID Connection_RM2::GetGuid(void) const
2062 {
2063 	return rakNetGuid;
2064 }
Deref(Replica2 * replica)2065 void Connection_RM2::Deref(Replica2* replica)
2066 {
2067 	lastConstructionList.RemoveIfExists(replica);
2068 	lastSerializationList.RemoveIfExists(replica);
2069 }
2070 
2071 #ifdef _MSC_VER
2072 #pragma warning( pop )
2073 #endif
2074 
2075 #endif // _RAKNET_SUPPORT_*
2076