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
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
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
00105 }
00106 void ConnectionGraph::Update(void)
00107 {
00108
00109
00110
00111
00112
00113
00114
00115
00116
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
00129 AddNewConnection(rakPeerInterface, systemAddress, rakNetGUID, 0);
00130 }
00131 else
00132 {
00133 if (autoAddNewConnections==false)
00134 return;
00135
00136
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
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;
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
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
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
00273 SerializeWeightedGraph(&outBitstream, graph);
00274
00275
00276
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
00287 AddParticipant(packet->systemAddress);
00288
00289 if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
00290 return;
00291
00292
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
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
00313 ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
00314 BroadcastGraphUpdate(ignoreList, rakPeerInterface);
00315 }
00316 void ConnectionGraph::OnNewConnectionInternal(Packet *packet)
00317 {
00318
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
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
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
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
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
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
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
00500
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
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
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_*