00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_ReplicaManager==1
00003
00004 #include "ReplicaManager.h"
00005 #include "RakPeerInterface.h"
00006 #include "GetTime.h"
00007 #include "MessageIdentifiers.h"
00008 #include "BitStream.h"
00009 #include "Replica.h"
00010 #if !defined(_PS3) && !defined(__PS3__) && !defined(SN_TARGET_PS3)
00011 #include <memory.h>
00012 #endif
00013 #include "RakAssert.h"
00014 #include <stdio.h>
00015 #include "RakAssert.h"
00016 #include "NetworkIDManager.h"
00017
00018 #ifdef _MSC_VER
00019 #pragma warning( push )
00020 #endif
00021
00022 int ReplicaManager::CommandStructComp( Replica* const &key, const ReplicaManager::CommandStruct &data )
00023 {
00024 if (key->GetSortPriority() < data.replica->GetSortPriority())
00025 return -1;
00026 else if (key->GetSortPriority() > data.replica->GetSortPriority())
00027 return 1;
00028 if (key->GetAllocationNumber() < data.replica->GetAllocationNumber())
00029 return -1;
00030 if (key->GetAllocationNumber()==data.replica->GetAllocationNumber())
00031 return 0;
00032 return 1;
00033 }
00034
00035 int ReplicaManager::RegisteredReplicaComp( Replica* const &key, const ReplicaManager::RegisteredReplica &data )
00036 {
00037 if (key->GetAllocationNumber() < data.replica->GetAllocationNumber())
00038 return -1;
00039 if (key->GetAllocationNumber()==data.replica->GetAllocationNumber())
00040 return 0;
00041 return 1;
00042 }
00043
00044 int ReplicaManager::RegisteredReplicaRefOrderComp( const unsigned int &key, const ReplicaManager::RegisteredReplica &data )
00045 {
00046 if (key < data.referenceOrder)
00047 return -1;
00048 if (key==data.referenceOrder)
00049 return 0;
00050 return 1;
00051 }
00052
00053 int ReplicaManager::RemoteObjectComp( Replica* const &key, const ReplicaManager::RemoteObject &data )
00054 {
00055 if (key->GetAllocationNumber() < data.replica->GetAllocationNumber())
00056 return -1;
00057 if (key->GetAllocationNumber()==data.replica->GetAllocationNumber())
00058 return 0;
00059 return 1;
00060 }
00061
00062 int ReplicaManager::ParticipantStructComp( const SystemAddress &key, ReplicaManager::ParticipantStruct * const &data )
00063 {
00064 if (key < data->systemAddress)
00065 return -1;
00066 if (key==data->systemAddress)
00067 return 0;
00068 return 1;
00069 }
00070
00071 ReplicaManager::ReplicaManager()
00072 {
00073 _constructionCB=0;
00074 _sendDownloadCompleteCB=0;
00075 _receiveDownloadCompleteCB=0;
00076 sendChannel=0;
00077 autoParticipateNewConnections=false;
00078 defaultScope=false;
00079 autoConstructToNewParticipants=false;
00080 autoSerializeInScope=false;
00081 nextReferenceIndex=0;
00082 #ifdef _DEBUG
00083 inUpdate=false;
00084 #endif
00085 }
00086 ReplicaManager::~ReplicaManager()
00087 {
00088 Clear();
00089 }
00090 void ReplicaManager::SetAutoParticipateNewConnections(bool autoAdd)
00091 {
00092 autoParticipateNewConnections=autoAdd;
00093 }
00094 bool ReplicaManager::AddParticipant(SystemAddress systemAddress)
00095 {
00096 RakAssert(systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00097
00098
00099 ParticipantStruct *participantStruct;
00100 participantStruct=GetParticipantBySystemAddress(systemAddress);
00101 if (participantStruct)
00102 return false;
00103
00104
00105 participantStruct = RakNet::OP_NEW<ParticipantStruct>( __FILE__, __LINE__ );
00106 participantStruct->systemAddress=systemAddress;
00107
00108
00109 participantStruct->callDownloadCompleteCB=true;
00110
00111
00112 participantList.Insert(systemAddress,participantStruct, true, __FILE__,__LINE__);
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 if (autoConstructToNewParticipants)
00141 {
00142
00143 unsigned i;
00144 CommandStruct replicaAndCommand;
00145 replicaAndCommand.command=REPLICA_EXPLICIT_CONSTRUCTION;
00146 if (defaultScope==true)
00147 replicaAndCommand.command |= REPLICA_SCOPE_TRUE;
00148 replicaAndCommand.userFlags=0;
00149 for (i=0; i < replicatedObjects.Size(); i++)
00150 {
00151 replicaAndCommand.replica=replicatedObjects[i].replica;
00152 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00153 }
00154 }
00155
00156 return true;
00157 }
00158 bool ReplicaManager::RemoveParticipant(SystemAddress systemAddress)
00159 {
00160 RakAssert(systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00161
00162
00163 ParticipantStruct *participantStruct;
00164 participantStruct=GetParticipantBySystemAddress(systemAddress);
00165
00166
00167 if (participantStruct)
00168 {
00169 participantList.Remove(systemAddress);
00170 RakNet::OP_DELETE(participantStruct, __FILE__, __LINE__);
00171 return true;
00172 }
00173
00174 return false;
00175 }
00176
00177 void ReplicaManager::Construct(Replica *replica, bool isCopy, SystemAddress systemAddress, bool broadcast)
00178 {
00179 RakAssert(replica);
00180
00181 unsigned i;
00182 ParticipantStruct *participantStruct;
00183 CommandStruct replicaAndCommand;
00184 unsigned index;
00185 bool objectExists;
00186 replicaAndCommand.replica=replica;
00187 replicaAndCommand.userFlags=0;
00188
00189 ReferencePointer(replica);
00190
00191 for (i=0; i < participantList.Size(); i++)
00192 {
00193 participantStruct=participantList[i];
00194 if ((broadcast==true && systemAddress!=participantStruct->systemAddress) ||
00195 (broadcast==false && systemAddress==participantStruct->systemAddress))
00196 {
00197 if (participantStruct->remoteObjectList.HasData(replica)==false)
00198 {
00199 index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00200
00201 if (objectExists)
00202 {
00203 #ifdef _DEBUG
00204
00205 RakAssert(isCopy==false);
00206 #endif
00207 participantStruct->commandList[index].command|=REPLICA_EXPLICIT_CONSTRUCTION;
00208 participantStruct->commandList[index].command&=0xFF ^ REPLICA_IMPLICIT_CONSTRUCTION;
00209
00210 if (defaultScope==true && (participantStruct->commandList[index].command & REPLICA_SCOPE_FALSE) == 0)
00211 participantStruct->commandList[index].command |= REPLICA_SCOPE_TRUE;
00212 }
00213 else
00214 {
00215 if (isCopy)
00216 replicaAndCommand.command=REPLICA_IMPLICIT_CONSTRUCTION;
00217 else
00218 replicaAndCommand.command=REPLICA_EXPLICIT_CONSTRUCTION;
00219
00220 if (defaultScope==true)
00221 replicaAndCommand.command |= REPLICA_SCOPE_TRUE;
00222
00223 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00224 }
00225 }
00226 }
00227 }
00228
00229
00230 Update();
00231 }
00232 void ReplicaManager::Destruct(Replica *replica, SystemAddress systemAddress, bool broadcast)
00233 {
00234 RakAssert(replica);
00235
00236 bool sendTimestamp;
00237 bool objectExists;
00238 unsigned replicatedObjectsIndex;
00239 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00240 if (objectExists==false)
00241 return;
00242
00243
00244 RakNet::BitStream outBitstream, userDataBitStream;
00245 unsigned i,tempIndex;
00246 bool replicaReferenced;
00247 ParticipantStruct *participantStruct;
00248 replicaReferenced=false;
00249 for (i=0; i < participantList.Size(); i++)
00250 {
00251 participantStruct=participantList[i];
00252
00253 if ((broadcast==true && systemAddress!=participantStruct->systemAddress) ||
00254 (broadcast==false && systemAddress==participantStruct->systemAddress))
00255 {
00256
00257 tempIndex = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00258 if (objectExists)
00259 {
00260
00261 if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID &&
00262 (replicatedObjects[replicatedObjectsIndex].allowedInterfaces & REPLICA_SEND_DESTRUCTION))
00263 {
00264 userDataBitStream.Reset();
00265 userDataBitStream.Write((MessageID)ID_REPLICA_MANAGER_DESTRUCTION);
00266 userDataBitStream.Write(replica->GetNetworkID());
00267 sendTimestamp=false;
00268 ReplicaReturnResult res = replica->SendDestruction(&userDataBitStream, participantStruct->systemAddress, &sendTimestamp);
00269 if (res==REPLICA_PROCESSING_DONE)
00270 {
00271 outBitstream.Reset();
00272 if (sendTimestamp)
00273 {
00274 outBitstream.Write((MessageID)ID_TIMESTAMP);
00275 outBitstream.Write(RakNet::GetTime());
00276 outBitstream.Write(&userDataBitStream);
00277 SendUnified(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->systemAddress, false);
00278 }
00279 else
00280 SendUnified(&userDataBitStream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->systemAddress, false);
00281 }
00282 }
00283
00284 participantStruct->remoteObjectList.RemoveAtIndex(tempIndex);
00285 }
00286
00287
00288 tempIndex = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00289
00290 if (objectExists)
00291 participantStruct->commandList.RemoveAtIndex(tempIndex);
00292 }
00293 else if (replicaReferenced==false)
00294 {
00295 bool objectExists;
00296 GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00297
00298
00299 if (objectExists)
00300 replicaReferenced=true;
00301 else if (participantStruct->remoteObjectList.HasData(replica))
00302 replicaReferenced=true;
00303 }
00304 }
00305
00306
00307 if (replicaReferenced==false)
00308 replicatedObjects.RemoveAtIndex(replicatedObjectsIndex);
00309 }
00310 void ReplicaManager::ReferencePointer(Replica *replica)
00311 {
00312
00313 if (replicatedObjects.HasData(replica)==false)
00314 {
00315 RegisteredReplica replicaAndTime;
00316 replicaAndTime.replica=replica;
00317 replicaAndTime.lastDeserializeTrue=0;
00318 replicaAndTime.allowedInterfaces=REPLICA_SET_ALL;
00319 replicaAndTime.referenceOrder=nextReferenceIndex++;
00320 replicatedObjects.Insert(replica,replicaAndTime, true, __FILE__,__LINE__);
00322 if (replica->GetNetworkIDManager()==0)
00323 replica->SetNetworkIDManager(rakPeerInterface->GetNetworkIDManager());
00324 }
00325 }
00326 void ReplicaManager::DereferencePointer(Replica *replica)
00327 {
00328 bool objectExists;
00329 unsigned replicatedObjectsIndex;
00330 unsigned tempIndex;
00331 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00332 if (objectExists==false)
00333 return;
00334 replicatedObjects.RemoveAtIndex(replicatedObjectsIndex);
00335
00336 ParticipantStruct *participantStruct;
00337 unsigned i;
00338 for (i=0; i < participantList.Size(); i++)
00339 {
00340 participantStruct=participantList[i];
00341
00342
00343 tempIndex = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00344
00345 if (objectExists)
00346 participantStruct->commandList.RemoveAtIndex(tempIndex);
00347
00348
00349 tempIndex = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00350 if (objectExists)
00351 participantStruct->remoteObjectList.RemoveAtIndex(tempIndex);
00352 }
00353 }
00354 void ReplicaManager::SetScope(Replica *replica, bool inScope, SystemAddress systemAddress, bool broadcast)
00355 {
00356 RakAssert(replica);
00357
00358
00359
00360 ReferencePointer(replica);
00361
00362
00363 unsigned i;
00364 ParticipantStruct *participantStruct;
00365 bool objectExists;
00366 unsigned index;
00367 CommandStruct replicaAndCommand;
00368 if (inScope)
00369 replicaAndCommand.command=REPLICA_SCOPE_TRUE;
00370 else
00371 replicaAndCommand.command=REPLICA_SCOPE_FALSE;
00372 replicaAndCommand.replica=replica;
00373 replicaAndCommand.userFlags=0;
00374 for (i=0; i < participantList.Size(); i++)
00375 {
00376 participantStruct=participantList[i];
00377
00378 if ((broadcast==true && systemAddress!=participantStruct->systemAddress) ||
00379 (broadcast==false && systemAddress==participantStruct->systemAddress))
00380 {
00381
00382 index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00383
00384 if (objectExists)
00385 {
00386
00387 if (inScope)
00388 {
00389 participantStruct->commandList[index].command&=0xFF ^ REPLICA_SCOPE_FALSE;
00390 participantStruct->commandList[index].command|=REPLICA_SCOPE_TRUE;
00391 }
00392 else
00393 {
00394 participantStruct->commandList[index].command&=0xFF ^ REPLICA_SCOPE_TRUE;
00395 participantStruct->commandList[index].command|=REPLICA_SCOPE_FALSE;
00396 }
00397 }
00398 else
00399 {
00400
00401 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00402 }
00403 }
00404 }
00405 }
00406 void ReplicaManager::SignalSerializeNeeded(Replica *replica, SystemAddress systemAddress, bool broadcast)
00407 {
00408 RakAssert(replica);
00409
00410
00411
00412 if (replicatedObjects.HasData(replica)==false)
00413 ReferencePointer(replica);
00414
00415
00416
00417 unsigned i;
00418 ParticipantStruct *participantStruct;
00419 bool objectExists;
00420 unsigned index;
00421 CommandStruct replicaAndCommand;
00422 replicaAndCommand.command=REPLICA_SERIALIZE;
00423 replicaAndCommand.replica=replica;
00424 replicaAndCommand.userFlags=0;
00425 for (i=0; i < participantList.Size(); i++)
00426 {
00427 participantStruct=participantList[i];
00428
00429 if ((broadcast==true && systemAddress!=participantStruct->systemAddress) ||
00430 (broadcast==false && systemAddress==participantStruct->systemAddress))
00431 {
00432
00433
00434 index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00435 if (objectExists)
00436 {
00437 participantStruct->commandList[index].command|=REPLICA_SERIALIZE;
00438 }
00439 else
00440 {
00441
00442 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00443 }
00444 }
00445 }
00446 }
00447 void ReplicaManager::SetReceiveConstructionCB(ReceiveConstructionInterface *ReceiveConstructionInterface)
00448 {
00449
00450 _constructionCB=ReceiveConstructionInterface;
00451 }
00452 void ReplicaManager::SetDownloadCompleteCB(SendDownloadCompleteInterface *sendDownloadComplete, ReceiveDownloadCompleteInterface *receiveDownloadComplete)
00453 {
00454
00455 _sendDownloadCompleteCB=sendDownloadComplete;
00456 _receiveDownloadCompleteCB=receiveDownloadComplete;
00457 }
00458 void ReplicaManager::SetSendChannel(unsigned char channel)
00459 {
00460
00461 sendChannel=channel;
00462 }
00463 void ReplicaManager::SetAutoConstructToNewParticipants(bool autoConstruct)
00464 {
00465 autoConstructToNewParticipants=autoConstruct;
00466 }
00467 void ReplicaManager::SetDefaultScope(bool scope)
00468 {
00469 defaultScope=scope;
00470 }
00471 void ReplicaManager::SetAutoSerializeInScope(bool autoSerialize)
00472 {
00473 autoSerializeInScope=autoSerialize;
00474 }
00475 void ReplicaManager::EnableReplicaInterfaces(Replica *replica, unsigned char interfaceFlags)
00476 {
00477 bool objectExists;
00478 unsigned replicatedObjectsIndex;
00479 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00480 if (objectExists==false)
00481 {
00482
00483
00484 ReferencePointer(replica);
00485 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00486 }
00487 replicatedObjects[replicatedObjectsIndex].allowedInterfaces|=interfaceFlags;
00488 }
00489 void ReplicaManager::DisableReplicaInterfaces(Replica *replica, unsigned char interfaceFlags)
00490 {
00491 bool objectExists;
00492 unsigned replicatedObjectsIndex;
00493 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00494 if (objectExists==false)
00495 {
00496
00497
00498 ReferencePointer(replica);
00499 replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists);
00500 }
00501 replicatedObjects[replicatedObjectsIndex].allowedInterfaces&= 0xFF ^ interfaceFlags;
00502 }
00503 bool ReplicaManager::IsConstructed(Replica *replica, SystemAddress systemAddress)
00504 {
00505 ParticipantStruct *participantStruct = GetParticipantBySystemAddress(systemAddress);
00506 if (participantStruct)
00507 {
00508 bool objectExists;
00509 participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00510 return objectExists;
00511 }
00512 return false;
00513 }
00514 bool ReplicaManager::IsInScope(Replica *replica, SystemAddress systemAddress)
00515 {
00516 ParticipantStruct *participantStruct = GetParticipantBySystemAddress(systemAddress);
00517 if (participantStruct)
00518 {
00519 bool objectExists;
00520 unsigned remoteObjectListIndex = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00521 if (objectExists)
00522 return participantStruct->remoteObjectList[remoteObjectListIndex].inScope;
00523 }
00524 return false;
00525 }
00526 unsigned ReplicaManager::GetReplicaCount(void) const
00527 {
00528 return replicatedObjects.Size();
00529 }
00530 Replica *ReplicaManager::GetReplicaAtIndex(unsigned index)
00531 {
00532 return replicatedObjects[index].replica;
00533 }
00534 unsigned ReplicaManager::GetParticipantCount(void) const
00535 {
00536 return participantList.Size();
00537 }
00538 SystemAddress ReplicaManager::GetParticipantAtIndex(unsigned index)
00539 {
00540 return participantList[index]->systemAddress;
00541 }
00542 bool ReplicaManager::HasParticipant(SystemAddress systemAddress)
00543 {
00544 return participantList.HasData(systemAddress);
00545 }
00546 void ReplicaManager::SignalSerializationFlags(Replica *replica, SystemAddress systemAddress, bool broadcast, bool set, unsigned int flags)
00547 {
00548 RakAssert(replica);
00549
00550
00551
00552 ReferencePointer(replica);
00553
00554 CommandStruct replicaAndCommand;
00555 replicaAndCommand.replica=replica;
00556 replicaAndCommand.userFlags=flags;
00557 replicaAndCommand.command=0;
00558
00559 bool objectExists;
00560 unsigned i, index;
00561 ParticipantStruct *participantStruct;
00562 for (i=0; i < participantList.Size(); i++)
00563 {
00564 participantStruct=participantList[i];
00565
00566 if ((broadcast==true && systemAddress!=participantStruct->systemAddress) ||
00567 (broadcast==false && systemAddress==participantStruct->systemAddress))
00568 {
00569
00570 index = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00571 if (objectExists)
00572 {
00573 if (set)
00574 participantStruct->remoteObjectList[index].userFlags|=flags;
00575 else
00576 participantStruct->remoteObjectList[index].userFlags&=~flags;
00577 }
00578 else
00579 {
00580
00581
00582 index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00583 if (objectExists)
00584 {
00585 if (set)
00586 participantStruct->commandList[index].userFlags|=flags;
00587 else
00588 participantStruct->commandList[index].userFlags&=~flags;
00589 }
00590 else if (set)
00591 {
00592
00593 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00594 }
00595 }
00596 }
00597 }
00598 }
00599 unsigned int* ReplicaManager::AccessSerializationFlags(Replica *replica, SystemAddress systemAddress)
00600 {
00601 RakAssert(replica);
00602
00603
00604
00605 ReferencePointer(replica);
00606
00607 unsigned index;
00608 bool objectExists;
00609 ParticipantStruct *participantStruct;
00610 CommandStruct replicaAndCommand;
00611 replicaAndCommand.replica=replica;
00612 replicaAndCommand.userFlags=0;
00613 replicaAndCommand.command=0;
00614
00615 participantStruct=GetParticipantBySystemAddress(systemAddress);
00616 if (participantStruct)
00617 {
00618
00619 index = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00620 if (objectExists)
00621 {
00622 return &(participantStruct->remoteObjectList[index].userFlags);
00623 }
00624 else
00625 {
00626
00627 index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists);
00628 if (objectExists)
00629 {
00630 return &(participantStruct->commandList[index].userFlags);
00631 }
00632 else
00633 {
00634
00635
00636 participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__);
00637
00638 return & (participantStruct->commandList[participantStruct->commandList.Size()-1].userFlags);
00639 }
00640 }
00641 }
00642
00643
00644 return 0;
00645 }
00646
00647 void ReplicaManager::Clear(void)
00648 {
00649
00650 unsigned i;
00651 for (i=0; i < participantList.Size(); i++)
00652 RakNet::OP_DELETE(participantList[i], __FILE__, __LINE__);
00653 participantList.Clear(false, __FILE__, __LINE__);
00654 replicatedObjects.Clear(false, __FILE__, __LINE__);
00655 nextReferenceIndex=0;
00656 }
00657 void ReplicaManager::AssertReplicatedObjectsClear(void)
00658 {
00659 RakAssert(replicatedObjects.Size()==0);
00660 }
00661 void ReplicaManager::AssertParticipantsClear(void)
00662 {
00663 RakAssert(participantList.Size()==0);
00664 }
00665 void ReplicaManager::Update(void)
00666 {
00667 if (participantList.Size()==0)
00668 return;
00669
00670
00671 #ifdef _DEBUG
00672 RakAssert(inUpdate==false);
00673 inUpdate=true;
00674 #endif
00675
00676 unsigned participantIndex, remoteObjectListIndex, replicatedObjectsIndex;
00677 ReplicaReturnResult res;
00678 bool sendTimestamp;
00679 ParticipantStruct *participantStruct;
00680 unsigned commandListIndex;
00681 RakNet::BitStream outBitstream, userDataBitstream;
00682 RakNetTime currentTime;
00683 bool objectExists;
00684 PacketPriority priority;
00685 PacketReliability reliability;
00686 ReceivedCommand *receivedCommand;
00687 Replica *replica;
00688
00689 unsigned char command;
00690 currentTime=0;
00691
00692
00693 for (participantIndex=0; participantIndex < participantList.Size(); participantIndex++)
00694 {
00695 participantStruct = participantList[participantIndex];
00696
00697
00698
00699
00700 if (participantStruct->callDownloadCompleteCB)
00701 {
00702 bool anyHasConstruction;
00703 unsigned j;
00704 anyHasConstruction=false;
00705 for (j=0; j < participantStruct->commandList.Size(); j++)
00706 {
00707 if (participantStruct->commandList[j].command & REPLICA_EXPLICIT_CONSTRUCTION)
00708 {
00709 anyHasConstruction=true;
00710 break;
00711 }
00712 }
00713
00714 if (anyHasConstruction==false)
00715 {
00716 ReplicaReturnResult sendDLComplete;
00717 userDataBitstream.Reset();
00718 if (_sendDownloadCompleteCB)
00719 sendDLComplete=_sendDownloadCompleteCB->SendDownloadComplete(&userDataBitstream, currentTime, participantStruct->systemAddress, this);
00720 else
00721 sendDLComplete=REPLICA_CANCEL_PROCESS;
00722 if (sendDLComplete==REPLICA_PROCESSING_DONE)
00723 {
00724 outBitstream.Reset();
00725 outBitstream.Write((MessageID)ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE);
00726 outBitstream.Write(&userDataBitstream, userDataBitstream.GetNumberOfBitsUsed());
00727 SendUnified(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->systemAddress, false);
00728 participantStruct->callDownloadCompleteCB=false;
00729 }
00730 else if (sendDLComplete==REPLICA_CANCEL_PROCESS)
00731 {
00732 participantStruct->callDownloadCompleteCB=false;
00733 }
00734 else
00735 {
00736 RakAssert(sendDLComplete==REPLICA_PROCESS_LATER);
00737
00738 }
00739 }
00740 }
00741
00742
00743 for (commandListIndex=0; commandListIndex < participantStruct->commandList.Size(); commandListIndex++)
00744 {
00745
00746 if (currentTime==0)
00747 currentTime=RakNet::GetTime();
00748
00749 replica=participantStruct->commandList[commandListIndex].replica;
00750 command=participantStruct->commandList[commandListIndex].command;
00751
00752 replicatedObjectsIndex=replicatedObjects.GetIndexFromKey(replica, &objectExists);
00753 #ifdef _DEBUG
00754 RakAssert(objectExists);
00755 #endif
00756 if (objectExists==false)
00757 continue;
00758
00759
00760
00761 if (command & REPLICA_EXPLICIT_CONSTRUCTION)
00762 {
00763 if (replicatedObjects[replicatedObjectsIndex].allowedInterfaces & REPLICA_SEND_CONSTRUCTION)
00764 {
00765 userDataBitstream.Reset();
00766 sendTimestamp=false;
00767 res=replica->SendConstruction(currentTime, participantStruct->systemAddress,
00768 participantStruct->commandList[commandListIndex].userFlags, &userDataBitstream, &sendTimestamp);
00769
00770 if (res==REPLICA_PROCESSING_DONE)
00771 {
00772 outBitstream.Reset();
00773
00774 if (sendTimestamp)
00775 {
00776 outBitstream.Write((MessageID)ID_TIMESTAMP);
00777 outBitstream.Write(currentTime);
00778 }
00779 outBitstream.Write((MessageID)ID_REPLICA_MANAGER_CONSTRUCTION);
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID)
00790 {
00791 outBitstream.Write(true);
00792 outBitstream.Write(replica->GetNetworkID());
00793 }
00794 else
00795 outBitstream.Write(false);
00796
00797 outBitstream.Write(&userDataBitstream, userDataBitstream.GetNumberOfBitsUsed());
00798
00799 SendUnified(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->systemAddress, false);
00800
00801
00802 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_EXPLICIT_CONSTRUCTION;
00803
00804
00805 RemoteObject remoteObject;
00806 remoteObject.replica=replica;
00807
00808 remoteObject.inScope=false;
00809 remoteObject.lastSendTime=0;
00810 remoteObject.userFlags=participantStruct->commandList[commandListIndex].userFlags;
00811
00812
00813 participantStruct->remoteObjectList.Insert(remoteObject.replica,remoteObject, true, __FILE__,__LINE__);
00814 }
00815 else if (res==REPLICA_PROCESS_IMPLICIT)
00816 {
00817
00818 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_EXPLICIT_CONSTRUCTION;
00819
00820
00821 RemoteObject remoteObject;
00822 remoteObject.replica=replica;
00823
00824 remoteObject.inScope=false;
00825 remoteObject.lastSendTime=0;
00826 remoteObject.userFlags=participantStruct->commandList[commandListIndex].userFlags;
00827
00828
00829 participantStruct->remoteObjectList.Insert(remoteObject.replica,remoteObject, true, __FILE__,__LINE__);
00830 }
00831 else if (res==REPLICA_PROCESS_LATER)
00832 {
00833 continue;
00834 }
00835 else
00836 {
00837 RakAssert(res==REPLICA_CANCEL_PROCESS);
00838 participantStruct->commandList[commandListIndex].command=0;
00839 }
00840 }
00841 else
00842 {
00843
00844 participantStruct->commandList[commandListIndex].command=0;
00845 }
00846 }
00847 else if (command & REPLICA_IMPLICIT_CONSTRUCTION)
00848 {
00849
00850 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_IMPLICIT_CONSTRUCTION;
00851
00852
00853 RemoteObject remoteObject;
00854 remoteObject.replica=replica;
00855
00856 remoteObject.inScope=false;
00857 remoteObject.lastSendTime=0;
00858 remoteObject.userFlags=participantStruct->commandList[commandListIndex].userFlags;
00859
00860
00861 participantStruct->remoteObjectList.Insert(remoteObject.replica,remoteObject, true, __FILE__,__LINE__);
00862 }
00863
00864
00865 remoteObjectListIndex = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists);
00866 if (objectExists)
00867 {
00868 command = participantStruct->commandList[commandListIndex].command;
00869
00870
00871 if ((command & (REPLICA_SCOPE_TRUE | REPLICA_SCOPE_FALSE)))
00872 {
00873 if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
00874 continue;
00875
00876 if (replicatedObjects[replicatedObjectsIndex].allowedInterfaces & REPLICA_SEND_SCOPE_CHANGE)
00877 {
00878 bool scopeTrue = (command & REPLICA_SCOPE_TRUE)!=0;
00879
00880
00881 if (participantStruct->remoteObjectList[remoteObjectListIndex].inScope!=scopeTrue)
00882 {
00883 userDataBitstream.Reset();
00884 sendTimestamp=false;
00885 res=replica->SendScopeChange(scopeTrue, &userDataBitstream, currentTime, participantStruct->systemAddress, &sendTimestamp);
00886
00887 if (res==REPLICA_PROCESSING_DONE)
00888 {
00889
00890 outBitstream.Reset();
00891 if (sendTimestamp)
00892 {
00893 outBitstream.Write((MessageID)ID_TIMESTAMP);
00894 outBitstream.Write(currentTime);
00895 }
00896 outBitstream.Write((MessageID)ID_REPLICA_MANAGER_SCOPE_CHANGE);
00897 outBitstream.Write(replica->GetNetworkID());
00898 outBitstream.Write(&userDataBitstream, userDataBitstream.GetNumberOfBitsUsed());
00899 SendUnified(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, sendChannel, participantStruct->systemAddress, false);
00900
00901
00902 participantStruct->remoteObjectList[remoteObjectListIndex].inScope=scopeTrue;
00903
00904
00905 if (scopeTrue && autoSerializeInScope)
00906 participantStruct->commandList[commandListIndex].command |= REPLICA_SERIALIZE;
00907
00908
00909 participantStruct->commandList[commandListIndex].command &= 0xFF ^ (REPLICA_SCOPE_TRUE | REPLICA_SCOPE_FALSE);
00910 }
00911 else if (res==REPLICA_CANCEL_PROCESS)
00912 {
00913
00914 participantStruct->commandList[commandListIndex].command &= 0xFF ^ (REPLICA_SCOPE_TRUE | REPLICA_SCOPE_FALSE);
00915 }
00916 else
00917 {
00918
00919 if (scopeTrue==false)
00920 continue;
00921
00922
00923 }
00924 }
00925 }
00926 else
00927 {
00928
00929 participantStruct->commandList[commandListIndex].command &= 0xFF ^ (REPLICA_SCOPE_TRUE | REPLICA_SCOPE_FALSE);
00930
00931
00932 participantStruct->remoteObjectList[remoteObjectListIndex].inScope=(command & REPLICA_SCOPE_TRUE)!=0;
00933 }
00934 }
00935
00936 command = participantStruct->commandList[commandListIndex].command;
00937
00938 if ((command & REPLICA_SERIALIZE))
00939 {
00940 if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
00941 continue;
00942
00943
00944 if (participantStruct->remoteObjectList[remoteObjectListIndex].inScope && (replicatedObjects[replicatedObjectsIndex].allowedInterfaces & REPLICA_SEND_SERIALIZE))
00945 {
00946 do
00947 {
00948 userDataBitstream.Reset();
00949 priority=HIGH_PRIORITY;
00950 reliability=RELIABLE_ORDERED;
00951 sendTimestamp=false;
00952 res=replica->Serialize(&sendTimestamp, &userDataBitstream, participantStruct->remoteObjectList[remoteObjectListIndex].lastSendTime, &priority, &reliability, currentTime, participantStruct->systemAddress, participantStruct->remoteObjectList[remoteObjectListIndex].userFlags);
00953
00954 if (res==REPLICA_PROCESSING_DONE || res==REPLICA_PROCESS_AGAIN)
00955 {
00956 participantStruct->remoteObjectList[remoteObjectListIndex].lastSendTime=currentTime;
00957
00958 outBitstream.Reset();
00959 if (sendTimestamp)
00960 {
00961 outBitstream.Write((MessageID)ID_TIMESTAMP);
00962 outBitstream.Write(currentTime);
00963 }
00964 outBitstream.Write((MessageID)ID_REPLICA_MANAGER_SERIALIZE);
00965 outBitstream.Write(replica->GetNetworkID());
00966 outBitstream.Write(&userDataBitstream, userDataBitstream.GetNumberOfBitsUsed());
00967 SendUnified(&outBitstream, priority, reliability, sendChannel, participantStruct->systemAddress, false);
00968
00969
00970 if (res==REPLICA_PROCESSING_DONE)
00971 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_SERIALIZE;
00972
00973 }
00974 else if (res==REPLICA_CANCEL_PROCESS)
00975 {
00976
00977 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_SERIALIZE;
00978 }
00979 else
00980 {
00981
00982 RakAssert(res==REPLICA_PROCESS_LATER);
00983 }
00984 } while(res==REPLICA_PROCESS_AGAIN);
00985 }
00986 else
00987 {
00988
00989 participantStruct->commandList[commandListIndex].command &= 0xFF ^ REPLICA_SERIALIZE;
00990 }
00991 }
00992 }
00993 }
00994
00995
00996 commandListIndex=participantStruct->commandList.Size();
00997 if (commandListIndex>0)
00998 {
00999 #ifdef _MSC_VER
01000 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
01001 #endif
01002 while (1)
01003 {
01004 if (participantStruct->commandList[commandListIndex-1].command==0)
01005 {
01006
01007 participantStruct->commandList.RemoveAtIndex(commandListIndex-1);
01008 }
01009
01010 if (--commandListIndex==0)
01011 break;
01012 }
01013 }
01014
01015
01016 while (participantStruct->pendingCommands.Size())
01017 {
01018 receivedCommand=participantStruct->pendingCommands.Pop();
01019 participantStruct=GetParticipantBySystemAddress(receivedCommand->systemAddress);
01020 if (participantStruct)
01021 {
01022 res=ProcessReceivedCommand(participantStruct, receivedCommand);
01023
01024 if (res==REPLICA_PROCESS_LATER)
01025 {
01026
01027 participantStruct->pendingCommands.PushAtHead(receivedCommand, 0, __FILE__,__LINE__);
01028
01029
01030 break;
01031 }
01032 else
01033 {
01034 RakAssert(res==REPLICA_CANCEL_PROCESS);
01035 }
01036 }
01037
01038
01039 RakNet::OP_DELETE(receivedCommand->userData, __FILE__, __LINE__);
01040 RakNet::OP_DELETE(receivedCommand, __FILE__, __LINE__);
01041 }
01042 }
01043 #ifdef _DEBUG
01044 inUpdate=false;
01045 #endif
01046 }
01047 void ReplicaManager::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
01048 {
01049 (void) systemAddress;
01050 (void) rakNetGUID;
01051 (void) lostConnectionReason;
01052
01053 RemoveParticipant(systemAddress);
01054 }
01055 void ReplicaManager::OnRakPeerShutdown(void)
01056 {
01057 Clear();
01058 }
01059 void ReplicaManager::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
01060 {
01061 (void) systemAddress;
01062 (void) rakNetGUID;
01063 (void) isIncoming;
01064
01065 if (autoParticipateNewConnections)
01066 AddParticipant(systemAddress);
01067 }
01068 PluginReceiveResult ReplicaManager::OnReceive(Packet *packet)
01069 {
01070 unsigned char packetIdentifier;
01071 if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
01072 {
01073 if ( packet->length > sizeof( unsigned char ) + sizeof( unsigned int ) )
01074 packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( unsigned int ) ];
01075 else
01076 return RR_STOP_PROCESSING_AND_DEALLOCATE;
01077 }
01078 else
01079 packetIdentifier = ( unsigned char ) packet->data[ 0 ];
01080
01081 switch (packetIdentifier)
01082 {
01083 case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
01084 if (_receiveDownloadCompleteCB==0)
01085 {
01086 return RR_STOP_PROCESSING_AND_DEALLOCATE;
01087 }
01088 case ID_REPLICA_MANAGER_CONSTRUCTION:
01089 case ID_REPLICA_MANAGER_DESTRUCTION:
01090 case ID_REPLICA_MANAGER_SCOPE_CHANGE:
01091 case ID_REPLICA_MANAGER_SERIALIZE:
01092 {
01093 ParticipantStruct *participantStruct;
01094 bool hasNetworkId=false;
01095 ReceivedCommand receivedCommand;
01096 bool b=true;
01097 RakNet::BitStream inBitstream(packet->data, packet->length, false);
01098
01099
01100 inBitstream.SetWriteOffset(packet->bitSize);
01101 receivedCommand.systemAddress=packet->systemAddress;
01102 receivedCommand.command=packetIdentifier;
01103
01104 if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
01105 {
01106 inBitstream.IgnoreBits(8);
01107 b=inBitstream.Read(receivedCommand.u1);
01108 }
01109 else
01110 receivedCommand.u1=0;
01111 inBitstream.IgnoreBits(8);
01112 receivedCommand.networkID=UNASSIGNED_NETWORK_ID;
01113 if (packetIdentifier==ID_REPLICA_MANAGER_CONSTRUCTION)
01114 {
01115 b=inBitstream.Read(hasNetworkId);
01116 if (hasNetworkId)
01117 b=inBitstream.Read(receivedCommand.networkID);
01118 }
01119 else if (packetIdentifier!=ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE)
01120 {
01121 b=inBitstream.Read(receivedCommand.networkID);
01122 }
01123
01124 if (b==false)
01125 {
01126
01127 #ifdef _DEBUG
01128 RakAssert(0);
01129 #endif
01130 return RR_STOP_PROCESSING_AND_DEALLOCATE;
01131 }
01132 receivedCommand.userData=&inBitstream;
01133 participantStruct=GetParticipantBySystemAddress(receivedCommand.systemAddress);
01134 if (participantStruct)
01135 {
01136
01137
01138 if (participantStruct->pendingCommands.Size()>0 || ProcessReceivedCommand(participantStruct, &receivedCommand)==REPLICA_PROCESS_LATER)
01139 {
01140
01141
01142
01143 ReceivedCommand *rc = RakNet::OP_NEW<ReceivedCommand>( __FILE__, __LINE__ );
01144 memcpy(rc, &receivedCommand, sizeof(ReceivedCommand));
01145
01146
01147 rc->userData = RakNet::OP_NEW<RakNet::BitStream>( __FILE__, __LINE__ );
01148 rc->userData->Write(&inBitstream, inBitstream.GetNumberOfBitsUsed());
01149
01150 participantStruct->pendingCommands.Push(rc, __FILE__, __LINE__ );
01151 }
01152 }
01153
01154 return RR_STOP_PROCESSING_AND_DEALLOCATE;
01155 }
01156 }
01157
01158 return RR_CONTINUE_PROCESSING;
01159 }
01160
01161 ReplicaManager::ParticipantStruct* ReplicaManager::GetParticipantBySystemAddress(const SystemAddress systemAddress) const
01162 {
01163 bool objectExists;
01164 unsigned index;
01165 index = participantList.GetIndexFromKey(systemAddress, &objectExists);
01166 if (objectExists==false)
01167 return 0;
01168 return participantList[index];
01169 }
01170 #ifdef _MSC_VER
01171 #pragma warning( disable : 4701 ) // warning C4701: local variable <variable name> may be used without having been initialized
01172 #endif
01173 ReplicaReturnResult ReplicaManager::ProcessReceivedCommand(ParticipantStruct *participantStruct, ReceivedCommand *receivedCommand)
01174 {
01175 (void) participantStruct;
01176
01177
01178 RakAssert(rakPeerInterface->GetNetworkIDManager());
01179 if (rakPeerInterface->GetNetworkIDManager()==0)
01180 return REPLICA_CANCEL_PROCESS;
01181
01182 Replica *replica = (Replica*) rakPeerInterface->GetNetworkIDManager()->GET_BASE_OBJECT_FROM_ID(receivedCommand->networkID);
01183
01184 bool objectExists;
01185 unsigned index=0;
01186 ReplicaReturnResult b;
01187 if (replica)
01188 {
01189 index = replicatedObjects.GetIndexFromKey(replica, &objectExists);
01190 if (objectExists==false)
01191 {
01192 if (receivedCommand->command==ID_REPLICA_MANAGER_CONSTRUCTION)
01193 {
01194
01195 #ifdef _DEBUG
01196 RakAssert(_constructionCB);
01197 #endif
01198
01199 return _constructionCB->ReceiveConstruction(receivedCommand->userData, receivedCommand->u1, receivedCommand->networkID, replica, receivedCommand->systemAddress, this);
01200 }
01201 else
01202 {
01203
01204
01205 return REPLICA_CANCEL_PROCESS;
01206 }
01207
01208 }
01209 }
01210
01211 if (receivedCommand->command==ID_REPLICA_MANAGER_SERIALIZE)
01212 {
01213 if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SERIALIZE))
01214 {
01215 b=replica->Deserialize(receivedCommand->userData, receivedCommand->u1, replicatedObjects[index].lastDeserializeTrue, receivedCommand->systemAddress);
01216 if (b==REPLICA_PROCESSING_DONE)
01217 replicatedObjects[index].lastDeserializeTrue=RakNet::GetTime();
01218 return b;
01219 }
01220 }
01221 else if (receivedCommand->command==ID_REPLICA_MANAGER_CONSTRUCTION)
01222 {
01223
01224 #ifdef _DEBUG
01225 RakAssert(_constructionCB);
01226 #endif
01227
01228 return _constructionCB->ReceiveConstruction(receivedCommand->userData, receivedCommand->u1, receivedCommand->networkID, replica, receivedCommand->systemAddress, this);
01229 }
01230 else if (receivedCommand->command==ID_REPLICA_MANAGER_SCOPE_CHANGE)
01231 {
01232 if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SCOPE_CHANGE))
01233 {
01234 return replica->ReceiveScopeChange(receivedCommand->userData, receivedCommand->systemAddress, receivedCommand->u1);
01235 }
01236 }
01237 else if (receivedCommand->command==ID_REPLICA_MANAGER_DESTRUCTION)
01238 {
01239 if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_DESTRUCTION))
01240 {
01241 return replica->ReceiveDestruction(receivedCommand->userData, receivedCommand->systemAddress, receivedCommand->u1);
01242 }
01243 }
01244 else if (receivedCommand->command==ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE)
01245 {
01246 if (_receiveDownloadCompleteCB)
01247 {
01248 return _receiveDownloadCompleteCB->ReceiveDownloadComplete(receivedCommand->userData, receivedCommand->systemAddress, this);
01249 }
01250 }
01251
01252 return REPLICA_CANCEL_PROCESS;
01253 }
01254
01255 ReplicaManager::ParticipantStruct::~ParticipantStruct()
01256 {
01257 ReceivedCommand *receivedCommand;
01258 while ( pendingCommands.Size() )
01259 {
01260 receivedCommand=pendingCommands.Pop();
01261 RakNet::OP_DELETE(receivedCommand->userData, __FILE__, __LINE__);
01262 RakNet::OP_DELETE(receivedCommand, __FILE__, __LINE__);
01263 }
01264 }
01265
01266 unsigned ReplicaManager::GetCommandListReplicaIndex(const DataStructures::List<ReplicaManager::CommandStruct> &commandList, Replica *replica, bool *objectExists) const
01267 {
01268 unsigned i;
01269 for (i=0; i < commandList.Size(); i++)
01270 {
01271 if (commandList[i].replica==replica)
01272 {
01273 *objectExists=true;
01274 return i;
01275 }
01276 }
01277 *objectExists=false;
01278 return 0;
01279 }
01280
01281 #ifdef _MSC_VER
01282 #pragma warning( pop )
01283 #endif
01284
01285 #endif // _RAKNET_SUPPORT_*