Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MP] Fix relay protocol routing with negative targets #95194

Merged
merged 1 commit into from
Aug 8, 2024

Conversation

Faless
Copy link
Collaborator

@Faless Faless commented Aug 6, 2024

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).

Tested with the following script:

extends Control

var last_id = 1

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	multiplayer.connected_to_server.connect(_connected)
	var peer = ENetMultiplayerPeer.new()
	if "--server" in OS.get_cmdline_args():
		peer.create_server(4343)
	else:
		peer.create_client("127.0.0.1", 4343)
	multiplayer.multiplayer_peer = peer
	multiplayer.peer_packet.connect(f1)
	multiplayer.peer_connected.connect(_peer_connected)


func _peer_connected(id):
	if id != 1:
		last_id = id


func _connected():
	await get_tree().create_timer(3).timeout
	(multiplayer as SceneMultiplayer).send_bytes(var_to_bytes(last_id), last_id)
	(multiplayer as SceneMultiplayer).send_bytes(var_to_bytes(-last_id), -last_id)
	(multiplayer as SceneMultiplayer).send_bytes(var_to_bytes(1), 1)
	(multiplayer as SceneMultiplayer).send_bytes(var_to_bytes(0), 0)
	(multiplayer as SceneMultiplayer).send_bytes(var_to_bytes(-1), -1)


func f1(from=0, data=PackedByteArray()):
	print("Called f1 from %d=%d in %d. Data: %d" % [multiplayer.get_remote_sender_id(), from, multiplayer.get_unique_id(), bytes_to_var(data)])

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).
@Faless Faless added bug topic:multiplayer cherrypick:4.1 Considered for cherry-picking into a future 4.1.x release cherrypick:4.2 Considered for cherry-picking into a future 4.2.x release labels Aug 6, 2024
@Faless Faless added this to the 4.3 milestone Aug 6, 2024
@akien-mga akien-mga requested a review from mhilbrunner August 6, 2024 11:38
@Jordyfel

This comment was marked as off-topic.

@akien-mga akien-mga merged commit 03afb92 into godotengine:master Aug 8, 2024
18 checks passed
@akien-mga
Copy link
Member

Thanks!

@Faless Faless deleted the mp/fix_relay_negative_target branch August 8, 2024 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug cherrypick:4.1 Considered for cherry-picking into a future 4.1.x release cherrypick:4.2 Considered for cherry-picking into a future 4.2.x release topic:multiplayer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants