[Net] Rename RPC "puppet" to "auth" (authority). Drop "master".

This commit completely removes the RPC_MODE_MASTER ("master" keyword),
and renames the RPC_MODE_PUPPET to RPC_MODE_AUTHORITY ("auth" keyword).

This commit also renames the "Node.[get|set]_network_master" methods to
"Node.[get|set]_network_authority".

This commit also renames the RPC_MODE_REMOTE constant to RPC_MODE_ANY.

RPC_MODE_MASTER in Godot 3.x meant that a given RPC would be callable by
any puppet peer on the master, while RPC_MODE_PUPPET meant that it would
be callable by the master on any puppet.

Beside proving to be very confusing to the user (referring to where it
could be called instead of who can call it) the RPC_MODE_MASTER is quite
useless. It is almost the same as RPC_MODE_REMOTE (anyone can call) with
the exception that the network master cannot. While this could be useful
to check in some case, in such a function you would anyway need to check
in code who is the caller via get_rpc_sender_id(), so adding the check
there for those rare cases does not warrants a dedicated mode.
This commit is contained in:
Fabio Alessandrelli 2021-08-10 20:44:06 +02:00
parent 838a449d64
commit 64b9f30b92
13 changed files with 44 additions and 67 deletions

View file

@ -96,14 +96,11 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
case MultiplayerAPI::RPC_MODE_DISABLED: {
return false;
} break;
case MultiplayerAPI::RPC_MODE_REMOTE: {
case MultiplayerAPI::RPC_MODE_ANY: {
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
return p_node->is_network_master();
} break;
case MultiplayerAPI::RPC_MODE_PUPPET: {
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
case MultiplayerAPI::RPC_MODE_AUTHORITY: {
return !p_node->is_network_authority() && p_remote_id == p_node->get_network_authority();
} break;
}
@ -369,7 +366,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
ERR_FAIL_COND(config.name == StringName());
bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from);
ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", authority is " + itos(p_node->get_network_authority()) + ".");
int argc = 0;
bool byte_only = false;
@ -1138,9 +1135,8 @@ void MultiplayerAPI::_bind_methods() {
ADD_SIGNAL(MethodInfo("server_disconnected"));
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
BIND_ENUM_CONSTANT(RPC_MODE_ANY);
BIND_ENUM_CONSTANT(RPC_MODE_AUTHORITY);
}
MultiplayerAPI::MultiplayerAPI() {

View file

@ -43,9 +43,8 @@ class MultiplayerAPI : public RefCounted {
public:
enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
RPC_MODE_REMOTE, // Using rpc() on it will call method in all remote peers
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets
RPC_MODE_ANY, // Any peer can call this rpc()
RPC_MODE_AUTHORITY, // Only the node's network authority (server by default) can call this rpc()
};
struct RPCConfig {

View file

@ -73,7 +73,7 @@
[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 threats such as remote code execution.
</member>
<member name="network_peer" type="MultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master, or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to authority, or it will become a regular client peer. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
</member>
<member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections" default="false">
If [code]true[/code], the MultiplayerAPI's [member network_peer] refuses new incoming connections.
@ -125,14 +125,11 @@
<constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode">
Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods.
</constant>
<constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. Calls and property changes are accepted from all remote peers, no matter if they are node's master or puppets.
<constant name="RPC_MODE_ANY" value="1" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not.
</constant>
<constant name="RPC_MODE_MASTER" value="2" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. Only accepts calls or property changes from the node's network puppets, see [method Node.set_network_master].
</constant>
<constant name="RPC_MODE_PUPPET" value="3" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be called or a property to be changed only on puppets for this node. Analogous to the [code]puppet[/code] keyword. Only accepts calls or property changes from the node's network master, see [method Node.set_network_master].
<constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode">
Used with [method Node.rpc_config] to set a method to be callable remotely only by the current network authority (which is the server by default). Analogous to the [code]@rpc(auth)[/code] annotation. See [method Node.set_network_authority].
</constant>
</constants>
</class>

View file

@ -246,10 +246,10 @@
If [code]include_internal[/code] is [code]false[/code], the index won't take internal children into account, i.e. first non-internal child will have index of 0 (see [code]internal[/code] parameter in [method add_child]).
</description>
</method>
<method name="get_network_master" qualifiers="const">
<method name="get_network_authority" qualifiers="const">
<return type="int" />
<description>
Returns the peer ID of the network master for this node. See [method set_network_master].
Returns the peer ID of the network authority for this node. See [method set_network_authority].
</description>
</method>
<method name="get_node" qualifiers="const">
@ -417,10 +417,10 @@
Returns [code]true[/code] if this node is currently inside a [SceneTree].
</description>
</method>
<method name="is_network_master" qualifiers="const">
<method name="is_network_authority" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the local system is the master of this node.
Returns [code]true[/code] if the local system is the authority of this node.
</description>
</method>
<method name="is_physics_processing" qualifiers="const">
@ -588,7 +588,7 @@
<argument index="2" name="transfer_mode" type="int" enum="MultiplayerPeer.TransferMode" default="2" />
<argument index="3" name="channel" type="int" default="0" />
<description>
Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum MultiplayerAPI.RPCMode] and [enum MultiplayerPeer.TransferMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]master[/code], [code]puppet[/code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code]). By default, methods are not exposed to networking (and RPCs).
Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum MultiplayerAPI.RPCMode] and [enum MultiplayerPeer.TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(auth)[/code]). By default, methods are not exposed to networking (and RPCs).
</description>
</method>
<method name="rpc_id" qualifiers="vararg">
@ -620,12 +620,12 @@
<description>
</description>
</method>
<method name="set_network_master">
<method name="set_network_authority">
<return type="void" />
<argument index="0" name="id" type="int" />
<argument index="1" name="recursive" type="bool" default="true" />
<description>
Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]puppet[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node.
Sets the node's network authority to the peer with the given peer ID. The network authority is the peer that has authority over the node on the network. Useful in conjunction with [method rpc_config] and the [MultiplayerAPI]. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the authority for all children of this node.
</description>
</method>
<method name="set_physics_process">

View file

@ -39,12 +39,8 @@ extern "C" {
typedef enum {
GODOT_METHOD_RPC_MODE_DISABLED,
GODOT_METHOD_RPC_MODE_REMOTE,
GODOT_METHOD_RPC_MODE_MASTER,
GODOT_METHOD_RPC_MODE_PUPPET,
GODOT_METHOD_RPC_MODE_REMOTESYNC,
GODOT_METHOD_RPC_MODE_MASTERSYNC,
GODOT_METHOD_RPC_MODE_PUPPETSYNC,
GODOT_METHOD_RPC_MODE_ANY,
GODOT_METHOD_RPC_MODE_AUTHORITY,
} godot_nativescript_method_rpc_mode;
typedef enum {

View file

@ -133,7 +133,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
// Networking.
register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_PUPPET>, 4, true);
register_annotation(MethodInfo("@rpc", { Variant::STRING, "mode" }, { Variant::STRING, "sync" }, { Variant::STRING, "transfer_mode" }, { Variant::INT, "transfer_channel" }), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_AUTHORITY>, 4, true);
// TODO: Warning annotations.
}
@ -3403,13 +3403,11 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod
if (i == 0) {
String mode = p_annotation->resolved_arguments[i].operator String();
if (mode == "any") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
} else if (mode == "master") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
} else if (mode == "puppet") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_ANY;
} else if (mode == "auth") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_AUTHORITY;
} else {
push_error(R"(Invalid RPC mode. Must be one of: 'any', 'master', or 'puppet')", p_annotation);
push_error(R"(Invalid RPC mode. Must be one of: 'any' or 'auth')", p_annotation);
return false;
}
} else if (i == 1) {

View file

@ -3466,13 +3466,10 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTE;
}
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTER;
return MultiplayerAPI::RPC_MODE_ANY;
}
if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPET;
return MultiplayerAPI::RPC_MODE_AUTHORITY;
}
return MultiplayerAPI::RPC_MODE_DISABLED;

