From 03b6e577ea04f9884918946fd4ee7147c5b25d7d Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 20 Aug 2024 19:27:20 +0200 Subject: [PATCH] unreliable packets --- include/blitz/godot/NetworkInterface.h | 2 + include/blitz/protocol/PacketDeclare.h | 4 +- include/blitz/protocol/PacketSender.h | 57 ++++++++++++++++++++++++++ src/blitz/godot/NetworkInterface.cpp | 57 ++++++++++++++++++++------ src/blitz/protocol/PacketSender.cpp | 39 ++++++++++++++++++ 5 files changed, 144 insertions(+), 15 deletions(-) create mode 100644 include/blitz/protocol/PacketSender.h create mode 100644 src/blitz/protocol/PacketSender.cpp diff --git a/include/blitz/godot/NetworkInterface.h b/include/blitz/godot/NetworkInterface.h index 5f53cb1..483a190 100644 --- a/include/blitz/godot/NetworkInterface.h +++ b/include/blitz/godot/NetworkInterface.h @@ -27,6 +27,8 @@ class NetworkInterface : public godot::Node, public protocol::PacketDispatcher { private: void RecievePacketDataReliable(godot::PackedByteArray a_PacketData); + void RecievePacketDataUnreliable(godot::PackedByteArray a_PacketData); + void RecievePacketDataUnreliableOrdered(godot::PackedByteArray a_PacketData); void OnPlayerConnected(PeerID a_PeerId); void OnPlayerDisconnected(PeerID a_PeerId); diff --git a/include/blitz/protocol/PacketDeclare.h b/include/blitz/protocol/PacketDeclare.h index a4340cb..101671c 100644 --- a/include/blitz/protocol/PacketDeclare.h +++ b/include/blitz/protocol/PacketDeclare.h @@ -12,7 +12,7 @@ namespace protocol { * \enum PacketSender * \brief Indicate who should send a packet */ -enum class PacketSender { +enum class PacketSenderType { /** Sent by clients and server */ Both, /** Sent by clients to the server */ @@ -36,7 +36,7 @@ enum class PacketSender { DeclarePacket(PlayerLeave, Reliable, Server) \ DeclarePacket(PlayerList, Reliable, Server) \ DeclarePacket(PlayerLogin, Reliable, Client) \ - DeclarePacket(PlayerPositionAndRotation, Reliable, Both) \ + DeclarePacket(PlayerPositionAndRotation, Unreliable, Both) \ DeclarePacket(PlayerShoot, Reliable, Both) \ DeclarePacket(PlayerStats, Reliable, Server) \ DeclarePacket(ServerConfig, Reliable, Server) \ diff --git a/include/blitz/protocol/PacketSender.h b/include/blitz/protocol/PacketSender.h new file mode 100644 index 0000000..e33f9d6 --- /dev/null +++ b/include/blitz/protocol/PacketSender.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +namespace blitz { + +class NetworkInterface; + +namespace protocol { + +/////////////////////// +/* PacketBroadcaster */ +/////////////////////// + +#define DeclarePacket(PacketName, Reliability, ...) void Visit(const protocol::packets::PacketName& a_Packet) override; + +class PacketBroadcaster : public protocol::PacketVisitor { + private: + NetworkInterface& m_NetworkInterface; + + public: + PacketBroadcaster(NetworkInterface& a_NetworkInterface) : m_NetworkInterface(a_NetworkInterface) {} + + void BroadcastPacket(const protocol::Packet& a_Packet) { + Check(a_Packet); + } + + DeclareAllPacket() +}; + + + + + + +////////////////// +/* PacketSender */ +////////////////// +class PacketSender : public protocol::PacketVisitor { + private: + NetworkInterface& m_NetworkInterface; + PeerID m_PeerId; + + public: + PacketSender(PeerID a_PeerId, NetworkInterface& a_NetworkInterface) : m_PeerId(a_PeerId), m_NetworkInterface(a_NetworkInterface) {} + + void SendPacket(const protocol::Packet& a_Packet) { + Check(a_Packet); + } + + DeclareAllPacket() +}; + +#undef DeclarePacket + +} // namespace protocol +} // namespace blitz diff --git a/src/blitz/godot/NetworkInterface.cpp b/src/blitz/godot/NetworkInterface.cpp index a412d2c..d69bfde 100644 --- a/src/blitz/godot/NetworkInterface.cpp +++ b/src/blitz/godot/NetworkInterface.cpp @@ -1,21 +1,37 @@ #include #include +#include #include +#include #include #include #include #include #include + namespace blitz { +#define RPC_CONFIG(functionName, rpc_mode, transfer_mode, call_local, channel) \ + { \ + Dictionary config; \ + config["rpc_mode"] = rpc_mode; \ + config["transfer_mode"] = transfer_mode; \ + config["call_local"] = call_local; \ + config["channel"] = channel; \ + rpc_config(functionName, config); \ + } + static const char ServerScenePath[] = "res://Scenes/Network/server.tscn"; using namespace godot; void NetworkInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("RecievePacketDataReliable", "a_PacketData"), &NetworkInterface::RecievePacketDataReliable); + ClassDB::bind_method(D_METHOD("RecievePacketDataUnreliable", "a_PacketData"), &NetworkInterface::RecievePacketDataUnreliable); + ClassDB::bind_method( + D_METHOD("RecievePacketDataUnreliableOrdered", "a_PacketData"), &NetworkInterface::RecievePacketDataUnreliableOrdered); // server ADD_SIGNAL(MethodInfo("player_connected", PropertyInfo(Variant::INT, "peer_id"))); @@ -33,13 +49,10 @@ NetworkInterface::NetworkInterface() {} NetworkInterface::~NetworkInterface() {} void NetworkInterface::_ready() { - // TODO: unreliable - Dictionary config; - config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER; - config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; - config["call_local"] = true; - config["channel"] = 0; - rpc_config("RecievePacketDataReliable", config); + RPC_CONFIG("RecievePacketDataReliable", MultiplayerAPI::RPC_MODE_ANY_PEER, MultiplayerPeer::TRANSFER_MODE_RELIABLE, true, 0); + RPC_CONFIG("RecievePacketDataUnreliable", MultiplayerAPI::RPC_MODE_ANY_PEER, MultiplayerPeer::TRANSFER_MODE_UNRELIABLE, true, 1); + RPC_CONFIG("RecievePacketDataUnreliableOrdered", MultiplayerAPI::RPC_MODE_ANY_PEER, + MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED, true, 2); get_multiplayer()->connect("peer_connected", callable_mp(this, &NetworkInterface::OnPlayerConnected)); get_multiplayer()->connect("peer_disconnected", callable_mp(this, &NetworkInterface::OnPlayerDisconnected)); @@ -49,13 +62,13 @@ void NetworkInterface::_ready() { } void NetworkInterface::BroadcastPacket(const protocol::Packet& a_Packet) { - PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); - rpc("RecievePacketDataReliable", byteArray); + protocol::PacketBroadcaster packetBroadcaster(*this); + packetBroadcaster.BroadcastPacket(a_Packet); } void NetworkInterface::SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet) { - PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); - rpc_id(a_Peer, "RecievePacketDataReliable", byteArray); + protocol::PacketSender packetSender(a_Peer, *this); + packetSender.SendPacket(a_Packet); } void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_PacketData) { @@ -66,9 +79,27 @@ void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_Packet } } +void NetworkInterface::RecievePacketDataUnreliable(godot::PackedByteArray a_PacketData) { + // we have to copy the function body in order to preserve the remote sender id + auto packet = protocol::PacketSerializer::Deserialize(a_PacketData); + if (packet) { + packet->m_Sender = get_multiplayer()->get_remote_sender_id(); + Dispatch(*packet); + } +} + +void NetworkInterface::RecievePacketDataUnreliableOrdered(godot::PackedByteArray a_PacketData) { + // we have to copy the function body in order to preserve the remote sender id + auto packet = protocol::PacketSerializer::Deserialize(a_PacketData); + if (packet) { + packet->m_Sender = get_multiplayer()->get_remote_sender_id(); + Dispatch(*packet); + } +} + Error NetworkInterface::JoinGame(const String& a_Address, uint16_t a_Port) { auto* peer = memnew(ENetMultiplayerPeer); - Error error = peer->create_client(a_Address, a_Port); + Error error = peer->create_client(a_Address, a_Port, 3); if (error) { OnConnectFail(); return error; @@ -80,7 +111,7 @@ Error NetworkInterface::JoinGame(const String& a_Address, uint16_t a_Port) { Error NetworkInterface::CreateGame(uint16_t a_Port, bool a_Dedicated) { auto* peer = memnew(ENetMultiplayerPeer); - Error error = peer->create_server(a_Port); + Error error = peer->create_server(a_Port, 50, 3); if (error) return error; diff --git a/src/blitz/protocol/PacketSender.cpp b/src/blitz/protocol/PacketSender.cpp new file mode 100644 index 0000000..33eb245 --- /dev/null +++ b/src/blitz/protocol/PacketSender.cpp @@ -0,0 +1,39 @@ +#include + +#include +#include + +namespace blitz { +namespace protocol { + +/////////////////////// +/* PacketBroadcaster */ +/////////////////////// + +#define DeclarePacket(PacketName, Reliability, ...) \ + void PacketBroadcaster::Visit(const protocol::packets::PacketName& a_Packet) { \ + m_NetworkInterface.rpc("RecievePacketData" #Reliability, protocol::PacketSerializer::Serialize(a_Packet)); \ + } + +DeclareAllPacket() + +#undef DeclarePacket + + + + + +////////////////// +/* PacketSender */ +////////////////// +#define DeclarePacket(PacketName, Reliability, ...) \ + void PacketSender::Visit(const protocol::packets::PacketName& a_Packet) { \ + m_NetworkInterface.rpc_id(m_PeerId, "RecievePacketData" #Reliability, protocol::PacketSerializer::Serialize(a_Packet)); \ + } + + DeclareAllPacket() + +#undef DeclarePacket + +} // namespace protocol +} // namespace blitz