diff options
author | Max Hilbrunner <mhilbrunner@users.noreply.github.com> | 2018-05-29 11:49:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-29 11:49:37 +0200 |
commit | 37146897673f66f51736bd7022a6682285d87f47 (patch) | |
tree | 76f810cefb7542fc4e3040d52810899a5e4ea40c /scene | |
parent | d0b62ce1558766134ea2fc6bcf912e837d0ae40b (diff) | |
parent | 4c69a495c948b1698a1634b506bf660bd49cdd76 (diff) |
Merge pull request #19243 from godotengine/revert-19021-rpc_sync_fix
Revert "RPCMode refactor, more sync modes"
Diffstat (limited to 'scene')
-rw-r--r-- | scene/main/node.cpp | 126 | ||||
-rw-r--r-- | scene/main/node.h | 24 |
2 files changed, 138 insertions, 12 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index ffb8acc687..3643aedb85 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -40,6 +40,7 @@ #include "viewport.h" VARIANT_ENUM_CAST(Node::PauseMode); +VARIANT_ENUM_CAST(Node::RPCMode); void Node::_notification(int p_notification) { @@ -484,18 +485,18 @@ bool Node::is_network_master() const { /***** RPC CONFIG ********/ -void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { +void Node::rpc_config(const StringName &p_method, RPCMode p_mode) { - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { + if (p_mode == RPC_MODE_DISABLED) { data.rpc_methods.erase(p_method); } else { data.rpc_methods[p_method] = p_mode; }; } -void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { +void Node::rset_config(const StringName &p_property, RPCMode p_mode) { - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { + if (p_mode == RPC_MODE_DISABLED) { data.rpc_properties.erase(p_property); } else { data.rpc_properties[p_property] = p_mode; @@ -717,14 +718,121 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { multiplayer = p_multiplayer; } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) { +const Map<StringName, Node::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) { return data.rpc_methods.find(p_method); } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) { +const Map<StringName, Node::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) { return data.rpc_properties.find(p_property); } +bool Node::can_call_rpc(const StringName &p_method, int p_from) const { + + const Map<StringName, RPCMode>::Element *E = data.rpc_methods.find(p_method); + if (E) { + + switch (E->get()) { + + case RPC_MODE_DISABLED: { + return false; + } break; + case RPC_MODE_REMOTE: { + return true; + } break; + case RPC_MODE_SYNC: { + return true; + } break; + case RPC_MODE_MASTER: { + return is_network_master(); + } break; + case RPC_MODE_SLAVE: { + return !is_network_master() && p_from == get_network_master(); + } break; + } + } + + if (get_script_instance()) { + //attempt with script + ScriptInstance::RPCMode rpc_mode = get_script_instance()->get_rpc_mode(p_method); + + switch (rpc_mode) { + + case ScriptInstance::RPC_MODE_DISABLED: { + return false; + } break; + case ScriptInstance::RPC_MODE_REMOTE: { + return true; + } break; + case ScriptInstance::RPC_MODE_SYNC: { + return true; + } break; + case ScriptInstance::RPC_MODE_MASTER: { + return is_network_master(); + } break; + case ScriptInstance::RPC_MODE_SLAVE: { + return !is_network_master() && p_from == get_network_master(); + } break; + } + } + + ERR_PRINTS("RPC from " + itos(p_from) + " on unauthorized method attempted: " + String(p_method) + " on base: " + String(Variant(this))); + return false; +} + +bool Node::can_call_rset(const StringName &p_property, int p_from) const { + + const Map<StringName, RPCMode>::Element *E = data.rpc_properties.find(p_property); + if (E) { + + switch (E->get()) { + + case RPC_MODE_DISABLED: { + return false; + } break; + case RPC_MODE_REMOTE: { + return true; + } break; + case RPC_MODE_SYNC: { + return true; + } break; + case RPC_MODE_MASTER: { + return is_network_master(); + } break; + case RPC_MODE_SLAVE: { + return !is_network_master() && p_from == get_network_master(); + } break; + } + } + + if (get_script_instance()) { + //attempt with script + ScriptInstance::RPCMode rpc_mode = get_script_instance()->get_rset_mode(p_property); + + switch (rpc_mode) { + + case ScriptInstance::RPC_MODE_DISABLED: { + return false; + } break; + case ScriptInstance::RPC_MODE_REMOTE: { + return true; + } break; + case ScriptInstance::RPC_MODE_SYNC: { + return true; + } break; + case ScriptInstance::RPC_MODE_MASTER: { + return is_network_master(); + } break; + case ScriptInstance::RPC_MODE_SLAVE: { + return !is_network_master() && p_from == get_network_master(); + } break; + } + } + + ERR_PRINTS("RSET from " + itos(p_from) + " on unauthorized property attempted: " + String(p_property) + " on base: " + String(Variant(this))); + + return false; +} + bool Node::can_process() const { ERR_FAIL_COND_V(!is_inside_tree(), false); @@ -2694,6 +2802,12 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_INTERNAL_PROCESS); BIND_CONSTANT(NOTIFICATION_INTERNAL_PHYSICS_PROCESS); + BIND_ENUM_CONSTANT(RPC_MODE_DISABLED); + BIND_ENUM_CONSTANT(RPC_MODE_REMOTE); + BIND_ENUM_CONSTANT(RPC_MODE_SYNC); + BIND_ENUM_CONSTANT(RPC_MODE_MASTER); + BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); + BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT); BIND_ENUM_CONSTANT(PAUSE_MODE_STOP); BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS); diff --git a/scene/main/node.h b/scene/main/node.h index 341349de79..540f34cba7 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -65,6 +65,15 @@ public: #endif }; + 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 / set property in all other peers + RPC_MODE_SYNC, // using rpc() on it will call method / set property in all other peers and locally + RPC_MODE_MASTER, // usinc rpc() on it will call method on wherever the master is, be it local or remote + RPC_MODE_SLAVE, // usinc rpc() on it will call method for all slaves, be it local or remote + }; + struct Comparator { bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); } @@ -111,8 +120,8 @@ private: Node *pause_owner; int network_master; - Map<StringName, MultiplayerAPI::RPCMode> rpc_methods; - Map<StringName, MultiplayerAPI::RPCMode> rpc_properties; + Map<StringName, RPCMode> rpc_methods; + Map<StringName, RPCMode> rpc_properties; // variables used to properly sort the node when processing, ignored otherwise //should move all the stuff below to bits @@ -395,8 +404,8 @@ public: int get_network_master() const; bool is_network_master() const; - void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC - void rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC + void rpc_config(const StringName &p_method, RPCMode p_mode); // config a local method for RPC + void rset_config(const StringName &p_property, RPCMode p_mode); // config a local property for RPC void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode @@ -414,8 +423,11 @@ public: Ref<MultiplayerAPI> get_multiplayer() const; Ref<MultiplayerAPI> get_custom_multiplayer() const; void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rset_mode(const StringName &p_property); + const Map<StringName, RPCMode>::Element *get_node_rpc_mode(const StringName &p_method); + const Map<StringName, RPCMode>::Element *get_node_rset_mode(const StringName &p_property); + + bool can_call_rpc(const StringName &p_method, int p_from) const; + bool can_call_rset(const StringName &p_property, int p_from) const; Node(); ~Node(); |