RelayPlugin.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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_RelayPlugin==1
  12. #include "RelayPlugin.h"
  13. #include "MessageIdentifiers.h"
  14. #include "RakPeerInterface.h"
  15. #include "BitStream.h"
  16. using namespace RakNet;
  17. STATIC_FACTORY_DEFINITIONS(RelayPlugin,RelayPlugin);
  18. RelayPlugin::RelayPlugin()
  19. {
  20. acceptAddParticipantRequests=false;
  21. }
  22. RelayPlugin::~RelayPlugin()
  23. {
  24. DataStructures::List<StrAndGuidAndRoom*> itemList;
  25. DataStructures::List<RakString> keyList;
  26. strToGuidHash.GetAsList(itemList, keyList, _FILE_AND_LINE_);
  27. guidToStrHash.Clear(_FILE_AND_LINE_);
  28. for (unsigned int i=0; i < itemList.Size(); i++)
  29. RakNet::OP_DELETE(itemList[i], _FILE_AND_LINE_);
  30. for (unsigned int i=0; i < chatRooms.Size(); i++)
  31. RakNet::OP_DELETE(chatRooms[i], _FILE_AND_LINE_);
  32. }
  33. RelayPluginEnums RelayPlugin::AddParticipantOnServer(const RakString &key, const RakNetGUID &guid)
  34. {
  35. ConnectionState cs = rakPeerInterface->GetConnectionState(guid);
  36. if (cs!=IS_CONNECTED)
  37. return RPE_ADD_CLIENT_TARGET_NOT_CONNECTED;
  38. if (strToGuidHash.HasData(key)==true)
  39. return RPE_ADD_CLIENT_NAME_ALREADY_IN_USE; // Name already in use
  40. // If GUID is already in use, remove existing
  41. StrAndGuidAndRoom *strAndGuidExisting;
  42. if (guidToStrHash.Pop(strAndGuidExisting, guid, _FILE_AND_LINE_))
  43. {
  44. strToGuidHash.Remove(strAndGuidExisting->str, _FILE_AND_LINE_);
  45. RakNet::OP_DELETE(strAndGuidExisting, _FILE_AND_LINE_);
  46. }
  47. StrAndGuidAndRoom *strAndGuid = RakNet::OP_NEW<StrAndGuidAndRoom>(_FILE_AND_LINE_);
  48. strAndGuid->guid=guid;
  49. strAndGuid->str=key;
  50. strToGuidHash.Push(key, strAndGuid, _FILE_AND_LINE_);
  51. guidToStrHash.Push(guid, strAndGuid, _FILE_AND_LINE_);
  52. return RPE_ADD_CLIENT_SUCCESS;
  53. }
  54. void RelayPlugin::RemoveParticipantOnServer(const RakNetGUID &guid)
  55. {
  56. StrAndGuidAndRoom *strAndGuid;
  57. if (guidToStrHash.Pop(strAndGuid, guid, _FILE_AND_LINE_))
  58. {
  59. LeaveGroup(&strAndGuid);
  60. strToGuidHash.Remove(strAndGuid->str, _FILE_AND_LINE_);
  61. RakNet::OP_DELETE(strAndGuid, _FILE_AND_LINE_);
  62. }
  63. }
  64. void RelayPlugin::SetAcceptAddParticipantRequests(bool accept)
  65. {
  66. acceptAddParticipantRequests=accept;
  67. }
  68. void RelayPlugin::AddParticipantRequestFromClient(const RakString &key, const RakNetGUID &relayPluginServerGuid)
  69. {
  70. BitStream bsOut;
  71. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  72. bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_REQUEST_FROM_CLIENT);
  73. bsOut.WriteCompressed(key);
  74. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
  75. }
  76. void RelayPlugin::RemoveParticipantRequestFromClient(const RakNetGUID &relayPluginServerGuid)
  77. {
  78. BitStream bsOut;
  79. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  80. bsOut.WriteCasted<MessageID>(RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT);
  81. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
  82. }
  83. // Send a message to a server running RelayPlugin, to forward a message to the system identified by \a key
  84. void RelayPlugin::SendToParticipant(const RakNetGUID &relayPluginServerGuid, const RakString &key, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
  85. {
  86. BitStream bsOut;
  87. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  88. bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_SERVER_FROM_CLIENT);
  89. bsOut.WriteCasted<unsigned char>(priority);
  90. bsOut.WriteCasted<unsigned char>(reliability);
  91. bsOut.Write(orderingChannel);
  92. bsOut.WriteCompressed(key);
  93. bsOut.Write(bitStream);
  94. SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
  95. }
  96. void RelayPlugin::SendGroupMessage(const RakNetGUID &relayPluginServerGuid, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
  97. {
  98. BitStream bsOut;
  99. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  100. bsOut.WriteCasted<MessageID>(RPE_GROUP_MESSAGE_FROM_CLIENT);
  101. bsOut.WriteCasted<unsigned char>(priority);
  102. bsOut.WriteCasted<unsigned char>(reliability);
  103. bsOut.Write(orderingChannel);
  104. bsOut.Write(bitStream);
  105. SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
  106. }
  107. void RelayPlugin::LeaveGroup(const RakNetGUID &relayPluginServerGuid)
  108. {
  109. BitStream bsOut;
  110. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  111. bsOut.WriteCasted<MessageID>(RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT);
  112. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
  113. }
  114. void RelayPlugin::GetGroupList(const RakNetGUID &relayPluginServerGuid)
  115. {
  116. BitStream bsOut;
  117. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  118. bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT);
  119. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
  120. }
  121. PluginReceiveResult RelayPlugin::OnReceive(Packet *packet)
  122. {
  123. if (packet->data[0]==ID_RELAY_PLUGIN)
  124. {
  125. switch (packet->data[1])
  126. {
  127. case RPE_MESSAGE_TO_SERVER_FROM_CLIENT:
  128. {
  129. BitStream bsIn(packet->data, packet->length, false);
  130. bsIn.IgnoreBytes(sizeof(MessageID)*2);
  131. PacketPriority priority;
  132. PacketReliability reliability;
  133. char orderingChannel;
  134. unsigned char cIn;
  135. bsIn.Read(cIn);
  136. priority = (PacketPriority) cIn;
  137. bsIn.Read(cIn);
  138. reliability = (PacketReliability) cIn;
  139. bsIn.Read(orderingChannel);
  140. RakString key;
  141. bsIn.ReadCompressed(key);
  142. BitStream bsData;
  143. bsIn.Read(&bsData);
  144. StrAndGuidAndRoom **strAndGuid = strToGuidHash.Peek(key);
  145. StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
  146. if (strAndGuid && strAndGuidSender)
  147. {
  148. BitStream bsOut;
  149. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  150. bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_CLIENT_FROM_SERVER);
  151. bsOut.WriteCompressed( (*strAndGuidSender)->str );
  152. bsOut.AlignWriteToByteBoundary();
  153. bsOut.Write(bsData);
  154. SendUnified(&bsOut, priority, reliability, orderingChannel, (*strAndGuid)->guid, false);
  155. }
  156. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  157. }
  158. case RPE_ADD_CLIENT_REQUEST_FROM_CLIENT:
  159. {
  160. BitStream bsIn(packet->data, packet->length, false);
  161. bsIn.IgnoreBytes(sizeof(MessageID)*2);
  162. RakString key;
  163. bsIn.ReadCompressed(key);
  164. BitStream bsOut;
  165. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  166. if (acceptAddParticipantRequests)
  167. bsOut.WriteCasted<MessageID>(AddParticipantOnServer(key, packet->guid));
  168. else
  169. bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_NOT_ALLOWED);
  170. bsOut.WriteCompressed(key);
  171. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
  172. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  173. }
  174. case RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT:
  175. {
  176. RemoveParticipantOnServer(packet->guid);
  177. }
  178. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  179. case RPE_GROUP_MESSAGE_FROM_CLIENT:
  180. {
  181. OnGroupMessageFromClient(packet);
  182. }
  183. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  184. case RPE_JOIN_GROUP_REQUEST_FROM_CLIENT:
  185. {
  186. OnJoinGroupRequestFromClient(packet);
  187. }
  188. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  189. case RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT:
  190. {
  191. OnLeaveGroupRequestFromClient(packet);
  192. }
  193. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  194. case RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT:
  195. {
  196. SendChatRoomsList(packet->guid);
  197. }
  198. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  199. }
  200. }
  201. return RR_CONTINUE_PROCESSING;
  202. }
  203. void RelayPlugin::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
  204. {
  205. (void) lostConnectionReason;
  206. (void) systemAddress;
  207. RemoveParticipantOnServer(rakNetGUID);
  208. }
  209. RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RP_Group* room, StrAndGuidAndRoom **strAndGuidSender)
  210. {
  211. if (strAndGuidSender==0)
  212. return 0;
  213. NotifyUsersInRoom(room, RPE_USER_ENTERED_ROOM, (*strAndGuidSender)->str);
  214. StrAndGuid sag;
  215. sag.guid=(*strAndGuidSender)->guid;
  216. sag.str=(*strAndGuidSender)->str;
  217. room->usersInRoom.Push(sag, _FILE_AND_LINE_);
  218. (*strAndGuidSender)->currentRoom=room->roomName;
  219. return room;
  220. }
  221. void RelayPlugin::JoinGroupRequest(const RakNetGUID &relayPluginServerGuid, RakString groupName)
  222. {
  223. BitStream bsOut;
  224. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  225. bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_REQUEST_FROM_CLIENT);
  226. bsOut.WriteCompressed(groupName);
  227. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
  228. }
  229. RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RakNetGUID userGuid, RakString roomName)
  230. {
  231. StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(userGuid);
  232. if (strAndGuidSender)
  233. {
  234. if (roomName.IsEmpty())
  235. return 0;
  236. if ((*strAndGuidSender)->currentRoom==roomName)
  237. return 0;
  238. if ((*strAndGuidSender)->currentRoom.IsEmpty()==false)
  239. LeaveGroup(strAndGuidSender);
  240. RakString userName = (*strAndGuidSender)->str;
  241. for (unsigned int i=0; i < chatRooms.Size(); i++)
  242. {
  243. if (chatRooms[i]->roomName==roomName)
  244. {
  245. // Join existing room
  246. return JoinGroup(chatRooms[i],strAndGuidSender);
  247. }
  248. }
  249. // Create new room
  250. RP_Group *room = RakNet::OP_NEW<RP_Group>(_FILE_AND_LINE_);
  251. room->roomName=roomName;
  252. chatRooms.Push(room, _FILE_AND_LINE_);
  253. return JoinGroup(room,strAndGuidSender);
  254. }
  255. return 0;
  256. }
  257. void RelayPlugin::LeaveGroup(StrAndGuidAndRoom **strAndGuidSender)
  258. {
  259. if (strAndGuidSender==0)
  260. return;
  261. RakString userName = (*strAndGuidSender)->str;
  262. for (unsigned int i=0; i < chatRooms.Size(); i++)
  263. {
  264. if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
  265. {
  266. (*strAndGuidSender)->currentRoom.Clear();
  267. RP_Group *room = chatRooms[i];
  268. for (unsigned int j=0; j < room->usersInRoom.Size(); j++)
  269. {
  270. if (room->usersInRoom[j].guid==(*strAndGuidSender)->guid)
  271. {
  272. room->usersInRoom.RemoveAtIndexFast(j);
  273. if (room->usersInRoom.Size()==0)
  274. {
  275. RakNet::OP_DELETE(room, _FILE_AND_LINE_);
  276. chatRooms.RemoveAtIndexFast(i);
  277. return;
  278. }
  279. }
  280. }
  281. NotifyUsersInRoom(room, RPE_USER_LEFT_ROOM, userName);
  282. return;
  283. }
  284. }
  285. }
  286. void RelayPlugin::NotifyUsersInRoom(RP_Group *room, int msg, const RakString& message)
  287. {
  288. for (unsigned int i=0; i < room->usersInRoom.Size(); i++)
  289. {
  290. BitStream bsOut;
  291. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  292. bsOut.WriteCasted<MessageID>(msg);
  293. bsOut.WriteCompressed(message);
  294. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false);
  295. }
  296. }
  297. void RelayPlugin::SendMessageToRoom(StrAndGuidAndRoom **strAndGuidSender, BitStream* message)
  298. {
  299. if ((*strAndGuidSender)->currentRoom.IsEmpty())
  300. return;
  301. for (unsigned int i=0; i < chatRooms.Size(); i++)
  302. {
  303. if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
  304. {
  305. BitStream bsOut;
  306. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  307. bsOut.WriteCasted<MessageID>(RPE_GROUP_MSG_FROM_SERVER);
  308. message->ResetReadPointer();
  309. bsOut.WriteCompressed((*strAndGuidSender)->str);
  310. bsOut.AlignWriteToByteBoundary();
  311. bsOut.Write(message);
  312. RP_Group *room = chatRooms[i];
  313. for (unsigned int i=0; i < room->usersInRoom.Size(); i++)
  314. {
  315. if (room->usersInRoom[i].guid!=(*strAndGuidSender)->guid)
  316. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false);
  317. }
  318. break;
  319. }
  320. }
  321. }
  322. void RelayPlugin::SendChatRoomsList(RakNetGUID target)
  323. {
  324. BitStream bsOut;
  325. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  326. bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REPLY_FROM_SERVER);
  327. bsOut.WriteCasted<uint16_t>(chatRooms.Size());
  328. for (unsigned int i=0; i < chatRooms.Size(); i++)
  329. {
  330. bsOut.WriteCompressed(chatRooms[i]->roomName);
  331. bsOut.WriteCasted<uint16_t>(chatRooms[i]->usersInRoom.Size());
  332. }
  333. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false);
  334. }
  335. void RelayPlugin::OnGroupMessageFromClient(Packet *packet)
  336. {
  337. BitStream bsIn(packet->data, packet->length, false);
  338. bsIn.IgnoreBytes(sizeof(MessageID)*2);
  339. PacketPriority priority;
  340. PacketReliability reliability;
  341. char orderingChannel;
  342. unsigned char cIn;
  343. bsIn.Read(cIn);
  344. priority = (PacketPriority) cIn;
  345. bsIn.Read(cIn);
  346. reliability = (PacketReliability) cIn;
  347. bsIn.Read(orderingChannel);
  348. BitStream bsData;
  349. bsIn.Read(&bsData);
  350. StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
  351. if (strAndGuidSender)
  352. {
  353. SendMessageToRoom(strAndGuidSender,&bsData);
  354. }
  355. }
  356. void RelayPlugin::OnJoinGroupRequestFromClient(Packet *packet)
  357. {
  358. BitStream bsIn(packet->data, packet->length, false);
  359. bsIn.IgnoreBytes(sizeof(MessageID)*2);
  360. RakString groupName;
  361. bsIn.ReadCompressed(groupName);
  362. RelayPlugin::RP_Group *groupJoined = JoinGroup(packet->guid, groupName);
  363. BitStream bsOut;
  364. bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
  365. if (groupJoined)
  366. {
  367. bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_SUCCESS);
  368. bsOut.WriteCasted<uint16_t>(groupJoined->usersInRoom.Size());
  369. for (unsigned int i=0; i < groupJoined->usersInRoom.Size(); i++)
  370. {
  371. bsOut.WriteCompressed(groupJoined->usersInRoom[i].str);
  372. }
  373. }
  374. else
  375. {
  376. bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_FAILURE);
  377. }
  378. SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
  379. }
  380. void RelayPlugin::OnLeaveGroupRequestFromClient(Packet *packet)
  381. {
  382. BitStream bsIn(packet->data, packet->length, false);
  383. bsIn.IgnoreBytes(sizeof(MessageID)*2);
  384. StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
  385. if (strAndGuidSender)
  386. LeaveGroup(strAndGuidSender);
  387. }
  388. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号