ConnectionGraph2.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "NativeFeatureIncludes.h"
  11. #if _RAKNET_SUPPORT_ConnectionGraph2==1
  12. #include "ConnectionGraph2.h"
  13. #include "RakPeerInterface.h"
  14. #include "MessageIdentifiers.h"
  15. #include "BitStream.h"
  16. using namespace RakNet;
  17. STATIC_FACTORY_DEFINITIONS(ConnectionGraph2,ConnectionGraph2)
  18. int RakNet::ConnectionGraph2::RemoteSystemComp( const RakNetGUID &key, RemoteSystem * const &data )
  19. {
  20. if (key < data->guid)
  21. return -1;
  22. if (key > data->guid)
  23. return 1;
  24. return 0;
  25. }
  26. int RakNet::ConnectionGraph2::SystemAddressAndGuidComp( const SystemAddressAndGuid &key, const SystemAddressAndGuid &data )
  27. {
  28. if (key.guid<data.guid)
  29. return -1;
  30. if (key.guid>data.guid)
  31. return 1;
  32. return 0;
  33. }
  34. ConnectionGraph2::ConnectionGraph2()
  35. {
  36. autoProcessNewConnections=true;
  37. }
  38. ConnectionGraph2::~ConnectionGraph2()
  39. {
  40. }
  41. bool ConnectionGraph2::GetConnectionListForRemoteSystem(RakNetGUID remoteSystemGuid, SystemAddress *saOut, RakNetGUID *guidOut, unsigned int *outLength)
  42. {
  43. if ((saOut==0 && guidOut==0) || outLength==0 || *outLength==0 || remoteSystemGuid==UNASSIGNED_RAKNET_GUID)
  44. {
  45. *outLength=0;
  46. return false;
  47. }
  48. bool objectExists;
  49. unsigned int idx = remoteSystems.GetIndexFromKey(remoteSystemGuid, &objectExists);
  50. if (objectExists==false)
  51. {
  52. *outLength=0;
  53. return false;
  54. }
  55. unsigned int idx2;
  56. if (remoteSystems[idx]->remoteConnections.Size() < *outLength)
  57. *outLength=remoteSystems[idx]->remoteConnections.Size();
  58. for (idx2=0; idx2 < *outLength; idx2++)
  59. {
  60. if (guidOut)
  61. guidOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].guid;
  62. if (saOut)
  63. saOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].systemAddress;
  64. }
  65. return true;
  66. }
  67. bool ConnectionGraph2::ConnectionExists(RakNetGUID g1, RakNetGUID g2)
  68. {
  69. if (g1==g2)
  70. return false;
  71. bool objectExists;
  72. unsigned int idx = remoteSystems.GetIndexFromKey(g1, &objectExists);
  73. if (objectExists==false)
  74. {
  75. return false;
  76. }
  77. SystemAddressAndGuid sag;
  78. sag.guid=g2;
  79. return remoteSystems[idx]->remoteConnections.HasData(sag);
  80. }
  81. uint16_t ConnectionGraph2::GetPingBetweenSystems(RakNetGUID g1, RakNetGUID g2) const
  82. {
  83. if (g1==g2)
  84. return 0;
  85. if (g1==rakPeerInterface->GetMyGUID())
  86. return (uint16_t) rakPeerInterface->GetAveragePing(g2);
  87. if (g2==rakPeerInterface->GetMyGUID())
  88. return (uint16_t) rakPeerInterface->GetAveragePing(g1);
  89. bool objectExists;
  90. unsigned int idx = remoteSystems.GetIndexFromKey(g1, &objectExists);
  91. if (objectExists==false)
  92. {
  93. return (uint16_t) -1;
  94. }
  95. SystemAddressAndGuid sag;
  96. sag.guid=g2;
  97. unsigned int idx2 = remoteSystems[idx]->remoteConnections.GetIndexFromKey(sag, &objectExists);
  98. if (objectExists==false)
  99. {
  100. return (uint16_t) -1;
  101. }
  102. return remoteSystems[idx]->remoteConnections[idx2].sendersPingToThatSystem;
  103. }
  104. /// Returns the system with the lowest total ping among all its connections. This can be used as the 'best host' for a peer to peer session
  105. RakNetGUID ConnectionGraph2::GetLowestAveragePingSystem(void) const
  106. {
  107. float lowestPing=-1.0;
  108. unsigned int lowestPingIdx=(unsigned int) -1;
  109. float thisAvePing=0.0f;
  110. unsigned int idx, idx2;
  111. int ap, count=0;
  112. for (idx=0; idx<remoteSystems.Size(); idx++)
  113. {
  114. thisAvePing=0.0f;
  115. ap = rakPeerInterface->GetAveragePing(remoteSystems[idx]->guid);
  116. if (ap!=-1)
  117. {
  118. thisAvePing+=(float) ap;
  119. count++;
  120. }
  121. }
  122. if (count>0)
  123. {
  124. lowestPing=thisAvePing/count;
  125. }
  126. for (idx=0; idx<remoteSystems.Size(); idx++)
  127. {
  128. thisAvePing=0.0f;
  129. count=0;
  130. RemoteSystem *remoteSystem = remoteSystems[idx];
  131. for (idx2=0; idx2 < remoteSystem->remoteConnections.Size(); idx2++)
  132. {
  133. ap=remoteSystem->remoteConnections[idx2].sendersPingToThatSystem;
  134. if (ap!=-1)
  135. {
  136. thisAvePing+=(float) ap;
  137. count++;
  138. }
  139. }
  140. if (count>0 && (lowestPing==-1.0f || thisAvePing/count < lowestPing))
  141. {
  142. lowestPing=thisAvePing/count;
  143. lowestPingIdx=idx;
  144. }
  145. }
  146. if (lowestPingIdx==(unsigned int) -1)
  147. return rakPeerInterface->GetMyGUID();
  148. return remoteSystems[lowestPingIdx]->guid;
  149. }
  150. void ConnectionGraph2::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
  151. {
  152. // Send notice to all existing connections
  153. RakNet::BitStream bs;
  154. if (lostConnectionReason==LCR_CONNECTION_LOST)
  155. bs.Write((MessageID)ID_REMOTE_CONNECTION_LOST);
  156. else
  157. bs.Write((MessageID)ID_REMOTE_DISCONNECTION_NOTIFICATION);
  158. bs.Write(systemAddress);
  159. bs.Write(rakNetGUID);
  160. SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
  161. bool objectExists;
  162. unsigned int idx = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
  163. if (objectExists)
  164. {
  165. RakNet::OP_DELETE(remoteSystems[idx],_FILE_AND_LINE_);
  166. remoteSystems.RemoveAtIndex(idx);
  167. }
  168. }
  169. void ConnectionGraph2::SetAutoProcessNewConnections(bool b)
  170. {
  171. autoProcessNewConnections=b;
  172. }
  173. bool ConnectionGraph2::GetAutoProcessNewConnections(void) const
  174. {
  175. return autoProcessNewConnections;
  176. }
  177. void ConnectionGraph2::AddParticipant(const SystemAddress &systemAddress, RakNetGUID rakNetGUID)
  178. {
  179. // Relay the new connection to other systems.
  180. RakNet::BitStream bs;
  181. bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
  182. bs.Write((uint32_t)1);
  183. bs.Write(systemAddress);
  184. bs.Write(rakNetGUID);
  185. bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(rakNetGUID));
  186. SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
  187. // Send everyone to the new guy
  188. DataStructures::List<SystemAddress> addresses;
  189. DataStructures::List<RakNetGUID> guids;
  190. rakPeerInterface->GetSystemList(addresses, guids);
  191. bs.Reset();
  192. bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
  193. BitSize_t writeOffset = bs.GetWriteOffset();
  194. bs.Write((uint32_t) addresses.Size());
  195. unsigned int i;
  196. uint32_t count=0;
  197. for (i=0; i < addresses.Size(); i++)
  198. {
  199. if (addresses[i]==systemAddress)
  200. continue;
  201. bs.Write(addresses[i]);
  202. bs.Write(guids[i]);
  203. bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(guids[i]));
  204. count++;
  205. }
  206. if (count>0)
  207. {
  208. BitSize_t writeOffset2 = bs.GetWriteOffset();
  209. bs.SetWriteOffset(writeOffset);
  210. bs.Write(count);
  211. bs.SetWriteOffset(writeOffset2);
  212. SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
  213. }
  214. bool objectExists;
  215. unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
  216. if (objectExists==false)
  217. {
  218. RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(_FILE_AND_LINE_);
  219. remoteSystem->guid=rakNetGUID;
  220. remoteSystems.InsertAtIndex(remoteSystem,ii,_FILE_AND_LINE_);
  221. }
  222. }
  223. void ConnectionGraph2::GetParticipantList(DataStructures::OrderedList<RakNetGUID, RakNetGUID> &participantList)
  224. {
  225. participantList.Clear(true, _FILE_AND_LINE_);
  226. unsigned int i;
  227. for (i=0; i < remoteSystems.Size(); i++)
  228. participantList.InsertAtEnd(remoteSystems[i]->guid, _FILE_AND_LINE_);
  229. }
  230. void ConnectionGraph2::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
  231. {
  232. (void) isIncoming;
  233. if (autoProcessNewConnections)
  234. AddParticipant(systemAddress, rakNetGUID);
  235. }
  236. PluginReceiveResult ConnectionGraph2::OnReceive(Packet *packet)
  237. {
  238. if (packet->data[0]==ID_REMOTE_CONNECTION_LOST || packet->data[0]==ID_REMOTE_DISCONNECTION_NOTIFICATION)
  239. {
  240. bool objectExists;
  241. unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
  242. if (objectExists)
  243. {
  244. RakNet::BitStream bs(packet->data,packet->length,false);
  245. bs.IgnoreBytes(1);
  246. SystemAddressAndGuid saag;
  247. bs.Read(saag.systemAddress);
  248. bs.Read(saag.guid);
  249. unsigned long idx2 = remoteSystems[idx]->remoteConnections.GetIndexFromKey(saag, &objectExists);
  250. if (objectExists)
  251. remoteSystems[idx]->remoteConnections.RemoveAtIndex(idx2);
  252. }
  253. }
  254. else if (packet->data[0]==ID_REMOTE_NEW_INCOMING_CONNECTION)
  255. {
  256. bool objectExists;
  257. unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
  258. if (objectExists)
  259. {
  260. uint32_t numAddresses;
  261. RakNet::BitStream bs(packet->data,packet->length,false);
  262. bs.IgnoreBytes(1);
  263. bs.Read(numAddresses);
  264. for (unsigned int idx2=0; idx2 < numAddresses; idx2++)
  265. {
  266. SystemAddressAndGuid saag;
  267. bs.Read(saag.systemAddress);
  268. bs.Read(saag.guid);
  269. bs.Read(saag.sendersPingToThatSystem);
  270. bool objectExists;
  271. unsigned int ii = remoteSystems[idx]->remoteConnections.GetIndexFromKey(saag, &objectExists);
  272. if (objectExists==false)
  273. remoteSystems[idx]->remoteConnections.InsertAtIndex(saag,ii,_FILE_AND_LINE_);
  274. }
  275. }
  276. }
  277. return RR_CONTINUE_PROCESSING;
  278. }
  279. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号