summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorMax Hilbrunner <mhilbrunner@users.noreply.github.com>2018-05-29 11:49:37 +0200
committerGitHub <noreply@github.com>2018-05-29 11:49:37 +0200
commit37146897673f66f51736bd7022a6682285d87f47 (patch)
tree76f810cefb7542fc4e3040d52810899a5e4ea40c /scene
parentd0b62ce1558766134ea2fc6bcf912e837d0ae40b (diff)
parent4c69a495c948b1698a1634b506bf660bd49cdd76 (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.cpp126
-rw-r--r--scene/main/node.h24
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();