Skip to content

Commit

Permalink
Merge pull request godotengine#67917 from Faless/mp/4.x_auth
Browse files Browse the repository at this point in the history
[MP] Add peer authentication support to the default MultiplayerAPI.
  • Loading branch information
akien-mga committed Nov 2, 2022
2 parents 23e793f + 33dda2e commit 30e4e7c
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 78 deletions.
35 changes: 10 additions & 25 deletions doc/classes/MultiplayerPeer.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MultiplayerPeer" inherits="PacketPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A high-level network interface to simplify multiplayer interactions.
Abstract class for specialized [PacketPeer]s used by the [MultiplayerAPI].
</brief_description>
<description>
Manages the connection to multiplayer peers. Assigns unique IDs to each client connected to the server. See also [MultiplayerAPI].
[b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice.
Manages the connection with one or more remote peers acting as server or client and assigning unique IDs to each of them. See also [MultiplayerAPI].
[b]Note:[/b] The [MultiplayerAPI] protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice.
[b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android.
</description>
<tutorials>
Expand Down Expand Up @@ -97,49 +97,34 @@
</member>
</members>
<signals>
<signal name="connection_failed">
<description>
Emitted when a connection attempt fails.
</description>
</signal>
<signal name="connection_succeeded">
<description>
Emitted when a connection attempt succeeds.
</description>
</signal>
<signal name="peer_connected">
<param index="0" name="id" type="int" />
<description>
Emitted by the server when a client connects.
Emitted when a remote peer connects.
</description>
</signal>
<signal name="peer_disconnected">
<param index="0" name="id" type="int" />
<description>
Emitted by the server when a client disconnects.
</description>
</signal>
<signal name="server_disconnected">
<description>
Emitted by clients when the server disconnects.
Emitted when a remote peer has disconnected.
</description>
</signal>
</signals>
<constants>
<constant name="CONNECTION_DISCONNECTED" value="0" enum="ConnectionStatus">
The ongoing connection disconnected.
The MultiplayerPeer is disconnected.
</constant>
<constant name="CONNECTION_CONNECTING" value="1" enum="ConnectionStatus">
A connection attempt is ongoing.
The MultiplayerPeer is currently connecting to a server.
</constant>
<constant name="CONNECTION_CONNECTED" value="2" enum="ConnectionStatus">
The connection attempt succeeded.
This MultiplayerPeer is connected.
</constant>
<constant name="TARGET_PEER_BROADCAST" value="0">
Packets are sent to the server and then redistributed to other peers.
Packets are sent to all connected peers.
</constant>
<constant name="TARGET_PEER_SERVER" value="1">
Packets are sent to the server alone.
Packets are sent to the remote peer acting as server.
</constant>
<constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode">
Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters.
Expand Down
9 changes: 1 addition & 8 deletions modules/enet/enet_multiplayer_peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,7 @@ void ENetMultiplayerPeer::_disconnect_inactive_peers() {
if (hosts.has(P)) {
hosts.erase(P);
}
if (active_mode == MODE_CLIENT) {
ERR_CONTINUE(P != TARGET_PEER_SERVER);
emit_signal(SNAME("server_disconnected"));
}
ERR_CONTINUE(active_mode == MODE_CLIENT && P != TARGET_PEER_SERVER);
emit_signal(SNAME("peer_disconnected"), P);
}
}
Expand All @@ -186,14 +183,10 @@ void ENetMultiplayerPeer::poll() {
if (ret == ENetConnection::EVENT_CONNECT) {
connection_status = CONNECTION_CONNECTED;
emit_signal(SNAME("peer_connected"), 1);
emit_signal(SNAME("connection_succeeded"));
} else if (ret == ENetConnection::EVENT_DISCONNECT) {
if (connection_status == CONNECTION_CONNECTED) {
// Client just disconnected from server.
emit_signal(SNAME("server_disconnected"));
emit_signal(SNAME("peer_disconnected"), 1);
} else {
emit_signal(SNAME("connection_failed"));
}
close();
} else if (ret == ENetConnection::EVENT_RECEIVE) {
Expand Down
47 changes: 47 additions & 0 deletions modules/multiplayer/doc_classes/SceneMultiplayer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,35 @@
Clears the current SceneMultiplayer network state (you shouldn't call this unless you know what you are doing).
</description>
</method>
<method name="complete_auth">
<return type="int" enum="Error" />
<param index="0" name="id" type="int" />
<description>
Mark the authentication step as completed for the remote peer identified by [param id]. The [signal MultiplayerAPI.peer_connected] signal will be emitted for this peer once the remote side also completes the authentication. No further authentication messages are expected to be received from this peer.
If a peer disconnects before completing authentication, either due to a network issue, the [member auth_timeout] expiring, or manually calling [method disconnect_peer], the [signal peer_authentication_failed] signal will be emitted instead of [signal MultiplayerAPI.peer_disconnected].
</description>
</method>
<method name="disconnect_peer">
<return type="void" />
<param index="0" name="id" type="int" />
<description>
Disconnects the peer identified by [param id], removing it from the list of connected peers, and closing the underlying connection with it.
</description>
</method>
<method name="get_authenticating_peers">
<return type="PackedInt32Array" />
<description>
Returns the IDs of the peers currently trying to authenticate with this [MultiplayerAPI].
</description>
</method>
<method name="send_auth">
<return type="int" enum="Error" />
<param index="0" name="id" type="int" />
<param index="1" name="data" type="PackedByteArray" />
<description>
Sends the specified [param data] to the remote peer identified by [param id] as part of an authentication message. This can be used to authenticate peers, and control when [signal MultiplayerAPI.peer_connected] is emitted (and the remote peer accepted as one of the connected peers).
</description>
</method>
<method name="send_bytes">
<return type="int" enum="Error" />
<param index="0" name="bytes" type="PackedByteArray" />
Expand All @@ -35,6 +64,12 @@
If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs.
[b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threat such as remote code execution.
</member>
<member name="auth_callback" type="Callable" setter="set_auth_callback" getter="get_auth_callback">
The callback to execute when when receiving authentication data sent via [method send_auth]. If the [Callable] is empty (default), peers will be automatically accepted as soon as they connect.
</member>
<member name="auth_timeout" type="float" setter="set_auth_timeout" getter="get_auth_timeout" default="3.0">
If set to a value greater than [code]0.0[/code], the maximum amount of time peers can stay in the authenticating state, after which the authentication will automatically fail. See the [signal peer_authenticating] and [signal peer_authentication_failed] signals.
</member>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="false">
If [code]true[/code], the MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] refuses new incoming connections.
</member>
Expand All @@ -48,6 +83,18 @@
</member>
</members>
<signals>
<signal name="peer_authenticating">
<param index="0" name="id" type="int" />
<description>
Emitted when this MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] connects to a new peer and a valid [member auth_callback] is set. In this case, the [signal MultiplayerAPI.peer_connected] will not be emitted until [method complete_auth] is called with given peer [param id]. While in this state, the peer will not be included in the list returned by [method MultiplayerAPI.get_peers] (but in the one returned by [method get_authenticating_peers]), and only authentication data will be sent or received. See [method send_auth] for sending authentication data.
</description>
</signal>
<signal name="peer_authentication_failed">
<param index="0" name="id" type="int" />
<description>
Emitted when this MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] disconnects from a peer for which authentication had not yet completed. See [signal peer_authenticating].
</description>
</signal>
<signal name="peer_packet">
<param index="0" name="id" type="int" />
<param index="1" name="packet" type="PackedByteArray" />
Expand Down
Loading

0 comments on commit 30e4e7c

Please sign in to comment.