SLikeNet  0.1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ReplicaManager3.cpp
Go to the documentation of this file.
1 /*
2  * Original work: Copyright (c) 2014, Oculus VR, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7  * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8  *
9  *
10  * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
11  *
12  * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13  * license found in the license.txt file in the root directory of this source tree.
14  */
15 
17 #if _RAKNET_SUPPORT_ReplicaManager3==1
18 
20 #include "slikenet/GetTime.h"
22 #include "slikenet/peerinterface.h"
24 
25 using namespace SLNet;
26 
27 // DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS(LastSerializationResult,Replica3*,replica);
28 
29 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
30 
31 bool PRO::operator==( const PRO& right ) const
32 {
33  return priority == right.priority && reliability == right.reliability && orderingChannel == right.orderingChannel && sendReceipt == right.sendReceipt;
34 }
35 
36 bool PRO::operator!=( const PRO& right ) const
37 {
38  return priority != right.priority || reliability != right.reliability || orderingChannel != right.orderingChannel || sendReceipt != right.sendReceipt;
39 }
40 
41 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
42 
43 int Connection_RM3::Replica3LSRComp( Replica3 * const &replica3, LastSerializationResult * const &data )
44 {
45  /*
46  if (replica3->GetNetworkID() < data->replica->GetNetworkID())
47  return -1;
48  if (replica3->GetNetworkID() > data->replica->GetNetworkID())
49  return 1;
50  */
51 
52  // 7/28/2013 - If GetNetworkID chagned during runtime, the list would be out of order and lookup would always fail or go out of bounds
53  // I remember before that I could not directly compare
54  if (replica3->referenceIndex < data->replica->referenceIndex)
55  return -1;
56  if (replica3->referenceIndex > data->replica->referenceIndex)
57  return 1;
58  return 0;
59 }
60 
61 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
62 
64 {
65  replica=0;
68 }
70 {
73 }
75 {
77  {
78  lastSerializationResultBS= SLNet::OP_NEW<LastSerializationResultBS>(_FILE_AND_LINE_);
79  }
80 }
81 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
82 
84 {
94 
95  for (unsigned int i=0; i < 255; i++)
96  worldsArray[i]=0;
97 
98  AddWorld(0);
99 }
100 
101 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
102 
104 {
106  {
107  for (unsigned int i=0; i < worldsList.Size(); i++)
108  {
109  RakAssert(worldsList[i]->connectionList.Size()==0);
110  }
111  }
112  Clear(true);
113 }
114 
115 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
116 
117 void ReplicaManager3::SetAutoManageConnections(bool autoCreate, bool autoDestroy)
118 {
119  autoCreateConnections=autoCreate;
120  autoDestroyConnections=autoDestroy;
121 }
122 
123 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
124 
126 {
127  return autoCreateConnections;
128 }
129 
130 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
131 
133 {
134  return autoDestroyConnections;
135 }
136 
137 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
138 
140  DataStructures::List<RakNetGUID> &participantListIn,
141  DataStructures::List<Connection_RM3*> &participantListOut,
142  WorldId worldId)
143 {
144  for (unsigned int index=0; index < participantListIn.Size(); index++)
145  {
146  if (GetConnectionByGUID(participantListIn[index], worldId)==NULL)
147  {
148  Connection_RM3 *connection = AllocConnection(rakPeerInterface->GetSystemAddressFromGuid(participantListIn[index]), participantListIn[index]);
149  if (connection)
150  {
151  PushConnection(connection);
152  participantListOut.Push(connection, _FILE_AND_LINE_);
153  }
154  }
155  }
156 }
157 
158 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
159 
161 {
162  if (newConnection==0)
163  return false;
164  if (GetConnectionByGUID(newConnection->GetRakNetGUID(), worldId))
165  return false;
166  // Was this intended?
167  RakAssert(newConnection->GetRakNetGUID()!=rakPeerInterface->GetMyGUID());
168 
169  RakAssert(worldsArray[worldId]!=0 && "World not in use");
170  RM3World *world = worldsArray[worldId];
171 
172  unsigned int index = world->connectionList.GetIndexOf(newConnection);
173  if (index==(unsigned int)-1)
174  {
175  world->connectionList.Push(newConnection,_FILE_AND_LINE_);
176 
177  // Send message to validate the connection
178  newConnection->SendValidation(rakPeerInterface, worldId);
179 
180  Connection_RM3::ConstructionMode constructionMode = newConnection->QueryConstructionMode();
182  {
183  unsigned int pushIdx;
184  for (pushIdx=0; pushIdx < world->userReplicaList.Size(); pushIdx++)
185  newConnection->OnLocalReference(world->userReplicaList[pushIdx], this);
186  }
187  }
188  return true;
189 }
190 
191 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
192 
194 {
196  replica3->DeallocReplica(connection);
198 }
199 
200 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
201 
202 SLNet::Connection_RM3 * ReplicaManager3::PopConnection(unsigned int index, WorldId worldId)
203 {
205  DataStructures::List<NetworkID> destructionList;
206  DataStructures::List<Replica3*> broadcastList;
207  SLNet::Connection_RM3 *connection;
208  unsigned int index2;
210 
211  RakAssert(worldsArray[worldId]!=0 && "World not in use");
212  RM3World *world = worldsArray[worldId];
213 
214  connection=world->connectionList[index];
215 
216  // Clear out downloadGroup
218 
219  RakNetGUID guid = connection->GetRakNetGUID();
220  // This might be wrong, I am relying on the variable creatingSystemGuid which is transmitted
221  // automatically from the first system to reference the object. However, if an object changes
222  // owners then it is not going to be returned here, and therefore QueryActionOnPopConnection()
223  // will not be called for the new owner.
224  GetReplicasCreatedByGuid(guid, replicaList);
225 
226  for (index2=0; index2 < replicaList.Size(); index2++)
227  {
228  action = replicaList[index2]->QueryActionOnPopConnection(connection);
229  replicaList[index2]->OnPoppedConnection(connection);
230  if (action==RM3AOPC_DELETE_REPLICA)
231  {
232  if (replicaList[index2]->GetNetworkIDManager())
233  destructionList.Push( replicaList[index2]->GetNetworkID(), _FILE_AND_LINE_ );
234  }
236  {
237  if (replicaList[index2]->GetNetworkIDManager())
238  destructionList.Push( replicaList[index2]->GetNetworkID(), _FILE_AND_LINE_ );
239 
240  broadcastList.Push( replicaList[index2], _FILE_AND_LINE_ );
241  }
242  else if (action==RM3AOPC_DO_NOTHING)
243  {
244  for (unsigned int index3 = 0; index3 < connection->queryToSerializeReplicaList.Size(); index3++)
245  {
246  LastSerializationResult *lsr = connection->queryToSerializeReplicaList[index3];
247  lsr->whenLastSerialized=0;
248  if (lsr->lastSerializationResultBS)
249  {
250  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
252  }
253  }
254  }
255  }
256 
257  BroadcastDestructionList(broadcastList, connection->GetSystemAddress());
258  for (index2=0; index2 < destructionList.Size(); index2++)
259  {
260  // Do lookup in case DeallocReplica destroyed one of of the later Replica3 instances in the list
261  Replica3* replicaToDestroy = world->networkIDManager->GET_OBJECT_FROM_ID<Replica3*>(destructionList[index2]);
262  if (replicaToDestroy)
263  {
264  replicaToDestroy->PreDestruction(connection);
265  replicaToDestroy->DeallocReplica(connection);
266  }
267  }
268 
269  world->connectionList.RemoveAtIndex(index);
270  return connection;
271 }
272 
273 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
274 
276 {
277  unsigned int index;
278 
279  RakAssert(worldsArray[worldId]!=0 && "World not in use");
280  RM3World *world = worldsArray[worldId];
281 
282  for (index=0; index < world->connectionList.Size(); index++)
283  {
284  if (world->connectionList[index]->GetRakNetGUID()==guid)
285  {
286  return PopConnection(index, worldId);
287  }
288  }
289  return 0;
290 }
291 
292 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
293 
294 void ReplicaManager3::Reference(SLNet::Replica3 *replica3, WorldId worldId)
295 {
296  RakAssert(worldsArray[worldId]!=0 && "World not in use");
297  RM3World *world = worldsArray[worldId];
298 
299  unsigned int index = ReferenceInternal(replica3, worldId);
300 
301  if (index!=(unsigned int)-1)
302  {
303  unsigned int pushIdx;
304  for (pushIdx=0; pushIdx < world->connectionList.Size(); pushIdx++)
305  {
306  Connection_RM3::ConstructionMode constructionMode = world->connectionList[pushIdx]->QueryConstructionMode();
308  {
309  world->connectionList[pushIdx]->OnLocalReference(replica3, this);
310  }
311  }
312  }
313 }
314 
315 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
316 
317 unsigned int ReplicaManager3::ReferenceInternal(SLNet::Replica3 *replica3, WorldId worldId)
318 {
319  RakAssert(worldsArray[worldId]!=0 && "World not in use");
320  RM3World *world = worldsArray[worldId];
321 
322  unsigned int index;
323  index = world->userReplicaList.GetIndexOf(replica3);
324  if (index==(unsigned int)-1)
325  {
326  RakAssert(world->networkIDManager);
327  replica3->SetNetworkIDManager(world->networkIDManager);
328  // If it crashes on rakPeerInterface==0 then you didn't call RakPeerInterface::AttachPlugin()
331  replica3->replicaManager=this;
332  if (replica3->referenceIndex==(uint32_t)-1)
333  {
335  }
336  world->userReplicaList.Push(replica3,_FILE_AND_LINE_);
337  return world->userReplicaList.Size()-1;
338  }
339  return (unsigned int) -1;
340 }
341 
342 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
343 
345 {
346  RakAssert(worldsArray[worldId]!=0 && "World not in use");
347  RM3World *world = worldsArray[worldId];
348 
349  unsigned int index, index2;
350  for (index=0; index < world->userReplicaList.Size(); index++)
351  {
352  if (world->userReplicaList[index]==replica3)
353  {
354  world->userReplicaList.RemoveAtIndex(index);
355  break;
356  }
357  }
358 
359  // Remove from all connections
360  for (index2=0; index2 < world->connectionList.Size(); index2++)
361  {
362  world->connectionList[index2]->OnDereference(replica3, this);
363  }
364 }
365 
366 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
367 
369 {
370  unsigned int index;
371  for (index=0; index < replicaListIn.Size(); index++)
372  Dereference(replicaListIn[index], worldId);
373 }
374 
375 
376 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
377 
379 {
380  //RakNetGUID myGuid = rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
382 }
383 
384 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
385 
387 {
388  RakAssert(worldsArray[worldId]!=0 && "World not in use");
389  RM3World *world = worldsArray[worldId];
390 
391  replicaListOut=world->userReplicaList;
392 }
393 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
394 
396 {
397  RakAssert(worldsArray[worldId]!=0 && "World not in use");
398  RM3World *world = worldsArray[worldId];
399 
400  replicaListOut.Clear(false,_FILE_AND_LINE_);
401  unsigned int index;
402  for (index=0; index < world->userReplicaList.Size(); index++)
403  {
404  if (world->userReplicaList[index]->creatingSystemGUID==guid)
405  replicaListOut.Push(world->userReplicaList[index],_FILE_AND_LINE_);
406  }
407 }
408 
409 
410 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
411 
412 unsigned ReplicaManager3::GetReplicaCount(WorldId worldId) const
413 {
414  RakAssert(worldsArray[worldId]!=0 && "World not in use");
415  RM3World *world = worldsArray[worldId];
416 
417  return world->userReplicaList.Size();
418 }
419 
420 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
421 
422 Replica3 *ReplicaManager3::GetReplicaAtIndex(unsigned index, WorldId worldId)
423 {
424  RakAssert(worldsArray[worldId]!=0 && "World not in use");
425  RM3World *world = worldsArray[worldId];
426 
427  return world->userReplicaList[index];
428 }
429 
430 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
431 
432 unsigned int ReplicaManager3::GetConnectionCount(WorldId worldId) const
433 {
434  RakAssert(worldsArray[worldId]!=0 && "World not in use");
435  RM3World *world = worldsArray[worldId];
436 
437  return world->connectionList.Size();
438 }
439 
440 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
441 
442 Connection_RM3* ReplicaManager3::GetConnectionAtIndex(unsigned index, WorldId worldId) const
443 {
444  RakAssert(worldsArray[worldId]!=0 && "World not in use");
445  RM3World *world = worldsArray[worldId];
446 
447  return world->connectionList[index];
448 }
449 
450 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
451 
453 {
454  RakAssert(worldsArray[worldId]!=0 && "World not in use");
455  RM3World *world = worldsArray[worldId];
456 
457  unsigned int index;
458  for (index=0; index < world->connectionList.Size(); index++)
459  {
460  if (world->connectionList[index]->GetSystemAddress()==sa)
461  {
462  return world->connectionList[index];
463  }
464  }
465  return 0;
466 }
467 
468 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
469 
471 {
472  RakAssert(worldsArray[worldId]!=0 && "World not in use");
473  RM3World *world = worldsArray[worldId];
474 
475  unsigned int index;
476  for (index=0; index < world->connectionList.Size(); index++)
477  {
478  if (world->connectionList[index]->GetRakNetGUID()==guid)
479  {
480  return world->connectionList[index];
481  }
482  }
483  return 0;
484 }
485 
486 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
487 
489 {
491 }
492 
493 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
494 
496 {
498 }
499 
500 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
501 
503 {
505 }
506 
507 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
508 
510 {
511  autoSerializeInterval=intervalMS;
512 }
513 
514 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
515 
516 void ReplicaManager3::GetConnectionsThatHaveReplicaConstructed(Replica3 *replica, DataStructures::List<Connection_RM3*> &connectionsThatHaveConstructedThisReplica, WorldId worldId)
517 {
518  RakAssert(worldsArray[worldId]!=0 && "World not in use");
519  RM3World *world = worldsArray[worldId];
520 
521  connectionsThatHaveConstructedThisReplica.Clear(false,_FILE_AND_LINE_);
522  unsigned int index;
523  for (index=0; index < world->connectionList.Size(); index++)
524  {
525  if (world->connectionList[index]->HasReplicaConstructed(replica))
526  connectionsThatHaveConstructedThisReplica.Push(world->connectionList[index],_FILE_AND_LINE_);
527  }
528 }
529 
530 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
531 
533 {
534  RakAssert(worldsArray[worldId]!=0 && "World not in use");
535  RM3World *world = worldsArray[worldId];
536 
537  unsigned int index;
538  for (index=0; index < world->connectionList.Size(); index++)
539  {
540  if (world->connectionList[index]->GetDownloadWasCompleted()==false)
541  return false;
542  }
543  return true;
544 }
545 
546 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
547 
548 void ReplicaManager3::Clear(bool deleteWorlds)
549 {
550  for (unsigned int i=0; i < worldsList.Size(); i++)
551  {
552  worldsList[i]->Clear(this);
553  if (deleteWorlds)
554  {
555  worldsArray[worldsList[i]->worldId]=0;
556  SLNet::OP_DELETE(worldsList[i], _FILE_AND_LINE_);
557  }
558  }
559  if (deleteWorlds)
561 }
562 
563 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
564 
566 {
568 }
569 
570 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
571 
573 {
574  if (replicaManager3->GetAutoDestroyConnections())
575  {
576  for (unsigned int i=0; i < connectionList.Size(); i++)
577  replicaManager3->DeallocConnection(connectionList[i]);
578  }
579  else
580  {
581  // Clear out downloadGroup even if not auto destroying the connection, since the packets need to go back to RakPeer
582  for (unsigned int i=0; i < connectionList.Size(); i++)
583  connectionList[i]->ClearDownloadGroup(replicaManager3->GetRakPeerInterface());
584  }
585 
586  for (unsigned int i=0; i < userReplicaList.Size(); i++)
587  {
588  userReplicaList[i]->replicaManager=0;
589  userReplicaList[i]->SetNetworkIDManager(0);
590  }
591  connectionList.Clear(true,_FILE_AND_LINE_);
592  userReplicaList.Clear(true,_FILE_AND_LINE_);
593 }
594 
595 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
596 
598 {
599  return defaultSendParameters;
600 }
601 
602 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
603 
605 {
606  RakAssert(worldsArray[worldId]==0 && "World already in use");
607 
608  RM3World *newWorld = SLNet::OP_NEW<RM3World>(_FILE_AND_LINE_);
609  newWorld->worldId=worldId;
610  worldsArray[worldId]=newWorld;
611  worldsList.Push(newWorld,_FILE_AND_LINE_);
612 }
613 
614 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
615 
617 {
618  RakAssert(worldsArray[worldId]!=0 && "World not in use");
619  for (unsigned int i=0; i < worldsList.Size(); i++)
620  {
621  if (worldsList[i]==worldsArray[worldId])
622  {
625  break;
626  }
627  }
628  worldsArray[worldId]=0;
629 
630 }
631 
632 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
633 
635 {
636  RakAssert(worldsArray[worldId]!=0 && "World not in use");
637  RM3World *world = worldsArray[worldId];
638 
639  return world->networkIDManager;
640 }
641 
642 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
643 
644 void ReplicaManager3::SetNetworkIDManager(NetworkIDManager *_networkIDManager, WorldId worldId)
645 {
646  RakAssert(worldsArray[worldId]!=0 && "World not in use");
647  RM3World *world = worldsArray[worldId];
648 
649  world->networkIDManager=_networkIDManager;
650 }
651 
652 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
653 
655 {
656  if (packet->length<2)
657  return RR_CONTINUE_PROCESSING;
658 
659  WorldId incomingWorldId;
660 
661  SLNet::Time timestamp=0;
662  unsigned char packetIdentifier, packetDataOffset;
663  if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
664  {
665  if ( packet->length > sizeof( unsigned char ) + sizeof(SLNet::Time ) )
666  {
667  packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof(SLNet::Time ) ];
668  // Required for proper endian swapping
669  SLNet::BitStream tsBs(packet->data+sizeof(MessageID),packet->length-1,false);
670  tsBs.Read(timestamp);
671  // Next line assumes worldId is only 1 byte
672  RakAssert(sizeof(WorldId)==1);
673  incomingWorldId=packet->data[sizeof( unsigned char )*2 + sizeof(SLNet::Time )];
674  packetDataOffset=sizeof( unsigned char )*3 + sizeof(SLNet::Time );
675  }
676  else
678  }
679  else
680  {
681  packetIdentifier = ( unsigned char ) packet->data[ 0 ];
682  // Next line assumes worldId is only 1 byte
683  RakAssert(sizeof(WorldId)==1);
684  incomingWorldId=packet->data[sizeof( unsigned char )];
685  packetDataOffset=sizeof( unsigned char )*2;
686  }
687 
688  if (worldsArray[incomingWorldId]==0)
689  return RR_CONTINUE_PROCESSING;
690 
691  switch (packetIdentifier)
692  {
694  return OnConstruction(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
696  return OnSerialize(packet, packet->data, packet->length, packet->guid, timestamp, packetDataOffset, incomingWorldId);
698  if (packet->wasGeneratedLocally==false)
699  {
700  return OnDownloadStarted(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
701  }
702  else
703  break;
705  if (packet->wasGeneratedLocally==false)
706  {
707  return OnDownloadComplete(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
708  }
709  else
710  break;
712  {
713  Connection_RM3 *connection = GetConnectionByGUID(packet->guid, incomingWorldId);
714  if (connection && connection->isValidated==false)
715  {
716  // This connection is now confirmed bidirectional
717  connection->isValidated=true;
718  // Reply back on validation
719  connection->SendValidation(rakPeerInterface,incomingWorldId);
720  }
721  }
722  }
723 
724  return RR_CONTINUE_PROCESSING;
725 }
726 
727 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
728 
729 void Connection_RM3::AutoConstructByQuery(ReplicaManager3 *replicaManager3, WorldId worldId)
730 {
731  ValidateLists(replicaManager3);
732 
733  ConstructionMode curConstructionMode = QueryConstructionMode();
734 
735  unsigned int index;
736  RM3ConstructionState constructionState;
738  index=0;
739 
740  constructedReplicasCulled.Clear(false,_FILE_AND_LINE_);
741  destroyedReplicasCulled.Clear(false,_FILE_AND_LINE_);
742 
743  if (curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
744  {
745  while (index < queryToConstructReplicaList.Size())
746  {
747  lsr=queryToConstructReplicaList[index];
748  constructionState=lsr->replica->QueryConstruction(this, replicaManager3);
749  if (constructionState==RM3CS_ALREADY_EXISTS_REMOTELY || constructionState==RM3CS_ALREADY_EXISTS_REMOTELY_DO_NOT_CONSTRUCT)
750  {
751  OnReplicaAlreadyExists(index, replicaManager3);
752  if (constructionState==RM3CS_ALREADY_EXISTS_REMOTELY)
753  constructedReplicasCulled.Push(lsr->replica,_FILE_AND_LINE_);
754 
755  /*
756  if (constructionState==RM3CS_ALREADY_EXISTS_REMOTELY)
757  {
758  // Serialize construction data to this connection
759  SLNet::BitStream bsOut;
760  bsOut.Write((MessageID)ID_REPLICA_MANAGER_3_SERIALIZE_CONSTRUCTION_EXISTING);
761  bsOut.Write(replicaManager3->GetWorldID());
762  NetworkID networkId;
763  networkId=lsr->replica->GetNetworkID();
764  bsOut.Write(networkId);
765  BitSize_t bitsWritten = bsOut.GetNumberOfBitsUsed();
766  lsr->replica->SerializeConstructionExisting(&bsOut, this);
767  if (bsOut.GetNumberOfBitsUsed()!=bitsWritten)
768  replicaManager3->SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,GetSystemAddress(), false);
769  }
770 
771  // Serialize first serialization to this connection.
772  // This is done here, as it isn't done in PushConstruction
773  SerializeParameters sp;
774  SLNet::BitStream emptyBs;
775  for (index=0; index < (unsigned int) RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; index++)
776  {
777  sp.lastSentBitstream[index]=&emptyBs;
778  sp.pro[index]=replicaManager3->GetDefaultSendParameters();
779  }
780  sp.bitsWrittenSoFar=0;
781  sp.destinationConnection=this;
782  sp.messageTimestamp=0;
783  sp.whenLastSerialized=0;
784 
785  SLNet::Replica3 *replica = lsr->replica;
786 
787  RM3SerializationResult res = replica->Serialize(&sp);
788  if (res!=RM3SR_NEVER_SERIALIZE_FOR_THIS_CONNECTION &&
789  res!=RM3SR_DO_NOT_SERIALIZE &&
790  res!=RM3SR_SERIALIZED_UNIQUELY)
791  {
792  bool allIndices[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
793  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
794  {
795  sp.bitsWrittenSoFar+=sp.outputBitstream[z].GetNumberOfBitsUsed();
796  allIndices[z]=true;
797  }
798  if (SendSerialize(replica, allIndices, sp.outputBitstream, sp.messageTimestamp, sp.pro, replicaManager3->GetRakPeerInterface(), replicaManager3->GetWorldID())==SSICR_SENT_DATA)
799  lsr->replica->whenLastSerialized=SLNet::GetTimeMS();
800  }
801  */
802  }
803  else if (constructionState==RM3CS_SEND_CONSTRUCTION)
804  {
805  OnConstructToThisConnection(index, replicaManager3);
806  RakAssert(lsr->replica);
807  constructedReplicasCulled.Push(lsr->replica,_FILE_AND_LINE_);
808  }
809  else if (constructionState==RM3CS_NEVER_CONSTRUCT)
810  {
811  OnNeverConstruct(index, replicaManager3);
812  }
813  else// if (constructionState==RM3CS_NO_ACTION)
814  {
815  // Do nothing
816  index++;
817  }
818  }
819 
820  if (curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
821  {
822  RM3DestructionState destructionState;
823  index=0;
824  while (index < queryToDestructReplicaList.Size())
825  {
826  lsr=queryToDestructReplicaList[index];
827  destructionState=lsr->replica->QueryDestruction(this, replicaManager3);
828  if (destructionState==RM3DS_SEND_DESTRUCTION)
829  {
830  OnSendDestructionFromQuery(index, replicaManager3);
831  destroyedReplicasCulled.Push(lsr->replica,_FILE_AND_LINE_);
832  }
833  else if (destructionState==RM3DS_DO_NOT_QUERY_DESTRUCTION)
834  {
835  OnDoNotQueryDestruction(index, replicaManager3);
836  }
837  else// if (destructionState==RM3CS_NO_ACTION)
838  {
839  // Do nothing
840  index++;
841  }
842  }
843  }
844  }
845  else if (curConstructionMode==QUERY_CONNECTION_FOR_REPLICA_LIST)
846  {
847  QueryReplicaList(constructedReplicasCulled,destroyedReplicasCulled);
848 
849  unsigned int idx1, idx2;
850 
851  // Create new
852  for (idx2=0; idx2 < constructedReplicasCulled.Size(); idx2++)
853  OnConstructToThisConnection(constructedReplicasCulled[idx2], replicaManager3);
854 
855  bool exists;
856  for (idx2=0; idx2 < destroyedReplicasCulled.Size(); idx2++)
857  {
858  exists=false;
859  bool objectExists;
860  idx1=constructedReplicaList.GetIndexFromKey(destroyedReplicasCulled[idx2], &objectExists);
861  if (objectExists)
862  {
863  constructedReplicaList.RemoveAtIndex(idx1);
864 
865  unsigned int j;
866  for (j=0; j < queryToSerializeReplicaList.Size(); j++)
867  {
868  if (queryToSerializeReplicaList[j]->replica==destroyedReplicasCulled[idx2] )
869  {
870  queryToSerializeReplicaList.RemoveAtIndex(j);
871  break;
872  }
873  }
874  }
875  }
876  }
877 
878  SendConstruction(constructedReplicasCulled,destroyedReplicasCulled,replicaManager3->defaultSendParameters,replicaManager3->rakPeerInterface,worldId,replicaManager3);
879 }
880 void ReplicaManager3::Update(void)
881 {
882  unsigned int index,index2,index3;
883 
884  WorldId worldId;
885  RM3World *world;
886  SLNet::Time time = SLNet::GetTime();
887 
888  for (index3=0; index3 < worldsList.Size(); index3++)
889  {
890  world = worldsList[index3];
891  worldId = world->worldId;
892 
893  for (index=0; index < world->connectionList.Size(); index++)
894  {
895  if (world->connectionList[index]->isValidated==false)
896  continue;
897  world->connectionList[index]->AutoConstructByQuery(this, worldId);
898  }
899  }
900 
902  {
903  for (index3=0; index3 < worldsList.Size(); index3++)
904  {
905  world = worldsList[index3];
906  worldId = world->worldId;
907 
908  for (index=0; index < world->userReplicaList.Size(); index++)
909  {
910  world->userReplicaList[index]->forceSendUntilNextUpdate=false;
911  world->userReplicaList[index]->OnUserReplicaPreSerializeTick();
912  }
913 
915  sp.curTime=time;
916  Connection_RM3 *connection;
919 
920  sp.messageTimestamp=0;
921  for (int i=0; i < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; i++)
923  index2=0;
924  for (index=0; index < world->connectionList.Size(); index++)
925  {
926  connection = world->connectionList[index];
927  sp.bitsWrittenSoFar=0;
928  index2=0;
929  sp.destinationConnection=connection;
930 
931  DataStructures::List<Replica3*> replicasToSerialize;
932  replicasToSerialize.Clear(true, _FILE_AND_LINE_);
933  if (connection->QuerySerializationList(replicasToSerialize))
934  {
935  // Update replica->lsr so we can lookup in the next block
936  // lsr is per connection / per replica
937  while (index2 < connection->queryToSerializeReplicaList.Size())
938  {
939  connection->queryToSerializeReplicaList[index2]->replica->lsr=connection->queryToSerializeReplicaList[index2];
940  index2++;
941  }
942 
943 
944  // User is manually specifying list of replicas to serialize
945  index2=0;
946  while (index2 < replicasToSerialize.Size())
947  {
948  lsr=replicasToSerialize[index2]->lsr;
949  RakAssert(lsr->replica==replicasToSerialize[index2]);
950 
952  ssicr=connection->SendSerializeIfChanged(lsr, &sp, GetRakPeerInterface(), worldId, this, time);
953  if (ssicr==SSICR_SENT_DATA)
954  lsr->whenLastSerialized=time;
955  index2++;
956  }
957  }
958  else
959  {
960  while (index2 < connection->queryToSerializeReplicaList.Size())
961  {
962  lsr=connection->queryToSerializeReplicaList[index2];
963 
964  sp.destinationConnection=connection;
966  ssicr=connection->SendSerializeIfChanged(lsr, &sp, GetRakPeerInterface(), worldId, this, time);
967  if (ssicr==SSICR_SENT_DATA)
968  {
969  lsr->whenLastSerialized=time;
970  index2++;
971  }
972  else if (ssicr==SSICR_NEVER_SERIALIZE)
973  {
974  // Removed from the middle of the list
975  }
976  else
977  index2++;
978  }
979  }
980  }
981  }
982 
984  }
985 }
986 
987 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
988 
989 void ReplicaManager3::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
990 {
991  (void) lostConnectionReason;
992  (void) systemAddress;
994  {
995  Connection_RM3 *connection = PopConnection(rakNetGUID);
996  if (connection)
997  DeallocConnection(connection);
998  }
999 }
1000 
1001 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1002 
1003 void ReplicaManager3::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
1004 {
1005  (void) isIncoming;
1007  {
1008  Connection_RM3 *connection = AllocConnection(systemAddress, rakNetGUID);
1009  if (connection)
1010  PushConnection(connection);
1011  }
1012 }
1013 
1014 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1015 
1017 {
1019  {
1020  RM3World *world;
1021  unsigned int index3;
1022  for (index3=0; index3 < worldsList.Size(); index3++)
1023  {
1024  world = worldsList[index3];
1025 
1026  while (world->connectionList.Size())
1027  {
1028  Connection_RM3 *connection = PopConnection(world->connectionList.Size()-1, world->worldId);
1029  if (connection)
1030  DeallocConnection(connection);
1031  }
1032  }
1033  }
1034 
1035 
1036  Clear(false);
1037 }
1038 
1039 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1040 
1041 void ReplicaManager3::OnDetach(void)
1042 {
1044 }
1045 
1046 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1047 
1048 PluginReceiveResult ReplicaManager3::OnConstruction(Packet *packet, unsigned char *packetData, int packetDataLength, RakNetGUID senderGuid, unsigned char packetDataOffset, WorldId worldId)
1049 {
1050  RM3World *world = worldsArray[worldId];
1051 
1052  Connection_RM3 *connection = GetConnectionByGUID(senderGuid, worldId);
1053  if (connection==0)
1054  {
1055  // Almost certainly a bug
1056  RakAssert("Got OnConstruction but no connection yet" && 0);
1057  return RR_CONTINUE_PROCESSING;
1058  }
1059  if (connection->groupConstructionAndSerialize)
1060  {
1061  connection->downloadGroup.Push(packet, __FILE__, __LINE__);
1062  return RR_STOP_PROCESSING;
1063  }
1064 
1065  SLNet::BitStream bsIn(packetData,packetDataLength,false);
1066  bsIn.IgnoreBytes(packetDataOffset);
1067  uint16_t constructionObjectListSize, destructionObjectListSize, index, index2;
1068  BitSize_t streamEnd, writeAllocationIDEnd;
1069  Replica3 *replica;
1070  NetworkID networkId;
1071  RakNetGUID creatingSystemGuid;
1072  bool actuallyCreateObject=false;
1073 
1074  DataStructures::List<bool> actuallyCreateObjectList;
1075  DataStructures::List<Replica3*> constructionTickStack;
1076 
1077  RakAssert(world->networkIDManager);
1078 
1079  bsIn.Read(constructionObjectListSize);
1080  for (index=0; index < constructionObjectListSize; index++)
1081  {
1082  bsIn.Read(streamEnd);
1083  bsIn.Read(networkId);
1084  Replica3* existingReplica = world->networkIDManager->GET_OBJECT_FROM_ID<Replica3*>(networkId);
1085  bsIn.Read(actuallyCreateObject);
1086  actuallyCreateObjectList.Push(actuallyCreateObject, _FILE_AND_LINE_);
1087  bsIn.AlignReadToByteBoundary();
1088 
1089  if (actuallyCreateObject)
1090  {
1091  bsIn.Read(creatingSystemGuid);
1092  bsIn.Read(writeAllocationIDEnd);
1093 
1094  //printf("OnConstruction: %i\n",networkId.guid.g); // Removeme
1095  if (existingReplica)
1096  {
1097  existingReplica->replicaManager=this;
1098 
1099  // Network ID already in use
1100  connection->OnDownloadExisting(existingReplica, this);
1101 
1102  constructionTickStack.Push(0, _FILE_AND_LINE_);
1103  bsIn.SetReadOffset(streamEnd);
1104  continue;
1105  }
1106 
1107  bsIn.AlignReadToByteBoundary();
1108  replica = connection->AllocReplica(&bsIn, this);
1109  if (replica==0)
1110  {
1111  constructionTickStack.Push(0, _FILE_AND_LINE_);
1112  bsIn.SetReadOffset(streamEnd);
1113  continue;
1114  }
1115 
1116  // Go past the bitStream written to with WriteAllocationID(). Necessary in case the user didn't read out the bitStream the same way it was written
1117  // bitOffset2 is already aligned
1118  bsIn.SetReadOffset(writeAllocationIDEnd);
1119 
1120  replica->SetNetworkIDManager(world->networkIDManager);
1121  replica->SetNetworkID(networkId);
1122 
1123  replica->replicaManager=this;
1124  replica->creatingSystemGUID=creatingSystemGuid;
1125 
1126  if (!replica->QueryRemoteConstruction(connection) ||
1127  !replica->DeserializeConstruction(&bsIn, connection))
1128  {
1129  DeallocReplicaNoBroadcastDestruction(connection, replica);
1130  bsIn.SetReadOffset(streamEnd);
1131  constructionTickStack.Push(0, _FILE_AND_LINE_);
1132  continue;
1133  }
1134 
1135  constructionTickStack.Push(replica, _FILE_AND_LINE_);
1136 
1137  // Register the replica
1138  ReferenceInternal(replica, worldId);
1139  }
1140  else
1141  {
1142  if (existingReplica)
1143  {
1144  existingReplica->DeserializeConstructionExisting(&bsIn, connection);
1145  constructionTickStack.Push(existingReplica, _FILE_AND_LINE_);
1146  }
1147  else
1148  {
1149  constructionTickStack.Push(0, _FILE_AND_LINE_);
1150  }
1151  }
1152 
1153 
1154  bsIn.SetReadOffset(streamEnd);
1155  bsIn.AlignReadToByteBoundary();
1156  }
1157 
1158  RakAssert(constructionTickStack.Size()==constructionObjectListSize);
1159  RakAssert(actuallyCreateObjectList.Size()==constructionObjectListSize);
1160 
1161  SLNet::BitStream empty;
1162  for (index=0; index < constructionObjectListSize; index++)
1163  {
1164  bool pdcWritten=false;
1165  bsIn.Read(pdcWritten);
1166  if (pdcWritten)
1167  {
1168  bsIn.AlignReadToByteBoundary();
1169  bsIn.Read(streamEnd);
1170  bsIn.Read(networkId);
1171  if (constructionTickStack[index]!=0)
1172  {
1173  bsIn.AlignReadToByteBoundary();
1174  if (actuallyCreateObjectList[index])
1175  constructionTickStack[index]->PostDeserializeConstruction(&bsIn, connection);
1176  else
1177  constructionTickStack[index]->PostDeserializeConstructionExisting(&bsIn, connection);
1178  }
1179  bsIn.SetReadOffset(streamEnd);
1180  }
1181  else
1182  {
1183  if (constructionTickStack[index]!=0)
1184  {
1185  if (actuallyCreateObjectList[index])
1186  constructionTickStack[index]->PostDeserializeConstruction(&empty, connection);
1187  else
1188  constructionTickStack[index]->PostDeserializeConstructionExisting(&empty, connection);
1189  }
1190  }
1191  }
1192  bsIn.AlignReadToByteBoundary();
1193 
1194  for (index=0; index < constructionObjectListSize; index++)
1195  {
1196  if (constructionTickStack[index]!=0)
1197  {
1198  if (actuallyCreateObjectList[index])
1199  {
1200  // Tell the connection(s) that this object exists since they just sent it to us
1201  connection->OnDownloadFromThisSystem(constructionTickStack[index], this);
1202 
1203  for (index2=0; index2 < world->connectionList.Size(); index2++)
1204  {
1205  if (world->connectionList[index2]!=connection)
1206  world->connectionList[index2]->OnDownloadFromOtherSystem(constructionTickStack[index], this);
1207  }
1208  }
1209  }
1210  }
1211 
1212  // Destructions
1213  bool b = bsIn.Read(destructionObjectListSize);
1214  (void) b;
1215  RakAssert(b);
1216  for (index=0; index < destructionObjectListSize; index++)
1217  {
1218  bsIn.Read(networkId);
1219  bsIn.Read(streamEnd);
1220  replica = world->networkIDManager->GET_OBJECT_FROM_ID<Replica3*>(networkId);
1221  if (replica==0)
1222  {
1223  // Unknown object
1224  bsIn.SetReadOffset(streamEnd);
1225  continue;
1226  }
1227  bsIn.Read(replica->deletingSystemGUID);
1228  if (replica->DeserializeDestruction(&bsIn,connection))
1229  {
1230  // Make sure it wasn't deleted in DeserializeDestruction
1231  if (world->networkIDManager->GET_OBJECT_FROM_ID<Replica3*>(networkId))
1232  {
1233  replica->PreDestruction(connection);
1234 
1235  // Forward deletion by remote system
1236  if (replica->QueryRelayDestruction(connection))
1237  BroadcastDestruction(replica,connection->GetSystemAddress());
1238  Dereference(replica);
1239  DeallocReplicaNoBroadcastDestruction(connection, replica);
1240  }
1241  }
1242  else
1243  {
1244  replica->PreDestruction(connection);
1245  connection->OnDereference(replica, this);
1246  }
1247 
1248  bsIn.AlignReadToByteBoundary();
1249  }
1250  return RR_CONTINUE_PROCESSING;
1251 }
1252 
1253 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1254 
1255 PluginReceiveResult ReplicaManager3::OnSerialize(Packet *packet, unsigned char *packetData, int packetDataLength, RakNetGUID senderGuid, SLNet::Time timestamp, unsigned char packetDataOffset, WorldId worldId)
1256 {
1257  Connection_RM3 *connection = GetConnectionByGUID(senderGuid, worldId);
1258  if (connection==0)
1259  return RR_CONTINUE_PROCESSING;
1260  if (connection->groupConstructionAndSerialize)
1261  {
1262  connection->downloadGroup.Push(packet, __FILE__, __LINE__);
1263  return RR_STOP_PROCESSING;
1264  }
1265 
1266  RM3World *world = worldsArray[worldId];
1267  RakAssert(world->networkIDManager);
1268  SLNet::BitStream bsIn(packetData,packetDataLength,false);
1269  bsIn.IgnoreBytes(packetDataOffset);
1270 
1271  struct DeserializeParameters ds;
1272  ds.timeStamp=timestamp;
1273  ds.sourceConnection=connection;
1274 
1275  Replica3 *replica;
1276  NetworkID networkId;
1277  BitSize_t bitsUsed;
1278  bsIn.Read(networkId);
1279  //printf("OnSerialize: %i\n",networkId.guid.g); // Removeme
1280  replica = world->networkIDManager->GET_OBJECT_FROM_ID<Replica3*>(networkId);
1281  if (replica)
1282  {
1283  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1284  {
1285  bsIn.Read(ds.bitstreamWrittenTo[z]);
1286  if (ds.bitstreamWrittenTo[z])
1287  {
1288  bsIn.ReadCompressed(bitsUsed);
1289  bsIn.AlignReadToByteBoundary();
1290  bsIn.Read(ds.serializationBitstream[z], bitsUsed);
1291  }
1292  }
1293  replica->Deserialize(&ds);
1294  }
1295  return RR_CONTINUE_PROCESSING;
1296 }
1297 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1298 
1299 PluginReceiveResult ReplicaManager3::OnDownloadStarted(Packet *packet, unsigned char *packetData, int packetDataLength, RakNetGUID senderGuid, unsigned char packetDataOffset, WorldId worldId)
1300 {
1301  Connection_RM3 *connection = GetConnectionByGUID(senderGuid, worldId);
1302  if (connection==0)
1303  return RR_CONTINUE_PROCESSING;
1304  if (connection->QueryGroupDownloadMessages() &&
1305  // ID_DOWNLOAD_STARTED will be processed twice, being processed the second time once ID_DOWNLOAD_COMPLETE arrives.
1306  // However, the second time groupConstructionAndSerialize will be set to true so it won't be processed a third time
1307  connection->groupConstructionAndSerialize==false
1308  )
1309  {
1310  // These messages will be held by the plugin and returned when the download is complete
1311  connection->groupConstructionAndSerialize=true;
1312  RakAssert(connection->downloadGroup.Size()==0);
1313  connection->downloadGroup.Push(packet, __FILE__, __LINE__);
1314  return RR_STOP_PROCESSING;
1315  }
1316 
1317  connection->groupConstructionAndSerialize=false;
1318  SLNet::BitStream bsIn(packetData,packetDataLength,false);
1319  bsIn.IgnoreBytes(packetDataOffset);
1320  connection->DeserializeOnDownloadStarted(&bsIn);
1321  return RR_CONTINUE_PROCESSING;
1322 }
1323 
1324 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1325 
1326 PluginReceiveResult ReplicaManager3::OnDownloadComplete(Packet *packet, unsigned char *packetData, int packetDataLength, RakNetGUID senderGuid, unsigned char packetDataOffset, WorldId worldId)
1327 {
1328  Connection_RM3 *connection = GetConnectionByGUID(senderGuid, worldId);
1329  if (connection==0)
1330  return RR_CONTINUE_PROCESSING;
1331 
1332  if (connection->groupConstructionAndSerialize==true && connection->downloadGroup.Size()>0)
1333  {
1334  // Push back buffered packets in front of this one
1335  unsigned int i;
1336  for (i=0; i < connection->downloadGroup.Size(); i++)
1337  rakPeerInterface->PushBackPacket(connection->downloadGroup[i],false);
1338 
1339  // Push this one to be last too. It will be processed again, but the second time
1340  // groupConstructionAndSerialize will be false and downloadGroup will be empty, so it will go past this block
1341  connection->downloadGroup.Clear(__FILE__,__LINE__);
1342  rakPeerInterface->PushBackPacket(packet,false);
1343 
1344  return RR_STOP_PROCESSING;
1345  }
1346 
1347  SLNet::BitStream bsIn(packetData,packetDataLength,false);
1348  bsIn.IgnoreBytes(packetDataOffset);
1349  connection->gotDownloadComplete=true;
1350  connection->DeserializeOnDownloadComplete(&bsIn);
1351  return RR_CONTINUE_PROCESSING;
1352 }
1353 
1354 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1355 
1357 {
1358  RM3World *world = worldsArray[worldId];
1359 
1360  unsigned int i;
1361  for (i=0; i < world->userReplicaList.Size(); i++)
1362  {
1363  if (world->userReplicaList[i]->GetNetworkID()==networkId)
1364  return world->userReplicaList[i];
1365  }
1366  return 0;
1367 }
1368 
1369 
1370 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1371 
1372 
1373 void ReplicaManager3::BroadcastDestructionList(DataStructures::List<Replica3*> &replicaListSource, const SystemAddress &exclusionAddress, WorldId worldId)
1374 {
1375  SLNet::BitStream bsOut;
1376  unsigned int i,j;
1377 
1378  RakAssert(worldsArray[worldId]!=0 && "World not in use");
1379  RM3World *world = worldsArray[worldId];
1380 
1381  DataStructures::List<Replica3*> replicaList;
1382 
1383  for (i=0; i < replicaListSource.Size(); i++)
1384  {
1385  if (replicaListSource[i]==currentlyDeallocatingReplica)
1386  continue;
1387  replicaList.Push(replicaListSource[i], __FILE__, __LINE__);
1388  }
1389 
1390  if (replicaList.Size()==0)
1391  return;
1392 
1393  for (i=0; i < replicaList.Size(); i++)
1394  {
1395  if (replicaList[i]->deletingSystemGUID==UNASSIGNED_RAKNET_GUID)
1396  replicaList[i]->deletingSystemGUID=GetRakPeerInterface()->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
1397  }
1398 
1399  for (j=0; j < world->connectionList.Size(); j++)
1400  {
1401  if (world->connectionList[j]->GetSystemAddress()==exclusionAddress)
1402  continue;
1403 
1404  bsOut.Reset();
1406  bsOut.Write(worldId);
1407  uint16_t cnt=0;
1408  bsOut.Write(cnt); // No construction
1409  cnt=(uint16_t) replicaList.Size();
1410  BitSize_t cntOffset=bsOut.GetWriteOffset();;
1411  bsOut.Write(cnt); // Overwritten at send call
1412  cnt=0;
1413 
1414  for (i=0; i < replicaList.Size(); i++)
1415  {
1416  if (world->connectionList[j]->HasReplicaConstructed(replicaList[i])==false)
1417  continue;
1418  cnt++;
1419 
1420  NetworkID networkId;
1421  networkId=replicaList[i]->GetNetworkID();
1422  bsOut.Write(networkId);
1423  BitSize_t offsetStart, offsetEnd;
1424  offsetStart=bsOut.GetWriteOffset();
1425  bsOut.Write(offsetStart);
1426  bsOut.Write(replicaList[i]->deletingSystemGUID);
1427  replicaList[i]->SerializeDestruction(&bsOut, world->connectionList[j]);
1428  bsOut.AlignWriteToByteBoundary();
1429  offsetEnd=bsOut.GetWriteOffset();
1430  bsOut.SetWriteOffset(offsetStart);
1431  bsOut.Write(offsetEnd);
1432  bsOut.SetWriteOffset(offsetEnd);
1433  }
1434 
1435  if (cnt>0)
1436  {
1437  BitSize_t curOffset=bsOut.GetWriteOffset();
1438  bsOut.SetWriteOffset(cntOffset);
1439  bsOut.Write(cnt);
1440  bsOut.SetWriteOffset(curOffset);
1442  }
1443  }
1444 }
1445 
1446 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1447 
1448 
1449 void ReplicaManager3::BroadcastDestruction(Replica3 *replica, const SystemAddress &exclusionAddress)
1450 {
1451  DataStructures::List<Replica3*> replicaList;
1452  replicaList.Push(replica, _FILE_AND_LINE_ );
1453  BroadcastDestructionList(replicaList,exclusionAddress);
1454 }
1455 
1456 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1457 
1458 
1459 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1460 
1461 Connection_RM3::Connection_RM3(const SystemAddress &_systemAddress, RakNetGUID _guid)
1462 : systemAddress(_systemAddress), guid(_guid)
1463 {
1464  isValidated=false;
1465  isFirstConstruction=true;
1466  groupConstructionAndSerialize=false;
1467  gotDownloadComplete=false;
1468 }
1469 
1470 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1471 
1473 {
1474  unsigned int i;
1475  for (i=0; i < constructedReplicaList.Size(); i++)
1477  for (i=0; i < queryToConstructReplicaList.Size(); i++)
1479 }
1480 
1481 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1482 
1484 {
1485  objectsTheyDoHave.Clear(true,_FILE_AND_LINE_);
1486  for (unsigned int idx=0; idx < constructedReplicaList.Size(); idx++)
1487  {
1488  objectsTheyDoHave.Push(constructedReplicaList[idx]->replica, _FILE_AND_LINE_ );
1489  }
1490 }
1491 
1492 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1493 
1495 {
1496  bool objectExists;
1497  constructedReplicaList.GetIndexFromKey(replica, &objectExists);
1498  return objectExists;
1499 }
1500 
1501 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1503 {
1504  bs->Reset();
1505 
1506  if (timestamp!=0)
1507  {
1509  bs->Write(timestamp);
1510  }
1512  bs->Write(worldId);
1513  bs->Write(replica->GetNetworkID());
1514 }
1515 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1517 {
1518  unsigned int i;
1519  for (i=0; i < downloadGroup.Size(); i++)
1520  rakPeerInterface->DeallocatePacket(downloadGroup[i]);
1521  downloadGroup.Clear(__FILE__,__LINE__);
1522 }
1523 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1524 SendSerializeIfChangedResult Connection_RM3::SendSerialize(SLNet::Replica3 *replica, bool indicesToSend[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS], SLNet::BitStream serializationData[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS], SLNet::Time timestamp, PRO sendParameters[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS], RakPeerInterface *rakPeer, unsigned char worldId, SLNet::Time curTime)
1525 {
1526  bool channelHasData;
1527  BitSize_t sum=0;
1528  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1529  {
1530  if (indicesToSend[z])
1531  sum+=serializationData[z].GetNumberOfBitsUsed();
1532  }
1533 
1534  SLNet::BitStream out;
1536 
1537  if (sum==0)
1538  {
1539  memset(bitsPerChannel, 0, sizeof(bitsPerChannel));
1540  replica->OnSerializeTransmission(&out, this, bitsPerChannel, curTime);
1541  return SSICR_DID_NOT_SEND_DATA;
1542  }
1543 
1545 
1546  BitSize_t bitsUsed;
1547 
1548  int channelIndex;
1549  PRO lastPro=sendParameters[0];
1550 
1551  for (channelIndex=0; channelIndex < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; channelIndex++)
1552  {
1553  if (channelIndex==0)
1554  {
1555  SendSerializeHeader(replica, timestamp, &out, worldId);
1556  }
1557  else if (lastPro!=sendParameters[channelIndex])
1558  {
1559  // Write out remainder
1560  for (int channelIndex2=channelIndex; channelIndex2 < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; channelIndex2++)
1561  {
1562  bitsPerChannel[channelIndex2]=0;
1563  out.Write(false);
1564  }
1565 
1566  // Send remainder
1567  replica->OnSerializeTransmission(&out, this, bitsPerChannel, curTime);
1568  rakPeer->Send(&out,lastPro.priority,lastPro.reliability,lastPro.orderingChannel,systemAddress,false,lastPro.sendReceipt);
1569 
1570  // If no data left to send, quit out
1571  bool anyData=false;
1572  for (int channelIndex2=channelIndex; channelIndex2 < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; channelIndex2++)
1573  {
1574  if (serializationData[channelIndex2].GetNumberOfBitsUsed()>0)
1575  {
1576  anyData=true;
1577  break;
1578  }
1579  }
1580  if (anyData==false)
1581  return SSICR_SENT_DATA;
1582 
1583  // Restart stream
1584  SendSerializeHeader(replica, timestamp, &out, worldId);
1585 
1586  for (int channelIndex2=0; channelIndex2 < channelIndex; channelIndex2++)
1587  {
1588  bitsPerChannel[channelIndex2]=0;
1589  out.Write(false);
1590  }
1591  lastPro=sendParameters[channelIndex];
1592  }
1593 
1594  bitsUsed=serializationData[channelIndex].GetNumberOfBitsUsed();
1595  channelHasData = indicesToSend[channelIndex]==true && bitsUsed>0;
1596  out.Write(channelHasData);
1597  if (channelHasData)
1598  {
1599  bitsPerChannel[channelIndex] = bitsUsed;
1600  out.WriteCompressed(bitsUsed);
1602  out.Write(serializationData[channelIndex]);
1603  // Crap, forgot this line, was a huge bug in that I'd only send to the first 3 systems
1604  serializationData[channelIndex].ResetReadPointer();
1605  }
1606  else
1607  {
1608  bitsPerChannel[channelIndex] = 0;
1609  }
1610  }
1611  replica->OnSerializeTransmission(&out, this, bitsPerChannel, curTime);
1612  rakPeer->Send(&out,lastPro.priority,lastPro.reliability,lastPro.orderingChannel,systemAddress,false,lastPro.sendReceipt);
1613  return SSICR_SENT_DATA;
1614 }
1615 
1616 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1617 
1619 {
1620  SLNet::Replica3 *replica = lsr->replica;
1621 
1622  if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
1623  return SSICR_DID_NOT_SEND_DATA;
1624 
1625  RM3QuerySerializationResult rm3qsr = replica->QuerySerialization(this);
1626  if (rm3qsr==RM3QSR_NEVER_CALL_SERIALIZE)
1627  {
1628  // Never again for this connection and replica pair
1629  OnNeverSerialize(lsr, replicaManager);
1630  return SSICR_NEVER_SERIALIZE;
1631  }
1632 
1633  if (rm3qsr==RM3QSR_DO_NOT_CALL_SERIALIZE)
1634  return SSICR_DID_NOT_SEND_DATA;
1635 
1636  if (replica->forceSendUntilNextUpdate)
1637  {
1638  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1639  {
1640  if (replica->lastSentSerialization.indicesToSend[z])
1642  }
1643  return SendSerialize(replica, replica->lastSentSerialization.indicesToSend, replica->lastSentSerialization.bitStream, sp->messageTimestamp, sp->pro, rakPeer, worldId, curTime);
1644  }
1645 
1646  for (int i=0; i < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; i++)
1647  {
1648  sp->outputBitstream[i].Reset();
1649  if (lsr->lastSerializationResultBS)
1651  else
1653  }
1654 
1655  RM3SerializationResult serializationResult = replica->Serialize(sp);
1656 
1657  if (serializationResult==RM3SR_NEVER_SERIALIZE_FOR_THIS_CONNECTION)
1658  {
1659  // Never again for this connection and replica pair
1660  OnNeverSerialize(lsr, replicaManager);
1661  return SSICR_NEVER_SERIALIZE;
1662  }
1663 
1664  if (serializationResult==RM3SR_DO_NOT_SERIALIZE)
1665  {
1666  // Don't serialize this tick only
1667  return SSICR_DID_NOT_SEND_DATA;
1668  }
1669 
1670  // This is necessary in case the user in the Serialize() function for some reason read the bitstream they also wrote
1671  // WIthout this code, the Write calls to another bitstream would not write the entire bitstream
1672  BitSize_t sum=0;
1673  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1674  {
1676  sum+=sp->outputBitstream[z].GetNumberOfBitsUsed();
1677  }
1678 
1679  if (sum==0)
1680  {
1681  // Don't serialize this tick only
1682  return SSICR_DID_NOT_SEND_DATA;
1683  }
1684 
1685  if (serializationResult==RM3SR_SERIALIZED_ALWAYS)
1686  {
1687  bool allIndices[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
1688  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1689  {
1691  allIndices[z]=true;
1692 
1693  lsr->AllocBS();
1697  }
1698  return SendSerialize(replica, allIndices, sp->outputBitstream, sp->messageTimestamp, sp->pro, rakPeer, worldId, curTime);
1699  }
1700 
1701  if (serializationResult==RM3SR_SERIALIZED_ALWAYS_IDENTICALLY)
1702  {
1703  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1704  {
1707  replica->lastSentSerialization.bitStream[z].Reset();
1710  replica->forceSendUntilNextUpdate=true;
1711  }
1712  return SendSerialize(replica, replica->lastSentSerialization.indicesToSend, sp->outputBitstream, sp->messageTimestamp, sp->pro, rakPeer, worldId, curTime);
1713  }
1714 
1715  bool indicesToSend[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
1716  if (serializationResult==RM3SR_BROADCAST_IDENTICALLY || serializationResult==RM3SR_BROADCAST_IDENTICALLY_FORCE_SERIALIZATION)
1717  {
1718  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1719  {
1720  if (sp->outputBitstream[z].GetNumberOfBitsUsed() > 0 &&
1721  (serializationResult==RM3SR_BROADCAST_IDENTICALLY_FORCE_SERIALIZATION ||
1723  memcmp(sp->outputBitstream[z].GetData(), replica->lastSentSerialization.bitStream[z].GetData(), sp->outputBitstream[z].GetNumberOfBytesUsed())!=0))))
1724  {
1725  indicesToSend[z]=true;
1726  replica->lastSentSerialization.indicesToSend[z]=true;
1728  replica->lastSentSerialization.bitStream[z].Reset();
1731  replica->forceSendUntilNextUpdate=true;
1732  }
1733  else
1734  {
1735  indicesToSend[z]=false;
1736  replica->lastSentSerialization.indicesToSend[z]=false;
1737  }
1738  }
1739  }
1740  else
1741  {
1742  lsr->AllocBS();
1743 
1744  // RM3SR_SERIALIZED_UNIQUELY
1745  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
1746  {
1747  if (sp->outputBitstream[z].GetNumberOfBitsUsed() > 0 &&
1750  )
1751  {
1752  indicesToSend[z]=true;
1757  }
1758  else
1759  {
1760  indicesToSend[z]=false;
1761  }
1762  }
1763  }
1764 
1765 
1766  if (serializationResult==RM3SR_BROADCAST_IDENTICALLY || serializationResult==RM3SR_BROADCAST_IDENTICALLY_FORCE_SERIALIZATION)
1767  replica->forceSendUntilNextUpdate=true;
1768 
1769  // Send out the data
1770  return SendSerialize(replica, indicesToSend, sp->outputBitstream, sp->messageTimestamp, sp->pro, rakPeer, worldId, curTime);
1771 }
1772 
1773 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1774 void Connection_RM3::OnLocalReference(Replica3* replica3, ReplicaManager3 *replicaManager)
1775 {
1776  ConstructionMode curConstructionMode = QueryConstructionMode();
1777  RakAssert(curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION);
1778  RakAssert(replica3);
1779  (void) replicaManager;
1780  (void) curConstructionMode;
1781 
1782 #ifdef _DEBUG
1783  for (unsigned int i=0; i < queryToConstructReplicaList.Size(); i++)
1784  {
1785  if (queryToConstructReplicaList[i]->replica==replica3)
1786  {
1787  RakAssert("replica added twice to queryToConstructReplicaList" && 0);
1788  }
1789  }
1790 
1791  if (constructedReplicaList.HasData(replica3)==true)
1792  {
1793  RakAssert("replica added to queryToConstructReplicaList when already in constructedReplicaList" && 0);
1794  }
1795 #endif
1796 
1797  LastSerializationResult* lsr= SLNet::OP_NEW<LastSerializationResult>(_FILE_AND_LINE_);
1798  lsr->replica=replica3;
1800 }
1801 
1802 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1803 
1804 void Connection_RM3::OnDereference(Replica3* replica3, ReplicaManager3 *replicaManager)
1805 {
1806  ValidateLists(replicaManager);
1807 
1808  if (replica3->GetNetworkIDManager() == 0)
1809  return;
1810 
1811  LastSerializationResult* lsr=0;
1812  unsigned int idx;
1813 
1814  bool objectExists;
1815  idx=constructedReplicaList.GetIndexFromKey(replica3, &objectExists);
1816  if (objectExists)
1817  {
1818  lsr=constructedReplicaList[idx];
1820  }
1821 
1822  for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
1823  {
1824  if (queryToConstructReplicaList[idx]->replica==replica3)
1825  {
1826  lsr=queryToConstructReplicaList[idx];
1828  break;
1829  }
1830  }
1831 
1832  for (idx=0; idx < queryToSerializeReplicaList.Size(); idx++)
1833  {
1834  if (queryToSerializeReplicaList[idx]->replica==replica3)
1835  {
1836  lsr=queryToSerializeReplicaList[idx];
1838  break;
1839  }
1840  }
1841 
1842  for (idx=0; idx < queryToDestructReplicaList.Size(); idx++)
1843  {
1844  if (queryToDestructReplicaList[idx]->replica==replica3)
1845  {
1846  lsr=queryToDestructReplicaList[idx];
1848  break;
1849  }
1850  }
1851 
1852  ValidateLists(replicaManager);
1853 
1854  if (lsr)
1856 
1857  ValidateLists(replicaManager);
1858 }
1859 
1860 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1861 
1862 void Connection_RM3::OnDownloadFromThisSystem(Replica3* replica3, ReplicaManager3 *replicaManager)
1863 {
1864  RakAssert(replica3);
1865 
1866  ValidateLists(replicaManager);
1867  LastSerializationResult* lsr= SLNet::OP_NEW<LastSerializationResult>(_FILE_AND_LINE_);
1868  lsr->replica=replica3;
1869 
1870  ConstructionMode curConstructionMode = QueryConstructionMode();
1871  if (curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
1872  {
1873  unsigned int j;
1874  for (j=0; j < queryToConstructReplicaList.Size(); j++)
1875  {
1876  if (queryToConstructReplicaList[j]->replica==replica3 )
1877  {
1879  break;
1880  }
1881  }
1882 
1884  }
1885 
1886  if (constructedReplicaList.Insert(lsr->replica, lsr, true, _FILE_AND_LINE_) != (unsigned) -1)
1887  {
1888  //assert(queryToSerializeReplicaList.GetIndexOf(replica3)==(unsigned int)-1);
1890  }
1891 
1892  ValidateLists(replicaManager);
1893 }
1894 
1895 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1896 
1898 {
1899  ConstructionMode curConstructionMode = QueryConstructionMode();
1900  if (curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
1901  {
1902  unsigned int j;
1903  for (j=0; j < queryToConstructReplicaList.Size(); j++)
1904  {
1905  if (queryToConstructReplicaList[j]->replica==replica3 )
1906  {
1907  return;
1908  }
1909  }
1910 
1911  OnLocalReference(replica3, replicaManager);
1912  }
1913 }
1914 
1915 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1916 
1917 void Connection_RM3::OnNeverConstruct(unsigned int queryToConstructIdx, ReplicaManager3 *replicaManager)
1918 {
1919  ConstructionMode curConstructionMode = QueryConstructionMode();
1920  RakAssert(curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION);
1921  (void) curConstructionMode;
1922 
1923  ValidateLists(replicaManager);
1924  LastSerializationResult* lsr = queryToConstructReplicaList[queryToConstructIdx];
1925  queryToConstructReplicaList.RemoveAtIndex(queryToConstructIdx);
1927  ValidateLists(replicaManager);
1928 }
1929 
1930 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1931 
1932 void Connection_RM3::OnConstructToThisConnection(unsigned int queryToConstructIdx, ReplicaManager3 *replicaManager)
1933 {
1934  ConstructionMode curConstructionMode = QueryConstructionMode();
1935  RakAssert(curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION);
1936  (void) curConstructionMode;
1937 
1938  ValidateLists(replicaManager);
1939  LastSerializationResult* lsr = queryToConstructReplicaList[queryToConstructIdx];
1940  queryToConstructReplicaList.RemoveAtIndex(queryToConstructIdx);
1941  //assert(constructedReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1943  //assert(queryToDestructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1945  //assert(queryToSerializeReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1947  ValidateLists(replicaManager);
1948 }
1949 
1950 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1951 
1953 {
1954  RakAssert(replica);
1956  (void) replicaManager;
1957 
1958  LastSerializationResult* lsr= SLNet::OP_NEW<LastSerializationResult>(_FILE_AND_LINE_);
1959  lsr->replica=replica;
1960  constructedReplicaList.Insert(replica,lsr,true,_FILE_AND_LINE_);
1962 }
1963 
1964 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1965 
1967 {
1968  ValidateLists(replicaManager);
1969 
1970  unsigned int j;
1971  for (j=0; j < queryToSerializeReplicaList.Size(); j++)
1972  {
1973  if (queryToSerializeReplicaList[j]==lsr )
1974  {
1976  break;
1977  }
1978  }
1979 
1980  ValidateLists(replicaManager);
1981 }
1982 
1983 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1984 
1985 void Connection_RM3::OnReplicaAlreadyExists(unsigned int queryToConstructIdx, ReplicaManager3 *replicaManager)
1986 {
1987  ConstructionMode curConstructionMode = QueryConstructionMode();
1988  RakAssert(curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION);
1989  (void) curConstructionMode;
1990 
1991  ValidateLists(replicaManager);
1992  LastSerializationResult* lsr = queryToConstructReplicaList[queryToConstructIdx];
1993  queryToConstructReplicaList.RemoveAtIndex(queryToConstructIdx);
1994  //assert(constructedReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1996  //assert(queryToDestructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1998  //assert(queryToSerializeReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
2000  ValidateLists(replicaManager);
2001 }
2002 
2003 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2004 
2005 void Connection_RM3::OnDownloadExisting(Replica3* replica3, ReplicaManager3 *replicaManager)
2006 {
2007  ValidateLists(replicaManager);
2008 
2009  ConstructionMode curConstructionMode = QueryConstructionMode();
2010  if (curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
2011  {
2012  unsigned int idx;
2013  for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
2014  {
2015  if (queryToConstructReplicaList[idx]->replica==replica3)
2016  {
2017  OnConstructToThisConnection(idx, replicaManager);
2018  return;
2019  }
2020  }
2021  }
2022  else
2023  {
2024  OnConstructToThisConnection(replica3, replicaManager);
2025  }
2026 }
2027 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2028 
2029 void Connection_RM3::OnSendDestructionFromQuery(unsigned int queryToDestructIdx, ReplicaManager3 *replicaManager)
2030 {
2031  ConstructionMode curConstructionMode = QueryConstructionMode();
2032  RakAssert(curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION || curConstructionMode==QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION);
2033  (void) curConstructionMode;
2034 
2035  ValidateLists(replicaManager);
2036  LastSerializationResult* lsr = queryToDestructReplicaList[queryToDestructIdx];
2037  queryToDestructReplicaList.RemoveAtIndex(queryToDestructIdx);
2038  unsigned int j;
2039  for (j=0; j < queryToSerializeReplicaList.Size(); j++)
2040  {
2041  if (queryToSerializeReplicaList[j]->replica==lsr->replica )
2042  {
2044  break;
2045  }
2046  }
2047  for (j=0; j < constructedReplicaList.Size(); j++)
2048  {
2049  if (constructedReplicaList[j]->replica==lsr->replica )
2050  {
2052  break;
2053  }
2054  }
2055  //assert(queryToConstructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
2057  ValidateLists(replicaManager);
2058 }
2059 
2060 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2061 
2062 void Connection_RM3::OnDoNotQueryDestruction(unsigned int queryToDestructIdx, ReplicaManager3 *replicaManager)
2063 {
2064  ValidateLists(replicaManager);
2065  queryToDestructReplicaList.RemoveAtIndex(queryToDestructIdx);
2066  ValidateLists(replicaManager);
2067 }
2068 
2069 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2070 
2071 void Connection_RM3::ValidateLists(ReplicaManager3 *replicaManager) const
2072 {
2073  (void) replicaManager;
2074  /*
2075 #ifdef _DEBUG
2076  // Each object should exist only once in either constructedReplicaList or queryToConstructReplicaList
2077  // replicaPointer from LastSerializationResult should be same among all lists
2078  unsigned int idx, idx2;
2079  for (idx=0; idx < constructedReplicaList.Size(); idx++)
2080  {
2081  idx2=queryToConstructReplicaList.GetIndexOf(constructedReplicaList[idx]->replica);
2082  if (idx2!=(unsigned int)-1)
2083  {
2084  int a=5;
2085  assert(a==0);
2086  int *b=0;
2087  *b=5;
2088  }
2089  }
2090 
2091  for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
2092  {
2093  idx2=constructedReplicaList.GetIndexOf(queryToConstructReplicaList[idx]->replica);
2094  if (idx2!=(unsigned int)-1)
2095  {
2096  int a=5;
2097  assert(a==0);
2098  int *b=0;
2099  *b=5;
2100  }
2101  }
2102 
2103  LastSerializationResult *lsr, *lsr2;
2104  for (idx=0; idx < constructedReplicaList.Size(); idx++)
2105  {
2106  lsr=constructedReplicaList[idx];
2107 
2108  idx2=queryToSerializeReplicaList.GetIndexOf(lsr->replica);
2109  if (idx2!=(unsigned int)-1)
2110  {
2111  lsr2=queryToSerializeReplicaList[idx2];
2112  if (lsr2!=lsr)
2113  {
2114  int a=5;
2115  assert(a==0);
2116  int *b=0;
2117  *b=5;
2118  }
2119  }
2120 
2121  idx2=queryToDestructReplicaList.GetIndexOf(lsr->replica);
2122  if (idx2!=(unsigned int)-1)
2123  {
2124  lsr2=queryToDestructReplicaList[idx2];
2125  if (lsr2!=lsr)
2126  {
2127  int a=5;
2128  assert(a==0);
2129  int *b=0;
2130  *b=5;
2131  }
2132  }
2133  }
2134  for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
2135  {
2136  lsr=queryToConstructReplicaList[idx];
2137 
2138  idx2=queryToSerializeReplicaList.GetIndexOf(lsr->replica);
2139  if (idx2!=(unsigned int)-1)
2140  {
2141  lsr2=queryToSerializeReplicaList[idx2];
2142  if (lsr2!=lsr)
2143  {
2144  int a=5;
2145  assert(a==0);
2146  int *b=0;
2147  *b=5;
2148  }
2149  }
2150 
2151  idx2=queryToDestructReplicaList.GetIndexOf(lsr->replica);
2152  if (idx2!=(unsigned int)-1)
2153  {
2154  lsr2=queryToDestructReplicaList[idx2];
2155  if (lsr2!=lsr)
2156  {
2157  int a=5;
2158  assert(a==0);
2159  int *b=0;
2160  *b=5;
2161  }
2162  }
2163  }
2164 
2165  // Verify pointer integrity
2166  for (idx=0; idx < constructedReplicaList.Size(); idx++)
2167  {
2168  if (constructedReplicaList[idx]->replica->replicaManager!=replicaManager)
2169  {
2170  int a=5;
2171  assert(a==0);
2172  int *b=0;
2173  *b=5;
2174  }
2175  }
2176 
2177  // Verify pointer integrity
2178  for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
2179  {
2180  if (queryToConstructReplicaList[idx]->replica->replicaManager!=replicaManager)
2181  {
2182  int a=5;
2183  assert(a==0);
2184  int *b=0;
2185  *b=5;
2186  }
2187  }
2188 #endif
2189  */
2190 }
2191 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2192 
2193 void Connection_RM3::SendConstruction(DataStructures::List<Replica3*> &newObjects, DataStructures::List<Replica3*> &deletedObjects, PRO sendParameters, SLNet::RakPeerInterface *rakPeer, unsigned char worldId, ReplicaManager3 *replicaManager3)
2194 {
2195  if (newObjects.Size()==0 && deletedObjects.Size()==0)
2196  return;
2197 
2198  // All construction and destruction takes place in the same network message
2199  // Otherwise, if objects rely on each other being created the same tick to be valid, this won't always be true
2200  // DataStructures::List<LastSerializationResult* > serializedObjects;
2201  BitSize_t offsetStart, offsetStart2, offsetEnd;
2202  unsigned int newListIndex, oldListIndex;
2203  SLNet::BitStream bsOut;
2204  NetworkID networkId;
2205  if (isFirstConstruction)
2206  {
2208  bsOut.Write(worldId);
2210  rakPeer->Send(&bsOut,sendParameters.priority,RELIABLE_ORDERED,sendParameters.orderingChannel,systemAddress,false,sendParameters.sendReceipt);
2211  }
2212 
2213  // LastSerializationResult* lsr;
2214  bsOut.Reset();
2215  bsOut.Write((MessageID)ID_REPLICA_MANAGER_CONSTRUCTION);
2216  bsOut.Write(worldId);
2217  uint16_t objectSize = (uint16_t) newObjects.Size();
2218  bsOut.Write(objectSize);
2219 
2220  // Construction
2221  for (newListIndex=0; newListIndex < newObjects.Size(); newListIndex++)
2222  {
2223  offsetStart=bsOut.GetWriteOffset();
2224  bsOut.Write(offsetStart); // overwritten to point to the end of the stream
2225  networkId=newObjects[newListIndex]->GetNetworkID();
2226  bsOut.Write(networkId);
2227 
2228  RM3ConstructionState cs = newObjects[newListIndex]->QueryConstruction(this, replicaManager3);
2229  bool actuallyCreateObject = cs==RM3CS_SEND_CONSTRUCTION;
2230  bsOut.Write(actuallyCreateObject);
2231  bsOut.AlignWriteToByteBoundary();
2232 
2233  if (actuallyCreateObject)
2234  {
2235  // Actually create the object
2236  bsOut.Write(newObjects[newListIndex]->creatingSystemGUID);
2237  offsetStart2=bsOut.GetWriteOffset();
2238  bsOut.Write(offsetStart2); // overwritten to point to after the call to WriteAllocationID
2239  bsOut.AlignWriteToByteBoundary(); // Give the user an aligned bitStream in case they use memcpy
2240  newObjects[newListIndex]->WriteAllocationID(this, &bsOut);
2241  bsOut.AlignWriteToByteBoundary(); // Give the user an aligned bitStream in case they use memcpy
2242  offsetEnd=bsOut.GetWriteOffset();
2243  bsOut.SetWriteOffset(offsetStart2);
2244  bsOut.Write(offsetEnd);
2245  bsOut.SetWriteOffset(offsetEnd);
2246  newObjects[newListIndex]->SerializeConstruction(&bsOut, this);
2247  }
2248  else
2249  {
2250  newObjects[newListIndex]->SerializeConstructionExisting(&bsOut, this);
2251  }
2252 
2253  bsOut.AlignWriteToByteBoundary();
2254  offsetEnd=bsOut.GetWriteOffset();
2255  bsOut.SetWriteOffset(offsetStart);
2256  bsOut.Write(offsetEnd);
2257  bsOut.SetWriteOffset(offsetEnd);
2258  }
2259 
2260  SLNet::BitStream bsOut2;
2261  for (newListIndex=0; newListIndex < newObjects.Size(); newListIndex++)
2262  {
2263  bsOut2.Reset();
2264  RM3ConstructionState cs = newObjects[newListIndex]->QueryConstruction(this, replicaManager3);
2265  if (cs==RM3CS_SEND_CONSTRUCTION)
2266  {
2267  newObjects[newListIndex]->PostSerializeConstruction(&bsOut2, this);
2268  }
2269  else
2270  {
2272  newObjects[newListIndex]->PostSerializeConstructionExisting(&bsOut2, this);
2273  }
2274  if (bsOut2.GetNumberOfBitsUsed()>0)
2275  {
2276  bsOut.Write(true);
2277  bsOut.AlignWriteToByteBoundary();
2278  offsetStart=bsOut.GetWriteOffset();
2279  bsOut.Write(offsetStart); // overwritten to point to the end of the stream
2280  networkId=newObjects[newListIndex]->GetNetworkID();
2281  bsOut.Write(networkId);
2282  bsOut.AlignWriteToByteBoundary(); // Give the user an aligned bitStream in case they use memcpy
2283  bsOut.Write(&bsOut2);
2284  bsOut.AlignWriteToByteBoundary(); // Give the user an aligned bitStream in case they use memcpy
2285  offsetEnd=bsOut.GetWriteOffset();
2286  bsOut.SetWriteOffset(offsetStart);
2287  bsOut.Write(offsetEnd);
2288  bsOut.SetWriteOffset(offsetEnd);
2289  }
2290  else
2291  bsOut.Write(false);
2292  }
2293  bsOut.AlignWriteToByteBoundary();
2294 
2295  // Destruction
2296  objectSize = (uint16_t) deletedObjects.Size();
2297  bsOut.Write(objectSize);
2298  for (oldListIndex=0; oldListIndex < deletedObjects.Size(); oldListIndex++)
2299  {
2300  networkId=deletedObjects[oldListIndex]->GetNetworkID();
2301  bsOut.Write(networkId);
2302  offsetStart=bsOut.GetWriteOffset();
2303  bsOut.Write(offsetStart);
2304  deletedObjects[oldListIndex]->deletingSystemGUID=rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
2305  bsOut.Write(deletedObjects[oldListIndex]->deletingSystemGUID);
2306  deletedObjects[oldListIndex]->SerializeDestruction(&bsOut, this);
2307  bsOut.AlignWriteToByteBoundary();
2308  offsetEnd=bsOut.GetWriteOffset();
2309  bsOut.SetWriteOffset(offsetStart);
2310  bsOut.Write(offsetEnd);
2311  bsOut.SetWriteOffset(offsetEnd);
2312  }
2313  rakPeer->Send(&bsOut,sendParameters.priority,RELIABLE_ORDERED,sendParameters.orderingChannel,systemAddress,false,sendParameters.sendReceipt);
2314 
2315  // TODO - shouldn't this be part of construction?
2316 
2317  // Initial Download serialize to a new system
2318  // Immediately send serialize after construction if the replica object already has saved data
2319  // If the object was serialized identically, and does not change later on, then the new connection never gets the data
2321  sp.whenLastSerialized=0;
2322  SLNet::BitStream emptyBs;
2323  for (int index=0; index < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; index++)
2324  {
2325  sp.lastSentBitstream[index]=&emptyBs;
2326  sp.pro[index]=sendParameters;
2327  sp.pro[index].reliability=RELIABLE_ORDERED;
2328  }
2329 
2330  sp.bitsWrittenSoFar=0;
2331 // SLNet::Time t = SLNet::GetTimeMS();
2332  for (newListIndex=0; newListIndex < newObjects.Size(); newListIndex++)
2333  {
2334  sp.destinationConnection=this;
2335  sp.messageTimestamp=0;
2336  SLNet::Replica3 *replica = newObjects[newListIndex];
2337  // 8/22/09 Forgot ResetWritePointer
2338  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
2339  {
2341  }
2342 
2343  RM3SerializationResult res = replica->Serialize(&sp);
2345  res!=RM3SR_DO_NOT_SERIALIZE &&
2347  {
2348  bool allIndices[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
2349  for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
2350  {
2352  allIndices[z]=true;
2353  }
2354  SendSerialize(replica, allIndices, sp.outputBitstream, sp.messageTimestamp, sp.pro, rakPeer, worldId, GetTime());
2356 
2357  }
2358  // else wait for construction request accepted before serializing
2359  }
2360 
2361  if (isFirstConstruction)
2362  {
2363  bsOut.Reset();
2365  bsOut.Write(worldId);
2367  rakPeer->Send(&bsOut,sendParameters.priority,RELIABLE_ORDERED,sendParameters.orderingChannel,systemAddress,false,sendParameters.sendReceipt);
2368  }
2369 
2370  isFirstConstruction=false;
2371 
2372 }
2373 
2374 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2375 
2377 {
2378  // Hijack to mean sendValidation
2379  SLNet::BitStream bsOut;
2381  bsOut.Write(worldId);
2382  rakPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
2383 }
2384 
2385 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2386 
2388 {
2391  replicaManager=0;
2393  lsr=0;
2394  referenceIndex = (uint32_t)-1;
2395 }
2396 
2397 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2398 
2400 {
2401  if (replicaManager)
2402  {
2403  replicaManager->Dereference(this);
2404  }
2405 }
2406 
2407 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2408 
2410 {
2411  replicaManager->BroadcastDestruction(this,UNASSIGNED_SYSTEM_ADDRESS);
2412 }
2413 
2414 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2415 
2417 {
2418  return creatingSystemGUID;
2419 }
2420 
2421 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2422 
2424 {
2425  (void) destinationConnection;
2427  return RM3CS_SEND_CONSTRUCTION;
2428  // Send back to the owner client too, because they couldn't assign the network ID
2429  if (isThisTheServer)
2430  return RM3CS_SEND_CONSTRUCTION;
2431  return RM3CS_NEVER_CONSTRUCT;
2432 }
2433 
2434 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2435 
2436 bool Replica3::QueryRemoteConstruction_ClientConstruction(SLNet::Connection_RM3 *sourceConnection, bool isThisTheServer)
2437 {
2438  (void) sourceConnection;
2439  (void) isThisTheServer;
2440 
2441  // OK to create
2442  return true;
2443 }
2444 
2445 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2446 
2448 {
2449  (void) destinationConnection;
2450 
2451  if (isThisTheServer)
2452  return RM3CS_SEND_CONSTRUCTION;
2453  return RM3CS_NEVER_CONSTRUCT;
2454 }
2455 
2456 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2457 
2458 bool Replica3::QueryRemoteConstruction_ServerConstruction(SLNet::Connection_RM3 *sourceConnection, bool isThisTheServer)
2459 {
2460  (void) sourceConnection;
2461  if (isThisTheServer)
2462  return false;
2463  return true;
2464 }
2465 
2466 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2467 
2469 {
2470  (void) destinationConnection;
2471 
2472  if (p2pMode==R3P2PM_SINGLE_OWNER)
2473  {
2474  // We send to all, others do nothing
2476  return RM3CS_SEND_CONSTRUCTION;
2477 
2478  // RM3CS_NEVER_CONSTRUCT will not send the object, and will not Serialize() it
2479  return RM3CS_NEVER_CONSTRUCT;
2480  }
2482  {
2483  return RM3CS_SEND_CONSTRUCTION;
2484  }
2486  {
2488  }
2490  {
2492  }
2493  else
2494  {
2496 
2497  // RM3CS_ALREADY_EXISTS_REMOTELY will not send the object, but WILL call QuerySerialization() and Serialize() on it.
2499  }
2500 }
2501 
2502 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2503 
2505 {
2506  (void) sourceConnection;
2507 
2508  return true;
2509 }
2510 
2511 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2512 
2514 {
2515  // Owner client sends to all
2517  return RM3QSR_CALL_SERIALIZE;
2518  // Server sends to all but owner client
2519  if (isThisTheServer && destinationConnection->GetRakNetGUID()!=creatingSystemGUID)
2520  return RM3QSR_CALL_SERIALIZE;
2521  // Remote clients do not send
2523 }
2524 
2525 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2526 
2528 {
2529  (void) destinationConnection;
2530  // Server sends to all
2531  if (isThisTheServer)
2532  return RM3QSR_CALL_SERIALIZE;
2533 
2534  // Clients do not send
2536 }
2537 
2538 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2539 
2541 {
2542  (void) destinationConnection;
2543 
2544  if (p2pMode==R3P2PM_SINGLE_OWNER)
2545  {
2546  // Owner peer sends to all
2548  return RM3QSR_CALL_SERIALIZE;
2549 
2550  // Remote peers do not send
2552  }
2554  {
2555  return RM3QSR_CALL_SERIALIZE;
2556  }
2558  {
2559  return RM3QSR_CALL_SERIALIZE;
2560  }
2562  {
2564  }
2565  else
2566  {
2569  }
2570 }
2571 
2572 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2573 
2575 {
2576  (void) droppedConnection;
2577  return RM3AOPC_DELETE_REPLICA;
2578 }
2579 
2580 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2581 
2583 {
2584  (void) droppedConnection;
2586 }
2587 
2588 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2589 
2591 {
2592  (void) droppedConnection;
2593  return RM3AOPC_DELETE_REPLICA;
2594 }
2595 
2596 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2597 
2598 #endif // _RAKNET_SUPPORT_*