ldn: Initial implementation
This commit is contained in:
parent
0cef3b47f3
commit
f5e635adda
15 changed files with 1134 additions and 126 deletions
|
@ -211,6 +211,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);
|
||||
|
|
|
@ -40,6 +40,7 @@ enum RoomMessageTypes : u8 {
|
|||
IdRoomInformation,
|
||||
IdSetGameInfo,
|
||||
IdProxyPacket,
|
||||
IdLdnPacket,
|
||||
IdChatMessage,
|
||||
IdNameCollision,
|
||||
IdIpCollision,
|
||||
|
|
|
@ -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;
|
||||
|
@ -107,6 +108,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);
|
||||
|
@ -449,6 +480,11 @@ RoomMember::RoomMemberImpl::CallbackSet<ProxyPacket>& RoomMember::RoomMemberImpl
|
|||
return callback_set_proxy_packet;
|
||||
}
|
||||
|
||||
template <>
|
||||
RoomMember::RoomMemberImpl::CallbackSet<LDNPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() {
|
||||
return callback_set_ldn_packet;
|
||||
}
|
||||
|
||||
template <>
|
||||
RoomMember::RoomMemberImpl::CallbackSet<RoomMember::State>&
|
||||
RoomMember::RoomMemberImpl::Callbacks::Get() {
|
||||
|
@ -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(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>);
|
||||
|
|
|
@ -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;
|
||||
|
@ -151,6 +168,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.
|
||||
|
@ -204,6 +227,16 @@ public:
|
|||
CallbackHandle<ProxyPacket> BindOnProxyPacketReceived(
|
||||
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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue