diff options
-rw-r--r-- | doc/classes/Popup.xml | 2 | ||||
-rw-r--r-- | modules/enet/doc_classes/NetworkedMultiplayerENet.xml | 3 | ||||
-rw-r--r-- | modules/enet/networked_multiplayer_enet.cpp | 70 | ||||
-rw-r--r-- | modules/enet/networked_multiplayer_enet.h | 3 |
4 files changed, 54 insertions, 24 deletions
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml index 2357ee2469..6b15b5a1ea 100644 --- a/doc/classes/Popup.xml +++ b/doc/classes/Popup.xml @@ -4,7 +4,7 @@ Base container control for popups and dialogs. </brief_description> <description> - Popup is a base [Control] used to show dialogs and popups. It's a subwindow and modal by default (see [Control]) and has helpers for custom popup behavior. + Popup is a base [Control] used to show dialogs and popups. It's a subwindow and modal by default (see [Control]) and has helpers for custom popup behavior. All popup methods ensure correct placement within the viewport. </description> <tutorials> </tutorials> diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index 4c10588aa6..78a8e94012 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -116,6 +116,9 @@ The compression method used for network packets. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all. </member> <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" /> + <member name="server_relay" type="bool" setter="set_server_relay_enabled" getter="is_server_relay_enabled" default="true"> + Enable or disable the server feature that notifies clients of other peers' connection/disconnection, and relays messages between them. When this option is [code]false[/code], clients won't be automatically notified of other peers and won't be able to send them packets through the server. + </member> <member name="transfer_channel" type="int" setter="set_transfer_channel" getter="get_transfer_channel" default="-1"> Set the default channel to be used to transfer data. By default, this value is [code]-1[/code] which means that ENet will only use 2 channels, one for reliable and one for unreliable packets. Channel [code]0[/code] is reserved, and cannot be used. Setting this member to any value between [code]0[/code] and [member channel_count] (excluded) will force ENet to use that channel for sending data. </member> diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 2f6ed5efc0..2f5307d041 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -255,6 +255,10 @@ void NetworkedMultiplayerENet::poll() { emit_signal("peer_connected", *new_id); if (server) { + // Do not notify other peers when server_relay is disabled. + if (!server_relay) + break; + // Someone connected, notify all the peers available for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { @@ -287,31 +291,34 @@ void NetworkedMultiplayerENet::poll() { if (!server) { emit_signal("connection_failed"); } - } else { + // Never fully connected. + break; + } - if (server) { - // Someone disconnected, notify everyone else - for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { + if (!server) { - if (E->key() == *id) - continue; + // Client just disconnected from server. + emit_signal("server_disconnected"); + close_connection(); + return; + } else if (server_relay) { - ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); - encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]); - encode_uint32(*id, &packet->data[4]); - enet_peer_send(E->get(), SYSCH_CONFIG, packet); - } - } else { - emit_signal("server_disconnected"); - close_connection(); - return; - } + // Server just received a client disconnect and is in relay mode, notify everyone else. + for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) { + + if (E->key() == *id) + continue; - emit_signal("peer_disconnected", *id); - peer_map.erase(*id); - memdelete(id); + ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE); + encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]); + encode_uint32(*id, &packet->data[4]); + enet_peer_send(E->get(), SYSCH_CONFIG, packet); + } } + emit_signal("peer_disconnected", *id); + peer_map.erase(*id); + memdelete(id); } break; case ENET_EVENT_TYPE_RECEIVE: { @@ -361,7 +368,13 @@ void NetworkedMultiplayerENet::poll() { packet.from = *id; - if (target == 0) { + if (target == 1) { + // To myself and only myself + incoming_packets.push_back(packet); + } else if (!server_relay) { + // No other destination is allowed when server is not relaying + continue; + } else if (target == 0) { // Re-send to everyone but sender :| incoming_packets.push_back(packet); @@ -398,9 +411,6 @@ void NetworkedMultiplayerENet::poll() { enet_packet_destroy(packet.packet); } - } else if (target == 1) { - // To myself and only myself - incoming_packets.push_back(packet); } else { // To someone else, specifically ERR_CONTINUE(!peer_map.has(target)); @@ -827,6 +837,16 @@ bool NetworkedMultiplayerENet::is_always_ordered() const { return always_ordered; } +void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) { + ERR_FAIL_COND(active); + + server_relay = p_enabled; +} + +bool NetworkedMultiplayerENet::is_server_relay_enabled() const { + return server_relay; +} + void NetworkedMultiplayerENet::_bind_methods() { ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0)); @@ -847,11 +867,14 @@ void NetworkedMultiplayerENet::_bind_methods() { ClassDB::bind_method(D_METHOD("get_channel_count"), &NetworkedMultiplayerENet::get_channel_count); ClassDB::bind_method(D_METHOD("set_always_ordered", "ordered"), &NetworkedMultiplayerENet::set_always_ordered); ClassDB::bind_method(D_METHOD("is_always_ordered"), &NetworkedMultiplayerENet::is_always_ordered); + ClassDB::bind_method(D_METHOD("set_server_relay_enabled", "enabled"), &NetworkedMultiplayerENet::set_server_relay_enabled); + ClassDB::bind_method(D_METHOD("is_server_relay_enabled"), &NetworkedMultiplayerENet::is_server_relay_enabled); ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "transfer_channel"), "set_transfer_channel", "get_transfer_channel"); ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "always_ordered"), "set_always_ordered", "is_always_ordered"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "server_relay"), "set_server_relay_enabled", "is_server_relay_enabled"); BIND_ENUM_CONSTANT(COMPRESS_NONE); BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER); @@ -865,6 +888,7 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() { active = false; server = false; refuse_connections = false; + server_relay = true; unique_id = 0; target_peer = 0; current_packet.packet = NULL; diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 8dcb202314..1c4c15ae7b 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -78,6 +78,7 @@ private: ENetHost *host; bool refuse_connections; + bool server_relay; ConnectionStatus connection_status; @@ -158,6 +159,8 @@ public: int get_channel_count() const; void set_always_ordered(bool p_ordered); bool is_always_ordered() const; + void set_server_relay_enabled(bool p_enabled); + bool is_server_relay_enabled() const; NetworkedMultiplayerENet(); ~NetworkedMultiplayerENet(); |