#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