diff options
Diffstat (limited to 'core/io')
28 files changed, 224 insertions, 74 deletions
diff --git a/core/io/compression.cpp b/core/io/compression.cpp index a113f3b61b..b51e50150e 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -175,7 +175,9 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p } break; case MODE_ZSTD: { ZSTD_DCtx *dctx = ZSTD_createDCtx(); - if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, (size_t)1 << zstd_window_log_size); + if (zstd_long_distance_matching) { + ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size); + } int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size); ZSTD_freeDCtx(dctx); return ret; @@ -189,4 +191,4 @@ int Compression::zlib_level = Z_DEFAULT_COMPRESSION; int Compression::gzip_level = Z_DEFAULT_COMPRESSION; int Compression::zstd_level = 3; bool Compression::zstd_long_distance_matching = false; -int Compression::zstd_window_log_size = 27; +int Compression::zstd_window_log_size = 27; // ZSTD_WINDOWLOG_LIMIT_DEFAULT diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index be960fbc25..24b40cbce8 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -143,6 +143,14 @@ public: return f._get_modified_time(p_file); } + virtual uint32_t _get_unix_permissions(const String &p_file) { + return f._get_unix_permissions(p_file); + } + + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { + return f._set_unix_permissions(p_file, p_permissions); + } + FileAccessBufferedFA(){ }; diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index b268d5c710..6c4310a572 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -373,6 +373,19 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) { return 0; } +uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) { + if (f) + return f->_get_unix_permissions(p_file); + return 0; +} + +Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { + if (f) { + return f->_set_unix_permissions(p_file, p_permissions); + } + return FAILED; +} + FileAccessCompressed::FileAccessCompressed() : cmode(Compression::MODE_ZSTD), writing(false), diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index f408b1bc29..773fed6a3a 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -91,6 +91,8 @@ public: virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file); + virtual uint32_t _get_unix_permissions(const String &p_file); + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); FileAccessCompressed(); virtual ~FileAccessCompressed(); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 6ad68dd74d..3ff9fa569c 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -100,6 +100,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); MD5Final(&md5); + ERR_EXPLAIN("The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid."); ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT); file = p_base; @@ -301,6 +302,16 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) { return 0; } +uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) { + + return 0; +} + +Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { + + return FAILED; +} + FileAccessEncrypted::FileAccessEncrypted() { file = NULL; diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index e77d62a9f4..d779a150ac 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -79,6 +79,8 @@ public: virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file); + virtual uint32_t _get_unix_permissions(const String &p_file); + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); FileAccessEncrypted(); ~FileAccessEncrypted(); diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 73952133c1..4db7811aaa 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -70,6 +70,8 @@ public: virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) { return 0; } + virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } FileAccessMemory(); }; diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 501a21a50d..2572602e16 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -118,7 +118,10 @@ void FileAccessNetworkClient::_thread_func() { FileAccessNetwork *fa = NULL; if (response != FileAccessNetwork::RESPONSE_DATA) { - ERR_FAIL_COND(!accesses.has(id)); + if (!accesses.has(id)) { + unlock_mutex(); + ERR_FAIL_COND(!accesses.has(id)); + } } if (accesses.has(id)) @@ -497,6 +500,16 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) { return exists_modtime; } +uint32_t FileAccessNetwork::_get_unix_permissions(const String &p_file) { + //could be implemented, not sure if worth it + return 0; +} + +Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { + + return FAILED; +} + void FileAccessNetwork::configure() { GLOBAL_DEF("network/remote_fs/page_size", 65536); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 5bbf7588c7..073b75a37b 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -159,6 +159,8 @@ public: virtual bool file_exists(const String &p_path); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file); + virtual uint32_t _get_unix_permissions(const String &p_file); + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions); static void configure(); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index c97b8cafac..d38d09c6bb 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -272,7 +272,7 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { if (eof) return 0; - int64_t to_read = p_length; + uint64_t to_read = p_length; if (to_read + pos > pf.size) { eof = true; to_read = int64_t(pf.size) - int64_t(pos); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index a90672ce26..a21dd7d22d 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -142,6 +142,8 @@ class FileAccessPack : public FileAccess { FileAccess *f; virtual Error _open(const String &p_path, int p_mode_flags); virtual uint64_t _get_modified_time(const String &p_file) { return 0; } + virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } public: virtual void close(); diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index fc8f85c07b..217176c0af 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -112,6 +112,8 @@ public: virtual bool file_exists(const String &p_name); ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo + virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; } + virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; } FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file); ~FileAccessZip(); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index e5c6d2a4f2..ce2054db36 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -429,7 +429,7 @@ Error HTTPClient::poll() { response_num = RESPONSE_OK; // Per the HTTP 1.1 spec, keep-alive is the default. - // Not following that specification breaks standard implemetations. + // Not following that specification breaks standard implementations. // Broken web servers should be fixed. bool keep_alive = true; diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index a5a0738140..a759e615c7 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -65,6 +65,9 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c if (!loader[i]->recognize(extension)) continue; Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale); + if (err != OK) { + ERR_PRINTS("Error loading image: " + p_file); + } if (err != ERR_FILE_UNRECOGNIZED) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 5087a63b68..d1b6b82cf0 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -768,7 +768,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = carray; } break; - default: { ERR_FAIL_V(ERR_BUG); } + default: { + ERR_FAIL_V(ERR_BUG); + } } return OK; @@ -794,7 +796,7 @@ 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_object_as_id) { +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects) { uint8_t *buf = r_buffer; @@ -819,11 +821,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } } break; case Variant::OBJECT: { - if (p_object_as_id) { + if (!p_full_objects) { flags |= ENCODE_FLAG_OBJECT_AS_ID; } } break; - default: {} // nothing to do at this stage + default: { + } // nothing to do at this stage } if (buf) { @@ -1086,22 +1089,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; case Variant::OBJECT: { - if (p_object_as_id) { - - if (buf) { - - Object *obj = p_variant; - ObjectID id = 0; - if (obj && ObjectDB::instance_validate(obj)) { - id = obj->get_instance_id(); - } - - encode_uint64(id, buf); - } - - r_len += 8; + if (p_full_objects) { - } else { Object *obj = p_variant; if (!obj) { if (buf) { @@ -1139,7 +1128,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo _encode_string(E->get().name, buf, r_len); int len; - Error err = encode_variant(obj->get(E->get().name), buf, len, p_object_as_id); + Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects); if (err) return err; ERR_FAIL_COND_V(len % 4, ERR_BUG); @@ -1148,6 +1137,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo buf += len; } } + } else { + if (buf) { + + Object *obj = p_variant; + ObjectID id = 0; + if (obj && ObjectDB::instance_validate(obj)) { + id = obj->get_instance_id(); + } + + encode_uint64(id, buf); + } + + r_len += 8; } } break; @@ -1180,14 +1182,14 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len++; //pad */ int len; - encode_variant(E->get(), buf, len, p_object_as_id); + encode_variant(E->get(), buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) buf += len; Variant *v = d.getptr(E->get()); ERR_FAIL_COND_V(!v, ERR_BUG); - encode_variant(*v, buf, len, p_object_as_id); + encode_variant(*v, buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) @@ -1209,7 +1211,7 @@ 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_object_as_id); + encode_variant(v.get(i), buf, len, p_full_objects); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) @@ -1229,11 +1231,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo buf += 4; PoolVector<uint8_t>::Read r = data.read(); copymem(buf, &r[0], datalen * datasize); + buf += datalen * datasize; } r_len += 4 + datalen * datasize; - while (r_len % 4) + while (r_len % 4) { r_len++; + if (buf) + *(buf++) = 0; + } } break; case Variant::POOL_INT_ARRAY: { @@ -1386,7 +1392,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4 * len; } break; - default: { ERR_FAIL_V(ERR_BUG); } + default: { + ERR_FAIL_V(ERR_BUG); + } } return OK; diff --git a/core/io/marshalls.h b/core/io/marshalls.h index 11c4b2c98e..f361c29754 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -199,7 +199,7 @@ public: EncodedObjectAsID(); }; -Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = true); -Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id = false); +Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = false); +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false); #endif diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 7680d47620..2779837190 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -46,7 +46,8 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas case MultiplayerAPI::RPC_MODE_MASTERSYNC: { if (is_master) r_skip_rpc = true; // I am the master, so skip remote call. - } // Do not break, fall over to other sync. + FALLTHROUGH; + } case MultiplayerAPI::RPC_MODE_REMOTESYNC: case MultiplayerAPI::RPC_MODE_PUPPETSYNC: { // Call it, sync always results in a local call. @@ -282,8 +283,9 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_ rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name); } - ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); - ERR_FAIL_COND(!_can_call_mode(p_node, rpc_mode, p_from)); + bool can_call = _can_call_mode(p_node, rpc_mode, p_from); + ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); + ERR_FAIL_COND(!can_call); int argc = p_packet[p_offset]; Vector<Variant> args; @@ -299,7 +301,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_ ERR_FAIL_COND(p_offset >= p_packet_len); int vlen; - Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen); + Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen, allow_object_decoding || network_peer->is_object_decoding_allowed()); ERR_EXPLAIN("Invalid packet received. Unable to decode RPC argument."); ERR_FAIL_COND(err != OK); @@ -331,11 +333,12 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p rset_mode = p_node->get_script_instance()->get_rset_mode(p_name); } - ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + "."); - ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from)); + bool can_call = _can_call_mode(p_node, rset_mode, p_from); + ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + "."); + ERR_FAIL_COND(!can_call); Variant value; - Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset); + Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed()); ERR_EXPLAIN("Invalid packet received. Unable to decode RSET value."); ERR_FAIL_COND(err != OK); @@ -526,11 +529,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p if (p_set) { // Set argument. - Error err = encode_variant(*p_arg[0], NULL, len); + Error err = encode_variant(*p_arg[0], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed()); ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!"); ERR_FAIL_COND(err != OK); MAKE_ROOM(ofs + len); - encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len); + encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed()); ofs += len; } else { @@ -539,11 +542,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p packet_cache.write[ofs] = p_argcount; ofs += 1; for (int i = 0; i < p_argcount; i++) { - Error err = encode_variant(*p_arg[i], NULL, len); + Error err = encode_variant(*p_arg[i], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed()); ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); ERR_FAIL_COND(err != OK); MAKE_ROOM(ofs + len); - encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len); + encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed()); ofs += len; } } @@ -631,7 +634,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED); int node_id = network_peer->get_unique_id(); - bool skip_rpc = false; + bool skip_rpc = node_id == p_peer_id; bool call_local_native = false; bool call_local_script = false; bool is_master = p_node->is_network_master(); @@ -658,8 +661,11 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const } if (call_local_native) { + int temp_id = rpc_sender_id; + rpc_sender_id = get_network_unique_id(); Variant::CallError ce; p_node->call(p_method, p_arg, p_argcount, ce); + rpc_sender_id = temp_id; if (ce.error != Variant::CallError::CALL_OK) { String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in local call: - " + error; @@ -669,9 +675,12 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const } if (call_local_script) { + int temp_id = rpc_sender_id; + rpc_sender_id = get_network_unique_id(); Variant::CallError ce; ce.error = Variant::CallError::CALL_OK; p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce); + rpc_sender_id = temp_id; if (ce.error != Variant::CallError::CALL_OK) { String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in script local call: - " + error; @@ -679,6 +688,9 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const return; } } + + ERR_EXPLAIN("RPC '" + p_method + "' on yourself is not allowed by selected mode"); + ERR_FAIL_COND(skip_rpc && !(call_local_native || call_local_script)); } void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) { @@ -692,13 +704,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const int node_id = network_peer->get_unique_id(); bool is_master = p_node->is_network_master(); - bool skip_rset = false; + bool skip_rset = node_id == p_peer_id; + bool set_local = false; if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { // Check that send mode can use local call. - - bool set_local = false; - const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property); if (E) { @@ -707,7 +717,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const if (set_local) { bool valid; + int temp_id = rpc_sender_id; + + rpc_sender_id = get_network_unique_id(); p_node->set(p_property, p_value, &valid); + rpc_sender_id = temp_id; if (!valid) { String error = "rset() aborted in local set, property not found: - " + String(p_property); @@ -721,8 +735,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const set_local = _should_call_local(rpc_mode, is_master, skip_rset); if (set_local) { + int temp_id = rpc_sender_id; + rpc_sender_id = get_network_unique_id(); bool valid = p_node->get_script_instance()->set(p_property, p_value); + rpc_sender_id = temp_id; if (!valid) { String error = "rset() aborted in local script set, property not found: - " + String(p_property); @@ -733,8 +750,11 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const } } - if (skip_rset) + if (skip_rset) { + ERR_EXPLAIN("RSET for '" + p_property + "' on yourself is not allowed by selected mode"); + ERR_FAIL_COND(!set_local); return; + } const Variant *vptr = &p_value; @@ -818,6 +838,16 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const { return ret; } +void MultiplayerAPI::set_allow_object_decoding(bool p_enable) { + + allow_object_decoding = p_enable; +} + +bool MultiplayerAPI::is_object_decoding_allowed() const { + + return allow_object_decoding; +} + void MultiplayerAPI::_bind_methods() { ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node); ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE)); @@ -838,6 +868,10 @@ void MultiplayerAPI::_bind_methods() { ClassDB::bind_method(D_METHOD("get_network_connected_peers"), &MultiplayerAPI::get_network_connected_peers); ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &MultiplayerAPI::set_refuse_new_network_connections); ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &MultiplayerAPI::is_refusing_new_network_connections); + ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &MultiplayerAPI::set_allow_object_decoding); + ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &MultiplayerAPI::is_object_decoding_allowed); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer"); @@ -859,7 +893,8 @@ void MultiplayerAPI::_bind_methods() { BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC); } -MultiplayerAPI::MultiplayerAPI() { +MultiplayerAPI::MultiplayerAPI() : + allow_object_decoding(false) { rpc_sender_id = 0; root_node = NULL; clear(); diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index a9cf77aaba..779dd043bd 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -63,6 +63,7 @@ private: int last_send_cache_id; Vector<uint8_t> packet_cache; Node *root_node; + bool allow_object_decoding; protected: static void _bind_methods(); @@ -126,6 +127,9 @@ public: void set_refuse_new_network_connections(bool p_refuse); bool is_refusing_new_network_connections() const; + void set_allow_object_decoding(bool p_enable); + bool is_object_decoding_allowed() const; + MultiplayerAPI(); ~MultiplayerAPI(); }; diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index d7bfdbbb37..c77c81f9e2 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -79,7 +79,7 @@ Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) { return put_packet(&r[0], len); } -Error PacketPeer::get_var(Variant &r_variant) { +Error PacketPeer::get_var(Variant &r_variant, bool p_allow_objects) { const uint8_t *buffer; int buffer_size; @@ -87,13 +87,13 @@ Error PacketPeer::get_var(Variant &r_variant) { if (err) return err; - return decode_variant(r_variant, buffer, buffer_size, NULL, allow_object_decoding); + return decode_variant(r_variant, buffer, buffer_size, NULL, p_allow_objects || allow_object_decoding); } -Error PacketPeer::put_var(const Variant &p_packet) { +Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) { int len; - Error err = encode_variant(p_packet, NULL, len, !allow_object_decoding); // compute len first + Error err = encode_variant(p_packet, NULL, len, p_full_objects || allow_object_decoding); // compute len first if (err) return err; @@ -102,15 +102,15 @@ Error PacketPeer::put_var(const Variant &p_packet) { uint8_t *buf = (uint8_t *)alloca(len); ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY); - err = encode_variant(p_packet, buf, len, !allow_object_decoding); + err = encode_variant(p_packet, buf, len, p_full_objects || allow_object_decoding); ERR_FAIL_COND_V(err, err); return put_packet(buf, len); } -Variant PacketPeer::_bnd_get_var() { +Variant PacketPeer::_bnd_get_var(bool p_allow_objects) { Variant var; - get_var(var); + get_var(var, p_allow_objects); return var; }; @@ -132,8 +132,8 @@ Error PacketPeer::_get_packet_error() const { void PacketPeer::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_var"), &PacketPeer::_bnd_get_var); - ClassDB::bind_method(D_METHOD("put_var", "var"), &PacketPeer::put_var); + ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &PacketPeer::_bnd_get_var, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("put_var", "var", "full_objects"), &PacketPeer::put_var, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_packet"), &PacketPeer::_get_packet); ClassDB::bind_method(D_METHOD("put_packet", "buffer"), &PacketPeer::_put_packet); ClassDB::bind_method(D_METHOD("get_packet_error"), &PacketPeer::_get_packet_error); diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 48c50eb76b..6475e4fed9 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -39,8 +39,7 @@ class PacketPeer : public Reference { GDCLASS(PacketPeer, Reference); - Variant _bnd_get_var(); - void _bnd_put_var(const Variant &p_var); + Variant _bnd_get_var(bool p_allow_objects = false); static void _bind_methods(); @@ -64,8 +63,8 @@ public: virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer); virtual Error put_packet_buffer(const PoolVector<uint8_t> &p_buffer); - virtual Error get_var(Variant &r_variant); - virtual Error put_var(const Variant &p_packet); + virtual Error get_var(Variant &r_variant, bool p_allow_objects = false); + virtual Error put_var(const Variant &p_packet, bool p_full_objects = false); void set_allow_object_decoding(bool p_enable); bool is_object_decoding_allowed() const; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 42070cd132..f25abc4aab 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1725,7 +1725,8 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant get_string_index(np.get_subname(i)); } break; - default: {} + default: { + } } } diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index b5fa412576..4a58d37ca5 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -94,6 +94,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy r_path_and_type.type = value; } else if (assign == "importer") { r_path_and_type.importer = value; + } else if (assign == "group_file") { + r_path_and_type.group_file = value; } else if (assign == "metadata") { r_path_and_type.metadata = value; } else if (assign == "valid") { @@ -294,6 +296,14 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat memdelete(f); } +String ResourceFormatImporter::get_import_group_file(const String &p_path) const { + + bool valid = true; + PathAndType pat; + _get_path_and_type(p_path, pat, &valid); + return valid ? pat.group_file : String(); +} + bool ResourceFormatImporter::is_import_valid(const String &p_path) const { bool valid = true; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 1c146c33d7..2e01989564 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -43,6 +43,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { String path; String type; String importer; + String group_file; Variant metadata; }; @@ -69,6 +70,7 @@ public: virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); } + virtual String get_import_group_file(const String &p_path) const; virtual bool exists(const String &p_path) const; virtual bool can_be_imported(const String &p_path) const; @@ -120,8 +122,11 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0; + virtual String get_option_group_file() const { return String(); } virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL) = 0; + + virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths) { return ERR_UNAVAILABLE; } virtual bool are_import_settings_valid(const String &p_path) const { return true; } virtual String get_import_settings_string() const { return String(); } }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index e4b694b64f..56d3b8b133 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -608,6 +608,30 @@ int ResourceLoader::get_import_order(const String &p_path) { return 0; } +String ResourceLoader::get_import_group_file(const String &p_path) { + String path = _path_remap(p_path); + + String local_path; + if (path.is_rel_path()) + local_path = "res://" + path; + else + local_path = ProjectSettings::get_singleton()->localize_path(path); + + for (int i = 0; i < loader_count; i++) { + + if (!loader[i]->recognize_path(local_path)) + continue; + /* + if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) + continue; + */ + + return loader[i]->get_import_group_file(p_path); + } + + return String(); //not found +} + bool ResourceLoader::is_import_valid(const String &p_path) { String path = _path_remap(p_path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index ca7610a0d2..9e7020be7c 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -81,6 +81,7 @@ public: virtual bool is_import_valid(const String &p_path) const { return true; } virtual bool is_imported(const String &p_path) const { return false; } virtual int get_import_order(const String &p_path) const { return 0; } + virtual String get_import_group_file(const String &p_path) const { return ""; } //no group virtual ~ResourceFormatLoader() {} }; @@ -155,6 +156,7 @@ public: static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map); static bool is_import_valid(const String &p_path); + static String get_import_group_file(const String &p_path); static bool is_imported(const String &p_path); static int get_import_order(const String &p_path); diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 3042c0f60a..6ad24a5f3a 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -221,14 +221,14 @@ void StreamPeer::put_utf8_string(const String &p_string) { put_u32(cs.length()); put_data((const uint8_t *)cs.get_data(), cs.length()); } -void StreamPeer::put_var(const Variant &p_variant) { +void StreamPeer::put_var(const Variant &p_variant, bool p_full_objects) { int len = 0; Vector<uint8_t> buf; - encode_variant(p_variant, NULL, len); + encode_variant(p_variant, NULL, len, p_full_objects); buf.resize(len); put_32(len); - encode_variant(p_variant, buf.ptrw(), len); + encode_variant(p_variant, buf.ptrw(), len, p_full_objects); put_data(buf.ptr(), buf.size()); } @@ -359,7 +359,7 @@ String StreamPeer::get_utf8_string(int p_bytes) { ret.parse_utf8((const char *)buf.ptr(), buf.size()); return ret; } -Variant StreamPeer::get_var() { +Variant StreamPeer::get_var(bool p_allow_objects) { int len = get_32(); Vector<uint8_t> var; @@ -369,7 +369,7 @@ Variant StreamPeer::get_var() { ERR_FAIL_COND_V(err != OK, Variant()); Variant ret; - decode_variant(ret, var.ptr(), len); + decode_variant(ret, var.ptr(), len, NULL, p_allow_objects); return ret; } @@ -398,7 +398,7 @@ void StreamPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("put_double", "value"), &StreamPeer::put_double); ClassDB::bind_method(D_METHOD("put_string", "value"), &StreamPeer::put_string); ClassDB::bind_method(D_METHOD("put_utf8_string", "value"), &StreamPeer::put_utf8_string); - ClassDB::bind_method(D_METHOD("put_var", "value"), &StreamPeer::put_var); + ClassDB::bind_method(D_METHOD("put_var", "value", "full_objects"), &StreamPeer::put_var, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_8"), &StreamPeer::get_8); ClassDB::bind_method(D_METHOD("get_u8"), &StreamPeer::get_u8); @@ -412,7 +412,7 @@ void StreamPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_double"), &StreamPeer::get_double); ClassDB::bind_method(D_METHOD("get_string", "bytes"), &StreamPeer::get_string, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("get_utf8_string", "bytes"), &StreamPeer::get_utf8_string, DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("get_var"), &StreamPeer::get_var); + ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &StreamPeer::get_var, DEFVAL(false)); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian_enabled"); } diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 059ccd016c..65e70995ad 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -73,7 +73,7 @@ public: void put_double(double p_val); void put_string(const String &p_string); void put_utf8_string(const String &p_string); - void put_var(const Variant &p_variant); + void put_var(const Variant &p_variant, bool p_full_objects = false); uint8_t get_u8(); int8_t get_8(); @@ -87,7 +87,7 @@ public: double get_double(); String get_string(int p_bytes = -1); String get_utf8_string(int p_bytes = -1); - Variant get_var(); + Variant get_var(bool p_allow_objects = false); StreamPeer() { big_endian = false; } }; diff --git a/core/io/zip_io.h b/core/io/zip_io.h index fb63878a4c..4eb1c8b46c 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -33,7 +33,7 @@ #include "core/os/file_access.h" -// Not direclty used in this header, but assumed available in downstream users +// Not directly used in this header, but assumed available in downstream users // like platform/*/export/export.cpp. Could be fixed, but probably better to have // thirdparty includes in as little headers as possible. #include "thirdparty/minizip/unzip.h" |