diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/marshalls.cpp | 18 | ||||
-rw-r--r-- | core/io/marshalls.h | 2 | ||||
-rw-r--r-- | core/io/multiplayer_api.cpp | 4 | ||||
-rw-r--r-- | core/io/multiplayer_peer.cpp | 24 | ||||
-rw-r--r-- | core/io/multiplayer_peer.h | 1 |
5 files changed, 38 insertions, 11 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 4a1d3e5212..4f85eced93 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1031,7 +1031,8 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { } } -Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects) { +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects, int p_depth) { + ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Potential inifite recursion detected. Bailing."); uint8_t *buf = r_buffer; r_len = 0; @@ -1380,10 +1381,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo _encode_string(E.name, buf, r_len); int len; - Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects); - if (err) { - return err; - } + Error err = encode_variant(obj->get(E.name), buf, len, p_full_objects, p_depth + 1); + ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { @@ -1433,7 +1432,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len++; //pad */ int len; - encode_variant(E, buf, len, p_full_objects); + Error err = encode_variant(E, buf, len, p_full_objects, p_depth + 1); + ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { @@ -1441,7 +1441,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } Variant *v = d.getptr(E); ERR_FAIL_COND_V(!v, ERR_BUG); - encode_variant(*v, buf, len, p_full_objects); + err = encode_variant(*v, buf, len, p_full_objects, p_depth + 1); + ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { @@ -1462,7 +1463,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo for (int i = 0; i < v.size(); i++) { int len; - encode_variant(v.get(i), buf, len, p_full_objects); + Error err = encode_variant(v.get(i), buf, len, p_full_objects, p_depth + 1); + ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { diff --git a/core/io/marshalls.h b/core/io/marshalls.h index 3ebed914a3..05804d5a46 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -213,6 +213,6 @@ public: }; Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false); -Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false); +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0); #endif // MARSHALLS_H diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 80610e12cb..d4f09b2135 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -63,7 +63,7 @@ const MultiplayerAPI::RPCConfig _get_rpc_config(const Node *p_node, const String const Vector<MultiplayerAPI::RPCConfig> node_config = p_node->get_node_rpc_methods(); for (int i = 0; i < node_config.size(); i++) { if (node_config[i].name == p_method) { - r_id = ((uint16_t)i) & (1 << 15); + r_id = ((uint16_t)i) | (1 << 15); return node_config[i]; } } @@ -89,7 +89,7 @@ const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_i config = p_node->get_script_instance()->get_rpc_methods(); } if (id < config.size()) { - return config[p_id]; + return config[id]; } return MultiplayerAPI::RPCConfig(); } diff --git a/core/io/multiplayer_peer.cpp b/core/io/multiplayer_peer.cpp index 8126b4cea3..8b3b1eef8e 100644 --- a/core/io/multiplayer_peer.cpp +++ b/core/io/multiplayer_peer.cpp @@ -30,6 +30,29 @@ #include "multiplayer_peer.h" +#include "core/os/os.h" + +uint32_t MultiplayerPeer::generate_unique_id() const { + uint32_t hash = 0; + + while (hash == 0 || hash == 1) { + hash = hash_djb2_one_32( + (uint32_t)OS::get_singleton()->get_ticks_usec()); + hash = hash_djb2_one_32( + (uint32_t)OS::get_singleton()->get_unix_time(), hash); + hash = hash_djb2_one_32( + (uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash); + hash = hash_djb2_one_32( + (uint32_t)((uint64_t)this), hash); // Rely on ASLR heap + hash = hash_djb2_one_32( + (uint32_t)((uint64_t)&hash), hash); // Rely on ASLR stack + + hash = hash & 0x7FFFFFFF; // Make it compatible with unsigned, since negative ID is used for exclusion + } + + return hash; +} + void MultiplayerPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &MultiplayerPeer::set_transfer_mode); ClassDB::bind_method(D_METHOD("get_transfer_mode"), &MultiplayerPeer::get_transfer_mode); @@ -41,6 +64,7 @@ void MultiplayerPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_connection_status"), &MultiplayerPeer::get_connection_status); ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerPeer::get_unique_id); + ClassDB::bind_method(D_METHOD("generate_unique_id"), &MultiplayerPeer::generate_unique_id); ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "enable"), &MultiplayerPeer::set_refuse_new_connections); ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &MultiplayerPeer::is_refusing_new_connections); diff --git a/core/io/multiplayer_peer.h b/core/io/multiplayer_peer.h index 432f47280f..91a3ad7954 100644 --- a/core/io/multiplayer_peer.h +++ b/core/io/multiplayer_peer.h @@ -72,6 +72,7 @@ public: virtual bool is_refusing_new_connections() const = 0; virtual ConnectionStatus get_connection_status() const = 0; + uint32_t generate_unique_id() const; MultiplayerPeer() {} }; |