You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Add ENet option to disable server relaying.
It's useless when building fully authoritative servers, and prevents various kinds of abuse.
This commit is contained in:
@@ -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 {
|
||||
|
||||
if (server) {
|
||||
// Someone disconnected, notify everyone else
|
||||
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
|
||||
|
||||
if (E->key() == *id)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
emit_signal("peer_disconnected", *id);
|
||||
peer_map.erase(*id);
|
||||
memdelete(id);
|
||||
// Never fully connected.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!server) {
|
||||
|
||||
// Client just disconnected from server.
|
||||
emit_signal("server_disconnected");
|
||||
close_connection();
|
||||
return;
|
||||
} else if (server_relay) {
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user