Skip to content

Commit

Permalink
Merge pull request #51481 from Faless/mp/4.x_no_pup
Browse files Browse the repository at this point in the history
[Net] Rename RPC "puppet" to "auth", drop "master".
  • Loading branch information
Faless authored Aug 30, 2021
2 parents 838a449 + fafddbc commit 9d38ebd
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 87 deletions.
16 changes: 6 additions & 10 deletions core/io/multiplayer_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 2 additions & 3 deletions core/io/multiplayer_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 5 additions & 8 deletions doc/classes/MultiplayerAPI.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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>
14 changes: 7 additions & 7 deletions doc/classes/Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down
8 changes: 2 additions & 6 deletions modules/gdnative/include/nativescript/godot_nativescript.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
46 changes: 19 additions & 27 deletions modules/gdscript/gdscript_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}

Expand Down Expand Up @@ -3399,43 +3399,35 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod

MultiplayerAPI::RPCConfig rpc_config;
rpc_config.rpc_mode = t_mode;
for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
if (i == 0) {
if (p_annotation->resolved_arguments.size()) {
int last = p_annotation->resolved_arguments.size() - 1;
if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) {
rpc_config.channel = p_annotation->resolved_arguments[last].operator int();
last -= 1;
}
if (last > 3) {
push_error(R"(Invalid RPC arguments. At most 4 arguments are allowed, where only the last argument can be an integer to specify the channel.')", p_annotation);
return false;
}
for (int i = last; i >= 0; i--) {
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;
} else {
push_error(R"(Invalid RPC mode. Must be one of: 'any', 'master', or 'puppet')", p_annotation);
return false;
}
} else if (i == 1) {
String sync = p_annotation->resolved_arguments[i].operator String();
if (sync == "sync") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_ANY;
} else if (mode == "auth") {
rpc_config.rpc_mode = MultiplayerAPI::RPC_MODE_AUTHORITY;
} else if (mode == "sync") {
rpc_config.sync = true;
} else if (sync == "nosync") {
} else if (mode == "nosync") {
rpc_config.sync = false;
} else {
push_error(R"(Invalid RPC sync mode. Must be one of: 'sync' or 'nosync')", p_annotation);
return false;
}
} else if (i == 2) {
String mode = p_annotation->resolved_arguments[i].operator String();
if (mode == "reliable") {
} else if (mode == "reliable") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
} else if (mode == "unreliable") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE;
} else if (mode == "ordered") {
rpc_config.transfer_mode = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED;
} else {
push_error(R"(Invalid RPC transfer mode. Must be one of: 'reliable', 'unreliable', 'ordered')", p_annotation);
return false;
push_error(R"(Invalid RPC argument. Must be one of: 'sync'/'nosync' (local calls), 'any'/'auth' (permission), 'reliable'/'unreliable'/'ordered' (transfer mode).)", p_annotation);
}
} else if (i == 3) {
rpc_config.channel = p_annotation->resolved_arguments[i].operator int();
}
}
switch (p_node->type) {
Expand Down
7 changes: 2 additions & 5 deletions modules/mono/csharp_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}
2 changes: 0 additions & 2 deletions modules/mono/mono_gd/gd_mono_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"));
Expand Down
1 change: 0 additions & 1 deletion modules/mono/mono_gd/gd_mono_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion modules/visual_script/visual_script_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
20 changes: 10 additions & 10 deletions scene/main/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ********/
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions scene/main/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class Node : public Object {
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.
Expand Down Expand Up @@ -462,9 +462,9 @@ class Node : public Object {
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;
Expand Down

0 comments on commit 9d38ebd

Please sign in to comment.