diff --git a/src/network/room.cpp b/src/network/room.cpp index 6dc7db341..0fdb5e68f 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -106,6 +106,12 @@ public: */ void HandleWifiPacket(const ENetEvent* event); + /** + * Extracts a chat entry from a received ENet packet and adds it to the chat queue. + * @param event The ENet event that was received. + */ + void HandleChatPacket(const ENetEvent* event); + /** * Removes the client from the members list if it was in it and announces the change * to all other clients. @@ -128,6 +134,9 @@ void Room::RoomImpl::ServerLoop() { case IdWifiPacket: HandleWifiPacket(&event); break; + case IdChatMessage: + HandleChatPacket(&event); + break; } enet_packet_destroy(event.packet); break; @@ -271,6 +280,35 @@ void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) { enet_host_flush(server); } +void Room::RoomImpl::HandleChatPacket(const ENetEvent* event) { + Packet in_packet; + in_packet.Append(event->packet->data, event->packet->dataLength); + + in_packet.IgnoreBytes(sizeof(MessageID)); + std::string message; + in_packet >> message; + auto CompareNetworkAddress = [&](const Member member) -> bool { + return member.peer == event->peer; + }; + const auto sending_member = std::find_if(members.begin(), members.end(), CompareNetworkAddress); + if (sending_member == members.end()) { + return; // Received a chat message from a unknown sender + } + + Packet out_packet; + out_packet << static_cast(IdChatMessage); + out_packet << sending_member->nickname; + out_packet << message; + + ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(), + ENET_PACKET_FLAG_RELIABLE); + for (auto it = members.begin(); it != members.end(); ++it) { + if (it->peer != event->peer) + enet_peer_send(it->peer, 0, enet_packet); + } + enet_host_flush(server); +} + void Room::RoomImpl::HandleClientDisconnection(ENetPeer* client) { // Remove the client from the members list. members.erase(std::remove_if(members.begin(), members.end(), diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index f919e4de0..d68bb551d 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp @@ -68,6 +68,12 @@ public: * @param event The ENet event that was received. */ void HandleWifiPackets(const ENetEvent* event); + + /** + * Extracts a chat entry from a received ENet packet and adds it to the chat queue. + * @param event The ENet event that was received. + */ + void HandleChatPacket(const ENetEvent* event); }; // RoomMemberImpl @@ -89,6 +95,9 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() { if (event.type == ENET_EVENT_TYPE_RECEIVE) { switch (event.packet->data[0]) { // TODO(B3N30): Handle the other message types + case IdChatMessage: + HandleChatPacket(&event); + break; case IdRoomInformation: HandleRoomInformationPacket(&event); break; @@ -208,6 +217,19 @@ void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) { // TODO(B3N30): Invoke callbacks } +void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) { + Packet packet; + packet.Append(event->packet->data, event->packet->dataLength); + + // Ignore the first byte, which is the message id. + packet.IgnoreBytes(sizeof(MessageID)); + + ChatEntry chat_entry{}; + packet >> chat_entry.nickname; + packet >> chat_entry.message; + // TODO(B3N30): Invoke callbacks +} + // RoomMember RoomMember::RoomMember() : room_member_impl{std::make_unique()} { room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); @@ -273,6 +295,13 @@ void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) { room_member_impl->Send(packet); } +void RoomMember::SendChatMessage(const std::string& message) { + Packet packet; + packet << static_cast(IdChatMessage); + packet << message; + room_member_impl->Send(packet); +} + void RoomMember::Leave() { ASSERT_MSG(room_member_impl->receive_thread != nullptr, "Must be in a room to leave it."); { diff --git a/src/network/room_member.h b/src/network/room_member.h index d23f5d4b6..693aa4e7f 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -24,6 +24,12 @@ struct WifiPacket { uint8_t channel; ///< WiFi channel where this frame was transmitted. }; +/// Represents a chat message. +struct ChatEntry { + std::string nickname; ///< Nickname of the client who sent this message. + std::string message; ///< Body of the message. +}; + /** * This is what a client [person joining a server] would use. * It also has to be used if you host a game yourself (You'd create both, a Room and a @@ -87,6 +93,12 @@ public: */ void SendWifiPacket(const WifiPacket& packet); + /** + * Sends a chat message to the room. + * @param message The contents of the message. + */ + void SendChatMessage(const std::string& message); + /** * Leaves the current room. */