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

ConnectionGraph.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "NativeFeatureIncludes.h"
00008 #if _RAKNET_SUPPORT_ConnectionGraph==1
00009 
00010 #include "ConnectionGraph.h"
00011 #include "RakPeerInterface.h"
00012 #include "MessageIdentifiers.h"
00013 #include "BitStream.h"
00014 #include "StringCompressor.h"
00015 #include "GetTime.h"
00016 #include <string.h>
00017 #include "RakAssert.h"
00018 #include "SHA1.h"
00019 
00020 #ifdef _MSC_VER
00021 #pragma warning( push )
00022 #endif
00023 
00024 static const int connectionGraphChannel=31;
00025 
00026 ConnectionGraph::SystemAddressAndGroupId::SystemAddressAndGroupId()
00027 {
00028 
00029 }
00030 ConnectionGraph::SystemAddressAndGroupId::~SystemAddressAndGroupId()
00031 {
00032 
00033 }
00034 ConnectionGraph::SystemAddressAndGroupId::SystemAddressAndGroupId(SystemAddress _systemAddress, ConnectionGraphGroupID _groupID, RakNetGUID _guid)
00035 {
00036         systemAddress=_systemAddress;
00037         groupId=_groupID;
00038         guid=_guid;
00039 }
00040 bool ConnectionGraph::SystemAddressAndGroupId::operator==( const ConnectionGraph::SystemAddressAndGroupId& right ) const
00041 {
00042 // Use system address, because the router plugin takes system addresses in the send list, rather than guids
00043         return systemAddress==right.systemAddress;
00044 }
00045 bool ConnectionGraph::SystemAddressAndGroupId::operator!=( const ConnectionGraph::SystemAddressAndGroupId& right ) const
00046 {
00047         return systemAddress!=right.systemAddress;
00048 }
00049 bool ConnectionGraph::SystemAddressAndGroupId::operator > ( const ConnectionGraph::SystemAddressAndGroupId& right ) const
00050 {
00051         return systemAddress>right.systemAddress;
00052 }
00053 bool ConnectionGraph::SystemAddressAndGroupId::operator < ( const ConnectionGraph::SystemAddressAndGroupId& right ) const
00054 {
00055         return systemAddress<right.systemAddress;
00056 }
00057 ConnectionGraph::ConnectionGraph()
00058 {
00059     pw=0;
00060         myGroupId=0;
00061         autoAddNewConnections=true;
00062 //      forceBroadcastTime=0;
00063         DataStructures::WeightedGraph<ConnectionGraph::SystemAddressAndGroupId, unsigned short, false>::IMPLEMENT_DEFAULT_COMPARISON();
00064         DataStructures::OrderedList<SystemAddress, SystemAddress>::IMPLEMENT_DEFAULT_COMPARISON();
00065         DataStructures::OrderedList<ConnectionGraph::SystemAddressAndGroupId, ConnectionGraph::SystemAddressAndGroupId>::IMPLEMENT_DEFAULT_COMPARISON();
00066         DataStructures::OrderedList<ConnectionGraphGroupID, ConnectionGraphGroupID>::IMPLEMENT_DEFAULT_COMPARISON();
00067 
00068         subscribedGroups.Insert(0,0, true, __FILE__, __LINE__);
00069 }
00070 
00071 ConnectionGraph::~ConnectionGraph()
00072 {
00073         if (pw)
00074                 RakNet::OP_DELETE_ARRAY(pw, __FILE__, __LINE__);
00075 }
00076 
00077 void ConnectionGraph::SetPassword(const char *password)
00078 {
00079         if (pw)
00080         {
00081                 RakNet::OP_DELETE_ARRAY(pw, __FILE__, __LINE__);
00082                 pw=0;
00083         }
00084 
00085         if (password && password[0])
00086         {
00087                 RakAssert(strlen(password)<256);
00088                 pw=(char*) rakMalloc_Ex( strlen(password)+1, __FILE__, __LINE__ );
00089                 strcpy(pw, password);
00090         }
00091 }
00092 DataStructures::WeightedGraph<ConnectionGraph::SystemAddressAndGroupId, unsigned short, false> *ConnectionGraph::GetGraph(void)
00093 {
00094         return &graph;
00095 }
00096 void ConnectionGraph::SetAutoAddNewConnections(bool autoAdd)
00097 {
00098         autoAddNewConnections=autoAdd;
00099 }
00100 void ConnectionGraph::OnRakPeerShutdown(void)
00101 {
00102         graph.Clear();
00103         participantList.Clear(false, __FILE__, __LINE__);
00104 //      forceBroadcastTime=0;
00105 }
00106 void ConnectionGraph::Update(void)
00107 {
00108 
00109 //      RakNetTime time = RakNet::GetTime();
00110 
00111         // If the time is past the next weight update time, then refresh all pings of all connected participants and send these out if substantially different.
00112 //      if (forceBroadcastTime && time > forceBroadcastTime)
00113 //      {
00114 //              DataStructures::OrderedList<SystemAddress,SystemAddress> none;
00115         //      BroadcastGraphUpdate(none, peer);
00116 //              forceBroadcastTime=0;
00117 //      }
00118 }
00119 void ConnectionGraph::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
00120 {
00121         if (isIncoming==false)
00122         {
00123                 if (autoAddNewConnections==false)
00124                         return;
00125 
00126                 RequestConnectionGraph(systemAddress);
00127 
00128                 // 0 is the default groupId
00129                 AddNewConnection(rakPeerInterface, systemAddress, rakNetGUID, 0);
00130         }
00131         else
00132         {
00133                 if (autoAddNewConnections==false)
00134                         return;
00135 
00136                 // 0 is the default groupId
00137                 AddNewConnection(rakPeerInterface, systemAddress, rakNetGUID, 0);
00138         }
00139 }
00140 PluginReceiveResult ConnectionGraph::OnReceive(Packet *packet)
00141 {
00142         switch (packet->data[0]) 
00143         {
00144         case ID_CONNECTION_GRAPH_REQUEST:
00145                 OnConnectionGraphRequest(packet);
00146                 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00147         case ID_CONNECTION_GRAPH_REPLY:
00148                 OnConnectionGraphReply(packet);
00149                 return RR_CONTINUE_PROCESSING;
00150         case ID_CONNECTION_GRAPH_UPDATE:
00151                 OnConnectionGraphUpdate(packet);
00152                 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00153         case ID_CONNECTION_GRAPH_NEW_CONNECTION:
00154                 OnNewConnectionInternal(packet);
00155                 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00156                 // Remove connection lost
00157         case ID_CONNECTION_GRAPH_CONNECTION_LOST:
00158         case ID_CONNECTION_GRAPH_DISCONNECTION_NOTIFICATION:
00159                 if (OnConnectionLostInternal(packet, packet->data[0]))
00160                 {
00161                         if (packet->data[0]==ID_CONNECTION_GRAPH_CONNECTION_LOST)
00162                                 packet->data[0]=ID_REMOTE_CONNECTION_LOST;
00163                         else
00164                                 packet->data[0]=ID_REMOTE_DISCONNECTION_NOTIFICATION;
00165                         return RR_CONTINUE_PROCESSING; // Return this packet to the user
00166                 }               
00167                 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00168         }
00169 
00170         return RR_CONTINUE_PROCESSING;
00171 }
00172 void ConnectionGraph::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
00173 {
00174         (void) rakNetGUID;
00175 
00176         if (lostConnectionReason==LCR_CLOSED_BY_USER || lostConnectionReason==LCR_DISCONNECTION_NOTIFICATION)
00177                 HandleDroppedConnection(rakPeerInterface, systemAddress, ID_CONNECTION_GRAPH_DISCONNECTION_NOTIFICATION);
00178         else
00179                 HandleDroppedConnection(rakPeerInterface, systemAddress, ID_CONNECTION_GRAPH_CONNECTION_LOST);
00180 }
00181 
00182 void ConnectionGraph::HandleDroppedConnection(RakPeerInterface *peer, SystemAddress systemAddress, unsigned char packetId)
00183 {
00184         RakAssert(peer);
00185         RemoveParticipant(systemAddress);
00186         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00187         RemoveAndRelayConnection(ignoreList, packetId, systemAddress, peer->GetExternalID(systemAddress), peer);
00188 }
00189 void ConnectionGraph::SetGroupId(ConnectionGraphGroupID groupId)
00190 {
00191         myGroupId=groupId;
00192 }
00193 void ConnectionGraph::AddNewConnection(RakPeerInterface *peer, SystemAddress systemAddress, RakNetGUID guid, ConnectionGraphGroupID groupId)
00194 {
00195         if (autoAddNewConnections==false && subscribedGroups.HasData(groupId)==false)
00196                 return;
00197 
00198         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00199         
00200         SystemAddressAndGroupId first, second;
00201         first.systemAddress=systemAddress;
00202         first.groupId=groupId;
00203         first.guid=guid;
00204         second.systemAddress=peer->GetExternalID(systemAddress);
00205         second.groupId=myGroupId;
00206         second.guid=peer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
00207 
00208         AddAndRelayConnection(ignoreList, first, second, (unsigned short)peer->GetAveragePing(systemAddress), peer);
00209 }
00210 void ConnectionGraph::SubscribeToGroup(ConnectionGraphGroupID groupId)
00211 {
00212         subscribedGroups.Insert(groupId, groupId, true, __FILE__, __LINE__);
00213 }
00214 void ConnectionGraph::UnsubscribeFromGroup(ConnectionGraphGroupID groupId)
00215 {
00216         subscribedGroups.Remove(groupId);
00217 }
00218 void ConnectionGraph::RequestConnectionGraph(SystemAddress systemAddress)
00219 {
00220         RakNet::BitStream outBitstream;
00221         outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_REQUEST);
00222         stringCompressor->EncodeString(pw,256,&outBitstream);
00223         rakPeerInterface->Send(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, systemAddress, false);
00224 
00225 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00226         RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_REQUEST from %i to %i\n", peer->GetInternalID().port, systemAddress.port);
00227 #endif
00228 }
00229 void ConnectionGraph::OnConnectionGraphRequest(Packet *packet)
00230 {
00231         char password[256];
00232         RakNet::BitStream inBitstream(packet->data, packet->length, false);
00233         inBitstream.IgnoreBits(8);
00234         stringCompressor->DecodeString(password,256,&inBitstream);
00235         if (pw && pw[0] && strcmp(pw, password)!=0)
00236                 return;
00237 
00238 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00239         RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_REPLY ");
00240 #endif
00241 
00242         RakNet::BitStream outBitstream;
00243         outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_REPLY);
00244         stringCompressor->EncodeString(pw,256,&outBitstream);
00245         SerializeWeightedGraph(&outBitstream, graph);
00246         SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);
00247 
00248 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00249         RAKNET_DEBUG_PRINTF("from %i to %i\n", peer->GetInternalID().port, packet->systemAddress.port);
00250 #endif
00251 
00252         // Add packet->systemAddress to the participant list if it is not already there
00253         AddParticipant(packet->systemAddress);
00254 }
00255 void ConnectionGraph::OnConnectionGraphReply(Packet *packet)
00256 {
00257         unsigned char password[256];
00258         RakNet::BitStream inBitstream(packet->data, packet->length, false);
00259         inBitstream.IgnoreBits(8);
00260         stringCompressor->DecodeString((char*)password,256,&inBitstream);
00261         if (pw && pw[0] && strcmp(pw, (const char*)password)!=0)
00262                 return;
00263 
00264         // Serialize the weighted graph and send it to them
00265         RakNet::BitStream outBitstream;
00266         outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_UPDATE);
00267 
00268 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00269         RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_UPDATE ");
00270 #endif
00271 
00272         // Send our current graph to the sender
00273         SerializeWeightedGraph(&outBitstream, graph);
00274 
00275 
00276         // Write the systems that have processed this graph so we don't resend to these systems
00277         outBitstream.Write((unsigned short) 1);
00278         outBitstream.Write(rakPeerInterface->GetExternalID(packet->systemAddress));
00279 
00280 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00281         RAKNET_DEBUG_PRINTF("from %i to %i\n", peer->GetInternalID().port, packet->systemAddress.port);
00282 #endif
00283 
00284         SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);
00285 
00286         // Add packet->systemAddress to the participant list if it is not already there
00287         AddParticipant(packet->systemAddress);
00288 
00289         if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
00290                 return;
00291 
00292         // Forward the updated graph to all current participants
00293         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00294         ignoreList.Insert(packet->systemAddress,packet->systemAddress, true, __FILE__, __LINE__);
00295         BroadcastGraphUpdate(ignoreList, rakPeerInterface);
00296 }
00297 void ConnectionGraph::OnConnectionGraphUpdate(Packet *packet)
00298 {
00299         // Only accept from participants
00300         if (participantList.HasData(packet->systemAddress)==false)
00301                 return;
00302 
00303         RakNet::BitStream inBitstream(packet->data, packet->length, false);
00304         inBitstream.IgnoreBits(8);
00305         
00306         if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
00307                 return;
00308 
00309         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00310         DeserializeIgnoreList(ignoreList, &inBitstream);
00311 
00312         // Forward the updated graph to all participants.
00313         ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
00314         BroadcastGraphUpdate(ignoreList, rakPeerInterface);
00315 }
00316 void ConnectionGraph::OnNewConnectionInternal(Packet *packet)
00317 {
00318         // Only accept from participants
00319         if (participantList.HasData(packet->systemAddress)==false)
00320                 return;
00321 
00322         SystemAddressAndGroupId node1, node2;
00323         unsigned short ping;
00324         RakNet::BitStream inBitstream(packet->data, packet->length, false);
00325         inBitstream.IgnoreBits(8);
00326         inBitstream.Read(node1.systemAddress);
00327         inBitstream.Read(node1.groupId);
00328         inBitstream.Read(node1.guid);
00329         inBitstream.Read(node2.systemAddress);
00330         inBitstream.Read(node2.groupId);
00331         inBitstream.Read(node2.guid);
00332         if (inBitstream.Read(ping)==false)
00333                 return;
00334         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00335         DeserializeIgnoreList(ignoreList, &inBitstream);
00336         ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
00337         AddAndRelayConnection(ignoreList, node1, node2, ping, rakPeerInterface);        
00338 }
00339 bool ConnectionGraph::OnConnectionLostInternal(Packet *packet, unsigned char packetId)
00340 {
00341         // Only accept from participants
00342         if (participantList.HasData(packet->systemAddress)==false)
00343                 return false;
00344 
00345         SystemAddress node1, node2;
00346         RakNet::BitStream inBitstream(packet->data, packet->length, false);
00347         inBitstream.IgnoreBits(8);
00348         // This is correct - group IDs are not written for removal, only addition.
00349         inBitstream.Read(node1);
00350         if (inBitstream.Read(node2)==false)
00351                 return false;
00352         DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
00353         DeserializeIgnoreList(ignoreList, &inBitstream);
00354         ignoreList.Insert(packet->systemAddress, packet->systemAddress, false, __FILE__, __LINE__);
00355         
00356         return RemoveAndRelayConnection(ignoreList, packetId, node1, node2, rakPeerInterface);
00357 }
00358 bool ConnectionGraph::DeserializeIgnoreList(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, RakNet::BitStream *inBitstream )
00359 {
00360         unsigned short count;
00361         SystemAddress temp;
00362         unsigned i;
00363         inBitstream->Read(count);
00364         for (i=0; i < count; i++)
00365         {
00366                 if (inBitstream->Read(temp)==false)
00367                 {
00368                         RakAssert(0);
00369                         return false;
00370                 }
00371                 ignoreList.Insert(temp,temp, false, __FILE__, __LINE__);
00372         }
00373         return true;
00374 }
00375 void ConnectionGraph::SerializeWeightedGraph(RakNet::BitStream *out, const DataStructures::WeightedGraph<ConnectionGraph::SystemAddressAndGroupId, unsigned short, false> &g) const
00376 {
00377         unsigned nodeIndex, connectionIndex;
00378         BitSize_t countOffset, oldOffset;
00379         unsigned short count;
00380         SystemAddressAndGroupId node1, node2;
00381         unsigned short weight;
00382         out->WriteCompressed(g.GetNodeCount());
00383         for (nodeIndex=0; nodeIndex < g.GetNodeCount(); nodeIndex++)
00384         {
00385                 // Write the node
00386                 node1=g.GetNodeAtIndex(nodeIndex);
00387 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00388                 RAKNET_DEBUG_PRINTF("[%i] ", node1.systemAddress.port);
00389 #endif
00390                 out->Write(node1.systemAddress);
00391                 out->Write(node1.groupId);
00392                 out->Write(node1.guid);
00393 
00394                 // Write the adjacency list count
00395                 count=(unsigned short)g.GetConnectionCount(nodeIndex);
00396                 out->AlignWriteToByteBoundary();
00397                 countOffset=out->GetWriteOffset();
00398                 out->Write(count);
00399                 count=0;
00400                 for (connectionIndex=0; connectionIndex < g.GetConnectionCount(nodeIndex); connectionIndex++)
00401                 {
00402                         g.GetConnectionAtIndex(nodeIndex, connectionIndex, node2, weight);
00403                         // For efficiencies' sake, only serialize the upper half of the connection pairs
00404                         if (node2 > node1)
00405                         {
00406                                 count++;
00407                                 out->Write(node2.systemAddress);
00408                                 out->Write(node2.groupId);
00409                                 out->Write(node2.guid);
00410                                 out->Write(weight);
00411 
00412 #ifdef _CONNECTION_GRAPH_DEBUG_PRINT
00413                                 RAKNET_DEBUG_PRINTF("(%i) ", node2.systemAddress.port);
00414 #endif
00415                         }
00416                 }
00417 
00418                 // Go back and change how many elements were written
00419                 oldOffset=out->GetWriteOffset();
00420                 out->SetWriteOffset(countOffset);
00421                 out->Write(count);
00422                 out->SetWriteOffset(oldOffset);
00423         }
00424 }
00425 bool ConnectionGraph::DeserializeWeightedGraph(RakNet::BitStream *inBitstream, RakPeerInterface *peer)
00426 {
00427         unsigned nodeCount, nodeIndex, connectionIndex;
00428         unsigned short connectionCount;
00429         SystemAddressAndGroupId node, connection;
00430         bool anyConnectionsNew=false;
00431         unsigned short weight;
00432         inBitstream->ReadCompressed(nodeCount);
00433         for (nodeIndex=0; nodeIndex < nodeCount; nodeIndex++)
00434         {
00435                 inBitstream->Read(node.systemAddress);
00436                 inBitstream->Read(node.groupId);
00437                 inBitstream->Read(node.guid);
00438 
00439                 inBitstream->AlignReadToByteBoundary();
00440                 if (inBitstream->Read(connectionCount)==false)
00441                 {
00442                         RakAssert(0);
00443                         return false;
00444                 }
00445                 for (connectionIndex=0; connectionIndex < connectionCount; connectionIndex++)
00446                 {
00447                         inBitstream->Read(connection.systemAddress);
00448                         inBitstream->Read(connection.groupId);
00449                         inBitstream->Read(connection.guid);
00450                         if (inBitstream->Read(weight)==false)
00451                         {
00452                                 RakAssert(0);
00453                                 return false;
00454                         }
00455                         if (subscribedGroups.HasData(connection.groupId)==false ||
00456                                 subscribedGroups.HasData(node.groupId)==false)
00457                                 continue;
00458                         RakAssert(node.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00459                         RakAssert(connection.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00460                         if (IsNewRemoteConnection(node,connection,peer))
00461                                 NotifyUserOfRemoteConnection(node,connection,weight,peer);
00462 
00463                         if (graph.HasConnection(node,connection)==false)
00464                                 anyConnectionsNew=true;
00465 
00466                         graph.AddConnection(node,connection,weight);
00467                 }
00468         }
00469         return anyConnectionsNew;
00470 }
00471 void ConnectionGraph::RemoveParticipant(SystemAddress systemAddress)
00472 {
00473         unsigned index;
00474         bool objectExists;
00475         index=participantList.GetIndexFromKey(systemAddress, &objectExists);
00476         if (objectExists)
00477                 participantList.RemoveAtIndex(index);
00478 }
00479 
00480 void ConnectionGraph::AddParticipant(SystemAddress systemAddress)
00481 {
00482         participantList.Insert(systemAddress,systemAddress, false, __FILE__, __LINE__);
00483 }
00484 
00485 void ConnectionGraph::AddAndRelayConnection(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2, unsigned short ping, RakPeerInterface *peer)
00486 {
00487         if (graph.HasConnection(conn1,conn2))
00488                 return;
00489 
00490         if (ping==65535)
00491                 ping=0;
00492         RakAssert(conn1.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00493         RakAssert(conn2.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
00494 
00495         if (IsNewRemoteConnection(conn1,conn2,peer))
00496         {
00497                 NotifyUserOfRemoteConnection(conn1,conn2,ping,peer);
00498 
00499                 // What was this return here for?
00500         //      return;
00501         }
00502 
00503         graph.AddConnection(conn1,conn2,ping);
00504 
00505         RakNet::BitStream outBitstream;
00506         outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_NEW_CONNECTION);
00507         outBitstream.Write(conn1.systemAddress);
00508         outBitstream.Write(conn1.groupId);
00509         outBitstream.Write(conn1.guid);
00510         outBitstream.Write(conn2.systemAddress);
00511         outBitstream.Write(conn2.groupId);
00512         outBitstream.Write(conn2.guid);
00513         outBitstream.Write(ping);
00514         ignoreList.Insert(conn2.systemAddress,conn2.systemAddress, false, __FILE__, __LINE__);
00515         ignoreList.Insert(conn1.systemAddress,conn1.systemAddress, false, __FILE__, __LINE__);
00516         SerializeIgnoreListAndBroadcast(&outBitstream, ignoreList, peer);
00517 }
00518 bool ConnectionGraph::RemoveAndRelayConnection(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, unsigned char packetId, const SystemAddress node1, const SystemAddress node2, RakPeerInterface *peer)
00519 {
00520         SystemAddressAndGroupId n1, n2;
00521         n1.systemAddress=node1;
00522         n2.systemAddress=node2;
00523         if (graph.HasConnection(n1,n2)==false)
00524                 return false;
00525         graph.RemoveConnection(n1,n2);
00526 
00527         // TODO - clear islands
00528 
00529         RakNet::BitStream outBitstream;
00530         outBitstream.Write(packetId);
00531         outBitstream.Write(node1);
00532         outBitstream.Write(node2);
00533 
00534         ignoreList.Insert(node1,node1, false, __FILE__, __LINE__);
00535         ignoreList.Insert(node2,node2, false, __FILE__, __LINE__);
00536         SerializeIgnoreListAndBroadcast(&outBitstream, ignoreList, peer);
00537 
00538         return true;
00539 }
00540 
00541 void ConnectionGraph::BroadcastGraphUpdate(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, RakPeerInterface *peer)
00542 {
00543         RakNet::BitStream outBitstream;
00544         outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_UPDATE);
00545         SerializeWeightedGraph(&outBitstream, graph);
00546         SerializeIgnoreListAndBroadcast(&outBitstream, ignoreList, peer);
00547 }
00548 void ConnectionGraph::SerializeIgnoreListAndBroadcast(RakNet::BitStream *outBitstream, DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, RakPeerInterface *peer)
00549 {
00550         DataStructures::List<SystemAddress> sendList;
00551         unsigned i;
00552         for (i=0; i < participantList.Size(); i++)
00553         {
00554                 if (ignoreList.HasData(participantList[i])==false)
00555                         sendList.Insert(participantList[i], __FILE__, __LINE__);
00556         }
00557         if (sendList.Size()==0)
00558                 return;
00559 
00560         SystemAddress self = peer->GetExternalID(sendList[0]);
00561         ignoreList.Insert(self,self, false, __FILE__, __LINE__);
00562         outBitstream->Write((unsigned short) (ignoreList.Size()+sendList.Size()));
00563         for (i=0; i < ignoreList.Size(); i++)
00564                 outBitstream->Write(ignoreList[i]);
00565         for (i=0; i < sendList.Size(); i++)
00566                 outBitstream->Write(sendList[i]);
00567 
00568         for (i=0; i < sendList.Size(); i++)
00569         {
00570                 peer->Send(outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, sendList[i], false);
00571         }
00572 }
00573 bool ConnectionGraph::IsNewRemoteConnection(const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2,RakPeerInterface *peer)
00574 {
00575         if (graph.HasConnection(conn1,conn2)==false &&
00576                 subscribedGroups.HasData(conn1.groupId) &&
00577                 subscribedGroups.HasData(conn2.groupId) &&
00578                 (peer->IsConnected(conn1.systemAddress)==false || peer->IsConnected(conn2.systemAddress)==false))
00579         {
00580                 SystemAddress externalId1, externalId2;
00581                 externalId1=peer->GetExternalID(conn1.systemAddress);
00582                 externalId2=peer->GetExternalID(conn2.systemAddress);
00583                 return (externalId1!=conn1.systemAddress && externalId1!=conn2.systemAddress &&
00584                         externalId2!=conn1.systemAddress && externalId2!=conn2.systemAddress);
00585         }
00586         return false;
00587 }
00588 void ConnectionGraph::NotifyUserOfRemoteConnection(const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2,unsigned short ping, RakPeerInterface *peer)
00589 {
00590         // Create a packet to tell the user of this event
00591         static const int length=(const int) (sizeof(MessageID) + (SystemAddress::size() + sizeof(ConnectionGraphGroupID) + RakNetGUID::size()) * 2 + sizeof(unsigned short));
00592         Packet *p = peer->AllocatePacket(length);
00593         RakNet::BitStream b(p->data, length, false);
00594         p->bitSize=p->length*8;
00595         b.SetWriteOffset(0);
00596         b.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
00597         b.Write(conn1.systemAddress);
00598         b.Write(conn1.groupId);
00599         b.Write(conn1.guid);
00600         b.Write(conn2.systemAddress);
00601         b.Write(conn2.groupId);
00602         b.Write(conn2.guid);
00603         b.Write(ping);
00604         if (peer->IsConnected(conn2.systemAddress)==false)
00605         {
00606                 p->systemAddress=conn2.systemAddress;
00607                 p->guid=conn2.guid;
00608         }
00609         else
00610         {
00611                 p->systemAddress=conn1.systemAddress;
00612                 p->guid=conn1.guid;
00613         }
00614         peer->PushBackPacket(p, false);
00615 }
00616 
00617 #ifdef _MSC_VER
00618 #pragma warning( pop )
00619 #endif
00620 
00621 #endif // _RAKNET_SUPPORT_*

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