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> ¤tVisibility, 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> ¤tVisibility, 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