| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "NativeFeatureIncludes.h"
- #if _RAKNET_SUPPORT_RelayPlugin==1
- #include "RelayPlugin.h"
- #include "MessageIdentifiers.h"
- #include "RakPeerInterface.h"
- #include "BitStream.h"
- using namespace RakNet;
- STATIC_FACTORY_DEFINITIONS(RelayPlugin,RelayPlugin);
- RelayPlugin::RelayPlugin()
- {
- acceptAddParticipantRequests=false;
- }
- RelayPlugin::~RelayPlugin()
- {
- DataStructures::List<StrAndGuidAndRoom*> itemList;
- DataStructures::List<RakString> keyList;
- strToGuidHash.GetAsList(itemList, keyList, _FILE_AND_LINE_);
- guidToStrHash.Clear(_FILE_AND_LINE_);
- for (unsigned int i=0; i < itemList.Size(); i++)
- RakNet::OP_DELETE(itemList[i], _FILE_AND_LINE_);
- for (unsigned int i=0; i < chatRooms.Size(); i++)
- RakNet::OP_DELETE(chatRooms[i], _FILE_AND_LINE_);
- }
- RelayPluginEnums RelayPlugin::AddParticipantOnServer(const RakString &key, const RakNetGUID &guid)
- {
- ConnectionState cs = rakPeerInterface->GetConnectionState(guid);
- if (cs!=IS_CONNECTED)
- return RPE_ADD_CLIENT_TARGET_NOT_CONNECTED;
- if (strToGuidHash.HasData(key)==true)
- return RPE_ADD_CLIENT_NAME_ALREADY_IN_USE; // Name already in use
- // If GUID is already in use, remove existing
- StrAndGuidAndRoom *strAndGuidExisting;
- if (guidToStrHash.Pop(strAndGuidExisting, guid, _FILE_AND_LINE_))
- {
- strToGuidHash.Remove(strAndGuidExisting->str, _FILE_AND_LINE_);
- RakNet::OP_DELETE(strAndGuidExisting, _FILE_AND_LINE_);
- }
- StrAndGuidAndRoom *strAndGuid = RakNet::OP_NEW<StrAndGuidAndRoom>(_FILE_AND_LINE_);
- strAndGuid->guid=guid;
- strAndGuid->str=key;
- strToGuidHash.Push(key, strAndGuid, _FILE_AND_LINE_);
- guidToStrHash.Push(guid, strAndGuid, _FILE_AND_LINE_);
- return RPE_ADD_CLIENT_SUCCESS;
- }
- void RelayPlugin::RemoveParticipantOnServer(const RakNetGUID &guid)
- {
- StrAndGuidAndRoom *strAndGuid;
- if (guidToStrHash.Pop(strAndGuid, guid, _FILE_AND_LINE_))
- {
- LeaveGroup(&strAndGuid);
- strToGuidHash.Remove(strAndGuid->str, _FILE_AND_LINE_);
- RakNet::OP_DELETE(strAndGuid, _FILE_AND_LINE_);
- }
- }
- void RelayPlugin::SetAcceptAddParticipantRequests(bool accept)
- {
- acceptAddParticipantRequests=accept;
- }
- void RelayPlugin::AddParticipantRequestFromClient(const RakString &key, const RakNetGUID &relayPluginServerGuid)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_REQUEST_FROM_CLIENT);
- bsOut.WriteCompressed(key);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
- }
- void RelayPlugin::RemoveParticipantRequestFromClient(const RakNetGUID &relayPluginServerGuid)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
- }
- // Send a message to a server running RelayPlugin, to forward a message to the system identified by \a key
- void RelayPlugin::SendToParticipant(const RakNetGUID &relayPluginServerGuid, const RakString &key, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_SERVER_FROM_CLIENT);
- bsOut.WriteCasted<unsigned char>(priority);
- bsOut.WriteCasted<unsigned char>(reliability);
- bsOut.Write(orderingChannel);
- bsOut.WriteCompressed(key);
- bsOut.Write(bitStream);
- SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
- }
- void RelayPlugin::SendGroupMessage(const RakNetGUID &relayPluginServerGuid, BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_GROUP_MESSAGE_FROM_CLIENT);
- bsOut.WriteCasted<unsigned char>(priority);
- bsOut.WriteCasted<unsigned char>(reliability);
- bsOut.Write(orderingChannel);
- bsOut.Write(bitStream);
- SendUnified(&bsOut, priority, reliability, orderingChannel, relayPluginServerGuid, false);
- }
- void RelayPlugin::LeaveGroup(const RakNetGUID &relayPluginServerGuid)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
- }
- void RelayPlugin::GetGroupList(const RakNetGUID &relayPluginServerGuid)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
- }
- PluginReceiveResult RelayPlugin::OnReceive(Packet *packet)
- {
- if (packet->data[0]==ID_RELAY_PLUGIN)
- {
- switch (packet->data[1])
- {
- case RPE_MESSAGE_TO_SERVER_FROM_CLIENT:
- {
- BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID)*2);
- PacketPriority priority;
- PacketReliability reliability;
- char orderingChannel;
- unsigned char cIn;
- bsIn.Read(cIn);
- priority = (PacketPriority) cIn;
- bsIn.Read(cIn);
- reliability = (PacketReliability) cIn;
- bsIn.Read(orderingChannel);
- RakString key;
- bsIn.ReadCompressed(key);
- BitStream bsData;
- bsIn.Read(&bsData);
- StrAndGuidAndRoom **strAndGuid = strToGuidHash.Peek(key);
- StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
- if (strAndGuid && strAndGuidSender)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_MESSAGE_TO_CLIENT_FROM_SERVER);
- bsOut.WriteCompressed( (*strAndGuidSender)->str );
- bsOut.AlignWriteToByteBoundary();
- bsOut.Write(bsData);
- SendUnified(&bsOut, priority, reliability, orderingChannel, (*strAndGuid)->guid, false);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- case RPE_ADD_CLIENT_REQUEST_FROM_CLIENT:
- {
- BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID)*2);
- RakString key;
- bsIn.ReadCompressed(key);
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- if (acceptAddParticipantRequests)
- bsOut.WriteCasted<MessageID>(AddParticipantOnServer(key, packet->guid));
- else
- bsOut.WriteCasted<MessageID>(RPE_ADD_CLIENT_NOT_ALLOWED);
- bsOut.WriteCompressed(key);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- case RPE_REMOVE_CLIENT_REQUEST_FROM_CLIENT:
- {
- RemoveParticipantOnServer(packet->guid);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case RPE_GROUP_MESSAGE_FROM_CLIENT:
- {
- OnGroupMessageFromClient(packet);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case RPE_JOIN_GROUP_REQUEST_FROM_CLIENT:
- {
- OnJoinGroupRequestFromClient(packet);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case RPE_LEAVE_GROUP_REQUEST_FROM_CLIENT:
- {
- OnLeaveGroupRequestFromClient(packet);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- case RPE_GET_GROUP_LIST_REQUEST_FROM_CLIENT:
- {
- SendChatRoomsList(packet->guid);
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- }
-
- return RR_CONTINUE_PROCESSING;
- }
- void RelayPlugin::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
- {
- (void) lostConnectionReason;
- (void) systemAddress;
- RemoveParticipantOnServer(rakNetGUID);
- }
- RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RP_Group* room, StrAndGuidAndRoom **strAndGuidSender)
- {
- if (strAndGuidSender==0)
- return 0;
- NotifyUsersInRoom(room, RPE_USER_ENTERED_ROOM, (*strAndGuidSender)->str);
- StrAndGuid sag;
- sag.guid=(*strAndGuidSender)->guid;
- sag.str=(*strAndGuidSender)->str;
- room->usersInRoom.Push(sag, _FILE_AND_LINE_);
- (*strAndGuidSender)->currentRoom=room->roomName;
- return room;
- }
- void RelayPlugin::JoinGroupRequest(const RakNetGUID &relayPluginServerGuid, RakString groupName)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_REQUEST_FROM_CLIENT);
- bsOut.WriteCompressed(groupName);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, relayPluginServerGuid, false);
- }
- RelayPlugin::RP_Group* RelayPlugin::JoinGroup(RakNetGUID userGuid, RakString roomName)
- {
- StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(userGuid);
- if (strAndGuidSender)
- {
- if (roomName.IsEmpty())
- return 0;
- if ((*strAndGuidSender)->currentRoom==roomName)
- return 0;
- if ((*strAndGuidSender)->currentRoom.IsEmpty()==false)
- LeaveGroup(strAndGuidSender);
- RakString userName = (*strAndGuidSender)->str;
- for (unsigned int i=0; i < chatRooms.Size(); i++)
- {
- if (chatRooms[i]->roomName==roomName)
- {
- // Join existing room
- return JoinGroup(chatRooms[i],strAndGuidSender);
- }
- }
- // Create new room
- RP_Group *room = RakNet::OP_NEW<RP_Group>(_FILE_AND_LINE_);
- room->roomName=roomName;
- chatRooms.Push(room, _FILE_AND_LINE_);
- return JoinGroup(room,strAndGuidSender);
- }
- return 0;
- }
- void RelayPlugin::LeaveGroup(StrAndGuidAndRoom **strAndGuidSender)
- {
- if (strAndGuidSender==0)
- return;
- RakString userName = (*strAndGuidSender)->str;
- for (unsigned int i=0; i < chatRooms.Size(); i++)
- {
- if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
- {
- (*strAndGuidSender)->currentRoom.Clear();
- RP_Group *room = chatRooms[i];
- for (unsigned int j=0; j < room->usersInRoom.Size(); j++)
- {
- if (room->usersInRoom[j].guid==(*strAndGuidSender)->guid)
- {
- room->usersInRoom.RemoveAtIndexFast(j);
- if (room->usersInRoom.Size()==0)
- {
- RakNet::OP_DELETE(room, _FILE_AND_LINE_);
- chatRooms.RemoveAtIndexFast(i);
- return;
- }
- }
- }
- NotifyUsersInRoom(room, RPE_USER_LEFT_ROOM, userName);
- return;
- }
- }
- }
- void RelayPlugin::NotifyUsersInRoom(RP_Group *room, int msg, const RakString& message)
- {
- for (unsigned int i=0; i < room->usersInRoom.Size(); i++)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(msg);
- bsOut.WriteCompressed(message);
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false);
- }
- }
- void RelayPlugin::SendMessageToRoom(StrAndGuidAndRoom **strAndGuidSender, BitStream* message)
- {
- if ((*strAndGuidSender)->currentRoom.IsEmpty())
- return;
- for (unsigned int i=0; i < chatRooms.Size(); i++)
- {
- if (chatRooms[i]->roomName==(*strAndGuidSender)->currentRoom)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_GROUP_MSG_FROM_SERVER);
- message->ResetReadPointer();
- bsOut.WriteCompressed((*strAndGuidSender)->str);
- bsOut.AlignWriteToByteBoundary();
- bsOut.Write(message);
- RP_Group *room = chatRooms[i];
- for (unsigned int i=0; i < room->usersInRoom.Size(); i++)
- {
- if (room->usersInRoom[i].guid!=(*strAndGuidSender)->guid)
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, room->usersInRoom[i].guid, false);
- }
- break;
- }
- }
- }
- void RelayPlugin::SendChatRoomsList(RakNetGUID target)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- bsOut.WriteCasted<MessageID>(RPE_GET_GROUP_LIST_REPLY_FROM_SERVER);
- bsOut.WriteCasted<uint16_t>(chatRooms.Size());
- for (unsigned int i=0; i < chatRooms.Size(); i++)
- {
- bsOut.WriteCompressed(chatRooms[i]->roomName);
- bsOut.WriteCasted<uint16_t>(chatRooms[i]->usersInRoom.Size());
- }
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false);
- }
- void RelayPlugin::OnGroupMessageFromClient(Packet *packet)
- {
- BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID)*2);
- PacketPriority priority;
- PacketReliability reliability;
- char orderingChannel;
- unsigned char cIn;
- bsIn.Read(cIn);
- priority = (PacketPriority) cIn;
- bsIn.Read(cIn);
- reliability = (PacketReliability) cIn;
- bsIn.Read(orderingChannel);
- BitStream bsData;
- bsIn.Read(&bsData);
-
- StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
- if (strAndGuidSender)
- {
- SendMessageToRoom(strAndGuidSender,&bsData);
- }
- }
- void RelayPlugin::OnJoinGroupRequestFromClient(Packet *packet)
- {
- BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID)*2);
- RakString groupName;
- bsIn.ReadCompressed(groupName);
- RelayPlugin::RP_Group *groupJoined = JoinGroup(packet->guid, groupName);
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_RELAY_PLUGIN);
- if (groupJoined)
- {
- bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_SUCCESS);
- bsOut.WriteCasted<uint16_t>(groupJoined->usersInRoom.Size());
- for (unsigned int i=0; i < groupJoined->usersInRoom.Size(); i++)
- {
- bsOut.WriteCompressed(groupJoined->usersInRoom[i].str);
- }
- }
- else
- {
- bsOut.WriteCasted<MessageID>(RPE_JOIN_GROUP_FAILURE);
- }
- SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
- }
- void RelayPlugin::OnLeaveGroupRequestFromClient(Packet *packet)
- {
- BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID)*2);
- StrAndGuidAndRoom **strAndGuidSender = guidToStrHash.Peek(packet->guid);
- if (strAndGuidSender)
- LeaveGroup(strAndGuidSender);
- }
- #endif // _RAKNET_SUPPORT_*
|