From 27a3581af14abe5b0b353ae31d8c6dd57984804f Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Mon, 19 Aug 2024 15:24:44 +0200 Subject: [PATCH] moved network interface --- godot/Scenes/Network/networking.tscn | 4 +- godot/Scenes/main.tscn | 5 +- .../godot}/NetworkInterface.h | 16 ++- include/client/Lobby.h | 32 ----- include/client/MainMenu.h | 7 + include/client/Server.h | 12 +- src/blitz/godot/NetworkInterface.cpp | 129 ++++++++++++++++++ src/client/Lobby.cpp | 99 -------------- src/client/Main.cpp | 1 - src/client/MainMenu.cpp | 29 +++- src/client/NetworkInterface.cpp | 50 ------- src/client/Server.cpp | 11 +- src/client/World.cpp | 7 +- src/client/register_types.cpp | 4 +- 14 files changed, 190 insertions(+), 216 deletions(-) rename include/{client => blitz/godot}/NetworkInterface.h (65%) delete mode 100644 include/client/Lobby.h create mode 100644 src/blitz/godot/NetworkInterface.cpp delete mode 100644 src/client/Lobby.cpp delete mode 100644 src/client/NetworkInterface.cpp diff --git a/godot/Scenes/Network/networking.tscn b/godot/Scenes/Network/networking.tscn index 9ad3fb5..edbb3c6 100644 --- a/godot/Scenes/Network/networking.tscn +++ b/godot/Scenes/Network/networking.tscn @@ -1,5 +1,3 @@ [gd_scene format=3 uid="uid://clafls1xhludi"] -[node name="Lobby" type="Lobby"] - -[node name="NetworkInterface" type="NetworkInterface" parent="."] +[node name="NetworkInterface" type="NetworkInterface"] diff --git a/godot/Scenes/main.tscn b/godot/Scenes/main.tscn index 0a6779b..1312a1c 100644 --- a/godot/Scenes/main.tscn +++ b/godot/Scenes/main.tscn @@ -5,11 +5,8 @@ [node name="Main" type="Main"] -[node name="Lobby" parent="." instance=ExtResource("1_06ibn")] +[node name="Network" parent="." instance=ExtResource("1_06ibn")] [node name="MainMenu" parent="." instance=ExtResource("2_lavg1")] -[connection signal="local_player_connected" from="Lobby" to="MainMenu" method="on_connected"] [connection signal="change_scene" from="MainMenu" to="." method="change_scene"] -[connection signal="create_game" from="MainMenu" to="Lobby" method="create_game"] -[connection signal="join_game" from="MainMenu" to="Lobby" method="join_game"] diff --git a/include/client/NetworkInterface.h b/include/blitz/godot/NetworkInterface.h similarity index 65% rename from include/client/NetworkInterface.h rename to include/blitz/godot/NetworkInterface.h index 6b6510e..5f53cb1 100644 --- a/include/client/NetworkInterface.h +++ b/include/blitz/godot/NetworkInterface.h @@ -1,10 +1,11 @@ #pragma once +#include #include #include -#include namespace blitz { + class NetworkInterface : public godot::Node, public protocol::PacketDispatcher { GDCLASS(NetworkInterface, godot::Node) protected: @@ -17,10 +18,21 @@ class NetworkInterface : public godot::Node, public protocol::PacketDispatcher { void BroadcastPacket(const protocol::Packet& a_Packet); void SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet); + godot::Error JoinGame(const godot::String& a_Address, uint16_t a_Port); + godot::Error CreateGame(uint16_t a_Port, bool a_Dedicated = false); + + void ShutdownNetwork(); + void _ready() override; - + private: void RecievePacketDataReliable(godot::PackedByteArray a_PacketData); + + void OnPlayerConnected(PeerID a_PeerId); + void OnPlayerDisconnected(PeerID a_PeerId); + void OnConnectOk(); + void OnConnectFail(); + void OnServerDisconnected(); }; } // namespace blitz \ No newline at end of file diff --git a/include/client/Lobby.h b/include/client/Lobby.h deleted file mode 100644 index f612a6b..0000000 --- a/include/client/Lobby.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include - -namespace blitz { - -class Lobby : public godot::Node { - GDCLASS(Lobby, godot::Node) - protected: - static void _bind_methods(); - - public: - Lobby(); - ~Lobby(); - - void _ready() override; - - godot::Error JoinGame(const godot::String& a_Address, uint16_t a_Port); - godot::Error CreateGame(uint16_t a_Port, bool a_Dedicated = false); - - void Shutdown(); - - private: - void OnPlayerConnected(PeerID a_PeerId); - void OnPlayerDisconnected(PeerID a_PeerId); - void OnConnectOk(); - void OnConnectFail(); - void OnServerDisconnected(); -}; - -} // namespace blitz \ No newline at end of file diff --git a/include/client/MainMenu.h b/include/client/MainMenu.h index 488861a..73157c9 100644 --- a/include/client/MainMenu.h +++ b/include/client/MainMenu.h @@ -2,6 +2,7 @@ #include #include +#include namespace blitz { @@ -22,11 +23,17 @@ class MainMenu : public godot::Control { godot::Button* m_CreateButton; godot::Button* m_QuitButton; + NetworkInterface* m_NetworkInterface; + void OnConnected(); + void OnDisconnected(); void OnJoinPressed(); void OnCreatePressed(); void OnQuitPressed(); + + void DisableButtons(); + void EnableButtons(); }; } // namespace blitz \ No newline at end of file diff --git a/include/client/Server.h b/include/client/Server.h index c2debff..2f6c7ab 100644 --- a/include/client/Server.h +++ b/include/client/Server.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace blitz { @@ -19,14 +19,14 @@ class Server : public godot::Node { void _ready() override; - void OnPlayerConnect(PeerID a_PeerId); - void OnPlayerDisconnect(PeerID a_PeerId); + void OnPlayerConnect(PeerID a_PeerId); + void OnPlayerDisconnect(PeerID a_PeerId); private: - Lobby* m_Lobby; - NetworkInterface* m_NetworkInterface; + Lobby* m_Lobby; + NetworkInterface* m_NetworkInterface; - godot::TypedArray m_Peers; + godot::TypedArray m_Peers; }; } // namespace blitz \ No newline at end of file diff --git a/src/blitz/godot/NetworkInterface.cpp b/src/blitz/godot/NetworkInterface.cpp new file mode 100644 index 0000000..a412d2c --- /dev/null +++ b/src/blitz/godot/NetworkInterface.cpp @@ -0,0 +1,129 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace blitz { + +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); + + // server + ADD_SIGNAL(MethodInfo("player_connected", PropertyInfo(Variant::INT, "peer_id"))); + ADD_SIGNAL(MethodInfo("player_disconnected", PropertyInfo(Variant::INT, "peer_id"))); + + // client + ADD_SIGNAL(MethodInfo("server_disconnected")); + ADD_SIGNAL(MethodInfo("local_player_connected")); + + protocol::PacketFactory::Init(); +} + +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); + + get_multiplayer()->connect("peer_connected", callable_mp(this, &NetworkInterface::OnPlayerConnected)); + get_multiplayer()->connect("peer_disconnected", callable_mp(this, &NetworkInterface::OnPlayerDisconnected)); + get_multiplayer()->connect("connected_to_server", callable_mp(this, &NetworkInterface::OnConnectOk)); + get_multiplayer()->connect("connection_failed", callable_mp(this, &NetworkInterface::OnConnectFail)); + get_multiplayer()->connect("server_disconnected", callable_mp(this, &NetworkInterface::OnServerDisconnected)); +} + +void NetworkInterface::BroadcastPacket(const protocol::Packet& a_Packet) { + PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); + rpc("RecievePacketDataReliable", byteArray); +} + +void NetworkInterface::SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet) { + PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); + rpc_id(a_Peer, "RecievePacketDataReliable", byteArray); +} + +void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_PacketData) { + 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); + if (error) { + OnConnectFail(); + return error; + } + + get_multiplayer()->set_multiplayer_peer(peer); + return Error::OK; +} + +Error NetworkInterface::CreateGame(uint16_t a_Port, bool a_Dedicated) { + auto* peer = memnew(ENetMultiplayerPeer); + Error error = peer->create_server(a_Port); + if (error) + return error; + + get_multiplayer()->set_multiplayer_peer(peer); + + Ref serverScene = ResourceLoader::get_singleton()->load(ServerScenePath); + add_child(serverScene->instantiate()); + + if (!a_Dedicated) { + emit_signal("local_player_connected"); + emit_signal("player_connected", get_multiplayer()->get_unique_id()); + } + + return Error::OK; +} + +void NetworkInterface::OnPlayerConnected(PeerID a_PeerId) { + emit_signal("player_connected", a_PeerId); +} + +void NetworkInterface::OnPlayerDisconnected(PeerID a_PeerId) { + emit_signal("player_disconnected", a_PeerId); +} + +void NetworkInterface::OnConnectOk() { + emit_signal("local_player_connected"); +} + +void NetworkInterface::OnConnectFail() { + ShutdownNetwork(); + emit_signal("server_disconnected"); +} + +void NetworkInterface::OnServerDisconnected() { + ShutdownNetwork(); + emit_signal("server_disconnected"); +} + +void NetworkInterface::ShutdownNetwork() { + get_multiplayer()->set_multiplayer_peer(nullptr); + if (auto* server = find_child("Server")) { + server->queue_free(); + } +} + +} // namespace blitz \ No newline at end of file diff --git a/src/client/Lobby.cpp b/src/client/Lobby.cpp deleted file mode 100644 index 07f2ccb..0000000 --- a/src/client/Lobby.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -using namespace godot; - -static const char ServerScenePath[] = "res://Scenes/Network/server.tscn"; - -namespace blitz { - -void Lobby::_bind_methods() { - godot::ClassDB::bind_method(godot::D_METHOD("create_game", "port", "dedicated"), &Lobby::CreateGame); - godot::ClassDB::bind_method(godot::D_METHOD("join_game", "address", "port"), &Lobby::JoinGame); - ADD_SIGNAL(MethodInfo("player_connected", PropertyInfo(Variant::INT, "peer_id"))); - ADD_SIGNAL(MethodInfo("player_disconnected", PropertyInfo(Variant::INT, "peer_id"))); - ADD_SIGNAL(MethodInfo("server_disconnected")); - ADD_SIGNAL(MethodInfo("local_player_connected")); -} - -Lobby::Lobby() {} - -Lobby::~Lobby() {} - -void Lobby::_ready() { - get_multiplayer()->connect("peer_connected", callable_mp(this, &Lobby::OnPlayerConnected)); - get_multiplayer()->connect("peer_disconnected", callable_mp(this, &Lobby::OnPlayerDisconnected)); - get_multiplayer()->connect("connected_to_server", callable_mp(this, &Lobby::OnConnectOk)); - get_multiplayer()->connect("connection_failed", callable_mp(this, &Lobby::OnConnectFail)); - get_multiplayer()->connect("server_disconnected", callable_mp(this, &Lobby::OnServerDisconnected)); -} - -Error Lobby::JoinGame(const String& a_Address, uint16_t a_Port) { - auto* peer = memnew(ENetMultiplayerPeer); - Error error = peer->create_client(a_Address, a_Port); - if (error) - return error; - - get_multiplayer()->set_multiplayer_peer(peer); - return Error::OK; -} - -Error Lobby::CreateGame(uint16_t a_Port, bool a_Dedicated) { - auto* peer = memnew(ENetMultiplayerPeer); - Error error = peer->create_server(a_Port); - if (error) - return error; - - get_multiplayer()->set_multiplayer_peer(peer); - - Ref serverScene = ResourceLoader::get_singleton()->load(ServerScenePath); - add_child(serverScene->instantiate()); - - if (!a_Dedicated) { - emit_signal("local_player_connected"); - emit_signal("player_connected", get_multiplayer()->get_unique_id()); - } - - return Error::OK; -} - -void Lobby::Shutdown() { - get_multiplayer()->set_multiplayer_peer(nullptr); - if (auto* server = find_child("Server")) { - remove_child(server); - } -} - -void Lobby::OnPlayerConnected(PeerID a_PeerId) { - if (get_multiplayer()->is_server()) { - emit_signal("player_connected", a_PeerId); - } -} - -void Lobby::OnPlayerDisconnected(PeerID a_PeerId) { - if (get_multiplayer()->is_server()) { - emit_signal("player_disconnected", a_PeerId); - } -} - -void Lobby::OnConnectOk() { - int32_t peerId = get_multiplayer()->get_unique_id(); - emit_signal("local_player_connected"); -} - -void Lobby::OnConnectFail() { - Shutdown(); -} - -void Lobby::OnServerDisconnected() { - Shutdown(); - emit_signal("server_disconnected"); -} - -} // namespace blitz \ No newline at end of file diff --git a/src/client/Main.cpp b/src/client/Main.cpp index 057fc23..920e8b2 100644 --- a/src/client/Main.cpp +++ b/src/client/Main.cpp @@ -7,7 +7,6 @@ #include #include -#include #include using namespace godot; diff --git a/src/client/MainMenu.cpp b/src/client/MainMenu.cpp index f2de218..7308ddc 100644 --- a/src/client/MainMenu.cpp +++ b/src/client/MainMenu.cpp @@ -9,8 +9,6 @@ namespace blitz { void MainMenu::_bind_methods() { godot::ClassDB::bind_method(godot::D_METHOD("on_connected"), &MainMenu::OnConnected); - ADD_SIGNAL(MethodInfo("create_game", PropertyInfo(Variant::INT, "port"), PropertyInfo(Variant::BOOL, "dedicated"))); - ADD_SIGNAL(MethodInfo("join_game", PropertyInfo(Variant::STRING, "address"), PropertyInfo(Variant::INT, "port"))); ADD_SIGNAL(MethodInfo("change_scene")); } @@ -30,9 +28,15 @@ void MainMenu::_ready() { DEV_ASSERT(m_CreateButton); DEV_ASSERT(m_QuitButton); + m_NetworkInterface = Object::cast_to(get_parent()->find_child("Network")); + DEV_ASSERT(m_NetworkInterface); + m_JoinButton->connect("pressed", callable_mp(this, &MainMenu::OnJoinPressed)); m_CreateButton->connect("pressed", callable_mp(this, &MainMenu::OnCreatePressed)); m_QuitButton->connect("pressed", callable_mp(this, &MainMenu::OnQuitPressed)); + + m_NetworkInterface->connect("local_player_connected", callable_mp(this, &MainMenu::OnConnected)); + m_NetworkInterface->connect("server_disconnected", callable_mp(this, &MainMenu::OnDisconnected)); } void MainMenu::OnConnected() { @@ -40,16 +44,33 @@ void MainMenu::OnConnected() { set_visible(false); } +void MainMenu::OnDisconnected() { + set_visible(true); + EnableButtons(); +} + void MainMenu::OnJoinPressed() { - emit_signal("join_game", "localhost", 25565); + DisableButtons(); + m_NetworkInterface->JoinGame("localhost", 25565); } void MainMenu::OnCreatePressed() { - emit_signal("create_game", 25565, false); + DisableButtons(); + m_NetworkInterface->CreateGame(25565); } void MainMenu::OnQuitPressed() { get_tree()->quit(); } +void MainMenu::DisableButtons() { + m_JoinButton->set_disabled(true); + m_CreateButton->set_disabled(true); +} + +void MainMenu::EnableButtons() { + m_JoinButton->set_disabled(false); + m_CreateButton->set_disabled(false); +} + } // namespace blitz \ No newline at end of file diff --git a/src/client/NetworkInterface.cpp b/src/client/NetworkInterface.cpp deleted file mode 100644 index 357f17c..0000000 --- a/src/client/NetworkInterface.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -namespace blitz { - -using namespace godot; - -void NetworkInterface::_bind_methods() { - ClassDB::bind_method(D_METHOD("RecievePacketDataReliable", "a_PacketData"), &NetworkInterface::RecievePacketDataReliable); - protocol::PacketFactory::Init(); -} - -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); -} - -void NetworkInterface::BroadcastPacket(const protocol::Packet& a_Packet) { - PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); - rpc("RecievePacketDataReliable", byteArray); -} - -void NetworkInterface::SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet) { - PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet); - rpc_id(a_Peer, "RecievePacketDataReliable", byteArray); -} - -void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_PacketData) { - auto packet = protocol::PacketSerializer::Deserialize(a_PacketData); - if (packet) { - packet->m_Sender = get_multiplayer()->get_remote_sender_id(); - Dispatch(*packet); - } -} - -} // namespace blitz \ No newline at end of file diff --git a/src/client/Server.cpp b/src/client/Server.cpp index cdb395a..9491cb0 100644 --- a/src/client/Server.cpp +++ b/src/client/Server.cpp @@ -1,7 +1,6 @@ #include -#include -#include +#include #include using namespace godot; @@ -19,13 +18,11 @@ void Server::_ready() { return; - m_Lobby = Object::cast_to(get_parent()); - DEV_ASSERT(m_Lobby); - m_NetworkInterface = Object::cast_to(m_Lobby->find_child("NetworkInterface")); + m_NetworkInterface = Object::cast_to(get_parent()); DEV_ASSERT(m_NetworkInterface); - m_Lobby->connect("player_connected", callable_mp(this, &Server::OnPlayerConnect)); - m_Lobby->connect("player_disconnected", callable_mp(this, &Server::OnPlayerDisconnect)); + m_NetworkInterface->connect("player_connected", callable_mp(this, &Server::OnPlayerConnect)); + m_NetworkInterface->connect("player_disconnected", callable_mp(this, &Server::OnPlayerDisconnect)); } void Server::OnPlayerConnect(PeerID a_PeerId) { diff --git a/src/client/World.cpp b/src/client/World.cpp index a8d0532..2d4d598 100644 --- a/src/client/World.cpp +++ b/src/client/World.cpp @@ -1,7 +1,7 @@ #include +#include #include -#include #include #include #include @@ -26,10 +26,7 @@ void World::_ready() { m_Players = find_child("Players"); DEV_ASSERT(m_Players); - auto* lobby = get_parent()->find_child("Lobby"); - DEV_ASSERT(lobby); - - m_NetworkInterface = Object::cast_to(lobby->find_child("NetworkInterface")); + m_NetworkInterface = Object::cast_to(get_parent()->find_child("Network")); DEV_ASSERT(m_NetworkInterface); m_NetworkInterface->RegisterHandler(protocol::PacketType::PlayerJoin, *this); diff --git a/src/client/register_types.cpp b/src/client/register_types.cpp index 334ef00..1e02b45 100644 --- a/src/client/register_types.cpp +++ b/src/client/register_types.cpp @@ -1,8 +1,7 @@ +#include #include -#include #include #include -#include #include #include #include @@ -17,7 +16,6 @@ static void RegisterClasses() { GDREGISTER_CLASS(blitz::Player); GDREGISTER_CLASS(blitz::FirstPersonPlayer); GDREGISTER_CLASS(blitz::MainMenu); - GDREGISTER_CLASS(blitz::Lobby); GDREGISTER_CLASS(blitz::World); GDREGISTER_CLASS(blitz::Main); GDREGISTER_CLASS(blitz::NetworkInterface);