SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
16 #include "slikenet/NativeFeatureIncludes.h"
17 #if _RAKNET_SUPPORT_RelayPlugin==1
18
19 #include "slikenet/RelayPlugin.h"
20 #include "slikenet/MessageIdentifiers.h"
21 #include "slikenet/peerinterface.h"
22 #include "slikenet/BitStream.h"
23
24 using namespace SLNet;
25
26 STATIC_FACTORY_DEFINITIONS(RelayPlugin,RelayPlugin);
27
28 RelayPlugin::RelayPlugin()
29 {
30 acceptAddParticipantRequests=false;
31 }
32
33 RelayPlugin::~RelayPlugin()
34 {
35 DataStructures::List<StrAndGuidAndRoom*> itemList;
36 DataStructures::List<RakString> keyList;
37 strToGuidHash.GetAsList(itemList, keyList, _FILE_AND_LINE_);
38 guidToStrHash.Clear(_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++)
42 SLNet::OP_DELETE(chatRooms[i], _FILE_AND_LINE_);
43 }
44
45 RelayPluginEnums RelayPlugin::AddParticipantOnServer(const RakString &key, const RakNetGUID &guid)
46 {
47 ConnectionState cs = rakPeerInterface->GetConnectionState(guid);
48 if (cs!=IS_CONNECTED)
49 return RPE_ADD_CLIENT_TARGET_NOT_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
69 return RPE_ADD_CLIENT_SUCCESS;
70 }
71 void RelayPlugin::RemoveParticipantOnServer(const RakNetGUID &guid)
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
82 void RelayPlugin::SetAcceptAddParticipantRequests(bool accept)
83 {
84 acceptAddParticipantRequests=accept;
85 }
86 void RelayPlugin::AddParticipantRequestFromClient(const RakString &key, const RakNetGUID &relayPluginServerGuid)
87 {
88 BitStream bsOut;
89 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
90 bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_REQUEST_FROM_CLIENT);
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;
97 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
98 bsOut.WriteCasted<MessageID>(RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT);
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;
105 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
106 bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_SERVER_FROM_CLIENT);
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;
117 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
118 bsOut.WriteCasted<MessageID>(RPE_GROUP_MESSAGE_FROM_CLIENT);
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;
128 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
129 bsOut.WriteCasted<MessageID>(RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT);
130 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
131 }
132 void RelayPlugin::GetGroupList(const RakNetGUID &relayPluginServerGuid)
133 {
134 BitStream bsOut;
135 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
136 bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT);
137 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
138 }
139 PluginReceiveResult RelayPlugin::OnReceive(Packet *packet)
140 {
141 if (packet->data[0]==ID_RELAY_PLUGIN)
142 {
143 switch (packet->data[1])
144 {
145 case RPE_MESSAGE_TO_SERVER_FROM_CLIENT:
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;
167 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
168 bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_CLIENT_FROM_SERVER);
169 bsOut.WriteCompressed( (*strAndGuidSender)->str );
170 bsOut.AlignWriteToByteBoundary();
171 bsOut.Write(bsData);
172 SendUnified(&bsOut, priority, reliability, orderingChannel, (*strAndGuid)->guid, false);
173 }
174
175 return RR_STOP_PROCESSING_AND_DEALLOCATE;
176 }
177
178 case RPE_ADD_CLIENT_REQUEST_FROM_CLIENT:
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;
185 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
186 if (acceptAddParticipantRequests)
187 bsOut.WriteCasted<MessageID>(AddParticipantOnServer(key, packet->guid));
188 else
189 bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_NOT_ALLOWED);
190 bsOut.WriteCompressed(key);
191 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
192
193 return RR_STOP_PROCESSING_AND_DEALLOCATE;
194 }
195 case RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT:
196 {
197 RemoveParticipantOnServer(packet->guid);
198 }
199 return RR_STOP_PROCESSING_AND_DEALLOCATE;
200 case RPE_GROUP_MESSAGE_FROM_CLIENT:
201 {
202 OnGroupMessageFromClient(packet);
203 }
204 return RR_STOP_PROCESSING_AND_DEALLOCATE;
205 case RPE_JOIN_GROUP_REQUEST_FROM_CLIENT:
206 {
207 OnJoinGroupRequestFromClient(packet);
208 }
209 return RR_STOP_PROCESSING_AND_DEALLOCATE;
210 case RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT:
211 {
212 OnLeaveGroupRequestFromClient(packet);
213 }
214 return RR_STOP_PROCESSING_AND_DEALLOCATE;
215 case RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT:
216 {
217 SendChatRoomsList(packet->guid);
218 }
219 return RR_STOP_PROCESSING_AND_DEALLOCATE;
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;
253 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
254 bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_REQUEST_FROM_CLIENT);
255 bsOut.WriteCompressed(groupName);
256 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
257 }
258 RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RakNetGUID userGuid, RakString roomName)
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;
286 chatRooms.Push(room, _FILE_AND_LINE_);
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 {
313 SLNet::OP_DELETE(room, _FILE_AND_LINE_);
314 chatRooms.RemoveAtIndexFast(i);
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;
332 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
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;
349 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
350 bsOut.WriteCasted<MessageID>(RPE_GROUP_MSG_FROM_SERVER);
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 }
367 void RelayPlugin::SendChatRoomsList(RakNetGUID target)
368 {
369 BitStream bsOut;
370 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
371 bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REPLY_FROM_SERVER);
372 bsOut.WriteCasted<uint16_t>(chatRooms.Size());
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 }
380 void RelayPlugin::OnGroupMessageFromClient(Packet *packet)
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 }
403 void RelayPlugin::OnJoinGroupRequestFromClient(Packet *packet)
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;
412 bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
413 if (groupJoined)
414 {
415 bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_SUCCESS);
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 {
424 bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_FAILURE);
425 }
426
427 SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
428 }
429 void RelayPlugin::OnLeaveGroupRequestFromClient(Packet *packet)
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_*