[MP] Fix relay protocol routing with negative targets

Godot supports sending messages to "all but one peer" by sending a
packet with a negative target (the negated ID of the excluded peer).

The relay protocol was incorrectly interpreting the values and relaying
the message to the wrong peers.

This issue only affected "send_bytes" since the other subsystem (RPC
and replication) "resolves" the correct IDs client-side (to match
visibility information).
This commit is contained in:
Fabio Alessandrelli 2024-08-06 13:15:55 +02:00
parent 4359c28fea
commit c5fa7354bb
1 changed files with 8 additions and 5 deletions

View File

@ -321,21 +321,24 @@ void SceneMultiplayer::_process_sys(int p_from, const uint8_t *p_packet, int p_p
multiplayer_peer->set_transfer_mode(p_mode); multiplayer_peer->set_transfer_mode(p_mode);
multiplayer_peer->set_transfer_channel(p_channel); multiplayer_peer->set_transfer_channel(p_channel);
if (peer > 0) { if (peer > 0) {
// Single destination.
multiplayer_peer->set_target_peer(peer); multiplayer_peer->set_target_peer(peer);
_send(data.ptr(), relay_buffer->get_position()); _send(data.ptr(), relay_buffer->get_position());
} else { } else {
// Multiple destinations.
for (const int &P : connected_peers) { for (const int &P : connected_peers) {
// Not to sender, nor excluded. // Not to sender, nor excluded.
if (P == p_from || (peer < 0 && P != -peer)) { if (P == p_from || P == -peer) {
continue; continue;
} }
multiplayer_peer->set_target_peer(P); multiplayer_peer->set_target_peer(P);
_send(data.ptr(), relay_buffer->get_position()); _send(data.ptr(), relay_buffer->get_position());
} }
} if (peer != -1) {
if (peer == 0 || peer == -1) { // The server is one of the targets, process the packet with sender as source.
should_process = true; should_process = true;
peer = p_from; // Process as the source. peer = p_from;
}
} }
} else { } else {
ERR_FAIL_COND(p_from != 1); // Bug. ERR_FAIL_COND(p_from != 1); // Bug.