Lobby2Client_Steam_Impl.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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 "Lobby2Client_Steam_Impl.h"
  11. #include "Lobby2Message_Steam.h"
  12. #include <stdlib.h>
  13. #include "NativeTypes.h"
  14. #include "MTUSize.h"
  15. #include <windows.h>
  16. using namespace RakNet;
  17. STATIC_FACTORY_DEFINITIONS(Lobby2Client_Steam,Lobby2Client_Steam_Impl)
  18. DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS(Lobby2Message,uint64_t,requestId);
  19. int Lobby2Client_Steam_Impl::SystemAddressAndRoomMemberComp( const SystemAddress &key, const Lobby2Client_Steam_Impl::RoomMember &data )
  20. {
  21. if (key<data.systemAddress)
  22. return -1;
  23. if (key==data.systemAddress)
  24. return 0;
  25. return 1;
  26. }
  27. int Lobby2Client_Steam_Impl::SteamIDAndRoomMemberComp( const uint64_t &key, const Lobby2Client_Steam_Impl::RoomMember &data )
  28. {
  29. if (key<data.steamIDRemote)
  30. return -1;
  31. if (key==data.steamIDRemote)
  32. return 0;
  33. return 1;
  34. }
  35. Lobby2Client_Steam_Impl::Lobby2Client_Steam_Impl() :
  36. m_CallbackLobbyDataUpdated( this, &Lobby2Client_Steam_Impl::OnLobbyDataUpdatedCallback ),
  37. m_CallbackPersonaStateChange( this, &Lobby2Client_Steam_Impl::OnPersonaStateChange ),
  38. m_CallbackLobbyDataUpdate( this, &Lobby2Client_Steam_Impl::OnLobbyDataUpdate ),
  39. m_CallbackChatDataUpdate( this, &Lobby2Client_Steam_Impl::OnLobbyChatUpdate ),
  40. m_CallbackChatMessageUpdate( this, &Lobby2Client_Steam_Impl::OnLobbyChatMessage ),
  41. m_CallbackP2PSessionRequest( this, &Lobby2Client_Steam_Impl::OnP2PSessionRequest ),
  42. m_CallbackP2PSessionConnectFail( this, &Lobby2Client_Steam_Impl::OnP2PSessionConnectFail )
  43. {
  44. // Must recompile RakNet with MAXIMUM_MTU_SIZE set to 1200 in the preprocessor settings
  45. RakAssert(MAXIMUM_MTU_SIZE<=1200);
  46. roomId=0;
  47. }
  48. Lobby2Client_Steam_Impl::~Lobby2Client_Steam_Impl()
  49. {
  50. }
  51. void Lobby2Client_Steam_Impl::SendMsg(Lobby2Message *msg)
  52. {
  53. if (msg->ClientImpl(this))
  54. {
  55. for (unsigned long i=0; i < callbacks.Size(); i++)
  56. {
  57. if (msg->callbackId==(uint32_t)-1 || msg->callbackId==callbacks[i]->callbackId)
  58. msg->CallCallback(callbacks[i]);
  59. }
  60. }
  61. else
  62. {
  63. // Won't be deleted by the user's call to Deref.
  64. msg->resultCode=L2RC_PROCESSING;
  65. msg->AddRef();
  66. PushDeferredCallback(msg);
  67. }
  68. }
  69. void Lobby2Client_Steam_Impl::Update(void)
  70. {
  71. SteamAPI_RunCallbacks();
  72. /*
  73. // sending data
  74. // must be a handle to a connected socket
  75. // data is all sent via UDP, and thus send sizes are limited to 1200 bytes; after this, many routers will start dropping packets
  76. // use the reliable flag with caution; although the resend rate is pretty aggressive,
  77. // it can still cause stalls in receiving data (like TCP)
  78. virtual bool SendDataOnSocket( SNetSocket_t hSocket, void *pubData, uint32 cubData, bool bReliable ) = 0;
  79. // receiving data
  80. // returns false if there is no data remaining
  81. // fills out *pcubMsgSize with the size of the next message, in bytes
  82. virtual bool IsDataAvailableOnSocket( SNetSocket_t hSocket, uint32 *pcubMsgSize ) = 0;
  83. // fills in pubDest with the contents of the message
  84. // messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
  85. // if *pcubMsgSize < cubDest, only partial data is written
  86. // returns false if no data is available
  87. virtual bool RetrieveDataFromSocket( SNetSocket_t hSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize ) = 0;
  88. */
  89. }
  90. void Lobby2Client_Steam_Impl::PushDeferredCallback(Lobby2Message *msg)
  91. {
  92. deferredCallbacks.Push(msg, msg->requestId, _FILE_AND_LINE_ );
  93. }
  94. void Lobby2Client_Steam_Impl::CallCBWithResultCode(Lobby2Message *msg, Lobby2ResultCode rc)
  95. {
  96. if (msg)
  97. {
  98. msg->resultCode=rc;
  99. for (unsigned long i=0; i < callbacks.Size(); i++)
  100. {
  101. if (msg->callbackId==(uint32_t)-1 || msg->callbackId==callbacks[i]->callbackId)
  102. msg->CallCallback(callbacks[i]);
  103. }
  104. }
  105. }
  106. void Lobby2Client_Steam_Impl::OnLobbyMatchListCallback( LobbyMatchList_t *pCallback, bool bIOFailure )
  107. {
  108. (void) bIOFailure;
  109. uint32_t i;
  110. for (i=0; i < deferredCallbacks.GetSize(); i++)
  111. {
  112. // Get any instance of Console_SearchRooms
  113. if (deferredCallbacks[i]->GetID()==L2MID_Console_SearchRooms)
  114. {
  115. Console_SearchRooms_Steam *callbackResult = (Console_SearchRooms_Steam *) deferredCallbacks[i];
  116. // iterate the returned lobbies with GetLobbyByIndex(), from values 0 to m_nLobbiesMatching-1
  117. // lobbies are returned in order of closeness to the user, so add them to the list in that order
  118. for ( uint32 iLobby = 0; iLobby < pCallback->m_nLobbiesMatching; iLobby++ )
  119. {
  120. CSteamID steamId = SteamMatchmaking()->GetLobbyByIndex( iLobby );
  121. callbackResult->roomIds.Push(steamId.ConvertToUint64(), _FILE_AND_LINE_ );
  122. RakNet::RakString s = SteamMatchmaking()->GetLobbyData( steamId, "name" );
  123. callbackResult->roomNames.Push(s, _FILE_AND_LINE_ );
  124. }
  125. CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
  126. msgFactory->Dealloc(callbackResult);
  127. deferredCallbacks.RemoveAtIndex(i);
  128. break;
  129. }
  130. }
  131. }
  132. void Lobby2Client_Steam_Impl::OnLobbyDataUpdatedCallback( LobbyDataUpdate_t *pCallback )
  133. {
  134. uint32_t i;
  135. for (i=0; i < deferredCallbacks.GetSize(); i++)
  136. {
  137. if (deferredCallbacks[i]->GetID()==L2MID_Console_GetRoomDetails)
  138. {
  139. Console_GetRoomDetails_Steam *callbackResult = (Console_GetRoomDetails_Steam *) deferredCallbacks[i];
  140. if (callbackResult->roomId==pCallback->m_ulSteamIDLobby)
  141. {
  142. const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( pCallback->m_ulSteamIDLobby, "name" );
  143. if ( pchLobbyName[0] )
  144. {
  145. callbackResult->roomName=pchLobbyName;
  146. }
  147. if (pCallback->m_bSuccess)
  148. CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
  149. else
  150. CallCBWithResultCode(callbackResult, L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND);
  151. msgFactory->Dealloc(callbackResult);
  152. deferredCallbacks.RemoveAtIndex(i);
  153. break;
  154. }
  155. }
  156. }
  157. Console_GetRoomDetails_Steam notification;
  158. const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( pCallback->m_ulSteamIDLobby, "name" );
  159. if ( pchLobbyName[0] )
  160. {
  161. notification.roomName=pchLobbyName;
  162. }
  163. notification.roomId=pCallback->m_ulSteamIDLobby;
  164. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  165. }
  166. void Lobby2Client_Steam_Impl::OnLobbyCreated( LobbyCreated_t *pCallback, bool bIOFailure )
  167. {
  168. (void) bIOFailure;
  169. uint32_t i;
  170. for (i=0; i < deferredCallbacks.GetSize(); i++)
  171. {
  172. if (deferredCallbacks[i]->GetID()==L2MID_Console_CreateRoom)
  173. {
  174. Console_CreateRoom_Steam *callbackResult = (Console_CreateRoom_Steam *) deferredCallbacks[i];
  175. callbackResult->roomId=pCallback->m_ulSteamIDLobby;
  176. SteamMatchmaking()->SetLobbyData( callbackResult->roomId, "name", callbackResult->roomName.C_String() );
  177. roomId=pCallback->m_ulSteamIDLobby;
  178. printf("\nNumber of Steam Lobby Members:%i in Lobby Name:%s\n", SteamMatchmaking()->GetNumLobbyMembers(roomId), callbackResult->roomName.C_String());
  179. RoomMember roomMember;
  180. roomMember.steamIDRemote=SteamMatchmaking()->GetLobbyOwner(roomId).ConvertToUint64();
  181. roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
  182. roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
  183. roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
  184. roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
  185. callbackResult->extendedResultCode=pCallback->m_eResult;
  186. if (pCallback->m_eResult==k_EResultOK)
  187. {
  188. CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
  189. }
  190. else
  191. {
  192. CallCBWithResultCode(callbackResult, L2RC_GENERAL_ERROR);
  193. }
  194. msgFactory->Dealloc(callbackResult);
  195. deferredCallbacks.RemoveAtIndex(i);
  196. // Commented out: Do not send the notification for yourself
  197. // CallRoomCallbacks();
  198. break;
  199. }
  200. }
  201. }
  202. void Lobby2Client_Steam_Impl::OnLobbyJoined( LobbyEnter_t *pCallback, bool bIOFailure )
  203. {
  204. (void) bIOFailure;
  205. uint32_t i;
  206. for (i=0; i < deferredCallbacks.GetSize(); i++)
  207. {
  208. if (deferredCallbacks[i]->GetID()==L2MID_Console_JoinRoom)
  209. {
  210. Console_JoinRoom_Steam *callbackResult = (Console_JoinRoom_Steam *) deferredCallbacks[i];
  211. if (pCallback->m_EChatRoomEnterResponse==k_EChatRoomEnterResponseSuccess)
  212. {
  213. roomId=pCallback->m_ulSteamIDLobby;
  214. CallCBWithResultCode(callbackResult, L2RC_SUCCESS);
  215. // First push to prevent being notified of ourselves
  216. RoomMember roomMember;
  217. roomMember.steamIDRemote=SteamUser()->GetSteamID().ConvertToUint64();
  218. roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
  219. roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
  220. roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
  221. roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
  222. CallRoomCallbacks();
  223. // In case the asynch lobby update didn't get it fast enough
  224. uint64_t myId64=SteamUser()->GetSteamID().ConvertToUint64();
  225. if (roomMembersById.HasData(myId64)==false)
  226. {
  227. roomMember.steamIDRemote=SteamMatchmaking()->GetLobbyOwner(roomId).ConvertToUint64();
  228. roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
  229. roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
  230. roomMembersByAddr.Insert(roomMember.systemAddress,roomMember,true,_FILE_AND_LINE_);
  231. roomMembersById.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
  232. }
  233. }
  234. else
  235. {
  236. CallCBWithResultCode(callbackResult, L2RC_Console_JoinRoom_NO_SUCH_ROOM);
  237. }
  238. msgFactory->Dealloc(callbackResult);
  239. deferredCallbacks.RemoveAtIndex(i);
  240. break;
  241. }
  242. }
  243. }
  244. bool Lobby2Client_Steam_Impl::IsCommandRunning( Lobby2MessageID msgId )
  245. {
  246. uint32_t i;
  247. for (i=0; i < deferredCallbacks.GetSize(); i++)
  248. {
  249. if (deferredCallbacks[i]->GetID()==msgId)
  250. {
  251. return true;
  252. }
  253. }
  254. return false;
  255. }
  256. void Lobby2Client_Steam_Impl::OnPersonaStateChange( PersonaStateChange_t *pCallback )
  257. {
  258. // callbacks are broadcast to all listeners, so we'll get this for every friend who changes state
  259. // so make sure the user is in the lobby before acting
  260. if ( !SteamFriends()->IsUserInSource( pCallback->m_ulSteamID, roomId ) )
  261. return;
  262. if ((pCallback->m_nChangeFlags & k_EPersonaChangeNameFirstSet) ||
  263. (pCallback->m_nChangeFlags & k_EPersonaChangeName))
  264. {
  265. Notification_Friends_StatusChange_Steam notification;
  266. notification.friendId=pCallback->m_ulSteamID;
  267. const char *pchName = SteamFriends()->GetFriendPersonaName( notification.friendId );
  268. notification.friendNewName=pchName;
  269. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  270. }
  271. }
  272. void Lobby2Client_Steam_Impl::OnLobbyDataUpdate( LobbyDataUpdate_t *pCallback )
  273. {
  274. // callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
  275. if ( roomId != pCallback->m_ulSteamIDLobby )
  276. return;
  277. Notification_Console_UpdateRoomParameters_Steam notification;
  278. notification.roomId=roomId;
  279. notification.roomNewName=SteamMatchmaking()->GetLobbyData( roomId, "name" );
  280. if (pCallback->m_bSuccess)
  281. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  282. else
  283. CallCBWithResultCode(&notification, L2RC_Console_GetRoomDetails_NO_ROOMS_FOUND);
  284. }
  285. void Lobby2Client_Steam_Impl::OnLobbyChatUpdate( LobbyChatUpdate_t *pCallback )
  286. {
  287. // callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
  288. if ( roomId != pCallback->m_ulSteamIDLobby )
  289. return;
  290. // Purpose: Handles users in the lobby joining or leaving ??????
  291. CallRoomCallbacks();
  292. }
  293. void Lobby2Client_Steam_Impl::OnLobbyChatMessage( LobbyChatMsg_t *pCallback )
  294. {
  295. CSteamID speaker;
  296. EChatEntryType entryType;
  297. char data[2048];
  298. int cubData=sizeof(data);
  299. SteamMatchmaking()->GetLobbyChatEntry( roomId, pCallback->m_iChatID, &speaker, data, cubData, &entryType);
  300. if (entryType==k_EChatEntryTypeChatMsg)
  301. {
  302. Notification_Console_RoomChatMessage_Steam notification;
  303. notification.message=data;
  304. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  305. }
  306. }
  307. void Lobby2Client_Steam_Impl::GetRoomMembers(DataStructures::OrderedList<uint64_t, uint64_t> &_roomMembers)
  308. {
  309. _roomMembers.Clear(true,_FILE_AND_LINE_);
  310. int cLobbyMembers = SteamMatchmaking()->GetNumLobbyMembers( roomId );
  311. for ( int i = 0; i < cLobbyMembers; i++ )
  312. {
  313. CSteamID steamIDLobbyMember = SteamMatchmaking()->GetLobbyMemberByIndex( roomId, i ) ;
  314. uint64_t memberid=steamIDLobbyMember.ConvertToUint64();
  315. _roomMembers.Insert(memberid,memberid,true,_FILE_AND_LINE_);
  316. }
  317. }
  318. const char * Lobby2Client_Steam_Impl::GetRoomMemberName(uint64_t memberId)
  319. {
  320. return SteamFriends()->GetFriendPersonaName( memberId );
  321. }
  322. bool Lobby2Client_Steam_Impl::IsRoomOwner(const uint64_t cSteamID)
  323. {
  324. if(SteamUser()->GetSteamID() == SteamMatchmaking()->GetLobbyOwner(cSteamID))
  325. return true;
  326. return false;
  327. }
  328. bool Lobby2Client_Steam_Impl::IsInRoom(void) const
  329. {
  330. return roomMembersById.Size() > 0;
  331. }
  332. void Lobby2Client_Steam_Impl::CallRoomCallbacks()
  333. {
  334. DataStructures::OrderedList<uint64_t,uint64_t> currentMembers;
  335. GetRoomMembers(currentMembers);
  336. DataStructures::OrderedList<uint64_t, RoomMember, SteamIDAndRoomMemberComp> updatedRoomMembers;
  337. bool anyChanges=false;
  338. unsigned int currentMemberIndex=0, oldMemberIndex=0;
  339. while (currentMemberIndex < currentMembers.Size() && oldMemberIndex < roomMembersById.Size())
  340. {
  341. if (currentMembers[currentMemberIndex]<roomMembersById[oldMemberIndex].steamIDRemote)
  342. {
  343. RoomMember roomMember;
  344. roomMember.steamIDRemote=currentMembers[currentMemberIndex];
  345. roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
  346. roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
  347. updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
  348. anyChanges=true;
  349. // new member
  350. NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);
  351. currentMemberIndex++;
  352. }
  353. else if (currentMembers[currentMemberIndex]>roomMembersById[oldMemberIndex].steamIDRemote)
  354. {
  355. anyChanges=true;
  356. // dropped member
  357. NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);
  358. oldMemberIndex++;
  359. }
  360. else
  361. {
  362. updatedRoomMembers.Insert(roomMembersById[oldMemberIndex].steamIDRemote,roomMembersById[oldMemberIndex],true,_FILE_AND_LINE_);
  363. currentMemberIndex++;
  364. oldMemberIndex++;
  365. }
  366. }
  367. while (oldMemberIndex < roomMembersById.Size())
  368. {
  369. anyChanges=true;
  370. // dropped member
  371. NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);
  372. oldMemberIndex++;
  373. }
  374. while (currentMemberIndex < currentMembers.Size())
  375. {
  376. RoomMember roomMember;
  377. roomMember.steamIDRemote=currentMembers[currentMemberIndex];
  378. roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
  379. roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
  380. updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);
  381. anyChanges=true;
  382. // new member
  383. NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);
  384. currentMemberIndex++;
  385. }
  386. if (anyChanges)
  387. {
  388. roomMembersById=updatedRoomMembers;
  389. roomMembersByAddr.Clear(true, _FILE_AND_LINE_);
  390. for (currentMemberIndex=0; currentMemberIndex < roomMembersById.Size(); currentMemberIndex++)
  391. {
  392. roomMembersByAddr.Insert(roomMembersById[currentMemberIndex].systemAddress, roomMembersById[currentMemberIndex], true, _FILE_AND_LINE_);
  393. }
  394. }
  395. }
  396. void Lobby2Client_Steam_Impl::NotifyNewMember(uint64_t memberId, SystemAddress remoteSystem)
  397. {
  398. // const char *pchName = SteamFriends()->GetFriendPersonaName( memberId );
  399. Notification_Console_MemberJoinedRoom_Steam notification;
  400. notification.roomId=roomId;
  401. notification.srcMemberId=memberId;
  402. notification.memberName=SteamFriends()->GetFriendPersonaName( memberId );
  403. notification.remoteSystem=remoteSystem;
  404. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  405. }
  406. void Lobby2Client_Steam_Impl::NotifyDroppedMember(uint64_t memberId, SystemAddress remoteSystem)
  407. {
  408. /// const char *pchName = SteamFriends()->GetFriendPersonaName( memberId );
  409. Notification_Console_MemberLeftRoom_Steam notification;
  410. notification.roomId=roomId;
  411. notification.srcMemberId=memberId;
  412. notification.memberName=SteamFriends()->GetFriendPersonaName( memberId );
  413. notification.remoteSystem=remoteSystem;
  414. CallCBWithResultCode(&notification, L2RC_SUCCESS);
  415. unsigned int i;
  416. bool objectExists;
  417. i = roomMembersById.GetIndexFromKey(memberId, &objectExists);
  418. if (objectExists)
  419. {
  420. rakPeerInterface->CloseConnection(roomMembersById[i].systemAddress,false);
  421. // Is this necessary?
  422. SteamNetworking()->CloseP2PSessionWithUser( memberId );
  423. }
  424. }
  425. void Lobby2Client_Steam_Impl::ClearRoom(void)
  426. {
  427. roomId=0;
  428. if (SteamNetworking())
  429. {
  430. for (unsigned int i=0; i < roomMembersById.Size(); i++)
  431. {
  432. SteamNetworking()->CloseP2PSessionWithUser( roomMembersById[i].steamIDRemote );
  433. }
  434. }
  435. roomMembersById.Clear(true,_FILE_AND_LINE_);
  436. roomMembersByAddr.Clear(true,_FILE_AND_LINE_);
  437. }
  438. void Lobby2Client_Steam_Impl::OnP2PSessionRequest( P2PSessionRequest_t *pCallback )
  439. {
  440. // we'll accept a connection from anyone
  441. SteamNetworking()->AcceptP2PSessionWithUser( pCallback->m_steamIDRemote );
  442. }
  443. void Lobby2Client_Steam_Impl::OnP2PSessionConnectFail( P2PSessionConnectFail_t *pCallback )
  444. {
  445. (void) pCallback;
  446. // we've sent a packet to the user, but it never got through
  447. // we can just use the normal timeout
  448. }
  449. void Lobby2Client_Steam_Impl::NotifyLeaveRoom(void)
  450. {
  451. ClearRoom();
  452. }
  453. int Lobby2Client_Steam_Impl::RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress )
  454. {
  455. bool objectExists;
  456. unsigned int i = roomMembersByAddr.GetIndexFromKey(systemAddress, &objectExists);
  457. if (objectExists)
  458. {
  459. if (SteamNetworking()->SendP2PPacket(roomMembersByAddr[i].steamIDRemote, data, length, k_EP2PSendUnreliable))
  460. return length;
  461. else
  462. return 0;
  463. }
  464. else if (systemAddress.GetPort()!=STEAM_UNUSED_PORT)
  465. {
  466. // return SocketLayer::SendTo_PC(s,data,length,systemAddress,_FILE_AND_LINE_);
  467. return -1;
  468. }
  469. return 0;
  470. }
  471. int Lobby2Client_Steam_Impl::RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread)
  472. {
  473. (void) calledFromMainThread;
  474. uint32 pcubMsgSize;
  475. if (SteamNetworking() && SteamNetworking()->IsP2PPacketAvailable(&pcubMsgSize))
  476. {
  477. CSteamID psteamIDRemote;
  478. if (SteamNetworking()->ReadP2PPacket(dataOut, MAXIMUM_MTU_SIZE, &pcubMsgSize, &psteamIDRemote))
  479. {
  480. uint64_t steamIDRemote64=psteamIDRemote.ConvertToUint64();
  481. unsigned int i;
  482. bool objectExists;
  483. i = roomMembersById.GetIndexFromKey(steamIDRemote64, &objectExists);
  484. if (objectExists)
  485. {
  486. *senderOut=roomMembersById[i].systemAddress;
  487. }
  488. return pcubMsgSize;
  489. }
  490. }
  491. return 0;
  492. }
  493. void Lobby2Client_Steam_Impl::OnRakPeerShutdown(void)
  494. {
  495. ClearRoom();
  496. }
  497. void Lobby2Client_Steam_Impl::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
  498. {
  499. (void) lostConnectionReason;
  500. (void) rakNetGUID;
  501. bool objectExists;
  502. unsigned int i = roomMembersByAddr.GetIndexFromKey(systemAddress, &objectExists);
  503. if (objectExists)
  504. {
  505. uint64_t steamIDRemote = roomMembersByAddr[i].steamIDRemote;
  506. SteamNetworking()->CloseP2PSessionWithUser( steamIDRemote );
  507. roomMembersByAddr.RemoveAtIndex(i);
  508. i = roomMembersById.GetIndexFromKey(steamIDRemote, &objectExists);
  509. RakAssert(objectExists);
  510. roomMembersById.RemoveAtIndex(i);
  511. }
  512. }
  513. void Lobby2Client_Steam_Impl::OnFailedConnectionAttempt(Packet *packet, PI2_FailedConnectionAttemptReason failedConnectionAttemptReason)
  514. {
  515. (void) failedConnectionAttemptReason;
  516. bool objectExists;
  517. unsigned int i = roomMembersByAddr.GetIndexFromKey(packet->systemAddress, &objectExists);
  518. if (objectExists)
  519. {
  520. uint64_t steamIDRemote = roomMembersByAddr[i].steamIDRemote;
  521. SteamNetworking()->CloseP2PSessionWithUser( steamIDRemote );
  522. roomMembersByAddr.RemoveAtIndex(i);
  523. i = roomMembersById.GetIndexFromKey(steamIDRemote, &objectExists);
  524. RakAssert(objectExists);
  525. roomMembersById.RemoveAtIndex(i);
  526. }
  527. }
  528. void Lobby2Client_Steam_Impl::OnAttach(void)
  529. {
  530. nextFreeSystemAddress=(uint32_t) rakPeerInterface->GetMyGUID().g;
  531. // If this asserts, call RakPeer::Startup() before attaching Lobby2Client_Steam
  532. DataStructures::List<RakNetSocket2* > sockets;
  533. rakPeerInterface->GetSockets(sockets);
  534. ((RNS2_Windows*)sockets[0])->SetSocketLayerOverride(this);
  535. }
  536. void Lobby2Client_Steam_Impl::OnDetach(void)
  537. {
  538. DataStructures::List<RakNetSocket2* > sockets;
  539. rakPeerInterface->GetSockets(sockets);
  540. ((RNS2_Windows*)sockets[0])->SetSocketLayerOverride(this);
  541. }
粤ICP备19079148号