summaryrefslogtreecommitdiff
path: root/modules/enet/networked_multiplayer_enet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/enet/networked_multiplayer_enet.cpp')
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp81
1 files changed, 57 insertions, 24 deletions
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index a787cd3b80..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));
@@ -440,6 +450,8 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
if (E->get()) {
enet_peer_disconnect_now(E->get(), unique_id);
+ int *id = (int *)(E->get()->data);
+ memdelete(id);
peers_disconnected = true;
}
}
@@ -455,6 +467,7 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
enet_host_destroy(host);
active = false;
incoming_packets.clear();
+ peer_map.clear();
unique_id = 1; // Server is 1
connection_status = CONNECTION_DISCONNECTED;
}
@@ -471,10 +484,13 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
// enet_peer_disconnect_now doesn't generate ENET_EVENT_TYPE_DISCONNECT,
// notify everyone else, send disconnect signal & remove from peer_map like in poll()
+ int *id = NULL;
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
- if (E->key() == p_peer)
+ if (E->key() == p_peer) {
+ id = (int *)(E->get()->data);
continue;
+ }
ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
@@ -482,6 +498,9 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
}
+ if (id)
+ memdelete(id);
+
emit_signal("peer_disconnected", p_peer);
peer_map.erase(p_peer);
} else {
@@ -818,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));
@@ -838,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);
@@ -856,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;