SLikeNet  0.1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RelayPlugin.cpp
Go to the documentation of this file.
1 /*
2  * Original work: 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  * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7  * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8  *
9  *
10  * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11  *
12  * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13  * license found in the license.txt file in the root directory of this source tree.
14  */
15 
17 #if _RAKNET_SUPPORT_RelayPlugin==1
18 
19 #include "slikenet/RelayPlugin.h"
21 #include "slikenet/peerinterface.h"
22 #include "slikenet/BitStream.h"
23 
24 using namespace SLNet;
25 
27 
29 {
31 }
32 
34 {
37  strToGuidHash.GetAsList(itemList, keyList, _FILE_AND_LINE_);
39  for (unsigned int i=0; i < itemList.Size(); i++)
40  SLNet::OP_DELETE(itemList[i], _FILE_AND_LINE_);
41  for (unsigned int i=0; i < chatRooms.Size(); i++)
43 }
44 
46 {
48  if (cs!=IS_CONNECTED)
50 
51  if (strToGuidHash.HasData(key)==true)
52  return RPE_ADD_CLIENT_NAME_ALREADY_IN_USE; // Name already in use
53 
54  // If GUID is already in use, remove existing
55  StrAndGuidAndRoom *strAndGuidExisting;
56  if (guidToStrHash.Pop(strAndGuidExisting, guid, _FILE_AND_LINE_))
57  {
58  strToGuidHash.Remove(strAndGuidExisting->str, _FILE_AND_LINE_);
59  SLNet::OP_DELETE(strAndGuidExisting, _FILE_AND_LINE_);
60  }
61 
62  StrAndGuidAndRoom *strAndGuid = SLNet::OP_NEW<StrAndGuidAndRoom>(_FILE_AND_LINE_);
63  strAndGuid->guid=guid;
64  strAndGuid->str=key;
65 
66  strToGuidHash.Push(key, strAndGuid, _FILE_AND_LINE_);
67  guidToStrHash.Push(guid, strAndGuid, _FILE_AND_LINE_);
68 
70 }
72 {
73  StrAndGuidAndRoom *strAndGuid;
74  if (guidToStrHash.Pop(strAndGuid, guid, _FILE_AND_LINE_))
75  {
76  LeaveGroup(&strAndGuid);
77  strToGuidHash.Remove(strAndGuid->str, _FILE_AND_LINE_);
78  SLNet::OP_DELETE(strAndGuid, _FILE_AND_LINE_);
79  }
80 }
81 
83 {
85 }
86 void RelayPlugin::AddParticipantRequestFromClient(const RakString &key, const RakNetGUID &relayPluginServerGuid)
87 {
88  BitStream bsOut;
91  bsOut.WriteCompressed(key);
92  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
93 }
94 void RelayPlugin::RemoveParticipantRequestFromClient(const RakNetGUID &relayPluginServerGuid)
95 {
96  BitStream bsOut;
99  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
100 }
101 // Send a message to a server running RelayPlugin, to forward a message to the system identified by \a key
102 void RelayPlugin::SendToParticipant(const RakNetGUID &relayPluginServerGuid, const RakString &key, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
103 {
104  BitStream bsOut;
107  bsOut.WriteCasted<unsigned char>(priority);
108  bsOut.WriteCasted<unsigned char>(reliability);
109  bsOut.Write(orderingChannel);
110  bsOut.WriteCompressed(key);
111  bsOut.Write(bitStream);
112  SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
113 }
114 void RelayPlugin::SendGroupMessage(const RakNetGUID &relayPluginServerGuid, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
115 {
116  BitStream bsOut;
119  bsOut.WriteCasted<unsigned char>(priority);
120  bsOut.WriteCasted<unsigned char>(reliability);
121  bsOut.Write(orderingChannel);
122  bsOut.Write(bitStream);
123  SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
124 }
125 void RelayPlugin::LeaveGroup(const RakNetGUID &relayPluginServerGuid)
126 {
127  BitStream bsOut;
130  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
131 }
132 void RelayPlugin::GetGroupList(const RakNetGUID &relayPluginServerGuid)
133 {
134  BitStream bsOut;
137  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
138 }
140 {
141  if (packet->data[0]==ID_RELAY_PLUGIN)
142  {
143  switch (packet->data[1])
144  {
146  {
147  BitStream bsIn(packet->data, packet->length, false);
148  bsIn.IgnoreBytes(sizeof(MessageID)*2);
149  PacketPriority priority;
150  PacketReliability reliability;
151  char orderingChannel;
152  unsigned char cIn;
153  bsIn.Read(cIn);
154  priority = (PacketPriority) cIn;
155  bsIn.Read(cIn);
156  reliability = (PacketReliability) cIn;
157  bsIn.Read(orderingChannel);
158  RakString key;
159  bsIn.ReadCompressed(key);
160  BitStream bsData;
161  bsIn.Read(&bsData);
162  StrAndGuidAndRoom **strAndGuid = strToGuidHash.Peek(key);
163  StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
164  if (strAndGuid && strAndGuidSender)
165  {
166  BitStream bsOut;
169  bsOut.WriteCompressed( (*strAndGuidSender)->str );
170  bsOut.AlignWriteToByteBoundary();
171  bsOut.Write(bsData);
172  SendUnified(&bsOut, priority, reliability, orderingChannel, (*strAndGuid)->guid, false);
173  }
174 
176  }
177 
179  {
180  BitStream bsIn(packet->data, packet->length, false);
181  bsIn.IgnoreBytes(sizeof(MessageID)*2);
182  RakString key;
183  bsIn.ReadCompressed(key);
184  BitStream bsOut;
187  bsOut.WriteCasted<MessageID>(AddParticipantOnServer(key, packet->guid));
188  else
190  bsOut.WriteCompressed(key);
191  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
192 
194  }
196  {
198  }
201  {
202  OnGroupMessageFromClient(packet);
203  }
206  {
208  }
211  {
213  }
216  {
217  SendChatRoomsList(packet->guid);
218  }
220  }
221 
222  }
223 
224  return RR_CONTINUE_PROCESSING;
225 }
226 
227 void RelayPlugin::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
228 {
229  (void) lostConnectionReason;
230  (void) systemAddress;
231 
232  RemoveParticipantOnServer(rakNetGUID);
233 }
234 
235 RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RP_Group* room, StrAndGuidAndRoom **strAndGuidSender)
236 {
237  if (strAndGuidSender==0)
238  return 0;
239 
240  NotifyUsersInRoom(room, RPE_USER_ENTERED_ROOM, (*strAndGuidSender)->str);
241  StrAndGuid sag;
242  sag.guid=(*strAndGuidSender)->guid;
243  sag.str=(*strAndGuidSender)->str;
244 
245  room->usersInRoom.Push(sag, _FILE_AND_LINE_);
246  (*strAndGuidSender)->currentRoom=room->roomName;
247 
248  return room;
249 }
250 void RelayPlugin::JoinGroupRequest(const RakNetGUID &relayPluginServerGuid, RakString groupName)
251 {
252  BitStream bsOut;
255  bsOut.WriteCompressed(groupName);
256  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
257 }
259 {
260  StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(userGuid);
261  if (strAndGuidSender)
262  {
263  if (roomName.IsEmpty())
264  return 0;
265 
266  if ((*strAndGuidSender)->currentRoom==roomName)
267  return 0;
268 
269  if ((*strAndGuidSender)->currentRoom.IsEmpty()==false)
270  LeaveGroup(strAndGuidSender);
271 
272  RakString userName = (*strAndGuidSender)->str;
273 
274  for (unsigned int i=0; i < chatRooms.Size(); i++)
275  {
276  if (chatRooms[i]->roomName==roomName)
277  {
278  // Join existing room
279  return JoinGroup(chatRooms[i],strAndGuidSender);
280  }
281  }
282 
283  // Create new room
284  RP_Group *room = SLNet::OP_NEW<RP_Group>(_FILE_AND_LINE_);
285  room->roomName=roomName;
287  return JoinGroup(room,strAndGuidSender);
288  }
289 
290  return 0;
291 }
292 void RelayPlugin::LeaveGroup(StrAndGuidAndRoom **strAndGuidSender)
293 {
294  if (strAndGuidSender==0)
295  return;
296 
297  RakString userName = (*strAndGuidSender)->str;
298  for (unsigned int i=0; i < chatRooms.Size(); i++)
299  {
300  if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
301  {
302  (*strAndGuidSender)->currentRoom.Clear();
303 
304  RP_Group *room = chatRooms[i];
305  for (unsigned int j=0; j < room->usersInRoom.Size(); j++)
306  {
307  if (room->usersInRoom[j].guid==(*strAndGuidSender)->guid)
308  {
309  room->usersInRoom.RemoveAtIndexFast(j);
310 
311  if (room->usersInRoom.Size()==0)
312  {
315  return;
316  }
317  }
318  }
319 
320  NotifyUsersInRoom(room, RPE_USER_LEFT_ROOM, userName);
321 
322  return;
323 
324  }
325  }
326 }
327 void RelayPlugin::NotifyUsersInRoom(RP_Group *room, int msg, const RakString& message)
328 {
329  for (unsigned int i=0; i < room->usersInRoom.Size(); i++)
330  {
331  BitStream bsOut;
333  bsOut.WriteCasted<MessageID>(msg);
334  bsOut.WriteCompressed(message);
335 
336  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false);
337  }
338 }
339 void RelayPlugin::SendMessageToRoom(StrAndGuidAndRoom **strAndGuidSender, BitStream* message)
340 {
341  if ((*strAndGuidSender)->currentRoom.IsEmpty())
342  return;
343 
344  for (unsigned int i=0; i < chatRooms.Size(); i++)
345  {
346  if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
347  {
348  BitStream bsOut;
351  message->ResetReadPointer();
352  bsOut.WriteCompressed((*strAndGuidSender)->str);
353  bsOut.AlignWriteToByteBoundary();
354  bsOut.Write(message);
355 
356  RP_Group *room = chatRooms[i];
357  for (unsigned int j=0; j < room->usersInRoom.Size(); j++)
358  {
359  if (room->usersInRoom[j].guid!=(*strAndGuidSender)->guid)
360  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[j].guid, false);
361  }
362 
363  break;
364  }
365  }
366 }
368 {
369  BitStream bsOut;
373  for (unsigned int i=0; i < chatRooms.Size(); i++)
374  {
375  bsOut.WriteCompressed(chatRooms[i]->roomName);
376  bsOut.WriteCasted<uint16_t>(chatRooms[i]->usersInRoom.Size());
377  }
378  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false);
379 }
381 {
382  BitStream bsIn(packet->data, packet->length, false);
383  bsIn.IgnoreBytes(sizeof(MessageID)*2);
384 
385  PacketPriority priority;
386  PacketReliability reliability;
387  char orderingChannel;
388  unsigned char cIn;
389  bsIn.Read(cIn);
390  priority = (PacketPriority) cIn;
391  bsIn.Read(cIn);
392  reliability = (PacketReliability) cIn;
393  bsIn.Read(orderingChannel);
394  BitStream bsData;
395  bsIn.Read(&bsData);
396 
397  StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
398  if (strAndGuidSender)
399  {
400  SendMessageToRoom(strAndGuidSender,&bsData);
401  }
402 }
404 {
405  BitStream bsIn(packet->data, packet->length, false);
406  bsIn.IgnoreBytes(sizeof(MessageID)*2);
407  RakString groupName;
408  bsIn.ReadCompressed(groupName);
409  RelayPlugin::RP_Group *groupJoined = JoinGroup(packet->guid, groupName);
410 
411  BitStream bsOut;
413  if (groupJoined)
414  {
416  bsOut.WriteCasted<uint16_t>(groupJoined->usersInRoom.Size());
417  for (unsigned int i=0; i < groupJoined->usersInRoom.Size(); i++)
418  {
419  bsOut.WriteCompressed(groupJoined->usersInRoom[i].str);
420  }
421  }
422  else
423  {
425  }
426 
427  SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
428 }
430 {
431  BitStream bsIn(packet->data, packet->length, false);
432  bsIn.IgnoreBytes(sizeof(MessageID)*2);
433  StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
434  if (strAndGuidSender)
435  LeaveGroup(strAndGuidSender);
436 }
437 #endif // _RAKNET_SUPPORT_*