SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
16 #include "slikenet/NativeFeatureIncludes.h"
17 #if _RAKNET_SUPPORT_ReplicaManager3==1
18
19 #include "slikenet/ReplicaManager3.h"
20 #include "slikenet/GetTime.h"
21 #include "slikenet/MessageIdentifiers.h"
22 #include "slikenet/peerinterface.h"
23 #include "slikenet/NetworkIDManager.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
63 LastSerializationResult::LastSerializationResult()
64 {
65 replica=0;
66 lastSerializationResultBS=0;
67 whenLastSerialized = SLNet::GetTime();
68 }
69 LastSerializationResult::~LastSerializationResult()
70 {
71 if (lastSerializationResultBS)
72 SLNet::OP_DELETE(lastSerializationResultBS,_FILE_AND_LINE_);
73 }
74 void LastSerializationResult::AllocBS(void)
75 {
76 if (lastSerializationResultBS==0)
77 {
78 lastSerializationResultBS= SLNet::OP_NEW<LastSerializationResultBS>(_FILE_AND_LINE_);
79 }
80 }
81 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
82
83 ReplicaManager3::ReplicaManager3()
84 {
85 defaultSendParameters.orderingChannel=0;
86 defaultSendParameters.priority=HIGH_PRIORITY;
87 defaultSendParameters.reliability=RELIABLE_ORDERED;
88 defaultSendParameters.sendReceipt=0;
89 autoSerializeInterval=30;
90 lastAutoSerializeOccurance=0;
91 autoCreateConnections=true;
92 autoDestroyConnections=true;
93 currentlyDeallocatingReplica=0;
94
95 for (unsigned int i=0; i < 255; i++)
96 worldsArray[i]=0;
97
98 AddWorld(0);
99 }
100
101 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
102
103 ReplicaManager3::~ReplicaManager3()
104 {
105 if (autoDestroyConnections)
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
125 bool ReplicaManager3::GetAutoCreateConnections(void) const
126 {
127 return autoCreateConnections;
128 }
129
130 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
131
132 bool ReplicaManager3::GetAutoDestroyConnections(void) const
133 {
134 return autoDestroyConnections;
135 }
136
137 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
138
139 void ReplicaManager3::AutoCreateConnectionList(
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
160 bool ReplicaManager3::PushConnection(SLNet::Connection_RM3 *newConnection, WorldId worldId)
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();
181 if (constructionMode==Connection_RM3::QUERY_REPLICA_FOR_CONSTRUCTION || constructionMode==Connection_RM3::QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
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
193 void ReplicaManager3::DeallocReplicaNoBroadcastDestruction(SLNet::Connection_RM3 *connection, SLNet::Replica3 *replica3)
194 {
195 currentlyDeallocatingReplica=replica3;
196 replica3->DeallocReplica(connection);
197 currentlyDeallocatingReplica=0;
198 }
199
200 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
201
202 SLNet::Connection_RM3 * ReplicaManager3::PopConnection(unsigned int index, WorldId worldId)
203 {
204 DataStructures::List<Replica3*> replicaList;
205 DataStructures::List<NetworkID> destructionList;
206 DataStructures::List<Replica3*> broadcastList;
207 SLNet::Connection_RM3 *connection;
208 unsigned int index2;
209 RM3ActionOnPopConnection action;
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
217 connection->ClearDownloadGroup(rakPeerInterface);
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 }
235 else if (action==RM3AOPC_DELETE_REPLICA_AND_BROADCAST_DESTRUCTION)
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++)
251 lsr->lastSerializationResultBS->bitStream[z].Reset();
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
275 SLNet::Connection_RM3 * ReplicaManager3::PopConnection(RakNetGUID guid, WorldId worldId)
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();
307 if (constructionMode==Connection_RM3::QUERY_REPLICA_FOR_CONSTRUCTION || constructionMode==Connection_RM3::QUERY_REPLICA_FOR_CONSTRUCTION_AND_DESTRUCTION)
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()
329 if (replica3->creatingSystemGUID==UNASSIGNED_RAKNET_GUID)
330 replica3->creatingSystemGUID=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
331 replica3->replicaManager=this;
332 if (replica3->referenceIndex==(uint32_t)-1)
333 {
334 replica3->referenceIndex=nextReferenceIndex++;
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
344 void ReplicaManager3::Dereference(SLNet::Replica3 *replica3, WorldId worldId)
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
368 void ReplicaManager3::DereferenceList(DataStructures::List<Replica3*> &replicaListIn, WorldId worldId)
369 {
370 unsigned int index;
371 for (index=0; index < replicaListIn.Size(); index++)
372 Dereference(replicaListIn[index], worldId);
373 }
374
375
376 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
377
378 void ReplicaManager3::GetReplicasCreatedByMe(DataStructures::List<Replica3*> &replicaListOut, WorldId worldId)
379 {
380 //RakNetGUID myGuid = rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
381 GetReplicasCreatedByGuid(rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS), replicaListOut, worldId);
382 }
383
384 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
385
386 void ReplicaManager3::GetReferencedReplicaList(DataStructures::List<Replica3*> &replicaListOut, WorldId worldId)
387 {
388 RakAssert(worldsArray[worldId]!=0 && "World not in use");
389 RM3World *world = worldsArray[worldId];
390
391 replicaListOut=world->userReplicaList;
392 }
393 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
394
395 void ReplicaManager3::GetReplicasCreatedByGuid(RakNetGUID guid, DataStructures::List<Replica3*> &replicaListOut, WorldId worldId)
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
452 Connection_RM3* ReplicaManager3::GetConnectionBySystemAddress(const SystemAddress &sa, WorldId worldId) const
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
470 Connection_RM3* ReplicaManager3::GetConnectionByGUID(RakNetGUID guid, WorldId worldId) const
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
488 void ReplicaManager3::SetDefaultOrderingChannel(char def)
489 {
490 defaultSendParameters.orderingChannel=def;
491 }
492
493 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
494
495 void ReplicaManager3::SetDefaultPacketPriority(PacketPriority def)
496 {
497 defaultSendParameters.priority=def;
498 }
499
500 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
501
502 void ReplicaManager3::SetDefaultPacketReliability(PacketReliability def)
503 {
504 defaultSendParameters.reliability=def;
505 }
506
507 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
508
509 void ReplicaManager3::SetAutoSerializeInterval(SLNet::Time intervalMS)
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
532 bool ReplicaManager3::GetAllConnectionDownloadsCompleted(WorldId worldId) const
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)
560 worldsList.Clear(false, _FILE_AND_LINE_);
561 }
562
563 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
564
565 ReplicaManager3::RM3World::RM3World()
566 {
567 networkIDManager=0;
568 }
569
570 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
571
572 void ReplicaManager3::RM3World::Clear(ReplicaManager3 *replicaManager3)
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
597 PRO ReplicaManager3::GetDefaultSendParameters(void) const
598 {
599 return defaultSendParameters;
600 }
601
602 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
603
604 void ReplicaManager3::AddWorld(WorldId worldId)
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
616 void ReplicaManager3::RemoveWorld(WorldId worldId)
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 {
623 SLNet::OP_DELETE(worldsList[i],_FILE_AND_LINE_);
624 worldsList.RemoveAtIndexFast(i);
625 break;
626 }
627 }
628 worldsArray[worldId]=0;
629
630 }
631
632 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
633
634 NetworkIDManager *ReplicaManager3::GetNetworkIDManager(WorldId worldId) const
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
654 PluginReceiveResult ReplicaManager3::OnReceive(Packet *packet)
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
677 return RR_STOP_PROCESSING_AND_DEALLOCATE;
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 {
693 case ID_REPLICA_MANAGER_CONSTRUCTION:
694 return OnConstruction(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
695 case ID_REPLICA_MANAGER_SERIALIZE:
696 return OnSerialize(packet, packet->data, packet->length, packet->guid, timestamp, packetDataOffset, incomingWorldId);
697 case ID_REPLICA_MANAGER_DOWNLOAD_STARTED:
698 if (packet->wasGeneratedLocally==false)
699 {
700 return OnDownloadStarted(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
701 }
702 else
703 break;
704 case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
705 if (packet->wasGeneratedLocally==false)
706 {
707 return OnDownloadComplete(packet, packet->data, packet->length, packet->guid, packetDataOffset, incomingWorldId);
708 }
709 else
710 break;
711 case ID_REPLICA_MANAGER_SCOPE_CHANGE:
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;
737 LastSerializationResult *lsr;
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
901 if (time - lastAutoSerializeOccurance >= autoSerializeInterval)
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
914 SerializeParameters sp;
915 sp.curTime=time;
916 Connection_RM3 *connection;
917 SendSerializeIfChangedResult ssicr;
918 LastSerializationResult *lsr;
919
920 sp.messageTimestamp=0;
921 for (int i=0; i < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; i++)
922 sp.pro[i]=defaultSendParameters;
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
951 sp.whenLastSerialized=lsr->whenLastSerialized;
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;
965 sp.whenLastSerialized=lsr->whenLastSerialized;
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
983 lastAutoSerializeOccurance=time;
984 }
985 }
986
987 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
988
989 void ReplicaManager3::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
990 {
991 (void) lostConnectionReason;
992 (void) systemAddress;
993 if (autoDestroyConnections)
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;
1006 if (autoCreateConnections)
1007 {
1008 Connection_RM3 *connection = AllocConnection(systemAddress, rakNetGUID);
1009 if (connection)
1010 PushConnection(connection);
1011 }
1012 }
1013
1014 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1015
1016 void ReplicaManager3::OnRakPeerShutdown(void)
1017 {
1018 if (autoDestroyConnections)
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 {
1043 OnRakPeerShutdown();
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
1356 Replica3* ReplicaManager3::GetReplicaByNetworkID(NetworkID networkId, WorldId worldId)
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();
1405 bsOut.Write((MessageID)ID_REPLICA_MANAGER_CONSTRUCTION);
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);
1441 rakPeerInterface->Send(&bsOut,defaultSendParameters.priority,defaultSendParameters.reliability,defaultSendParameters.orderingChannel,world->connectionList[j]->GetSystemAddress(),false, defaultSendParameters.sendReceipt);
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
1472 Connection_RM3::~Connection_RM3()
1473 {
1474 unsigned int i;
1475 for (i=0; i < constructedReplicaList.Size(); i++)
1476 SLNet::OP_DELETE(constructedReplicaList[i], _FILE_AND_LINE_);
1477 for (i=0; i < queryToConstructReplicaList.Size(); i++)
1478 SLNet::OP_DELETE(queryToConstructReplicaList[i], _FILE_AND_LINE_);
1479 }
1480
1481 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1482
1483 void Connection_RM3::GetConstructedReplicas(DataStructures::List<Replica3*> &objectsTheyDoHave)
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
1494 bool Connection_RM3::HasReplicaConstructed(SLNet::Replica3 *replica)
1495 {
1496 bool objectExists;
1497 constructedReplicaList.GetIndexFromKey(replica, &objectExists);
1498 return objectExists;
1499 }
1500
1501 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1502 void Connection_RM3::SendSerializeHeader(SLNet::Replica3 *replica, SLNet::Time timestamp, SLNet::BitStream *bs, WorldId worldId)
1503 {
1504 bs->Reset();
1505
1506 if (timestamp!=0)
1507 {
1508 bs->Write((MessageID)ID_TIMESTAMP);
1509 bs->Write(timestamp);
1510 }
1511 bs->Write((MessageID)ID_REPLICA_MANAGER_SERIALIZE);
1512 bs->Write(worldId);
1513 bs->Write(replica->GetNetworkID());
1514 }
1515 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1516 void Connection_RM3::ClearDownloadGroup(RakPeerInterface *rakPeerInterface)
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;
1535 BitSize_t bitsPerChannel[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
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
1544 RakAssert(replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID);
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);
1601 out.AlignWriteToByteBoundary();
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
1618 SendSerializeIfChangedResult Connection_RM3::SendSerializeIfChanged(LastSerializationResult *lsr, SerializeParameters *sp, SLNet::RakPeerInterface *rakPeer, unsigned char worldId, ReplicaManager3 *replicaManager, SLNet::Time curTime)
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])
1641 sp->bitsWrittenSoFar+=replica->lastSentSerialization.bitStream[z].GetNumberOfBitsUsed();
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)
1650 sp->lastSentBitstream[i]=&lsr->lastSerializationResultBS->bitStream[i];
1651 else
1652 sp->lastSentBitstream[i]=&replica->lastSentSerialization.bitStream[i];
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 {
1675 sp->outputBitstream[z].ResetReadPointer();
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 {
1690 sp->bitsWrittenSoFar+=sp->outputBitstream[z].GetNumberOfBitsUsed();
1691 allIndices[z]=true;
1692
1693 lsr->AllocBS();
1694 lsr->lastSerializationResultBS->bitStream[z].Reset();
1695 lsr->lastSerializationResultBS->bitStream[z].Write(&sp->outputBitstream[z]);
1696 sp->outputBitstream[z].ResetReadPointer();
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 {
1705 replica->lastSentSerialization.indicesToSend[z]=sp->outputBitstream[z].GetNumberOfBitsUsed()>0;
1706 sp->bitsWrittenSoFar+=sp->outputBitstream[z].GetNumberOfBitsUsed();
1707 replica->lastSentSerialization.bitStream[z].Reset();
1708 replica->lastSentSerialization.bitStream[z].Write(&sp->outputBitstream[z]);
1709 sp->outputBitstream[z].ResetReadPointer();
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 ||
1722 ((sp->outputBitstream[z].GetNumberOfBitsUsed()!=replica->lastSentSerialization.bitStream[z].GetNumberOfBitsUsed() ||
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;
1727 sp->bitsWrittenSoFar+=sp->outputBitstream[z].GetNumberOfBitsUsed();
1728 replica->lastSentSerialization.bitStream[z].Reset();
1729 replica->lastSentSerialization.bitStream[z].Write(&sp->outputBitstream[z]);
1730 sp->outputBitstream[z].ResetReadPointer();
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 &&
1748 (sp->outputBitstream[z].GetNumberOfBitsUsed()!=lsr->lastSerializationResultBS->bitStream[z].GetNumberOfBitsUsed() ||
1749 memcmp(sp->outputBitstream[z].GetData(), lsr->lastSerializationResultBS->bitStream[z].GetData(), sp->outputBitstream[z].GetNumberOfBytesUsed())!=0)
1750 )
1751 {
1752 indicesToSend[z]=true;
1753 sp->bitsWrittenSoFar+=sp->outputBitstream[z].GetNumberOfBitsUsed();
1754 lsr->lastSerializationResultBS->bitStream[z].Reset();
1755 lsr->lastSerializationResultBS->bitStream[z].Write(&sp->outputBitstream[z]);
1756 sp->outputBitstream[z].ResetReadPointer();
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;
1799 queryToConstructReplicaList.Push(lsr,_FILE_AND_LINE_);
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];
1819 constructedReplicaList.RemoveAtIndex(idx);
1820 }
1821
1822 for (idx=0; idx < queryToConstructReplicaList.Size(); idx++)
1823 {
1824 if (queryToConstructReplicaList[idx]->replica==replica3)
1825 {
1826 lsr=queryToConstructReplicaList[idx];
1827 queryToConstructReplicaList.RemoveAtIndex(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];
1837 queryToSerializeReplicaList.RemoveAtIndex(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];
1847 queryToDestructReplicaList.RemoveAtIndex(idx);
1848 break;
1849 }
1850 }
1851
1852 ValidateLists(replicaManager);
1853
1854 if (lsr)
1855 SLNet::OP_DELETE(lsr,_FILE_AND_LINE_);
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 {
1878 queryToConstructReplicaList.RemoveAtIndex(j);
1879 break;
1880 }
1881 }
1882
1883 queryToDestructReplicaList.Push(lsr,_FILE_AND_LINE_);
1884 }
1885
1886 if (constructedReplicaList.Insert(lsr->replica, lsr, true, _FILE_AND_LINE_) != (unsigned) -1)
1887 {
1888 //assert(queryToSerializeReplicaList.GetIndexOf(replica3)==(unsigned int)-1);
1889 queryToSerializeReplicaList.Push(lsr,_FILE_AND_LINE_);
1890 }
1891
1892 ValidateLists(replicaManager);
1893 }
1894
1895 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1896
1897 void Connection_RM3::OnDownloadFromOtherSystem(Replica3* replica3, ReplicaManager3 *replicaManager)
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);
1926 SLNet::OP_DELETE(lsr,_FILE_AND_LINE_);
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);
1942 constructedReplicaList.Insert(lsr->replica,lsr,true,_FILE_AND_LINE_);
1943 //assert(queryToDestructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1944 queryToDestructReplicaList.Push(lsr,_FILE_AND_LINE_);
1945 //assert(queryToSerializeReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1946 queryToSerializeReplicaList.Push(lsr,_FILE_AND_LINE_);
1947 ValidateLists(replicaManager);
1948 }
1949
1950 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1951
1952 void Connection_RM3::OnConstructToThisConnection(Replica3 *replica, ReplicaManager3 *replicaManager)
1953 {
1954 RakAssert(replica);
1955 RakAssert(QueryConstructionMode()==QUERY_CONNECTION_FOR_REPLICA_LIST);
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_);
1961 queryToSerializeReplicaList.Push(lsr,_FILE_AND_LINE_);
1962 }
1963
1964 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1965
1966 void Connection_RM3::OnNeverSerialize(LastSerializationResult *lsr, ReplicaManager3 *replicaManager)
1967 {
1968 ValidateLists(replicaManager);
1969
1970 unsigned int j;
1971 for (j=0; j < queryToSerializeReplicaList.Size(); j++)
1972 {
1973 if (queryToSerializeReplicaList[j]==lsr )
1974 {
1975 queryToSerializeReplicaList.RemoveAtIndex(j);
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);
1995 constructedReplicaList.Insert(lsr->replica,lsr,true,_FILE_AND_LINE_);
1996 //assert(queryToDestructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1997 queryToDestructReplicaList.Push(lsr,_FILE_AND_LINE_);
1998 //assert(queryToSerializeReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
1999 queryToSerializeReplicaList.Push(lsr,_FILE_AND_LINE_);
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 {
2043 queryToSerializeReplicaList.RemoveAtIndex(j);
2044 break;
2045 }
2046 }
2047 for (j=0; j < constructedReplicaList.Size(); j++)
2048 {
2049 if (constructedReplicaList[j]->replica==lsr->replica )
2050 {
2051 constructedReplicaList.RemoveAtIndex(j);
2052 break;
2053 }
2054 }
2055 //assert(queryToConstructReplicaList.GetIndexOf(lsr->replica)==(unsigned int)-1);
2056 queryToConstructReplicaList.Push(lsr,_FILE_AND_LINE_);
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 {
2207 bsOut.Write((MessageID)ID_REPLICA_MANAGER_DOWNLOAD_STARTED);
2208 bsOut.Write(worldId);
2209 SerializeOnDownloadStarted(&bsOut);
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 {
2271 RakAssert(cs==RM3CS_ALREADY_EXISTS_REMOTELY);
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
2320 SerializeParameters sp;
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 {
2340 sp.outputBitstream[z].ResetWritePointer();
2341 }
2342
2343 RM3SerializationResult res = replica->Serialize(&sp);
2344 if (res!=RM3SR_NEVER_SERIALIZE_FOR_THIS_CONNECTION &&
2345 res!=RM3SR_DO_NOT_SERIALIZE &&
2346 res!=RM3SR_SERIALIZED_UNIQUELY)
2347 {
2348 bool allIndices[RM3_NUM_OUTPUT_BITSTREAM_CHANNELS];
2349 for (int z=0; z < RM3_NUM_OUTPUT_BITSTREAM_CHANNELS; z++)
2350 {
2351 sp.bitsWrittenSoFar+=sp.outputBitstream[z].GetNumberOfBitsUsed();
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();
2364 bsOut.Write((MessageID)ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE);
2365 bsOut.Write(worldId);
2366 SerializeOnDownloadComplete(&bsOut);
2367 rakPeer->Send(&bsOut,sendParameters.priority,RELIABLE_ORDERED,sendParameters.orderingChannel,systemAddress,false,sendParameters.sendReceipt);
2368 }
2369
2370 isFirstConstruction=false;
2371
2372 }
2373
2374 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2375
2376 void Connection_RM3::SendValidation(SLNet::RakPeerInterface *rakPeer, WorldId worldId)
2377 {
2378 // Hijack to mean sendValidation
2379 SLNet::BitStream bsOut;
2380 bsOut.Write((MessageID)ID_REPLICA_MANAGER_SCOPE_CHANGE);
2381 bsOut.Write(worldId);
2382 rakPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
2383 }
2384
2385 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2386
2387 Replica3::Replica3()
2388 {
2389 creatingSystemGUID=UNASSIGNED_RAKNET_GUID;
2390 deletingSystemGUID=UNASSIGNED_RAKNET_GUID;
2391 replicaManager=0;
2392 forceSendUntilNextUpdate=false;
2393 lsr=0;
2394 referenceIndex = (uint32_t)-1;
2395 }
2396
2397 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2398
2399 Replica3::~Replica3()
2400 {
2401 if (replicaManager)
2402 {
2403 replicaManager->Dereference(this);
2404 }
2405 }
2406
2407 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2408
2409 void Replica3::BroadcastDestruction(void)
2410 {
2411 replicaManager->BroadcastDestruction(this,UNASSIGNED_SYSTEM_ADDRESS);
2412 }
2413
2414 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2415
2416 RakNetGUID Replica3::GetCreatingSystemGUID(void) const
2417 {
2418 return creatingSystemGUID;
2419 }
2420
2421 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2422
2423 RM3ConstructionState Replica3::QueryConstruction_ClientConstruction(SLNet::Connection_RM3 *destinationConnection, bool isThisTheServer)
2424 {
2425 (void) destinationConnection;
2426 if (creatingSystemGUID==replicaManager->GetRakPeerInterface()->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS))
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
2447 RM3ConstructionState Replica3::QueryConstruction_ServerConstruction(SLNet::Connection_RM3 *destinationConnection, bool isThisTheServer)
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
2468 RM3ConstructionState Replica3::QueryConstruction_PeerToPeer(SLNet::Connection_RM3 *destinationConnection, Replica3P2PMode p2pMode)
2469 {
2470 (void) destinationConnection;
2471
2472 if (p2pMode==R3P2PM_SINGLE_OWNER)
2473 {
2474 // We send to all, others do nothing
2475 if (creatingSystemGUID==replicaManager->GetRakPeerInterface()->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS))
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 }
2481 else if (p2pMode==R3P2PM_MULTI_OWNER_CURRENTLY_AUTHORITATIVE)
2482 {
2483 return RM3CS_SEND_CONSTRUCTION;
2484 }
2485 else if (p2pMode==R3P2PM_STATIC_OBJECT_CURRENTLY_AUTHORITATIVE)
2486 {
2487 return RM3CS_ALREADY_EXISTS_REMOTELY;
2488 }
2489 else if (p2pMode==R3P2PM_STATIC_OBJECT_NOT_CURRENTLY_AUTHORITATIVE)
2490 {
2491 return RM3CS_ALREADY_EXISTS_REMOTELY_DO_NOT_CONSTRUCT;
2492 }
2493 else
2494 {
2495 RakAssert(p2pMode==R3P2PM_MULTI_OWNER_NOT_CURRENTLY_AUTHORITATIVE);
2496
2497 // RM3CS_ALREADY_EXISTS_REMOTELY will not send the object, but WILL call QuerySerialization() and Serialize() on it.
2498 return RM3CS_ALREADY_EXISTS_REMOTELY;
2499 }
2500 }
2501
2502 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2503
2504 bool Replica3::QueryRemoteConstruction_PeerToPeer(SLNet::Connection_RM3 *sourceConnection)
2505 {
2506 (void) sourceConnection;
2507
2508 return true;
2509 }
2510
2511 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2512
2513 RM3QuerySerializationResult Replica3::QuerySerialization_ClientSerializable(SLNet::Connection_RM3 *destinationConnection, bool isThisTheServer)
2514 {
2515 // Owner client sends to all
2516 if (creatingSystemGUID==replicaManager->GetRakPeerInterface()->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS))
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
2522 return RM3QSR_NEVER_CALL_SERIALIZE;
2523 }
2524
2525 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2526
2527 RM3QuerySerializationResult Replica3::QuerySerialization_ServerSerializable(SLNet::Connection_RM3 *destinationConnection, bool isThisTheServer)
2528 {
2529 (void) destinationConnection;
2530 // Server sends to all
2531 if (isThisTheServer)
2532 return RM3QSR_CALL_SERIALIZE;
2533
2534 // Clients do not send
2535 return RM3QSR_NEVER_CALL_SERIALIZE;
2536 }
2537
2538 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2539
2540 RM3QuerySerializationResult Replica3::QuerySerialization_PeerToPeer(SLNet::Connection_RM3 *destinationConnection, Replica3P2PMode p2pMode)
2541 {
2542 (void) destinationConnection;
2543
2544 if (p2pMode==R3P2PM_SINGLE_OWNER)
2545 {
2546 // Owner peer sends to all
2547 if (creatingSystemGUID==replicaManager->GetRakPeerInterface()->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS))
2548 return RM3QSR_CALL_SERIALIZE;
2549
2550 // Remote peers do not send
2551 return RM3QSR_NEVER_CALL_SERIALIZE;
2552 }
2553 else if (p2pMode==R3P2PM_MULTI_OWNER_CURRENTLY_AUTHORITATIVE)
2554 {
2555 return RM3QSR_CALL_SERIALIZE;
2556 }
2557 else if (p2pMode==R3P2PM_STATIC_OBJECT_CURRENTLY_AUTHORITATIVE)
2558 {
2559 return RM3QSR_CALL_SERIALIZE;
2560 }
2561 else if (p2pMode==R3P2PM_STATIC_OBJECT_NOT_CURRENTLY_AUTHORITATIVE)
2562 {
2563 return RM3QSR_DO_NOT_CALL_SERIALIZE;
2564 }
2565 else
2566 {
2567 RakAssert(p2pMode==R3P2PM_MULTI_OWNER_NOT_CURRENTLY_AUTHORITATIVE);
2568 return RM3QSR_DO_NOT_CALL_SERIALIZE;
2569 }
2570 }
2571
2572 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2573
2574 RM3ActionOnPopConnection Replica3::QueryActionOnPopConnection_Client(SLNet::Connection_RM3 *droppedConnection) const
2575 {
2576 (void) droppedConnection;
2577 return RM3AOPC_DELETE_REPLICA;
2578 }
2579
2580 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2581
2582 RM3ActionOnPopConnection Replica3::QueryActionOnPopConnection_Server(SLNet::Connection_RM3 *droppedConnection) const
2583 {
2584 (void) droppedConnection;
2585 return RM3AOPC_DELETE_REPLICA_AND_BROADCAST_DESTRUCTION;
2586 }
2587
2588 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2589
2590 RM3ActionOnPopConnection Replica3::QueryActionOnPopConnection_PeerToPeer(SLNet::Connection_RM3 *droppedConnection) const
2591 {
2592 (void) droppedConnection;
2593 return RM3AOPC_DELETE_REPLICA;
2594 }
2595
2596 // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2597
2598 #endif // _RAKNET_SUPPORT_*