summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/network.cpp2
-rw-r--r--src/network/room.cpp63
-rw-r--r--src/network/room.h1
-rw-r--r--src/network/room_member.cpp57
-rw-r--r--src/network/room_member.h35
5 files changed, 156 insertions, 2 deletions
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 0841e4134..6652a186b 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -15,7 +15,7 @@ RoomNetwork::RoomNetwork() {
bool RoomNetwork::Init() {
if (enet_initialize() != 0) {
- LOG_ERROR(Network, "Error initalizing ENet");
+ LOG_ERROR(Network, "Error initializing ENet");
return false;
}
m_room = std::make_shared<Room>();
diff --git a/src/network/room.cpp b/src/network/room.cpp
index 8c63b255b..dc5dbce7f 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -212,6 +212,12 @@ public:
void HandleProxyPacket(const ENetEvent* event);
/**
+ * Broadcasts this packet to all members except the sender.
+ * @param event The ENet event containing the data
+ */
+ void HandleLdnPacket(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.
*/
@@ -247,6 +253,9 @@ void Room::RoomImpl::ServerLoop() {
case IdProxyPacket:
HandleProxyPacket(&event);
break;
+ case IdLdnPacket:
+ HandleLdnPacket(&event);
+ break;
case IdChatMessage:
HandleChatPacket(&event);
break;
@@ -861,6 +870,60 @@ void Room::RoomImpl::HandleProxyPacket(const ENetEvent* event) {
enet_host_flush(server);
}
+void Room::RoomImpl::HandleLdnPacket(const ENetEvent* event) {
+ Packet in_packet;
+ in_packet.Append(event->packet->data, event->packet->dataLength);
+
+ in_packet.IgnoreBytes(sizeof(u8)); // Message type
+
+ in_packet.IgnoreBytes(sizeof(u8)); // LAN packet type
+ in_packet.IgnoreBytes(sizeof(IPv4Address)); // Local IP
+
+ IPv4Address remote_ip;
+ in_packet.Read(remote_ip); // Remote IP
+
+ bool broadcast;
+ in_packet.Read(broadcast); // Broadcast
+
+ Packet out_packet;
+ out_packet.Append(event->packet->data, event->packet->dataLength);
+ ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(),
+ ENET_PACKET_FLAG_RELIABLE);
+
+ const auto& destination_address = remote_ip;
+ if (broadcast) { // Send the data to everyone except the sender
+ std::lock_guard lock(member_mutex);
+ bool sent_packet = false;
+ for (const auto& member : members) {
+ if (member.peer != event->peer) {
+ sent_packet = true;
+ enet_peer_send(member.peer, 0, enet_packet);
+ }
+ }
+
+ if (!sent_packet) {
+ enet_packet_destroy(enet_packet);
+ }
+ } else {
+ std::lock_guard lock(member_mutex);
+ auto member = std::find_if(members.begin(), members.end(),
+ [destination_address](const Member& member_entry) -> bool {
+ return member_entry.fake_ip == destination_address;
+ });
+ if (member != members.end()) {
+ enet_peer_send(member->peer, 0, enet_packet);
+ } else {
+ LOG_ERROR(Network,
+ "Attempting to send to unknown IP address: "
+ "{}.{}.{}.{}",
+ destination_address[0], destination_address[1], destination_address[2],
+ destination_address[3]);
+ enet_packet_destroy(enet_packet);
+ }
+ }
+ enet_host_flush(server);
+}
+
void Room::RoomImpl::HandleChatPacket(const ENetEvent* event) {
Packet in_packet;
in_packet.Append(event->packet->data, event->packet->dataLength);
diff --git a/src/network/room.h b/src/network/room.h
index c2a4b1a70..edbd3ecfb 100644
--- a/src/network/room.h
+++ b/src/network/room.h
@@ -40,6 +40,7 @@ enum RoomMessageTypes : u8 {
IdRoomInformation,
IdSetGameInfo,
IdProxyPacket,
+ IdLdnPacket,
IdChatMessage,
IdNameCollision,
IdIpCollision,
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index 06818af78..b94cb24ad 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -58,6 +58,7 @@ public:
private:
CallbackSet<ProxyPacket> callback_set_proxy_packet;
+ CallbackSet<LDNPacket> callback_set_ldn_packet;
CallbackSet<ChatEntry> callback_set_chat_messages;
CallbackSet<StatusMessageEntry> callback_set_status_messages;
CallbackSet<RoomInformation> callback_set_room_information;
@@ -108,6 +109,12 @@ public:
void HandleProxyPackets(const ENetEvent* event);
/**
+ * Extracts an LdnPacket from a received ENet packet.
+ * @param event The ENet event that was received.
+ */
+ void HandleLdnPackets(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.
*/
@@ -166,6 +173,9 @@ void RoomMember::RoomMemberImpl::MemberLoop() {
case IdProxyPacket:
HandleProxyPackets(&event);
break;
+ case IdLdnPacket:
+ HandleLdnPackets(&event);
+ break;
case IdChatMessage:
HandleChatPacket(&event);
break;
@@ -372,6 +382,27 @@ void RoomMember::RoomMemberImpl::HandleProxyPackets(const ENetEvent* event) {
Invoke<ProxyPacket>(proxy_packet);
}
+void RoomMember::RoomMemberImpl::HandleLdnPackets(const ENetEvent* event) {
+ LDNPacket ldn_packet{};
+ Packet packet;
+ packet.Append(event->packet->data, event->packet->dataLength);
+
+ // Ignore the first byte, which is the message id.
+ packet.IgnoreBytes(sizeof(u8)); // Ignore the message type
+
+ u8 packet_type;
+ packet.Read(packet_type);
+ ldn_packet.type = static_cast<LDNPacketType>(packet_type);
+
+ packet.Read(ldn_packet.local_ip);
+ packet.Read(ldn_packet.remote_ip);
+ packet.Read(ldn_packet.broadcast);
+
+ packet.Read(ldn_packet.data);
+
+ Invoke<LDNPacket>(ldn_packet);
+}
+
void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) {
Packet packet;
packet.Append(event->packet->data, event->packet->dataLength);
@@ -450,6 +481,11 @@ RoomMember::RoomMemberImpl::CallbackSet<ProxyPacket>& RoomMember::RoomMemberImpl
}
template <>
+RoomMember::RoomMemberImpl::CallbackSet<LDNPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() {
+ return callback_set_ldn_packet;
+}
+
+template <>
RoomMember::RoomMemberImpl::CallbackSet<RoomMember::State>&
RoomMember::RoomMemberImpl::Callbacks::Get() {
return callback_set_state;
@@ -607,6 +643,21 @@ void RoomMember::SendProxyPacket(const ProxyPacket& proxy_packet) {
room_member_impl->Send(std::move(packet));
}
+void RoomMember::SendLdnPacket(const LDNPacket& ldn_packet) {
+ Packet packet;
+ packet.Write(static_cast<u8>(IdLdnPacket));
+
+ packet.Write(static_cast<u8>(ldn_packet.type));
+
+ packet.Write(ldn_packet.local_ip);
+ packet.Write(ldn_packet.remote_ip);
+ packet.Write(ldn_packet.broadcast);
+
+ packet.Write(ldn_packet.data);
+
+ room_member_impl->Send(std::move(packet));
+}
+
void RoomMember::SendChatMessage(const std::string& message) {
Packet packet;
packet.Write(static_cast<u8>(IdChatMessage));
@@ -663,6 +714,11 @@ RoomMember::CallbackHandle<ProxyPacket> RoomMember::BindOnProxyPacketReceived(
return room_member_impl->Bind(callback);
}
+RoomMember::CallbackHandle<LDNPacket> RoomMember::BindOnLdnPacketReceived(
+ std::function<void(const LDNPacket&)> callback) {
+ return room_member_impl->Bind(std::move(callback));
+}
+
RoomMember::CallbackHandle<RoomInformation> RoomMember::BindOnRoomInformationChanged(
std::function<void(const RoomInformation&)> callback) {
return room_member_impl->Bind(callback);
@@ -699,6 +755,7 @@ void RoomMember::Leave() {
}
template void RoomMember::Unbind(CallbackHandle<ProxyPacket>);
+template void RoomMember::Unbind(CallbackHandle<LDNPacket>);
template void RoomMember::Unbind(CallbackHandle<RoomMember::State>);
template void RoomMember::Unbind(CallbackHandle<RoomMember::Error>);
template void RoomMember::Unbind(CallbackHandle<RoomInformation>);
diff --git a/src/network/room_member.h b/src/network/room_member.h
index f578f7f6a..0d6417294 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -17,7 +17,24 @@ namespace Network {
using AnnounceMultiplayerRoom::GameInfo;
using AnnounceMultiplayerRoom::RoomInformation;
-/// Information about the received WiFi packets.
+enum class LDNPacketType : u8 {
+ Scan,
+ ScanResp,
+ Connect,
+ SyncNetwork,
+ Disconnect,
+ DestroyNetwork,
+};
+
+struct LDNPacket {
+ LDNPacketType type;
+ IPv4Address local_ip;
+ IPv4Address remote_ip;
+ bool broadcast;
+ std::vector<u8> data;
+};
+
+/// Information about the received proxy packets.
struct ProxyPacket {
SockAddrIn local_endpoint;
SockAddrIn remote_endpoint;
@@ -152,6 +169,12 @@ public:
void SendProxyPacket(const ProxyPacket& packet);
/**
+ * Sends an LDN packet to the room.
+ * @param packet The WiFi packet to send.
+ */
+ void SendLdnPacket(const LDNPacket& packet);
+
+ /**
* Sends a chat message to the room.
* @param message The contents of the message.
*/
@@ -205,6 +228,16 @@ public:
std::function<void(const ProxyPacket&)> callback);
/**
+ * Binds a function to an event that will be triggered every time an LDNPacket is received.
+ * The function wil be called everytime the event is triggered.
+ * The callback function must not bind or unbind a function. Doing so will cause a deadlock
+ * @param callback The function to call
+ * @return A handle used for removing the function from the registered list
+ */
+ CallbackHandle<LDNPacket> BindOnLdnPacketReceived(
+ std::function<void(const LDNPacket&)> callback);
+
+ /**
* Binds a function to an event that will be triggered every time the RoomInformation changes.
* The function wil be called every time the event is triggered.
* The callback function must not bind or unbind a function. Doing so will cause a deadlock