View file

@ -5,9 +5,6 @@ namespace Godot
[AttributeUsage(AttributeTargets.Method)]
public class RemoteAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method)]
public class MasterAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method)]
public class PuppetAttribute : Attribute {}
}

View file

@ -141,7 +141,6 @@ void CachedData::clear_godot_api_cache() {
class_SignalAttribute = nullptr;
class_ToolAttribute = nullptr;
class_RemoteAttribute = nullptr;
class_MasterAttribute = nullptr;
class_PuppetAttribute = nullptr;
class_GodotMethodAttribute = nullptr;
field_GodotMethodAttribute_methodName = nullptr;
@ -267,7 +266,6 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute));
CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));

View file

@ -112,7 +112,6 @@ struct CachedData {
GDMonoClass *class_SignalAttribute;
GDMonoClass *class_ToolAttribute;
GDMonoClass *class_RemoteAttribute;
GDMonoClass *class_MasterAttribute;
GDMonoClass *class_PuppetAttribute;
GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName;

View file

@ -163,7 +163,7 @@ void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const
p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000"));
}
p_list->push_back(PropertyInfo(Variant::BOOL, "stack/stackless"));
p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Master,Puppet,Remote Sync,Master Sync,Puppet Sync"));
p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Any,Authority"));
}
int VisualScriptFunction::get_output_sequence_port_count() const {

View file

@ -517,24 +517,24 @@ void Node::_propagate_process_owner(Node *p_owner, int p_pause_notification, int
}
}
void Node::set_network_master(int p_peer_id, bool p_recursive) {
data.network_master = p_peer_id;
void Node::set_network_authority(int p_peer_id, bool p_recursive) {
data.network_authority = p_peer_id;
if (p_recursive) {
for (int i = 0; i < data.children.size(); i++) {
data.children[i]->set_network_master(p_peer_id, true);
data.children[i]->set_network_authority(p_peer_id, true);
}
}
}
int Node::get_network_master() const {
return data.network_master;
int Node::get_network_authority() const {
return data.network_authority;
}
bool Node::is_network_master() const {
bool Node::is_network_authority() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
return get_multiplayer()->get_network_unique_id() == data.network_master;
return get_multiplayer()->get_network_unique_id() == data.network_authority;
}
/***** RPC CONFIG ********/
@ -2738,10 +2738,10 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_ready"), &Node::request_ready);
ClassDB::bind_method(D_METHOD("set_network_master", "id", "recursive"), &Node::set_network_master, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_network_master"), &Node::get_network_master);
ClassDB::bind_method(D_METHOD("set_network_authority", "id", "recursive"), &Node::set_network_authority, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_network_authority"), &Node::get_network_authority);
ClassDB::bind_method(D_METHOD("is_network_master"), &Node::is_network_master);
ClassDB::bind_method(D_METHOD("is_network_authority"), &Node::is_network_authority);
ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
ClassDB::bind_method(D_METHOD("get_custom_multiplayer"), &Node::get_custom_multiplayer);

View file

@ -127,7 +127,7 @@ private:
ProcessMode process_mode = PROCESS_MODE_INHERIT;
Node *process_owner = nullptr;
int network_master = 1; // Server by default.
int network_authority = 1; // Server by default.
Vector<MultiplayerAPI::RPCConfig> rpc_methods;
// Variables used to properly sort the node when processing, ignored otherwise.
@ -462,9 +462,9 @@ public:
bool is_displayed_folded() const;
/* NETWORK */
void set_network_master(int p_peer_id, bool p_recursive = true);
int get_network_master() const;
bool is_network_master() const;
void set_network_authority(int p_peer_id, bool p_recursive = true);
int get_network_authority() const;
bool is_network_authority() const;
uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_rpc_mode, MultiplayerPeer::TransferMode p_transfer_mode, int p_channel = 0); // config a local method for RPC
Vector<MultiplayerAPI::RPCConfig> get_node_rpc_methods() const;