From 9d0c889583952bc46368608df6823e19d291310f Mon Sep 17 00:00:00 2001
From: Relintai <relintai@protonmail.com>
Date: Fri, 19 Aug 2022 00:36:24 +0200
Subject: [PATCH] Added a few small networking related helper methods to Node.
 Made the rpc macros in Entity use them.

---
 modules/entity_spell_system/entities/entity.h | 99 +++++++++----------
 scene/main/node.cpp                           |  4 +
 scene/main/node.h                             | 11 ++-
 3 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/modules/entity_spell_system/entities/entity.h b/modules/entity_spell_system/entities/entity.h
index 3f9e8ea8e..853505101 100644
--- a/modules/entity_spell_system/entities/entity.h
+++ b/modules/entity_spell_system/entities/entity.h
@@ -22,9 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */
 
+#include "core/containers/vector.h"
 #include "core/object/object.h"
 #include "core/string/ustring.h"
-#include "core/containers/vector.h"
 
 #include "core/io/networked_multiplayer_peer.h"
 
@@ -131,20 +131,20 @@ struct EntityStat {
 #define SET_RPC_PUPPETSYNC(p_method_name) rpc_config(p_method_name, MultiplayerAPI::RPC_MODE_PUPPETSYNC);
 
 // f.e.   RPC(method, arg0, arg1, etc)
-#define RPC(func, ...)                                                                           \
-	if (is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server()) { \
-		rpc(#func, ##__VA_ARGS__);                                                               \
-	}                                                                                            \
+#define RPC(func, ...)             \
+	if (is_network_server()) {     \
+		rpc(#func, ##__VA_ARGS__); \
+	}                              \
 	func(__VA_ARGS__);
 
-#define VRPC(func, ...)                                                                          \
-	if (is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server()) { \
-		vrpc(#func, ##__VA_ARGS__);                                                              \
-	}                                                                                            \
+#define VRPC(func, ...)             \
+	if (is_network_server()) {      \
+		vrpc(#func, ##__VA_ARGS__); \
+	}                               \
 	func(__VA_ARGS__);
 
 #define ORPC(func, ...)                                             \
-	if (is_inside_tree() && get_tree()->has_network_peer()) {       \
+	if (has_network_peer()) {                                       \
 		if (get_tree()->is_network_server()) {                      \
 			if (get_network_master() != 1) {                        \
 				rpc_id(get_network_master(), #func, ##__VA_ARGS__); \
@@ -156,75 +156,68 @@ struct EntityStat {
 		func(__VA_ARGS__);                                          \
 	}
 
-#define RPCS(func, ...)                                       \
-	if (is_inside_tree() && get_tree()->has_network_peer()) { \
-		if (get_tree()->is_network_server()) {                \
-			func(__VA_ARGS__);                                \
-		} else {                                              \
-			rpc_id(1, #func, ##__VA_ARGS__);                  \
-		}                                                     \
-	} else {                                                  \
-		func(__VA_ARGS__);                                    \
+#define RPCS(func, ...)                        \
+	if (has_network_peer()) {                  \
+		if (get_tree()->is_network_server()) { \
+			func(__VA_ARGS__);                 \
+		} else {                               \
+			rpc_id(1, #func, ##__VA_ARGS__);   \
+		}                                      \
+	} else {                                   \
+		func(__VA_ARGS__);                     \
 	}
 
 //RPC Objects
 
-#define RPCOBJ(rpcfunc, rpc_var, normalfunc, normal_var)      \
-	if (is_inside_tree() && get_tree()->has_network_peer()) { \
-		rpc(#rpcfunc, rpc_var);                               \
-	}                                                         \
+#define RPCOBJ(rpcfunc, rpc_var, normalfunc, normal_var) \
+	if (has_network_peer()) {                            \
+		rpc(#rpcfunc, rpc_var);                          \
+	}                                                    \
 	normalfunc(normal_var);
 
-#define VRPCOBJ(rpcfunc, rpc_var, normalfunc, normal_var)     \
-	if (is_inside_tree() && get_tree()->has_network_peer()) { \
-		vrpc(#rpcfunc, rpc_var);                              \
-	}                                                         \
+#define VRPCOBJ(rpcfunc, rpc_var, normalfunc, normal_var) \
+	if (has_network_peer()) {                             \
+		vrpc(#rpcfunc, rpc_var);                          \
+	}                                                     \
 	normalfunc(normal_var);
 
-#define VRPCOBJ12(rpcfunc, rpc_var, normalfunc, normal_var1, normal_var2)                        \
-	if (is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server()) { \
-		vrpc(#rpcfunc, rpc_var);                                                                 \
-	}                                                                                            \
+#define VRPCOBJ12(rpcfunc, rpc_var, normalfunc, normal_var1, normal_var2) \
+	if (is_network_server()) {                                            \
+		vrpc(#rpcfunc, rpc_var);                                          \
+	}                                                                     \
 	normalfunc(normal_var1, normal_var2);
 
-#define VRPCOBJP(rpcfunc, rpc_var1, rpc_var2, normalfunc, normal_var1, normal_var2)              \
-	if (is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server()) { \
-		vrpc(#rpcfunc, rpc_var1, rpc_var2);                                                      \
-	}                                                                                            \
+#define VRPCOBJP(rpcfunc, rpc_var1, rpc_var2, normalfunc, normal_var1, normal_var2) \
+	if (is_network_server()) {                                                      \
+		vrpc(#rpcfunc, rpc_var1, rpc_var2);                                         \
+	}                                                                               \
 	normalfunc(normal_var1, normal_var2);
 
 #define ORPCOBJ(rpcfunc, rpc_var, normalfunc, normal_var)                 \
-	if (is_inside_tree() && get_tree()->has_network_peer()) {             \
+	if (has_network_peer()) {                                             \
 		if (get_tree()->is_network_server() && get_network_master() != 1) \
 			rpc_id(get_network_master(), #rpcfunc, rpc_var);              \
 	}                                                                     \
 	normalfunc(normal_var);
 
-#define RPCSOBJ(rpcfunc, rpc_var, normalfunc, normal_var)     \
-	if (is_inside_tree() && get_tree()->has_network_peer()) { \
-		if (get_tree()->is_network_server()) {                \
-			normalfunc(normal_var);                           \
-		} else {                                              \
-			rpc_id(1, #rpcfunc, rpc_var);                     \
-		}                                                     \
-	} else {                                                  \
-		normalfunc(normal_var);                               \
+#define RPCSOBJ(rpcfunc, rpc_var, normalfunc, normal_var) \
+	if (has_network_peer()) {                             \
+		if (get_tree()->is_network_server()) {            \
+			normalfunc(normal_var);                       \
+		} else {                                          \
+			rpc_id(1, #rpcfunc, rpc_var);                 \
+		}                                                 \
+	} else {                                              \
+		normalfunc(normal_var);                           \
 	}
 
 #define ORPCOBJP(rpcfunc, rpc_var1, rpc_var2, normalfunc, normal_var1, normal_var2) \
-	if (is_inside_tree() && get_tree()->has_network_peer()) {                       \
+	if (has_network_peer()) {                                                       \
 		if (get_tree()->is_network_server() && get_network_master() != 1)           \
 			rpc_id(get_network_master(), #rpcfunc, rpc_var1, rpc_var2);             \
 	}                                                                               \
 	normalfunc(normal_var1, normal_var2);
 
-// f.e. RSET(rset("property", "value"), property, value)
-#define RSET(rset_func, variable, value)                                                         \
-	if (is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server()) { \
-		rset_func;                                                                               \
-	}                                                                                            \
-	variable = value;
-
 class Entity : public Node {
 	GDCLASS(Entity, Node);
 
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 19a09ff66..1ee38da5d 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -3289,6 +3289,10 @@ void Node::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned);
 #endif
 
+	ClassDB::bind_method(D_METHOD("has_network_peer"), &Node::has_network_peer);
+	ClassDB::bind_method(D_METHOD("is_network_server"), &Node::is_network_server);
+	ClassDB::bind_method(D_METHOD("is_network_client"), &Node::is_network_client);
+
 	ClassDB::bind_method(D_METHOD("sees_get", "index"), &Node::sees_get);
 	ClassDB::bind_method(D_METHOD("sees_remove_index", "index"), &Node::sees_remove_index);
 	ClassDB::bind_method(D_METHOD("sees_remove", "entity"), &Node::sees_remove);
diff --git a/scene/main/node.h b/scene/main/node.h
index 7ab540989..777afce83 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -512,6 +512,15 @@ public:
 	bool is_displayed_folded() const;
 
 	/* NETWORK */
+	_FORCE_INLINE_ bool has_network_peer() {
+		return is_inside_tree() && get_tree()->has_network_peer();
+	}
+	_FORCE_INLINE_ bool is_network_server() {
+		return is_inside_tree() && get_tree()->has_network_peer() && get_tree()->is_network_server();
+	}
+	_FORCE_INLINE_ bool is_network_client() {
+		return is_inside_tree() && get_tree()->has_network_peer() && !get_tree()->is_network_server();
+	}
 
 	Node *sees_get(int p_index);
 	void sees_remove_index(int p_index);
@@ -536,7 +545,7 @@ public:
 	void rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
 	void rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
 	void vrpc(const StringName &p_method, VARIANT_ARG_LIST); //visibility rpc. Useful for implementing fog of war
-	void vrpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); 
+	void vrpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST);
 
 	void rpcp(int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount);