[Networking] Mode is 0, master is 1 despite using remote keyword on server

Godot Version

3.6

Question

Hey! Using a dedicated server with websockets for my multiplayer game. The architecture consists of a gateway, an authenticator, a game server and the clients. The gateway, game server and clients are to use websockets, while the authenticator just uses NetworkedMultiplayerENet.

The clients connect to the gateway first to log in. Here’s the client-side code for logging in (the client connects to the gateway once they enter their credentials.)

# When ready, stop this node from running the _process function
func _ready():
	set_process(false)
	get_tree().connect("connected_to_server", self, "_connectionSucceeded")
	get_tree().connect("connection_failed", self, "_connectionFailed")
	get_tree().connect("server_disconnected", self, "_serverDisconnected")

# Every frame, poll the custom multiplayer instance if it exists and has peers
func _process(_delta):
	if custom_multiplayer==null:
		return
	if not custom_multiplayer.network_peer:
		return;
	custom_multiplayer.poll()
	client.poll()

# Connects to the gateway server
func connectToServer(_username, _password, _newAccount):
	client = WebSocketClient.new()
	var err = client.connect_to_url("[myPublicIP]:1910", PoolStringArray(), true)
	if err != OK:
		print("Unable to connect")
		return
	get_tree().network_peer = client
	set_process(true)

	# Reinitialises the high-level multiplayer instance and custom multiplayer API
	gatewayAPI = MultiplayerAPI.new()

	# Stores the locally stored username, password and newAccount variables in the corresponding global variables
	username = _username
	password = _password
	newAccount = _newAccount

	# Initialises the custom multiplayer API
	custom_multiplayer = gatewayAPI
	custom_multiplayer.root_node = self
	custom_multiplayer.network_peer = client

# Outputs that the connection to the gateway failed
func _connectionFailed():
	print("Failed to connect to login server")

func _serverDisconnected():
	print("Login server disconnected")

# Outputs that the connection to the gateway succeeded and sends a login or account registration request depending on the user's selection
func _connectionSucceeded():
	print("Successfully connected to login server")
	if newAccount:
		requestCreateAccount()
	else:
		requestLogin()

# Sends a login request to the gateway
func requestLogin():
	print("Connecting to gateway to request login")
	rpc_id(1, "loginRequest", username, password)

	username = ""
	password = ""

Here is the gateway’s code:

# When all nodes are loaded, start the server
func _ready():
	startServer()

# Poll the custom multiplayer instance every frame
func _process(_delta):
	if not custom_multiplayer.network_peer:
		return;
	custom_multiplayer.poll()
	gatewayServer.poll()

# Start the server
func startServer():
	gatewayServer = WebSocketServer.new()
	var err = gatewayServer.listen(1910, PoolStringArray(), true)
	if err != OK:
		print("Unable to start server")
		set_process(false)
		return
	get_tree().network_peer = gatewayServer
	get_tree().connect("network_peer_connected", self, "_peerConnected")
	get_tree().connect("network_peer_disconnected", self, "_peerDisconnected")

	# Initialises the custom multiplayer instance
	custom_multiplayer = gatewayAPI
	custom_multiplayer.root_node = self
	custom_multiplayer.network_peer = gatewayServer

	print("Gateway server started")

func _peerConnected(playerID):
	print("User "+str(playerID)+" connected")
	
func _peerDisconnected(playerID):
	print("User "+str(playerID)+" disconnected")

# Receives login requests from the players and sends them to the authenticator
remote func loginRequest(username, password):
	print("Login request received")
	var playerID = custom_multiplayer.get_rpc_sender_id()
	Authenticate.authenticatePlayer(username, password, playerID)

I keep getting the following two errors when I try logging in on the client, the first error being on the gateway and the second on the client.

Gateway error:

"_process_rpc: RPC 'loginRequest' is not allowed on node /root from: 987201720. Mode is 0, master is 1."

Client error:

"_process_confirm_path: Invalid packet received. Tries to confirm a path which was not found in cache."

I’m assuming this means that something happens to the packet sent when calling rpc_id on the client, but I’m really not sure. As seen in the gateway’s code, I do use the remote keyword on the loginRequest function.

I followed a tutorial and first implemented all of my code using NetworkedMultiplayerENet, and now I’m changing it to use WebSockets so that the game can be played on a browser.

What’s happening? :frowning:

I don’t think this is supposed to work. Client script doesn’t have loginRequest and the “gateway server” hashes for loginRequest at client scripts node path wouldn’t match.

The rpc functions signature must match on all instances (that receive the rpc).

I cannot tell how your scene or project is structured. My suggestion is to split “Client” and “Gateway” into different nodes. Declare the rpc interface. This must be the same for all instances. Define your initialization flow. If your client interfaces with the gateway via rpc, it needs to also have the gateway node at the same path as the gateway server has it’s gateway node.

Turns out part of the the issue was in this line of code in the gateway:
get_tree().network_peer = gatewayServer
Removing this line allowed the gateway to receive the client’s loginRequest RPC, carry out the necessary actions and attempt to return the login request to the client.
This resulted in these errors on the client:
_process_confirm_path: Invalid packet received. Tries to confirm a path which was not found in cache.
_process_rpc: RPC 'returnLoginRequest' is not allowed on node /root from: 1. Mode is 0, master is 1.

Also, the rpc interface script on the gateway server and on the client are both at the same path, /root/Gateway. From the second error on the client, it looks like the rpc tries to run on /root instead of on /root/Gateway.

I’m guessing the issue is with what I set to be the network_peer on either the client, server or both.

Thanks for replying by the way!

1 Like