• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ReplicaManager2.cpp

Go to the documentation of this file.
00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_ReplicaManager2==1
00003 
00004 #include "ReplicaManager2.h"
00005 #include "MessageIdentifiers.h"
00006 #include "RakAssert.h"
00007 #include "RakPeerInterface.h"
00008 #include "NetworkIDManager.h"
00009 
00010 using namespace RakNet;
00011 
00012 unsigned char Replica2::clientSharedID=0;
00013 Replica2* Replica2::clientPtrArray[256];
00014 
00015 
00016 #ifdef _MSC_VER
00017 #pragma warning( push )
00018 #endif
00019 
00020 bool SerializationContext::IsSerializationCommand(SerializationType r)
00021 {
00022         return r>=SEND_SERIALIZATION_GENERIC_TO_SYSTEM && r<=RELAY_SERIALIZATION_TO_SYSTEMS;
00023 }
00024 bool SerializationContext::IsDownloadCommand(SerializationType r)
00025 {
00026         return r>=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM && r<=SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
00027 }
00028 bool SerializationContext::IsDestructionCommand(SerializationType r)
00029 {
00030         return r>=SEND_DESTRUCTION_GENERIC_TO_SYSTEM && r<=RELAY_DESTRUCTION_TO_SYSTEMS;
00031 }
00032 bool SerializationContext::IsConstructionCommand(SerializationType r)
00033 {
00034         return r>=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM && r<=SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT;
00035 }
00036 bool SerializationContext::IsVisibilityCommand(SerializationType r)
00037 {
00038         return r>=SEND_VISIBILITY_TRUE_TO_SYSTEM && r<=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
00039 }
00040 bool SerializationContext::IsVisible(SerializationType r)
00041 {
00042         return r==SEND_VISIBILITY_TRUE_TO_SYSTEM || r==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM || r==RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
00043 }
00044 
00045 int ReplicaManager2::Replica2CompByNetworkID( const NetworkID &key, RakNet::Replica2 * const &data )
00046 {
00047         if (key < data->GetNetworkID())
00048                 return -1;
00049         if (key == data->GetNetworkID())
00050                 return 0;
00051         return 1;
00052 }
00053 
00054 int ReplicaManager2::Replica2ObjectComp( RakNet::Replica2 * const &key, RakNet::Replica2 * const &data )
00055 {
00056         if (key->GetAllocationNumber()<data->GetAllocationNumber())
00057                 return -1;
00058         if (key->GetAllocationNumber()==data->GetAllocationNumber())
00059                 return 0;
00060         return 1;
00061 }
00062 
00063 int ReplicaManager2::Connection_RM2CompBySystemAddress( const SystemAddress &key, RakNet::Connection_RM2 * const &data )
00064 {
00065         if (key < data->GetSystemAddress())
00066                 return -1;
00067         if (key == data->GetSystemAddress())
00068                 return 0;
00069         return 1;
00070 }
00071 
00072 ReplicaManager2::ReplicaManager2()
00073 {
00074         connectionFactoryInterface=0;
00075         defaultOrderingChannel=0;
00076         defaultPacketPriority=HIGH_PRIORITY;
00077         defaultPacketReliablity=RELIABLE_ORDERED;
00078         autoUpdateConstruction=true;
00079         autoUpdateVisibility=true;
00080         autoAddNewConnections=true;
00081         doReplicaAutoUpdate=true;
00082         DataStructures::OrderedList<SystemAddress,SystemAddress>::IMPLEMENT_DEFAULT_COMPARISON();
00083 }
00084 ReplicaManager2::~ReplicaManager2()
00085 {
00086 }
00087 void ReplicaManager2::SendConstruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
00088                                                 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
00089                                                 unsigned char localClientId, SerializationType type, 
00090                                                 PacketPriority priority, PacketReliability reliability, char orderingChannel)
00091 {
00092         if (replica==0)
00093                 return;
00094 
00095         // Why would you request an object you already have?
00096         if (replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID && replica->QueryIsConstructionAuthority()==false)
00097                 return;
00098 
00099         if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
00100                 return;
00101 
00102         RakAssert(replica->QueryConstruction(0)!=BQR_NEVER);
00103 
00104         bool newConnection;
00105         Connection_RM2* connection;
00106 
00107         // Add to list of replicas if not already there
00108         bool newReference;
00109         Reference(replica, &newReference);
00110         
00111         RakNet::BitStream bs;
00112         WriteHeader(&bs, ID_REPLICA_MANAGER_CONSTRUCTION, timestamp);
00113         bs.Write((unsigned char) type);
00114         bs.Write(replica->GetNetworkID());
00115         bs.Write(localClientId);
00116         
00117         if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
00118         {
00119                 connection = AutoCreateConnection(recipient, &newConnection);
00120                 if (connection==0)
00121                         return;
00122 
00123                 if (newConnection)
00124                 {
00125                         // If a new connection, the replica was constructed automatically anyway
00126                         DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00127                         return;
00128                 }
00129 
00130                 if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
00131                         return;
00132                 bs.AlignWriteToByteBoundary();
00133                 bs.Write(replicaData);
00134 
00135                 // Lookup connection by target. If does not exist, create
00136                 
00137                 AddConstructionReference(connection, replica);
00138                 if (sendMessage)
00139                 {
00140                         // Send the packet
00141                         Send(&bs, recipient, priority, reliability, orderingChannel);
00142 
00143                         if (newReference && replica->QueryVisibility(connection)==BQR_ALWAYS)
00144                         {
00145 //                              SerializationContext sc;
00146 //                              sc.recipientAddress=recipient;
00147 //                              sc.timestamp=timestamp;
00148 //                              sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
00149 //                              sc.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
00150                                 replica->SendSerialize(recipient, SEND_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
00151                         }
00152                 }
00153         }
00154         else
00155         {
00156                 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
00157                 CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
00158                 WriteExclusionList(&bs, exclusionList);
00159                 bs.AlignWriteToByteBoundary();
00160                 bs.Write(replicaData);
00161 
00162                 unsigned i;
00163                 for (i=0; i < culledOutput.Size(); i++)
00164                 {
00165                         connection=culledOutput[i];
00166                         AddConstructionReference(connection, replica);
00167 
00168                         if (sendMessage)
00169                                 Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
00170 
00171                         if (newReference && replica->QueryIsSerializationAuthority() && replica->QueryVisibility(connection)==BQR_ALWAYS)
00172                         {
00173 //                              SerializationContext sc;
00174 //                              sc.recipientAddress=connection->GetSystemAddress();
00175 //                              sc.timestamp=0;
00176 //                              sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
00177 //                              sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
00178                                 replica->SendSerialize(connection->GetSystemAddress(), BROADCAST_SERIALIZATION_CONSTRUCTION_TO_SYSTEM);
00179                         }
00180                 }
00181         }       
00182 }
00183 
00184 void ReplicaManager2::SendDestruction(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp, bool sendMessage,
00185                                                 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
00186                                                 SerializationType type, 
00187                                                 PacketPriority priority, PacketReliability reliability, char orderingChannel)
00188 {
00189         if (replica==0)
00190                 return;
00191 
00192         if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
00193                 return;
00194 
00195         if (replica->QueryIsDestructionAuthority()==false)
00196                 return;
00197 
00198         if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
00199         {
00200                 bool newConnection;
00201 
00202                 // Lookup connection by target. If does not exist, create
00203                 Connection_RM2* connection = AutoCreateConnection(recipient, &newConnection);
00204                 if (connection==0)
00205                         return;
00206 
00207                 // Have this system stop referencing the replica object
00208                 connection->Deref(replica);
00209 
00210                 if (newConnection)
00211                 {
00212                         // If a new connection, the object didn't exist anyway
00213                         DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00214                         return;
00215                 }
00216         }
00217 
00218         if (sendMessage && replica->GetNetworkID()!=UNASSIGNED_NETWORK_ID)
00219         {
00220                 // Send the packet
00221                 RakNet::BitStream bs;
00222                 WriteHeader(&bs, ID_REPLICA_MANAGER_DESTRUCTION, timestamp);
00223                 bs.Write((unsigned char) type);
00224                 bs.Write(replica->GetNetworkID());
00225                 
00226                 if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
00227                 {
00228                         if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
00229                                 return;
00230                         bs.AlignWriteToByteBoundary();
00231                         bs.Write(replicaData);
00232 
00233                         Send(&bs, recipient, priority, reliability, orderingChannel);
00234                 }
00235                 else
00236                 {
00237                         DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
00238                         GetConnectionsWithReplicaConstructed(replica, output);
00239                         CullByAndAddToExclusionList(output, culledOutput, exclusionList);
00240                         WriteExclusionList(&bs, exclusionList);
00241                         bs.AlignWriteToByteBoundary();
00242                         bs.Write(replicaData);
00243 
00244                         unsigned i;
00245                         for (i=0; i < output.Size(); i++)
00246                                 Send(&bs, output[i]->GetSystemAddress(), priority, reliability, orderingChannel);
00247                 }
00248         }
00249 }
00250 
00251 void ReplicaManager2::SendSerialize(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
00252                                                 DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
00253                                                 SerializationType type, 
00254                                                  PacketPriority priority, PacketReliability reliability, char orderingChannel)
00255 {
00256         if (replica==0)
00257                 return;
00258 
00259         if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
00260                 return;
00261 
00262         if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
00263                 return;
00264 
00265         if (replica->QueryIsSerializationAuthority()==false)
00266                 return;
00267 
00268         // Add to list of replicas if not already there
00269         bool newReference;
00270         Reference(replica, &newReference);
00271 
00272         if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
00273         {
00274                 replica->BroadcastConstruction();
00275         }
00276 
00277         bool newConnection;
00278         Connection_RM2* connection;
00279 
00280         RakNet::BitStream bs;
00281         WriteHeader(&bs, ID_REPLICA_MANAGER_SERIALIZE, timestamp);
00282         bs.Write((unsigned char) type);
00283         bs.Write(replica->GetNetworkID());
00284 
00285         if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
00286         {
00287                 connection = AutoCreateConnection(recipient, &newConnection);
00288                 if (connection==0)
00289                         return;
00290                 if (newConnection)
00291                         DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00292 
00293                 if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
00294                         return;
00295                 bs.AlignWriteToByteBoundary();
00296                 bs.Write(replicaData);
00297 
00298                 // Send the packet
00299                 Send(&bs, recipient, priority, reliability, orderingChannel);
00300         }
00301         else
00302         {
00303                 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> output, culledOutput;
00304                 GetConnectionsWithSerializeVisibility(replica, output);
00305 
00306                 CullByAndAddToExclusionList(output, culledOutput, exclusionList);
00307                 WriteExclusionList(&bs, exclusionList);
00308                 bs.AlignWriteToByteBoundary();
00309                 bs.Write(replicaData);
00310 
00311                 unsigned i;
00312                 for (i=0; i < culledOutput.Size(); i++)
00313                 {
00314                         connection=culledOutput[i];     
00315                         Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
00316                 }
00317         }       
00318 }
00319 void ReplicaManager2::SendVisibility(Replica2 *replica, BitStream *replicaData, SystemAddress recipient, RakNetTime timestamp,
00320                                                          DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList,
00321                                                          SerializationType type, 
00322                                                          PacketPriority priority, PacketReliability reliability, char orderingChannel)
00323 {
00324         if (replica==0)
00325                 return;
00326 
00327         bool newConnection;
00328         Connection_RM2* connection;
00329 
00330         if (recipient==UNASSIGNED_SYSTEM_ADDRESS && connectionList.Size()==0)
00331                 return;
00332 
00333         if (replica->GetNetworkID()==UNASSIGNED_NETWORK_ID)
00334                 return;
00335 
00336         // Add to list of replicas if not already there
00337         bool newReference;
00338         Reference(replica, &newReference);
00339 
00340         if (newReference && replica->QueryConstruction(0)==BQR_ALWAYS)
00341         {
00342                 replica->BroadcastConstruction();
00343         }
00344 
00345         RakNet::BitStream bs;
00346         WriteHeader(&bs, ID_REPLICA_MANAGER_SCOPE_CHANGE, timestamp);
00347         bs.Write((unsigned char) type);
00348         bs.Write(replica->GetNetworkID());
00349 
00350         if (recipient!=UNASSIGNED_SYSTEM_ADDRESS)
00351         {
00352                 if (AddToAndWriteExclusionList(recipient, &bs, exclusionList)==false)
00353                         return;
00354 
00355                 connection = AutoCreateConnection(recipient, &newConnection);
00356                 if (connection==0)
00357                         return;
00358                 if (newConnection)
00359                         DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00360 
00361                 bs.AlignWriteToByteBoundary();
00362                 bs.Write(replicaData);
00363 
00364                 if (SerializationContext::IsVisibilityCommand(type))
00365                 {
00366                         if (SerializationContext::IsVisible(type))
00367                                 AddVisibilityReference(connection, replica);
00368                         else
00369                                 RemoveVisibilityReference(connection, replica);
00370                 }
00371                 // Send the packet
00372                 Send(&bs, recipient, priority, reliability, orderingChannel);
00373         }
00374         else
00375         {
00376                 DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
00377                 CullByAndAddToExclusionList(connectionList, culledOutput, exclusionList);
00378                 WriteExclusionList(&bs, exclusionList);
00379                 bs.AlignWriteToByteBoundary();
00380                 bs.Write(replicaData);
00381 
00382                 unsigned i;
00383                 for (i=0; i < culledOutput.Size(); i++)
00384                 {
00385                         connection=culledOutput[i];
00386                         if (SerializationContext::IsVisible(type))
00387                                 AddVisibilityReference(connection, replica);
00388                         else
00389                                 RemoveVisibilityReference(connection, replica);
00390                         Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
00391                 }
00392         }       
00393 }
00394 void ReplicaManager2::Dereference(Replica2 *replica)
00395 {
00396         unsigned i;
00397         if (replica==0)
00398                 return;
00399 
00400         for (i=0; i < connectionList.Size(); i++)
00401         {
00402                 connectionList[i]->lastConstructionList.RemoveIfExists(replica);
00403                 connectionList[i]->lastSerializationList.RemoveIfExists(replica);
00404         }
00405 
00406         for (i=0; i < fullReplicaUnorderedList.Size(); i++)
00407         {
00408                 if (fullReplicaUnorderedList[i]==replica)
00409                 {
00410                         fullReplicaUnorderedList.RemoveAtIndex(i);
00411                         break;
00412                 }
00413         }
00414 
00415         fullReplicaOrderedList.RemoveIfExists(replica);
00416         alwaysDoConstructReplicaOrderedList.RemoveIfExists(replica);
00417         alwaysDoSerializeReplicaOrderedList.RemoveIfExists(replica);
00418         variableConstructReplicaOrderedList.RemoveIfExists(replica);
00419         variableSerializeReplicaOrderedList.RemoveIfExists(replica);
00420 }
00421 void ReplicaManager2::Update(void)
00422 {
00423         unsigned i;
00424 
00425         if (autoUpdateConstruction || autoUpdateVisibility)
00426         {
00427                 for (i=0; i < connectionList.Size(); i++)
00428                 {
00429                         if (autoUpdateConstruction)
00430                                 connectionList[i]->SetConstructionByReplicaQuery(this);
00431                         if (autoUpdateVisibility)
00432                                 connectionList[i]->SetVisibilityByReplicaQuery(this);
00433                 }
00434         }
00435 
00436         if (doReplicaAutoUpdate)
00437         {
00438                 RakNetTime currentTime = RakNet::GetTime();
00439                 for (i=0; i < fullReplicaUnorderedList.Size(); i++)
00440                 {
00441                         fullReplicaUnorderedList[i]->ElapseAutoSerializeTimers(currentTime-lastUpdateTime,false);
00442                 }
00443                 lastUpdateTime=currentTime;
00444         }
00445 
00446 }
00447 unsigned ReplicaManager2::GetReplicaCount(void) const
00448 {
00449         return fullReplicaUnorderedList.Size();
00450 }
00451 Replica2 *ReplicaManager2::GetReplicaAtIndex(unsigned index)
00452 {
00453         return fullReplicaUnorderedList[index];
00454 }
00455 void ReplicaManager2::SetAutoAddNewConnections(bool autoDownload)
00456 {
00457         autoAddNewConnections=autoDownload;
00458 }
00459 void ReplicaManager2::SetDoReplicaAutoSerializeUpdate(bool autoUpdate)
00460 {
00461         doReplicaAutoUpdate=autoUpdate;
00462 }
00463 void ReplicaManager2::SetConnectionFactory(Connection_RM2Factory *factory)
00464 {
00465         RakAssert(factory);
00466         connectionFactoryInterface=factory;
00467 }
00468 unsigned ReplicaManager2::GetConnectionCount(void) const
00469 {
00470         return connectionList.Size();
00471 }
00472 Connection_RM2* ReplicaManager2::GetConnectionAtIndex(unsigned index) const
00473 {
00474         return connectionList[index];
00475 }
00476 Connection_RM2* ReplicaManager2::GetConnectionBySystemAddress(SystemAddress systemAddress) const
00477 {
00478         bool objectExists;
00479         unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
00480         if (objectExists)
00481                 return connectionList[index];
00482         return 0;
00483 }
00484 unsigned int ReplicaManager2::GetConnectionIndexBySystemAddress(SystemAddress systemAddress) const
00485 {
00486         bool objectExists;
00487         unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
00488         if (objectExists)
00489                 return index;
00490         return (unsigned int) -1;
00491 }
00492 void ReplicaManager2::SetDefaultOrderingChannel(char def)
00493 {
00494         defaultOrderingChannel=def;
00495 }
00496 void ReplicaManager2::SetDefaultPacketPriority(PacketPriority def)
00497 {
00498         defaultPacketPriority=def;
00499 }
00500 void ReplicaManager2::SetDefaultPacketReliability(PacketReliability def)
00501 {
00502         defaultPacketReliablity=def;
00503 }
00504 void ReplicaManager2::SetAutoUpdateScope(bool construction, bool visibility)
00505 {
00506         autoUpdateConstruction=construction;
00507         autoUpdateVisibility=visibility;
00508 }
00509 void ReplicaManager2::RecalculateVisibility(Replica2 *replica)
00510 {
00511         Dereference(replica);
00512         bool newReference;
00513         Reference(replica, &newReference);
00514 
00515         if (replica->QueryConstruction(0)==BQR_NEVER && autoUpdateConstruction)
00516         {
00517                 // Destroy on all systems
00518                 replica->SendDestruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_DESTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
00519         }
00520         if (replica->QueryConstruction(0)==BQR_ALWAYS && autoUpdateConstruction)
00521         {
00522                 // Create on all systems
00523                 replica->SendConstruction(UNASSIGNED_SYSTEM_ADDRESS, SEND_CONSTRUCTION_VISIBILITY_RECALCULATION_TO_SYSTEM);
00524         }
00525         if (replica->QueryVisibility(0)==BQR_ALWAYS && autoUpdateVisibility)
00526         {
00527                 // Set visibility and creation on all systems
00528                 replica->SendVisibility(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
00529                 replica->SendSerialize(UNASSIGNED_SYSTEM_ADDRESS, UNDEFINED_REASON);
00530         }
00531 }
00532 void ReplicaManager2::GetConnectionsWithReplicaConstructed(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
00533 {
00534         BooleanQueryResult res;
00535         res = replica->QueryConstruction(0);
00536         if (res==BQR_ALWAYS)
00537         {
00538                 output=connectionList;
00539         }
00540         else if (res!=BQR_NEVER)
00541         {
00542                 unsigned i;
00543                 for (i=0; i < connectionList.Size(); i++)
00544                 {
00545                         if (connectionList[i]->lastConstructionList.HasData(replica))
00546                                 output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false, __FILE__,__LINE__);
00547                 }
00548         }
00549 }
00550 void ReplicaManager2::GetConnectionsWithSerializeVisibility(Replica2 *replica, DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &output)
00551 {
00552         BooleanQueryResult res;
00553         res = replica->QueryVisibility(0);
00554         if (res==BQR_ALWAYS)
00555         {
00556                 GetConnectionsWithReplicaConstructed(replica, output);
00557         }
00558         else if (res!=BQR_NEVER)
00559         {
00560                 unsigned i;
00561                 for (i=0; i < connectionList.Size(); i++)
00562                 {
00563                         if (connectionList[i]->lastSerializationList.HasData(replica))
00564                                 output.Insert(connectionList[i]->GetSystemAddress(),connectionList[i], false, __FILE__,__LINE__);
00565                 }
00566         }
00567 }
00568 RakPeerInterface *ReplicaManager2::GetRakPeer(void) const
00569 {
00570         return rakPeerInterface;
00571 }
00572 Connection_RM2* ReplicaManager2::AutoCreateConnection(SystemAddress systemAddress, bool *newConnection)
00573 {
00574         if (autoAddNewConnections)
00575                 return CreateConnectionIfDoesNotExist(systemAddress, newConnection);
00576         else
00577         {
00578                 bool objectExists;
00579                 unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
00580                 *newConnection=false;
00581                 if (objectExists==false)
00582                 {
00583                         return 0;
00584                 }
00585                 return connectionList[index];
00586         }
00587 }
00588 Connection_RM2* ReplicaManager2::CreateConnectionIfDoesNotExist(SystemAddress systemAddress, bool *newConnection)
00589 {
00590         bool objectExists;
00591         unsigned index = connectionList.GetIndexFromKey(systemAddress, &objectExists);
00592         if (objectExists==false)
00593         {
00594                 // If it crashes here, you need to call SetConnection_RM2Factory
00595                 Connection_RM2 *connection = connectionFactoryInterface->AllocConnection();
00596                 connection->SetSystemAddress(systemAddress);
00597                 connection->SetGuid(rakPeerInterface->GetGuidFromSystemAddress(systemAddress));
00598                 connectionList.Insert(systemAddress, connection, false, __FILE__,__LINE__);
00599                 *newConnection=true;
00600                 return connection;
00601         }
00602         *newConnection=false;
00603         return connectionList[index];
00604 }
00605 bool ReplicaManager2::AddNewConnection(SystemAddress systemAddress)
00606 {
00607         bool newConnection;
00608         Connection_RM2* connection = CreateConnectionIfDoesNotExist(systemAddress, &newConnection);
00609         if (newConnection)
00610                 DownloadToNewConnection(connection, 0, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00611         return newConnection;
00612 }
00613 bool ReplicaManager2::RemoveConnection(SystemAddress systemAddress)
00614 {
00615         unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
00616         if (index!=(unsigned int) -1)
00617         {
00618                 connectionFactoryInterface->DeallocConnection(connectionList[index]);
00619                 connectionList.RemoveAtIndex(index);
00620                 return true;
00621         }
00622         return false;
00623 }
00624 bool ReplicaManager2::HasConnection(SystemAddress systemAddress)
00625 {
00626         unsigned int index = GetConnectionIndexBySystemAddress(systemAddress);
00627         return index!=(unsigned int) -1;
00628 }
00629 void ReplicaManager2::Reference(Replica2* replica, bool *newReference)
00630 {
00631         replica->SetReplicaManager(this);
00632 
00633         bool objectExists;
00634         unsigned index = fullReplicaOrderedList.GetIndexFromKey(replica,&objectExists);
00635         if (objectExists==false)
00636         {
00637                 fullReplicaUnorderedList.Insert(replica, __FILE__, __LINE__);
00638                 fullReplicaOrderedList.InsertAtIndex(replica, index, __FILE__,__LINE__);
00639 
00640                 BooleanQueryResult queryResult;
00641                 queryResult = replica->QueryConstruction(0);
00642                 if (queryResult==BQR_ALWAYS)
00643                         alwaysDoConstructReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
00644                 else if (queryResult!=BQR_NEVER)
00645                         variableConstructReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
00646                 queryResult = replica->QueryVisibility(0);
00647                 if (queryResult==BQR_ALWAYS)
00648                         alwaysDoSerializeReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
00649                 else if (queryResult!=BQR_NEVER)
00650                         variableSerializeReplicaOrderedList.Insert(replica,replica, false, __FILE__,__LINE__);
00651 
00652                 if (newReference)
00653                         *newReference=true;
00654 
00655                 return;
00656         }
00657         if (newReference)
00658                 *newReference=false;
00659 }
00660 void ReplicaManager2::AddConstructionReference(Connection_RM2* connection, Replica2* replica)
00661 {
00662         if (replica->QueryIsConstructionAuthority() && replica->QueryConstruction(0)!=BQR_ALWAYS && replica->QueryConstruction(0)!=BQR_NEVER)
00663                 connection->lastConstructionList.Insert(replica, replica, false, __FILE__,__LINE__);
00664 }
00665 void ReplicaManager2::AddVisibilityReference(Connection_RM2* connection, Replica2* replica)
00666 {
00667         if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
00668                 connection->lastSerializationList.Insert(replica, replica, false, __FILE__,__LINE__);
00669 }
00670 void ReplicaManager2::RemoveVisibilityReference(Connection_RM2* connection, Replica2* replica)
00671 {
00672         if (replica->QueryIsVisibilityAuthority() && replica->QueryVisibility(0)!=BQR_ALWAYS && replica->QueryVisibility(0)!=BQR_NEVER)
00673                 connection->lastSerializationList.RemoveIfExists(replica);
00674 }
00675 void ReplicaManager2::WriteHeader(RakNet::BitStream *bs, MessageID type, RakNetTime timestamp)
00676 {
00677         if (timestamp!=0)
00678         {
00679                 bs->Write((MessageID)ID_TIMESTAMP);
00680                 bs->Write(timestamp);
00681         }
00682         bs->Write(type);
00683 }
00684 void ReplicaManager2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
00685 {
00686         (void) systemAddress;
00687         (void) rakNetGUID;
00688         (void) lostConnectionReason;
00689 
00690         RemoveConnection(systemAddress);
00691 }
00692 void ReplicaManager2::OnRakPeerShutdown(void)
00693 {
00694         Clear();
00695 }
00696 void ReplicaManager2::OnAttach(void)
00697 {
00698         lastUpdateTime=RakNet::GetTime();
00699 }
00700 void ReplicaManager2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
00701 {
00702         (void) systemAddress;
00703         (void) rakNetGUID;
00704         (void) isIncoming;
00705 
00706         if (autoAddNewConnections)
00707                 AddNewConnection(systemAddress);
00708 }
00709 PluginReceiveResult ReplicaManager2::OnReceive(Packet *packet)
00710 {
00711         RakNetTime timestamp=0;
00712         unsigned char packetIdentifier, packetDataOffset;
00713         if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
00714         {
00715                 if ( packet->length > sizeof( unsigned char ) + sizeof( RakNetTime ) )
00716                 {
00717                         packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( RakNetTime ) ];
00718                         // Required for proper endian swapping
00719                         RakNet::BitStream tsBs(packet->data+sizeof(MessageID),packet->length-1,false);
00720                         tsBs.Read(timestamp);
00721                         packetDataOffset=sizeof( unsigned char )*2 + sizeof( RakNetTime );
00722                 }
00723                 else
00724                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00725         }
00726         else
00727         {
00728                 packetIdentifier = ( unsigned char ) packet->data[ 0 ];
00729                 packetDataOffset=sizeof( unsigned char );
00730         }
00731 
00732         switch (packetIdentifier)
00733         {
00734         case ID_REPLICA_MANAGER_DOWNLOAD_STARTED:
00735                 return OnDownloadStarted(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00736         case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
00737                 return OnDownloadComplete(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00738         case ID_REPLICA_MANAGER_CONSTRUCTION:
00739                 return OnConstruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00740         case ID_REPLICA_MANAGER_DESTRUCTION:
00741                 return OnDestruction(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00742         case ID_REPLICA_MANAGER_SCOPE_CHANGE:
00743                 return OnVisibilityChange(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00744         case ID_REPLICA_MANAGER_SERIALIZE:
00745                 return OnSerialize(packet->data+packetDataOffset, packet->length-packetDataOffset, packet->systemAddress, timestamp);
00746         }
00747 
00748         return RR_CONTINUE_PROCESSING;
00749 }
00750 PluginReceiveResult ReplicaManager2::OnDownloadStarted(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00751 {
00752         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00753         bool newConnection;
00754         Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
00755         if (connection==0)
00756                 return RR_CONTINUE_PROCESSING;
00757         SerializationType serializationType;
00758         unsigned char c;
00759         incomingBitstream.Read(c);
00760         serializationType=(SerializationType) c;
00761         incomingBitstream.AlignReadToByteBoundary();
00762         connection->DeserializeDownloadStarted(&incomingBitstream, sender, this, timestamp, serializationType);
00763 
00764         if (newConnection)
00765                 DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00766         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00767 }
00768 PluginReceiveResult ReplicaManager2::OnDownloadComplete(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00769 {
00770         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00771         bool newConnection;
00772         Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
00773         if (connection==0)
00774                 return RR_CONTINUE_PROCESSING;
00775         SerializationType serializationType;
00776         unsigned char c;
00777         incomingBitstream.Read(c);
00778         serializationType=(SerializationType) c;
00779         incomingBitstream.AlignReadToByteBoundary();
00780         connection->DeserializeDownloadComplete(&incomingBitstream, sender, this, timestamp, serializationType);
00781 
00782         if (newConnection)
00783                 DownloadToNewConnection(connection, timestamp, defaultPacketPriority, defaultPacketReliablity, defaultOrderingChannel);
00784         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00785 }
00786 
00787 PluginReceiveResult ReplicaManager2::OnConstruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00788 {
00789         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00790         bool newConnection;
00791         Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
00792         if (connection==0)
00793                 return RR_CONTINUE_PROCESSING;
00794         SerializationType serializationType;
00795         unsigned char c;
00796         incomingBitstream.Read(c);
00797         serializationType=(SerializationType) c;
00798         NetworkID networkId=UNASSIGNED_NETWORK_ID;
00799         unsigned char localClientId=255;
00800         bool success;
00801         incomingBitstream.Read(networkId);
00802         success=incomingBitstream.Read(localClientId);
00803         RakAssert(success);
00804 
00805         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
00806         ReadExclusionList(&incomingBitstream, exclusionList);
00807         exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
00808 
00809         Replica2* replica;
00810         // The prefix misaligns the data from the send, which is a problem if the user uses aligned data
00811         incomingBitstream.AlignReadToByteBoundary();
00812         replica = connection->ReceiveConstruct(&incomingBitstream, networkId, sender, localClientId, serializationType, this, timestamp,exclusionList);
00813         if (replica)
00814         {
00815                 // Register this object on this connection
00816                 AddConstructionReference(connection, replica);
00817         }
00818         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00819 }
00820 PluginReceiveResult ReplicaManager2::OnDestruction(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00821 {
00822         if (HasConnection(sender)==false)
00823                 return RR_CONTINUE_PROCESSING;
00824 
00825         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00826         SerializationType serializationType;
00827         unsigned char c;
00828         incomingBitstream.Read(c);
00829         serializationType=(SerializationType) c;
00830         NetworkID networkId;
00831         incomingBitstream.Read(networkId);
00832         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
00833         ReadExclusionList(&incomingBitstream, exclusionList);
00834         exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
00835         Replica2 * replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2*>( networkId );
00836         if (replica)
00837         {
00838                 // Verify that this is a registered object, so it actually is a Replica2
00839                 if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
00840                 {
00841                         // This object is not registered
00842                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00843                 }
00844 
00845                 // The prefix misaligns the data from the send, which is a problem if the user uses aligned data
00846                 incomingBitstream.AlignReadToByteBoundary();
00847                 replica->ReceiveDestruction(sender, &incomingBitstream, serializationType, timestamp,exclusionList );
00848         }
00849         // else this object is unknown
00850 
00851         
00852         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00853 }
00854 PluginReceiveResult ReplicaManager2::OnVisibilityChange(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00855 {
00856         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00857         bool newConnection;
00858         Connection_RM2* connection = AutoCreateConnection(sender, &newConnection);
00859         if (connection==0)
00860                 return RR_CONTINUE_PROCESSING;
00861         SerializationType serializationType;
00862         
00863         unsigned char c;
00864         incomingBitstream.Read(c);
00865         serializationType=(SerializationType) c;
00866         NetworkID networkId;
00867         incomingBitstream.Read(networkId);
00868         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
00869         ReadExclusionList(&incomingBitstream, exclusionList);
00870         exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
00871         
00872         Replica2 *replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
00873         if (replica)
00874         {
00875                 // Verify that this is a registered object, so it actually is a Replica2
00876                 if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
00877                 {
00878                         RakAssert(0);
00879                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00880                 }
00881 
00882                 // The prefix misaligns the data from the send, which is a problem if the user uses aligned data
00883                 incomingBitstream.AlignReadToByteBoundary();
00884                 replica->ReceiveVisibility(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
00885 
00886                 AddConstructionReference(connection, replica);
00887 
00888                 // Update the last known visibility list
00889                 if (SerializationContext::IsVisibilityCommand(serializationType))
00890                 {
00891                         if (SerializationContext::IsVisible(serializationType))
00892                                 AddVisibilityReference(connection, replica);
00893                         else
00894                                 RemoveVisibilityReference(connection, replica);
00895                 }
00896         }
00897         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00898 }
00899 PluginReceiveResult ReplicaManager2::OnSerialize(unsigned char *packetData, int packetDataLength, SystemAddress sender, RakNetTime timestamp)
00900 {
00901         RakNet::BitStream incomingBitstream(packetData, packetDataLength, false);
00902         Connection_RM2* connection = GetConnectionBySystemAddress(sender);
00903         if (connection==0)
00904                 return RR_CONTINUE_PROCESSING;
00905         SerializationType serializationType;
00906         unsigned char c;
00907         incomingBitstream.Read(c);
00908         serializationType=(SerializationType) c;
00909         NetworkID networkId;
00910         incomingBitstream.Read(networkId);
00911         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
00912         ReadExclusionList(&incomingBitstream, exclusionList);
00913         exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
00914 
00915         Replica2 *replica = rakPeerInterface->GetNetworkIDManager()->GET_OBJECT_FROM_ID<Replica2 *>( networkId );
00916         if (replica)
00917         {
00918                 // Verify that this is a registered object, so it actually is a Replica2
00919                 if (fullReplicaOrderedList.HasData((Replica2 *)replica)==false)
00920                 {
00921                         RakAssert(0);
00922                         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00923                 }
00924 
00925                 exclusionList.Insert(sender,sender, false, __FILE__,__LINE__);
00926 
00927                 // The prefix misaligns the data from the send, which is a problem if the user uses aligned data
00928                 incomingBitstream.AlignReadToByteBoundary();
00929                 replica->ReceiveSerialize(sender, &incomingBitstream, serializationType, timestamp,exclusionList);
00930 
00931                 AddConstructionReference(connection, replica);
00932         }
00933         return RR_STOP_PROCESSING_AND_DEALLOCATE;
00934 }
00935 bool ReplicaManager2::AddToAndWriteExclusionList(SystemAddress recipient, RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
00936 {
00937         if (exclusionList.HasData(recipient))
00938                 return false;
00939         exclusionList.Insert(recipient,recipient,true, __FILE__,__LINE__);
00940         WriteExclusionList(bs,exclusionList);
00941         return true;
00942 }
00943 void ReplicaManager2::WriteExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
00944 {
00945         bs->WriteCompressed(exclusionList.Size());
00946         for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionList.Size(); exclusionListIndex++ )
00947                 bs->Write(exclusionList[exclusionListIndex]);
00948 }
00949 
00950 void ReplicaManager2::CullByAndAddToExclusionList(
00951                                                                  DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &inputList,
00952                                                                  DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> &culledOutput,
00953                                                                  DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
00954 {
00955         Connection_RM2* connection;
00956         unsigned i;
00957         unsigned exclusionListIndex=0;
00958         for (i=0; i < inputList.Size(); i++)
00959         {
00960                 connection=inputList[i];
00961                 while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < connection->GetSystemAddress())
00962                         exclusionListIndex++;
00963                 if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==connection->GetSystemAddress())
00964                 {
00965                         exclusionListIndex++;
00966                         continue;
00967                 }
00968                 culledOutput.InsertAtEnd(connection, __FILE__,__LINE__);
00969         }
00970 
00971         for (i=0; i < culledOutput.Size(); i++)
00972                 exclusionList.Insert(culledOutput[i]->GetSystemAddress(),culledOutput[i]->GetSystemAddress(),true, __FILE__,__LINE__);
00973 }
00974 void ReplicaManager2::ReadExclusionList(RakNet::BitStream *bs, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
00975 {
00976         unsigned int exclusionListSize;
00977         bs->ReadCompressed(exclusionListSize);
00978         for (unsigned exclusionListIndex=0; exclusionListIndex < exclusionListSize; exclusionListIndex++)
00979         {
00980                 SystemAddress systemToExclude;
00981                 bs->Read(systemToExclude);
00982                 exclusionList.InsertAtEnd(systemToExclude, __FILE__,__LINE__);
00983         }
00984 }
00985 void ReplicaManager2::Send(RakNet::BitStream *bs, SystemAddress recipient, PacketPriority priority, PacketReliability reliability, char orderingChannel)
00986 {
00987         if (priority==NUMBER_OF_PRIORITIES)
00988                 priority=defaultPacketPriority;
00989         if (reliability==NUMBER_OF_RELIABILITIES)
00990                 reliability=defaultPacketReliablity;
00991         if (orderingChannel==-1)
00992                 orderingChannel=defaultOrderingChannel;
00993         SendUnified(bs, priority,reliability,orderingChannel,recipient,false);
00994 }
00995 void ReplicaManager2::Clear(void)
00996 {
00997         fullReplicaUnorderedList.Clear(false, __FILE__, __LINE__);
00998         fullReplicaOrderedList.Clear(false, __FILE__, __LINE__);
00999         alwaysDoConstructReplicaOrderedList.Clear(false, __FILE__, __LINE__);
01000         alwaysDoSerializeReplicaOrderedList.Clear(false, __FILE__, __LINE__);
01001         variableConstructReplicaOrderedList.Clear(false, __FILE__, __LINE__);
01002         variableSerializeReplicaOrderedList.Clear(false, __FILE__, __LINE__);
01003         unsigned i;
01004         for (i=0; i < connectionList.Size(); i++)
01005                 connectionFactoryInterface->DeallocConnection(connectionList[i]);
01006         connectionList.Clear(false, __FILE__, __LINE__);
01007 }
01008 void ReplicaManager2::DownloadToNewConnection(Connection_RM2* connection, RakNetTime timestamp, PacketPriority priority, PacketReliability reliability, char orderingChannel)
01009 {
01010         unsigned int i;
01011         RakNet::BitStream bs, bs2;
01012         BooleanQueryResult bqr;
01013         SystemAddress systemAddress = connection->GetSystemAddress();
01014         SerializationContext serializationContext;
01015         serializationContext.recipientAddress=systemAddress;
01016         serializationContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01017         serializationContext.serializationType=SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM;
01018         serializationContext.timestamp=0;
01019 
01020         // bs2 is so SerializeDownloadStarted can change the timestamp
01021         bs2.AlignWriteToByteBoundary();
01022         connection->SerializeDownloadStarted(&bs2, this, &serializationContext);
01023         WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_STARTED, timestamp);
01024         bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
01025         bs.Write(&bs2);
01026         Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
01027 
01028         DataStructures::List<Replica2*> initialDownloadList;
01029         DataStructures::List<Replica2*> culledDownloadList;
01030         connection->SortInitialDownload(fullReplicaUnorderedList, initialDownloadList);
01031 
01032         // Construct all objects before serializing them. This way the recipient will have valid NetworkID references.
01033         // Send all objects that always exist
01034         for (i=0; i < initialDownloadList.Size(); i++)
01035         {
01036                 if (initialDownloadList[i]->QueryIsConstructionAuthority())
01037                 {
01038                         bqr=initialDownloadList[i]->QueryConstruction(connection);
01039                         if (bqr==BQR_ALWAYS || bqr==BQR_YES)
01040                         {
01041                                 initialDownloadList[i]->SendConstruction(systemAddress, SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
01042                                 culledDownloadList.Insert(initialDownloadList[i], __FILE__, __LINE__ );
01043                         }
01044                         // Remember for this particular connection that we already sent this update to this system
01045                         if (bqr==BQR_YES)
01046                                 AddConstructionReference(connection, initialDownloadList[i]);
01047                 }
01048         }
01049 
01050         bool notVisible;
01051 
01052         // Send all objects that are always visible
01053         for (i=0; i < culledDownloadList.Size(); i++)
01054         {
01055                 notVisible=false;
01056                 if (culledDownloadList[i]->QueryIsVisibilityAuthority())
01057                 {
01058                         bqr=culledDownloadList[i]->QueryVisibility(connection);
01059                         if (bqr==BQR_ALWAYS || bqr==BQR_YES)
01060                         {
01061                                 culledDownloadList[i]->SendVisibility(systemAddress, SEND_VISIBILITY_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
01062                                 // Remember for this particular connection that we already sent this update to this system
01063                                 if (bqr==BQR_YES)
01064                                         AddVisibilityReference(connection, culledDownloadList[i]);
01065                         }
01066                         else
01067                                 notVisible=true;
01068                 }
01069 
01070                 if (culledDownloadList[i]->QueryIsSerializationAuthority() && notVisible==false)
01071                         culledDownloadList[i]->SendSerialize(systemAddress, SEND_DATA_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
01072         }
01073 
01074         bs.Reset();
01075         // bs2 is so SerializeDownloadComplete can change the timestamp
01076         bs2.AlignWriteToByteBoundary();
01077         connection->SerializeDownloadComplete(&bs2, this,&serializationContext);
01078         WriteHeader(&bs, ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE, timestamp);
01079         bs.Write((unsigned char) SEND_CONSTRUCTION_SERIALIZATION_AUTO_INITIAL_DOWNLOAD_TO_SYSTEM);
01080         bs.Write(&bs2);
01081         Send(&bs, connection->GetSystemAddress(), priority, reliability, orderingChannel);
01082 }
01083 Replica2::Replica2()
01084 {
01085         rm2=0;
01086         hasClientID=false;
01087 
01088         DataStructures::Map<SerializationType, AutoSerializeEvent*>::IMPLEMENT_DEFAULT_COMPARISON();
01089 }
01090 Replica2::~Replica2()
01091 {
01092         DereferenceFromDestruction();
01093 }
01094 
01095 void Replica2::SetReplicaManager(ReplicaManager2* rm)
01096 {
01097         rm2=rm;
01098         if (GetNetworkIDManager()==0)
01099                 SetNetworkIDManager(rm->GetRakPeer()->GetNetworkIDManager());
01100 }
01101 ReplicaManager2* Replica2::GetReplicaManager(void) const
01102 {
01103         return rm2;
01104 }
01105 bool Replica2::SerializeDestruction(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
01106 {
01107         (void) bitStream;
01108         (void) serializationContext;
01109 
01110         return true;
01111 }
01112 bool Replica2::Serialize(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
01113 {
01114         (void) bitStream;
01115         (void) serializationContext;
01116 
01117         return true;
01118 }
01119 bool Replica2::SerializeVisibility(RakNet::BitStream *bitStream, SerializationContext *serializationContext)
01120 {
01121         (void) bitStream;
01122         (void) serializationContext;
01123 
01124         return true;
01125 }
01126 void Replica2::DeserializeDestruction(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
01127 {
01128         (void) bitStream;
01129         (void) serializationType;
01130         (void) sender;
01131         (void) timestamp;
01132 
01133 }
01134 void Replica2::Deserialize(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
01135 {
01136         (void) bitStream;
01137         (void) serializationType;
01138         (void) sender;
01139         (void) timestamp;
01140 }
01141 void Replica2::DeserializeVisibility(RakNet::BitStream *bitStream, SerializationType serializationType, SystemAddress sender, RakNetTime timestamp)
01142 {
01143         (void) bitStream;
01144         (void) serializationType;
01145         (void) sender;
01146         (void) timestamp;
01147 }
01148 void Replica2::SendConstruction(SystemAddress recipientAddress, SerializationType serializationType)
01149 {
01150         RakNet::BitStream bs;
01151         SerializationContext defaultContext;
01152 
01153         if (serializationType==UNDEFINED_REASON)
01154         {
01155                 if (QueryIsConstructionAuthority()==false)
01156                         defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
01157                 else
01158                         defaultContext.serializationType=SEND_CONSTRUCTION_GENERIC_TO_SYSTEM;
01159         }
01160         else
01161                 defaultContext.serializationType=serializationType;
01162 
01163         defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01164         defaultContext.recipientAddress=recipientAddress;
01165         defaultContext.timestamp=0;
01166 
01167         unsigned char localId;
01168         if (QueryIsConstructionAuthority()==false)
01169         {
01170                 clientPtrArray[Replica2::clientSharedID]=this; 
01171                 localId=Replica2::clientSharedID++;
01172         }
01173         else
01174                 localId=0;
01175 
01176         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01177         // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
01178         bs.AlignWriteToByteBoundary();
01179         if (SerializeConstruction(&bs, &defaultContext))
01180                 rm2->SendConstruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,localId,defaultContext.serializationType);
01181 }
01182 void Replica2::SendDestruction(SystemAddress recipientAddress, SerializationType serializationType)
01183 {
01184         RakNet::BitStream bs;
01185         SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
01186 
01187         if (serializationType==UNDEFINED_REASON)
01188                 defaultContext.serializationType=SEND_DESTRUCTION_GENERIC_TO_SYSTEM;
01189 
01190         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01191         // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
01192         bs.AlignWriteToByteBoundary();
01193         if (SerializeDestruction(&bs, &defaultContext))
01194                 rm2->SendDestruction(this,&bs,recipientAddress,defaultContext.timestamp,true,exclusionList,defaultContext.serializationType);
01195 }
01196 void Replica2::SendSerialize(SystemAddress recipientAddress, SerializationType serializationType)
01197 {
01198         RakNet::BitStream bs;
01199         SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
01200 
01201         if (serializationType==UNDEFINED_REASON)
01202                 defaultContext.serializationType=SEND_SERIALIZATION_GENERIC_TO_SYSTEM;
01203 
01204         // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
01205         bs.AlignWriteToByteBoundary();
01206         if (Serialize(&bs, &defaultContext))
01207         {
01208                 DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01209                 rm2->SendSerialize(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
01210         }
01211 }
01212 void Replica2::SendVisibility(SystemAddress recipientAddress, SerializationType serializationType)
01213 {
01214         RakNet::BitStream bs;
01215         SerializationContext defaultContext(serializationType, UNASSIGNED_SYSTEM_ADDRESS, recipientAddress,0);
01216 
01217         if (serializationType==UNDEFINED_REASON)
01218                 defaultContext.serializationType=SEND_VISIBILITY_TRUE_TO_SYSTEM;
01219 
01220         // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
01221         bs.AlignWriteToByteBoundary();
01222         if (SerializeVisibility(&bs, &defaultContext))
01223         {
01224                 DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01225                 rm2->SendVisibility(this,&bs,recipientAddress,defaultContext.timestamp,exclusionList,defaultContext.serializationType);
01226         }
01227 }
01228 void Replica2::BroadcastSerialize(SerializationContext *serializationContext)
01229 {
01230         RakNet::BitStream bs;
01231         SerializationContext defaultContext(BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
01232         SerializationContext *usedContext;
01233         if (serializationContext)
01234                 usedContext=serializationContext;
01235         else
01236                 usedContext=&defaultContext;
01237 
01238         bool newReference;
01239         rm2->Reference(this, &newReference);
01240 
01241         // If this is a new object, then before sending serialization we should send construction to all systems
01242         if (newReference && QueryConstruction(0)==BQR_ALWAYS)
01243         {
01244                 BroadcastConstruction();
01245         }
01246 
01247         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01248         for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
01249         {
01250                 usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
01251                 if (usedContext->relaySourceAddress==usedContext->recipientAddress)
01252                         continue;
01253                 bs.Reset();
01254                 // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
01255                 bs.AlignWriteToByteBoundary();
01256                 if (Serialize(&bs, usedContext)==false)
01257                         continue;
01258                 exclusionList.Clear(false, __FILE__, __LINE__);
01259                 for (unsigned j=0; j < rm2->connectionList.Size(); j++)
01260                 {
01261                         if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
01262                                 exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
01263                 }
01264                 rm2->SendSerialize(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
01265         }
01266 }
01267 
01268 void Replica2::ReceiveSerialize(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
01269 {
01270         // Force all autoserialize timers to go off early, so any variable changes from the Deserialize event do not themselves trigger an autoserialize event
01271         ForceElapseAllAutoserializeTimers(false);
01272 
01273         // Deserialize the new data
01274         Deserialize(serializedObject, serializationType, sender, timestamp);
01275 
01276         // Update last values for all autoserialize timers
01277         ForceElapseAllAutoserializeTimers(true);
01278 
01279         SerializationContext serializationContext;
01280         serializationContext.serializationType=RELAY_SERIALIZATION_TO_SYSTEMS;
01281         serializationContext.timestamp=timestamp;
01282         serializationContext.relaySourceAddress=sender;
01283 
01284 
01285         BooleanQueryResult bqr;
01286         RakNet::BitStream bs;
01287         unsigned exclusionListIndex=0;
01288         for (unsigned i=0; i < rm2->connectionList.Size(); i++)
01289         {
01290                 serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
01291                 while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
01292                         exclusionListIndex++;
01293                 if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
01294                 {
01295                         exclusionListIndex++;
01296                         continue;
01297                 }
01298 
01299                 // Don't relay serializations if this object should not be visible
01300                 bqr=QueryVisibility(rm2->connectionList[i]);
01301                 if (bqr==BQR_NEVER || bqr==BQR_NO)
01302                         continue;
01303 
01304                 bs.Reset();
01305                 if (Serialize(&bs, &serializationContext)==false)
01306                         continue;
01307                 rm2->SendSerialize(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
01308         }
01309 }
01310 
01311 void Replica2::BroadcastConstruction(SerializationContext *serializationContext)
01312 {
01313         RakNet::BitStream bs;
01314         SerializationContext defaultContext(BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS,0);
01315         SerializationContext *usedContext;
01316         if (serializationContext)
01317                 usedContext=serializationContext;
01318         else
01319         {
01320                 usedContext=&defaultContext;
01321                 if (QueryIsConstructionAuthority()==false)
01322                         defaultContext.serializationType=SEND_CONSTRUCTION_REQUEST_TO_SERVER;
01323         }       
01324 
01325         bool newReference;
01326         rm2->Reference(this, &newReference);
01327 
01328         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01329 
01330         for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
01331         {
01332                 usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
01333                 if (usedContext->relaySourceAddress==usedContext->recipientAddress)
01334                         continue;
01335                 bs.Reset();
01336                 if (SerializeConstruction(&bs, usedContext)==false)
01337                         continue;
01338                 unsigned char localId;
01339                 if (QueryIsConstructionAuthority()==false)
01340                 {
01341                         clientPtrArray[Replica2::clientSharedID]=this;
01342                         localId=Replica2::clientSharedID++;
01343                 }
01344                 else
01345                         localId=0;
01346                 exclusionList.Clear(false, __FILE__, __LINE__);
01347                 for (unsigned j=0; j < rm2->connectionList.Size(); j++)
01348                 {
01349                         if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
01350                                 exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
01351                 }
01352                 rm2->SendConstruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList, localId, usedContext->serializationType);
01353         }
01354 
01355 
01356         bool notVisible=false;
01357         BooleanQueryResult bqr;
01358         bqr=QueryVisibility(0);
01359 
01360         if (bqr==BQR_ALWAYS)
01361                 BroadcastVisibility(true);
01362         else if (bqr==BQR_NEVER)
01363                 notVisible=true;
01364 
01365         if (notVisible==false)
01366                 BroadcastSerialize();
01367 }
01368 Replica2 * Replica2::ReceiveConstructionReply(SystemAddress sender, BitStream *replicaData, bool constructionAllowed)
01369 {
01370         (void) replicaData;
01371         (void) sender;
01372 
01373         if (constructionAllowed==false)
01374         {
01375                 //RakNet::OP_DELETE(this, __FILE__, __LINE__);
01376                 delete this;
01377                 return 0;
01378         }
01379 
01380         return this;
01381 }
01382 void Replica2::DereferenceFromDestruction(void)
01383 {
01384         if (rm2)
01385                 rm2->Dereference(this);
01386         if (hasClientID)
01387                 clientPtrArray[clientID]=0;
01388         ClearAutoSerializeTimers();
01389 }
01390 void Replica2::BroadcastDestruction(SerializationContext *serializationContext)
01391 {
01392         RakNet::BitStream bs;
01393         SerializationContext defaultContext(BROADCAST_DESTRUCTION_GENERIC_TO_SYSTEM, UNASSIGNED_SYSTEM_ADDRESS, UNASSIGNED_SYSTEM_ADDRESS, 0);
01394         SerializationContext *usedContext;
01395         if (serializationContext)
01396                 usedContext=serializationContext;
01397         else
01398                 usedContext=&defaultContext;
01399 
01400         DataStructures::OrderedList<SystemAddress, Connection_RM2*,ReplicaManager2::Connection_RM2CompBySystemAddress> culledOutput;
01401         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01402         rm2->CullByAndAddToExclusionList(rm2->connectionList, culledOutput, exclusionList);
01403 
01404         for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
01405         {
01406                 usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
01407                 if (usedContext->relaySourceAddress==usedContext->recipientAddress)
01408                         continue;
01409                 bs.Reset();
01410                 if (SerializeDestruction(&bs, usedContext)==false)
01411                         continue;
01412                 exclusionList.Clear(false, __FILE__, __LINE__);
01413                 for (unsigned j=0; j < rm2->connectionList.Size(); j++)
01414                 {
01415                         if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
01416                                 exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
01417                 }
01418                 rm2->SendDestruction(this,&bs,usedContext->recipientAddress,usedContext->timestamp,true,exclusionList,usedContext->serializationType);
01419         }
01420 }
01421 void Replica2::BroadcastVisibility(bool isVisible, SerializationContext *serializationContext)
01422 {
01423         RakNet::BitStream bs;
01424         SerializationContext defaultContext;
01425         SerializationContext *usedContext;
01426 
01427         if (serializationContext)
01428         {
01429                 usedContext=serializationContext;
01430         }
01431         else
01432         {
01433                 if (isVisible)
01434                         defaultContext.serializationType=BROADCAST_VISIBILITY_TRUE_TO_SYSTEM;
01435                 else
01436                         defaultContext.serializationType=BROADCAST_VISIBILITY_FALSE_TO_SYSTEM;
01437                 defaultContext.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01438                 defaultContext.timestamp=0;
01439                 usedContext=&defaultContext;
01440         }
01441 
01442         if ((QueryVisibility(0)==BQR_ALWAYS && isVisible==false) ||
01443                 (QueryVisibility(0)==BQR_NEVER && isVisible==true))
01444         {
01445                 // This doesn't make sense
01446                 RakAssert(0);
01447                 return;
01448         }
01449 
01450         bool newReference;
01451         rm2->Reference(this, &newReference);
01452 
01453         // If this is a new object, then before sending visibility we should send construction to all systems
01454         if (newReference && QueryConstruction(0)==BQR_ALWAYS)
01455         {
01456                 BroadcastConstruction();
01457         }
01458 
01459         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01460         for (unsigned i=0; i < rm2->GetConnectionCount(); i++)
01461         {
01462                 usedContext->recipientAddress=rm2->GetConnectionAtIndex(i)->GetSystemAddress();
01463                 if (usedContext->relaySourceAddress==usedContext->recipientAddress)
01464                         continue;
01465                 bs.Reset();
01466                 if (SerializeVisibility(&bs, usedContext)==false)
01467                         continue;
01468                 exclusionList.Clear(false, __FILE__, __LINE__);
01469                 for (unsigned j=0; j < rm2->connectionList.Size(); j++)
01470                 {
01471                         if (rm2->connectionList[j]->GetSystemAddress()!=usedContext->recipientAddress)
01472                                 exclusionList.InsertAtEnd(rm2->connectionList[j]->GetSystemAddress(), __FILE__,__LINE__);
01473                 }
01474                 rm2->SendVisibility(this,&bs,usedContext->recipientAddress,usedContext->timestamp,exclusionList,usedContext->serializationType);
01475         }
01476 
01477         if (newReference && QueryVisibility(0)==BQR_ALWAYS)
01478         {
01479                 BroadcastSerialize();
01480         }
01481 }
01482 
01483 void Replica2::ReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
01484 {
01485         DeserializeDestruction(serializedObject, serializationType, sender, timestamp);
01486 
01487         SerializationContext serializationContext;
01488         serializationContext.serializationType=RELAY_DESTRUCTION_TO_SYSTEMS;
01489         serializationContext.relaySourceAddress=sender;
01490         serializationContext.timestamp=0;
01491 
01492         RakNet::BitStream bs;
01493         unsigned exclusionListIndex=0;
01494         for (unsigned i=0; i < rm2->connectionList.Size(); i++)
01495         {
01496                 serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
01497 
01498                 while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
01499                         exclusionListIndex++;
01500                 if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
01501                 {
01502                         exclusionListIndex++;
01503                         continue;
01504                 }
01505 
01506                 bs.Reset();
01507                 if (SerializeDestruction(&bs, &serializationContext)==false)
01508                         continue;
01509                 rm2->SendDestruction(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList,serializationContext.serializationType);
01510         }
01511 
01512         DeleteOnReceiveDestruction(sender, serializedObject, serializationType, timestamp, exclusionList);
01513 }
01514 void Replica2::DeleteOnReceiveDestruction(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList )
01515 {
01516         (void) sender;
01517         (void) serializedObject;
01518         (void) serializationType;
01519         (void) timestamp;
01520         (void) exclusionList;
01521         //RakNet::OP_DELETE(this, __FILE__, __LINE__);
01522         delete this;
01523 }
01524 void Replica2::ReceiveVisibility(SystemAddress sender, RakNet::BitStream *serializedObject, SerializationType serializationType, RakNetTime timestamp, DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
01525 {
01526         DeserializeVisibility(serializedObject, serializationType, sender, timestamp);
01527 
01528         SerializationContext serializationContext;
01529         if (serializationType==SEND_VISIBILITY_TRUE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_TRUE_TO_SYSTEM)
01530                 serializationContext.serializationType=RELAY_VISIBILITY_TRUE_TO_SYSTEMS;
01531         else if (serializationType==SEND_VISIBILITY_FALSE_TO_SYSTEM || serializationType==BROADCAST_VISIBILITY_FALSE_TO_SYSTEM)
01532                 serializationContext.serializationType=RELAY_VISIBILITY_FALSE_TO_SYSTEMS;
01533         else
01534                 serializationContext.serializationType=serializationType;
01535         serializationContext.timestamp=timestamp;
01536         serializationContext.relaySourceAddress=sender;
01537 
01538         RakNet::BitStream bs;
01539         unsigned exclusionListIndex=0;
01540         for (unsigned i=0; i < rm2->connectionList.Size(); i++)
01541         {
01542                 serializationContext.recipientAddress=rm2->connectionList[i]->GetSystemAddress();
01543 
01544                 while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
01545                         exclusionListIndex++;
01546                 if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
01547                 {
01548                         exclusionListIndex++;
01549                         continue;
01550                 }
01551 
01552                 bs.Reset();
01553                 if (SerializeVisibility(&bs, &serializationContext)==false)
01554                         continue;
01555                 rm2->SendVisibility(this,&bs,serializationContext.recipientAddress,serializationContext.timestamp,exclusionList,serializationContext.serializationType);
01556         }
01557 }
01558 BooleanQueryResult Replica2::QueryConstruction(Connection_RM2 *connection)
01559 {
01560         (void) connection;
01561 
01562         return BQR_ALWAYS;
01563 }
01564 BooleanQueryResult Replica2::QueryVisibility(Connection_RM2 *connection)
01565 {
01566         (void) connection;
01567 
01568         return BQR_ALWAYS;
01569 }
01570 bool Replica2::QueryIsConstructionAuthority(void) const
01571 {
01572         return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
01573 }
01574 bool Replica2::QueryIsDestructionAuthority(void) const
01575 {
01576         return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
01577 }
01578 bool Replica2::QueryIsVisibilityAuthority(void) const
01579 {
01580         return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
01581 }
01582 bool Replica2::QueryIsSerializationAuthority(void) const
01583 {
01584         return rm2->GetRakPeer()->GetNetworkIDManager()->IsNetworkIDAuthority();
01585 }
01586 bool Replica2::AllowRemoteConstruction(SystemAddress sender, RakNet::BitStream *replicaData, SerializationType type, RakNetTime timestamp)
01587 {
01588         (void) sender;
01589         (void) replicaData;
01590         (void) type;
01591         (void) timestamp;
01592 
01593         return true;
01594 }
01595 void Replica2::ForceElapseAllAutoserializeTimers(bool resynchOnly)
01596 {
01597         ElapseAutoSerializeTimers(99999999, resynchOnly);
01598 }
01599 void Replica2::OnConstructionComplete(RakNet::BitStream *replicaData, SystemAddress sender, SerializationType type, ReplicaManager2 *replicaManager, RakNetTime timestamp, NetworkID networkId, bool networkIDCollision)
01600 {
01601         (void) replicaData;
01602         (void) sender;
01603         (void) type;
01604         (void) replicaManager;
01605         (void) timestamp;
01606         (void) networkId;
01607         (void) networkIDCollision;
01608 }
01609 void Replica2::ElapseAutoSerializeTimers(RakNetTime timeElapsed, bool resynchOnly)
01610 {
01611         AutoSerializeEvent* ase;
01612         unsigned i;
01613         for (i=0; i < autoSerializeTimers.Size(); i++)
01614         {
01615                 ase = autoSerializeTimers[i];
01616                 if (ase->remainingCountdown>timeElapsed)
01617                 {
01618                         ase->remainingCountdown-=timeElapsed;
01619                 }
01620                 else
01621                 {
01622                         ase->remainingCountdown=ase->initialCountdown;
01623 
01624                         RakNet::BitStream *lastWrite, *newWrite;
01625                         if (ase->writeToResult1)
01626                         {
01627                                 newWrite=&ase->lastAutoSerializeResult1;
01628                                 lastWrite=&ase->lastAutoSerializeResult2;
01629                         }
01630                         else
01631                         {
01632                                 newWrite=&ase->lastAutoSerializeResult2;
01633                                 lastWrite=&ase->lastAutoSerializeResult1;
01634                         }
01635                         newWrite->Reset();
01636                         OnAutoSerializeTimerElapsed(ase->serializationType,newWrite,lastWrite,ase->remainingCountdown, resynchOnly);
01637                         ase->writeToResult1=!ase->writeToResult1;
01638 
01639                 }
01640         }
01641 }
01642 void Replica2::OnAutoSerializeTimerElapsed(SerializationType serializationType, RakNet::BitStream *output, RakNet::BitStream *lastOutput, RakNetTime lastAutoSerializeCountdown, bool resynchOnly)
01643 {
01644         (void) lastAutoSerializeCountdown;
01645 
01646         SerializationContext context;
01647         if (resynchOnly)
01648                 context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
01649         else
01650                 context.serializationType=serializationType;
01651         context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01652         context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
01653         context.timestamp=0;
01654         if (Serialize(output, &context))
01655         {
01656                 if (resynchOnly==false &&
01657                         output->GetNumberOfBitsUsed()>0 &&
01658                         (output->GetNumberOfBitsUsed()!=lastOutput->GetNumberOfBitsUsed() ||
01659                         memcmp(output->GetData(), lastOutput->GetData(), (size_t) output->GetNumberOfBytesUsed())!=0))
01660                 {
01661                         BroadcastAutoSerialize(&context, output);
01662                 }
01663         }
01664 }
01665 void Replica2::BroadcastAutoSerialize(SerializationContext *serializationContext, RakNet::BitStream *serializedObject)
01666 {
01667         DataStructures::OrderedList<SystemAddress,SystemAddress> exclusionList;
01668         rm2->SendSerialize(this,serializedObject,UNASSIGNED_SYSTEM_ADDRESS, serializationContext->timestamp, exclusionList, BROADCAST_AUTO_SERIALIZE_TO_SYSTEM);
01669 }
01670 void Replica2::AddAutoSerializeTimer(RakNetTime interval, SerializationType serializationType, RakNetTime countdown )
01671 {
01672         if (countdown==(RakNetTime)-1)
01673                 countdown=interval;
01674         if (autoSerializeTimers.Has(serializationType))
01675         {
01676                 AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
01677                 if (interval==0)
01678                 {
01679                         // Elapse this timer immediately, then go back to initialCountdown
01680                         ase->remainingCountdown=ase->initialCountdown;
01681 
01682                         RakNet::BitStream *lastWrite, *newWrite;
01683                         if (ase->writeToResult1)
01684                         {
01685                                 newWrite=&ase->lastAutoSerializeResult1;
01686                                 lastWrite=&ase->lastAutoSerializeResult2;
01687                         }
01688                         else
01689                         {
01690                                 newWrite=&ase->lastAutoSerializeResult2;
01691                                 lastWrite=&ase->lastAutoSerializeResult1;
01692                         }
01693                         newWrite->Reset();
01694 
01695                         OnAutoSerializeTimerElapsed(serializationType,newWrite,lastWrite,ase->initialCountdown, false);
01696 
01697                         ase->remainingCountdown=ase->initialCountdown;
01698                 }
01699                 else
01700                 {
01701                         ase->initialCountdown=interval;
01702                         ase->remainingCountdown=countdown;
01703                 }
01704         }
01705         else
01706         {               
01707                 AutoSerializeEvent *ase = RakNet::OP_NEW<AutoSerializeEvent>( __FILE__, __LINE__ );
01708                 ase->serializationType=serializationType;
01709                 ase->initialCountdown=interval;
01710                 ase->remainingCountdown=countdown;
01711                 ase->writeToResult1=true;
01712 
01713                 SerializationContext context;
01714                 context.serializationType=AUTOSERIALIZE_RESYNCH_ONLY;
01715                 context.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01716                 context.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
01717                 context.timestamp=0;
01718                 Serialize(&ase->lastAutoSerializeResult2, &context);
01719 
01720                 autoSerializeTimers.Set(serializationType,ase);
01721         }
01722 }
01723 RakNetTime Replica2::GetTimeToNextAutoSerialize(SerializationType serializationType)
01724 {
01725         if (autoSerializeTimers.Has(serializationType))
01726         {
01727                 AutoSerializeEvent *ase = autoSerializeTimers.Get(serializationType);
01728                 return ase->remainingCountdown;
01729         }
01730         return (RakNetTime)-1;
01731 }
01732 void Replica2::CancelAutoSerializeTimer(SerializationType serializationType)
01733 {
01734         unsigned i=0;
01735         while (i < autoSerializeTimers.Size())
01736         {
01737                 if (autoSerializeTimers[i]->serializationType==serializationType)
01738                 {
01739                         RakNet::OP_DELETE(autoSerializeTimers[i], __FILE__, __LINE__);
01740                         autoSerializeTimers.RemoveAtIndex(i);
01741                 }
01742                 else
01743                         i++;
01744         }
01745 }
01746 void Replica2::ClearAutoSerializeTimers(void)
01747 {
01748         unsigned i;
01749         for (i=0; i < autoSerializeTimers.Size(); i++)
01750                 RakNet::OP_DELETE(autoSerializeTimers[i], __FILE__, __LINE__);
01751         autoSerializeTimers.Clear();
01752 }
01753 Connection_RM2::Connection_RM2()
01754 {
01755         rakNetGuid=UNASSIGNED_RAKNET_GUID;
01756         systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
01757 }
01758 Connection_RM2::~Connection_RM2()
01759 {
01760 }
01761 void Connection_RM2::SetConstructionByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &currentVisibility, ReplicaManager2 *replicaManager)
01762 {
01763         (void) replicaManager;
01764 
01765         DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentConstructionList, exclusiveToLastConstructionList;
01766         CalculateListExclusivity(currentVisibility, lastConstructionList, exclusiveToCurrentConstructionList, exclusiveToLastConstructionList);
01767 
01768         unsigned i;
01769         for (i=0; i < exclusiveToCurrentConstructionList.Size(); i++)
01770         {
01771                 // Construct
01772                 if (exclusiveToCurrentConstructionList[i]->QueryIsConstructionAuthority())
01773                 {
01774                         exclusiveToCurrentConstructionList[i]->SendConstruction(systemAddress);
01775                 //      lastConstructionList.Insert(exclusiveToCurrentConstructionList[i],exclusiveToCurrentConstructionList[i],true);
01776                 }
01777         }
01778 
01779         for (i=0; i < exclusiveToLastConstructionList.Size(); i++)
01780         {
01781                 // Destruction
01782                 if (exclusiveToLastConstructionList[i]->QueryIsDestructionAuthority())
01783                 {
01784                         exclusiveToLastConstructionList[i]->SendDestruction(systemAddress);
01785                         lastConstructionList.RemoveIfExists(exclusiveToLastConstructionList[i]);
01786                         lastSerializationList.RemoveIfExists(exclusiveToLastConstructionList[i]);
01787                 }
01788         }
01789 }
01790 void Connection_RM2::SetVisibilityByList(DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &currentVisibility, ReplicaManager2 *replicaManager)
01791 {
01792         (void) replicaManager;
01793 
01794         DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> exclusiveToCurrentSerializationList, exclusiveToLastSerializationList;
01795         CalculateListExclusivity(currentVisibility, lastSerializationList, exclusiveToCurrentSerializationList, exclusiveToLastSerializationList);
01796 
01797         unsigned i;
01798         for (i=0; i < exclusiveToCurrentSerializationList.Size(); i++)
01799         {
01800                 // In scope
01801                 if (exclusiveToCurrentSerializationList[i]->QueryIsVisibilityAuthority())
01802                 {
01803                         exclusiveToCurrentSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_TRUE_TO_SYSTEM);
01804                         exclusiveToCurrentSerializationList[i]->SendSerialize(systemAddress);
01805                 //      lastSerializationList.Insert(exclusiveToCurrentSerializationList[i],exclusiveToCurrentSerializationList[i], true);
01806                 }
01807         }
01808 
01809         for (i=0; i < exclusiveToLastSerializationList.Size(); i++)
01810         {
01811                 // Out of scope
01812                 if (exclusiveToLastSerializationList[i]->QueryIsVisibilityAuthority())
01813                 {
01814                         exclusiveToLastSerializationList[i]->SendVisibility(systemAddress,SEND_VISIBILITY_FALSE_TO_SYSTEM);
01815                         lastSerializationList.RemoveIfExists(exclusiveToLastSerializationList[i]);
01816                 }
01817         }
01818 }
01819 void Connection_RM2::CalculateListExclusivity(
01820                                                           const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listOne,
01821                                                           const DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &listTwo,
01822                                                           DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListOne, 
01823                                                           DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> &exclusiveToListTwo
01824                                                           ) const
01825 {
01826         int res;
01827         unsigned listOneIndex=0, listTwoIndex=0;
01828 
01829         while (listOneIndex<listOne.Size() && listTwoIndex < listTwo.Size())
01830         {
01831                 res = ReplicaManager2::Replica2ObjectComp(listOne[listOneIndex],listTwo[listTwoIndex]);
01832                 if (res<0)
01833                 {
01834                         exclusiveToListOne.InsertAtEnd(listOne[listOneIndex], __FILE__,__LINE__);
01835                         listOneIndex++;
01836                 }
01837                 else if (res>0)
01838                 {
01839                         exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex], __FILE__,__LINE__);
01840                         listTwoIndex++;
01841                 }
01842                 else
01843                 {
01844                         listOneIndex++;
01845                         listTwoIndex++;
01846                 }
01847         }
01848 
01849         while (listOneIndex<listOne.Size())
01850         {
01851                 exclusiveToListOne.InsertAtEnd(listOne[listOneIndex], __FILE__,__LINE__);
01852                 listOneIndex++;
01853         }
01854 
01855         while (listTwoIndex<listTwo.Size())
01856         {
01857                 exclusiveToListTwo.InsertAtEnd(listTwo[listTwoIndex], __FILE__,__LINE__);
01858                 listTwoIndex++;
01859         }
01860 }
01861 void Connection_RM2::SetConstructionByReplicaQuery(ReplicaManager2 *replicaManager)
01862 {
01863         DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> constructedObjects;
01864 
01865         unsigned i;
01866         BooleanQueryResult res;
01867         for (i=0; i < replicaManager->variableConstructReplicaOrderedList.Size(); i++)
01868         {
01869                 if (replicaManager->variableConstructReplicaOrderedList[i]->QueryIsConstructionAuthority())
01870                 {
01871                         res = replicaManager->variableConstructReplicaOrderedList[i]->QueryConstruction(this);
01872                         if (res==BQR_YES || res==BQR_ALWAYS) // TODO - optimize ALWAYS here
01873                                 constructedObjects.InsertAtEnd(replicaManager->variableConstructReplicaOrderedList[i], __FILE__,__LINE__);
01874                 }
01875         }
01876 
01877         SetConstructionByList(constructedObjects, replicaManager);
01878 }
01879 void Connection_RM2::SetVisibilityByReplicaQuery(ReplicaManager2 *replicaManager)
01880 {
01881         DataStructures::OrderedList<Replica2*, Replica2*, ReplicaManager2::Replica2ObjectComp> currentVisibility;
01882 
01883         unsigned i;
01884         BooleanQueryResult res;
01885         for (i=0; i < replicaManager->variableSerializeReplicaOrderedList.Size(); i++)
01886         {
01887                 if (replicaManager->variableSerializeReplicaOrderedList[i]->QueryIsVisibilityAuthority())
01888                 {
01889                         res = replicaManager->variableSerializeReplicaOrderedList[i]->QueryVisibility(this);
01890                         if (res==BQR_YES || res==BQR_ALWAYS) // TODO - optimize ALWAYS here
01891                                 currentVisibility.InsertAtEnd(replicaManager->variableSerializeReplicaOrderedList[i], __FILE__,__LINE__);
01892                 }
01893         }
01894 
01895         SetVisibilityByList(currentVisibility, replicaManager);
01896 }
01897 void Connection_RM2::SortInitialDownload( const DataStructures::List<Replica2*> &orderedDownloadList, DataStructures::List<Replica2*> &initialDownloadList ) {
01898                 initialDownloadList = orderedDownloadList;
01899 }
01900 void Connection_RM2::SerializeDownloadStarted(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
01901         (void) objectData;
01902         (void) replicaManager;
01903         (void) serializationContext;
01904 }
01905 void Connection_RM2::SerializeDownloadComplete(RakNet::BitStream *objectData, ReplicaManager2 *replicaManager, SerializationContext *serializationContext) {
01906         (void) objectData;
01907         (void) replicaManager;
01908         (void) serializationContext;
01909 }
01910 void Connection_RM2::DeserializeDownloadStarted(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
01911         (void) objectData;
01912         (void) sender;
01913         (void) replicaManager;
01914         (void) timestamp;
01915         (void) replicaManager;
01916         (void) serializationType;
01917 }
01918 void Connection_RM2::DeserializeDownloadComplete(RakNet::BitStream *objectData, SystemAddress sender, ReplicaManager2 *replicaManager, RakNetTime timestamp, SerializationType serializationType){
01919         (void) objectData;
01920         (void) sender;
01921         (void) replicaManager;
01922         (void) timestamp;
01923         (void) serializationType;
01924 }
01925 Replica2 * Connection_RM2::ReceiveConstruct(RakNet::BitStream *replicaData, NetworkID networkId, SystemAddress sender, unsigned char localClientId, SerializationType type,
01926                                         ReplicaManager2 *replicaManager, RakNetTime timestamp,
01927                                         DataStructures::OrderedList<SystemAddress,SystemAddress> &exclusionList)
01928 {
01929         Replica2 *obj=0;
01930 
01931         bool newReference=false;
01932         if (type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT || type==SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT)
01933         {
01934                 obj = Replica2::clientPtrArray[localClientId];
01935                 if (obj)
01936                 {
01937                         // The prefix misaligns the data from the send, which is a problem if the user uses aligned data
01938                         replicaData->AlignReadToByteBoundary();
01939                         obj = obj->ReceiveConstructionReply(sender, replicaData, type==SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
01940                         obj->SetNetworkID(networkId);
01941                         replicaManager->Reference(obj, &newReference);
01942                         replicaManager->AddConstructionReference(this,obj);
01943 
01944                         // The object could not be serialized before because it didn't have a NetworkID. So serialize it now.
01945                         if (obj->QueryIsSerializationAuthority() && (obj->QueryVisibility(this)==BQR_ALWAYS || obj->QueryVisibility(this)==BQR_YES))
01946                         {
01947                                 SerializationContext sc;
01948                                 sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
01949                                 sc.timestamp=timestamp;
01950                                 sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
01951                                 sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
01952                                 obj->BroadcastSerialize(&sc);
01953 
01954                                 replicaManager->AddVisibilityReference(this,obj);
01955                         }
01956                 }
01957         }
01958         else
01959         {
01960                 // Create locally send back reply
01961                 bool collision = replicaManager->GetRakPeer()->GetNetworkIDManager()->GET_OBJECT_FROM_ID<NetworkIDObject*>( networkId )!=0;
01962                 replicaData->AlignReadToByteBoundary();
01963                 obj = Construct(replicaData, sender, type, replicaManager, timestamp, networkId, collision);
01964                 if (obj)
01965                 {
01966                         replicaManager->Reference(obj, &newReference);
01967 
01968                         if (obj->AllowRemoteConstruction(sender, replicaData, type, timestamp)==false)
01969                         {
01970                                 if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
01971                                         obj->SendConstruction(sender, SEND_CONSTRUCTION_REPLY_DENIED_TO_CLIENT);
01972                                 //RakNet::OP_DELETE(obj, __FILE__, __LINE__);
01973                                 delete obj;
01974                                 obj=0;
01975                         }
01976                         else
01977                         {
01978                                 if (networkId!=UNASSIGNED_NETWORK_ID)
01979                                         obj->SetNetworkID(networkId);
01980 
01981                                 RakNet::BitStream bs;
01982                                 SerializationContext serializationContext;
01983                                 serializationContext.relaySourceAddress=sender;
01984                                 serializationContext.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
01985 
01986                                 if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
01987                                         serializationContext.serializationType=BROADCAST_CONSTRUCTION_REQUEST_ACCEPTED_TO_SYSTEM;
01988                                 else 
01989                                         serializationContext.serializationType=BROADCAST_CONSTRUCTION_GENERIC_TO_SYSTEM;
01990                                 exclusionList.Insert(sender,sender,false, __FILE__,__LINE__);
01991 
01992                                 unsigned exclusionListIndex=0;
01993                                 for (unsigned i=0; i < replicaManager->connectionList.Size(); i++)
01994                                 {
01995                                         serializationContext.recipientAddress=replicaManager->connectionList[i]->GetSystemAddress();
01996 
01997                                         while (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex] < serializationContext.recipientAddress)
01998                                                 exclusionListIndex++;
01999                                         if (exclusionListIndex < exclusionList.Size() && exclusionList[exclusionListIndex]==serializationContext.recipientAddress)
02000                                         {
02001                                                 exclusionListIndex++;
02002                                                 continue;
02003                                         }
02004 
02005                                         BooleanQueryResult queryConstruction = obj->QueryConstruction(0);
02006                                         if ( (queryConstruction==BQR_ALWAYS || queryConstruction==BQR_NEVER) &&
02007                                                 replicaManager->autoUpdateConstruction )
02008                                         {
02009                                                 // Relay autoUpdateConstruction is on, and the construction is not variable
02010                                                 bs.Reset();
02011                                                 if (obj->SerializeConstruction(&bs, &serializationContext)==false)
02012                                                         continue;
02013                                                 unsigned char localId;
02014                                                 if (obj->QueryIsConstructionAuthority()==false)
02015                                                         localId=Replica2::clientSharedID++;
02016                                                 else
02017                                                         localId=0;
02018                                                 replicaManager->SendConstruction(obj,&bs,serializationContext.recipientAddress,serializationContext.timestamp,true,exclusionList, localId, serializationContext.serializationType);
02019                                         }
02020                                 }
02021 
02022                                 if (type==SEND_CONSTRUCTION_REQUEST_TO_SERVER)
02023                                 {
02024                                         DataStructures::OrderedList<SystemAddress,SystemAddress> emptyList;
02025                                         // // The prefix misaligns the data for the send, which is a problem if the user uses aligned data
02026                                         bs.AlignWriteToByteBoundary();
02027                                         replicaManager->SendConstruction(obj, &bs, sender, timestamp, true,
02028                                                 emptyList, localClientId, SEND_CONSTRUCTION_REPLY_ACCEPTED_TO_CLIENT);
02029                                 }
02030 
02031                                 replicaData->AlignReadToByteBoundary();
02032                                 obj->OnConstructionComplete(replicaData, sender, type, replicaManager, timestamp, networkId, collision);
02033                         }
02034                 }
02035         }
02036 
02037         if (obj && newReference && obj->QueryIsSerializationAuthority() && obj->QueryVisibility(this)==BQR_ALWAYS)
02038         {
02039                 SerializationContext sc;
02040                 sc.recipientAddress=UNASSIGNED_SYSTEM_ADDRESS;
02041                 sc.timestamp=timestamp;
02042                 sc.relaySourceAddress=UNASSIGNED_SYSTEM_ADDRESS;
02043                 sc.serializationType=BROADCAST_SERIALIZATION_GENERIC_TO_SYSTEM;
02044                 obj->BroadcastSerialize(&sc);
02045         }
02046 
02047         return obj;
02048 }
02049 void Connection_RM2::SetSystemAddress(SystemAddress sa)
02050 {
02051         systemAddress=sa;
02052 }
02053 SystemAddress Connection_RM2::GetSystemAddress(void) const
02054 {
02055         return systemAddress;
02056 }
02057 void Connection_RM2::SetGuid(RakNetGUID guid)
02058 {
02059         rakNetGuid=guid;
02060 }
02061 RakNetGUID Connection_RM2::GetGuid(void) const
02062 {
02063         return rakNetGuid;
02064 }
02065 void Connection_RM2::Deref(Replica2* replica)
02066 {
02067         lastConstructionList.RemoveIfExists(replica);
02068         lastSerializationList.RemoveIfExists(replica);
02069 }
02070 
02071 #ifdef _MSC_VER
02072 #pragma warning( pop )
02073 #endif
02074 
02075 #endif // _RAKNET_SUPPORT_*

Generated on Thu Sep 30 2010 01:27:27 for RakNet by  doxygen 1.7.1