Add object encoding param to serialization methods
Network peers get_var/put_var
File get_var/store_var
GDScript/Mono/VisualScript bytes2var/var2bytes
Add MultiplayerAPI.allow_object_decoding member which deprecates PacketPeer.allow_object_decoding.
Break ABI compatibaility (API compatibility for GDNative).
(cherry picked from commit 393e62b98a
)
This commit is contained in:
parent
a1ad05df86
commit
e0fe795433
|
@ -1908,18 +1908,18 @@ bool _File::file_exists(const String &p_name) const {
|
||||||
return FileAccess::exists(p_name);
|
return FileAccess::exists(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _File::store_var(const Variant &p_var) {
|
void _File::store_var(const Variant &p_var, bool p_full_objects) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(p_var, NULL, len);
|
Error err = encode_variant(p_var, NULL, len, p_full_objects);
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
|
|
||||||
PoolVector<uint8_t> buff;
|
PoolVector<uint8_t> buff;
|
||||||
buff.resize(len);
|
buff.resize(len);
|
||||||
PoolVector<uint8_t>::Write w = buff.write();
|
PoolVector<uint8_t>::Write w = buff.write();
|
||||||
|
|
||||||
err = encode_variant(p_var, &w[0], len);
|
err = encode_variant(p_var, &w[0], len, p_full_objects);
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
w = PoolVector<uint8_t>::Write();
|
w = PoolVector<uint8_t>::Write();
|
||||||
|
|
||||||
|
@ -1927,7 +1927,7 @@ void _File::store_var(const Variant &p_var) {
|
||||||
store_buffer(buff);
|
store_buffer(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant _File::get_var() const {
|
Variant _File::get_var(bool p_allow_objects) const {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!f, Variant());
|
ERR_FAIL_COND_V(!f, Variant());
|
||||||
uint32_t len = get_32();
|
uint32_t len = get_32();
|
||||||
|
@ -1937,7 +1937,7 @@ Variant _File::get_var() const {
|
||||||
PoolVector<uint8_t>::Read r = buff.read();
|
PoolVector<uint8_t>::Read r = buff.read();
|
||||||
|
|
||||||
Variant v;
|
Variant v;
|
||||||
Error err = decode_variant(v, &r[0], len);
|
Error err = decode_variant(v, &r[0], len, NULL, p_allow_objects);
|
||||||
ERR_FAIL_COND_V(err != OK, Variant());
|
ERR_FAIL_COND_V(err != OK, Variant());
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -1980,7 +1980,7 @@ void _File::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_endian_swap"), &_File::get_endian_swap);
|
ClassDB::bind_method(D_METHOD("get_endian_swap"), &_File::get_endian_swap);
|
||||||
ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap);
|
ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap);
|
||||||
ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error);
|
ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error);
|
||||||
ClassDB::bind_method(D_METHOD("get_var"), &_File::get_var);
|
ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &_File::get_var, DEFVAL(false));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8);
|
ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8);
|
||||||
ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16);
|
ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16);
|
||||||
|
@ -1993,7 +1993,7 @@ void _File::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line);
|
ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line);
|
||||||
ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(","));
|
ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(","));
|
||||||
ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string);
|
ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string);
|
||||||
ClassDB::bind_method(D_METHOD("store_var", "value"), &_File::store_var);
|
ClassDB::bind_method(D_METHOD("store_var", "value", "full_objects"), &_File::store_var, DEFVAL(false));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("store_pascal_string", "string"), &_File::store_pascal_string);
|
ClassDB::bind_method(D_METHOD("store_pascal_string", "string"), &_File::store_pascal_string);
|
||||||
ClassDB::bind_method(D_METHOD("get_pascal_string"), &_File::get_pascal_string);
|
ClassDB::bind_method(D_METHOD("get_pascal_string"), &_File::get_pascal_string);
|
||||||
|
@ -2223,17 +2223,17 @@ _Marshalls *_Marshalls::get_singleton() {
|
||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _Marshalls::variant_to_base64(const Variant &p_var) {
|
String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) {
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(p_var, NULL, len);
|
Error err = encode_variant(p_var, NULL, len, p_full_objects);
|
||||||
ERR_FAIL_COND_V(err != OK, "");
|
ERR_FAIL_COND_V(err != OK, "");
|
||||||
|
|
||||||
PoolVector<uint8_t> buff;
|
PoolVector<uint8_t> buff;
|
||||||
buff.resize(len);
|
buff.resize(len);
|
||||||
PoolVector<uint8_t>::Write w = buff.write();
|
PoolVector<uint8_t>::Write w = buff.write();
|
||||||
|
|
||||||
err = encode_variant(p_var, &w[0], len);
|
err = encode_variant(p_var, &w[0], len, p_full_objects);
|
||||||
ERR_FAIL_COND_V(err != OK, "");
|
ERR_FAIL_COND_V(err != OK, "");
|
||||||
|
|
||||||
int b64len = len / 3 * 4 + 4 + 1;
|
int b64len = len / 3 * 4 + 4 + 1;
|
||||||
|
@ -2249,7 +2249,7 @@ String _Marshalls::variant_to_base64(const Variant &p_var) {
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
Variant _Marshalls::base64_to_variant(const String &p_str) {
|
Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) {
|
||||||
|
|
||||||
int strlen = p_str.length();
|
int strlen = p_str.length();
|
||||||
CharString cstr = p_str.ascii();
|
CharString cstr = p_str.ascii();
|
||||||
|
@ -2261,7 +2261,7 @@ Variant _Marshalls::base64_to_variant(const String &p_str) {
|
||||||
int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
|
int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
|
||||||
|
|
||||||
Variant v;
|
Variant v;
|
||||||
Error err = decode_variant(v, &w[0], len);
|
Error err = decode_variant(v, &w[0], len, NULL, p_allow_objects);
|
||||||
ERR_FAIL_COND_V(err != OK, Variant());
|
ERR_FAIL_COND_V(err != OK, Variant());
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -2340,8 +2340,8 @@ String _Marshalls::base64_to_utf8(const String &p_str) {
|
||||||
|
|
||||||
void _Marshalls::_bind_methods() {
|
void _Marshalls::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("variant_to_base64", "variant"), &_Marshalls::variant_to_base64);
|
ClassDB::bind_method(D_METHOD("variant_to_base64", "variant", "full_objects"), &_Marshalls::variant_to_base64, DEFVAL(false));
|
||||||
ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str"), &_Marshalls::base64_to_variant);
|
ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str", "allow_objects"), &_Marshalls::base64_to_variant, DEFVAL(false));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("raw_to_base64", "array"), &_Marshalls::raw_to_base64);
|
ClassDB::bind_method(D_METHOD("raw_to_base64", "array"), &_Marshalls::raw_to_base64);
|
||||||
ClassDB::bind_method(D_METHOD("base64_to_raw", "base64_str"), &_Marshalls::base64_to_raw);
|
ClassDB::bind_method(D_METHOD("base64_to_raw", "base64_str"), &_Marshalls::base64_to_raw);
|
||||||
|
|
|
@ -463,7 +463,7 @@ public:
|
||||||
double get_double() const;
|
double get_double() const;
|
||||||
real_t get_real() const;
|
real_t get_real() const;
|
||||||
|
|
||||||
Variant get_var() const;
|
Variant get_var(bool p_allow_objects = false) const;
|
||||||
|
|
||||||
PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
|
PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
|
||||||
String get_line() const;
|
String get_line() const;
|
||||||
|
@ -500,7 +500,7 @@ public:
|
||||||
|
|
||||||
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
|
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
|
||||||
|
|
||||||
void store_var(const Variant &p_var);
|
void store_var(const Variant &p_var, bool p_full_objects = false);
|
||||||
|
|
||||||
bool file_exists(const String &p_name) const; ///< return true if a file exists
|
bool file_exists(const String &p_name) const; ///< return true if a file exists
|
||||||
|
|
||||||
|
@ -569,8 +569,8 @@ protected:
|
||||||
public:
|
public:
|
||||||
static _Marshalls *get_singleton();
|
static _Marshalls *get_singleton();
|
||||||
|
|
||||||
String variant_to_base64(const Variant &p_var);
|
String variant_to_base64(const Variant &p_var, bool p_full_objects = false);
|
||||||
Variant base64_to_variant(const String &p_str);
|
Variant base64_to_variant(const String &p_str, bool p_allow_objects = false);
|
||||||
|
|
||||||
String raw_to_base64(const PoolVector<uint8_t> &p_arr);
|
String raw_to_base64(const PoolVector<uint8_t> &p_arr);
|
||||||
PoolVector<uint8_t> base64_to_raw(const String &p_str);
|
PoolVector<uint8_t> base64_to_raw(const String &p_str);
|
||||||
|
|
|
@ -299,7 +299,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
|
||||||
ERR_FAIL_COND(p_offset >= p_packet_len);
|
ERR_FAIL_COND(p_offset >= p_packet_len);
|
||||||
|
|
||||||
int vlen;
|
int vlen;
|
||||||
Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen, network_peer->is_object_decoding_allowed());
|
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_EXPLAIN("Invalid packet received. Unable to decode RPC argument.");
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
|
||||||
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
|
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
|
||||||
|
|
||||||
Variant value;
|
Variant value;
|
||||||
Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, network_peer->is_object_decoding_allowed());
|
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_EXPLAIN("Invalid packet received. Unable to decode RSET value.");
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
|
@ -526,11 +526,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
|
||||||
|
|
||||||
if (p_set) {
|
if (p_set) {
|
||||||
// Set argument.
|
// Set argument.
|
||||||
Error err = encode_variant(*p_arg[0], NULL, len, network_peer->is_object_decoding_allowed());
|
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_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
MAKE_ROOM(ofs + len);
|
MAKE_ROOM(ofs + len);
|
||||||
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, network_peer->is_object_decoding_allowed());
|
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||||
ofs += len;
|
ofs += len;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -539,11 +539,11 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
|
||||||
packet_cache.write[ofs] = p_argcount;
|
packet_cache.write[ofs] = p_argcount;
|
||||||
ofs += 1;
|
ofs += 1;
|
||||||
for (int i = 0; i < p_argcount; i++) {
|
for (int i = 0; i < p_argcount; i++) {
|
||||||
Error err = encode_variant(*p_arg[i], NULL, len, network_peer->is_object_decoding_allowed());
|
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_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
|
||||||
ERR_FAIL_COND(err != OK);
|
ERR_FAIL_COND(err != OK);
|
||||||
MAKE_ROOM(ofs + len);
|
MAKE_ROOM(ofs + len);
|
||||||
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, network_peer->is_object_decoding_allowed());
|
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||||
ofs += len;
|
ofs += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -818,6 +818,16 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const {
|
||||||
return ret;
|
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() {
|
void MultiplayerAPI::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
|
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));
|
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 +848,10 @@ void MultiplayerAPI::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_network_connected_peers"), &MultiplayerAPI::get_network_connected_peers);
|
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("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("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::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");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer");
|
||||||
|
|
||||||
|
@ -859,7 +873,8 @@ void MultiplayerAPI::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
|
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiplayerAPI::MultiplayerAPI() {
|
MultiplayerAPI::MultiplayerAPI() :
|
||||||
|
allow_object_decoding(false) {
|
||||||
rpc_sender_id = 0;
|
rpc_sender_id = 0;
|
||||||
root_node = NULL;
|
root_node = NULL;
|
||||||
clear();
|
clear();
|
||||||
|
|
|
@ -63,6 +63,7 @@ private:
|
||||||
int last_send_cache_id;
|
int last_send_cache_id;
|
||||||
Vector<uint8_t> packet_cache;
|
Vector<uint8_t> packet_cache;
|
||||||
Node *root_node;
|
Node *root_node;
|
||||||
|
bool allow_object_decoding;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -126,6 +127,9 @@ public:
|
||||||
void set_refuse_new_network_connections(bool p_refuse);
|
void set_refuse_new_network_connections(bool p_refuse);
|
||||||
bool is_refusing_new_network_connections() const;
|
bool is_refusing_new_network_connections() const;
|
||||||
|
|
||||||
|
void set_allow_object_decoding(bool p_enable);
|
||||||
|
bool is_object_decoding_allowed() const;
|
||||||
|
|
||||||
MultiplayerAPI();
|
MultiplayerAPI();
|
||||||
~MultiplayerAPI();
|
~MultiplayerAPI();
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,7 +79,7 @@ Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) {
|
||||||
return put_packet(&r[0], len);
|
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;
|
const uint8_t *buffer;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
|
@ -87,13 +87,13 @@ Error PacketPeer::get_var(Variant &r_variant) {
|
||||||
if (err)
|
if (err)
|
||||||
return 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;
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -102,15 +102,15 @@ Error PacketPeer::put_var(const Variant &p_packet) {
|
||||||
|
|
||||||
uint8_t *buf = (uint8_t *)alloca(len);
|
uint8_t *buf = (uint8_t *)alloca(len);
|
||||||
ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY);
|
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);
|
ERR_FAIL_COND_V(err, err);
|
||||||
|
|
||||||
return put_packet(buf, len);
|
return put_packet(buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant PacketPeer::_bnd_get_var() {
|
Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
|
||||||
Variant var;
|
Variant var;
|
||||||
get_var(var);
|
get_var(var, p_allow_objects);
|
||||||
|
|
||||||
return var;
|
return var;
|
||||||
};
|
};
|
||||||
|
@ -132,8 +132,8 @@ Error PacketPeer::_get_packet_error() const {
|
||||||
|
|
||||||
void PacketPeer::_bind_methods() {
|
void PacketPeer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_var"), &PacketPeer::_bnd_get_var);
|
ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &PacketPeer::_bnd_get_var, DEFVAL(false));
|
||||||
ClassDB::bind_method(D_METHOD("put_var", "var"), &PacketPeer::put_var);
|
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("get_packet"), &PacketPeer::_get_packet);
|
||||||
ClassDB::bind_method(D_METHOD("put_packet", "buffer"), &PacketPeer::_put_packet);
|
ClassDB::bind_method(D_METHOD("put_packet", "buffer"), &PacketPeer::_put_packet);
|
||||||
ClassDB::bind_method(D_METHOD("get_packet_error"), &PacketPeer::_get_packet_error);
|
ClassDB::bind_method(D_METHOD("get_packet_error"), &PacketPeer::_get_packet_error);
|
||||||
|
|
|
@ -39,8 +39,7 @@ class PacketPeer : public Reference {
|
||||||
|
|
||||||
GDCLASS(PacketPeer, Reference);
|
GDCLASS(PacketPeer, Reference);
|
||||||
|
|
||||||
Variant _bnd_get_var();
|
Variant _bnd_get_var(bool p_allow_objects = false);
|
||||||
void _bnd_put_var(const Variant &p_var);
|
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
@ -64,8 +63,8 @@ public:
|
||||||
virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer);
|
virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer);
|
||||||
virtual Error put_packet_buffer(const PoolVector<uint8_t> &p_buffer);
|
virtual Error put_packet_buffer(const PoolVector<uint8_t> &p_buffer);
|
||||||
|
|
||||||
virtual Error get_var(Variant &r_variant);
|
virtual Error get_var(Variant &r_variant, bool p_allow_objects = false);
|
||||||
virtual Error put_var(const Variant &p_packet);
|
virtual Error put_var(const Variant &p_packet, bool p_full_objects = false);
|
||||||
|
|
||||||
void set_allow_object_decoding(bool p_enable);
|
void set_allow_object_decoding(bool p_enable);
|
||||||
bool is_object_decoding_allowed() const;
|
bool is_object_decoding_allowed() const;
|
||||||
|
|
|
@ -221,14 +221,14 @@ void StreamPeer::put_utf8_string(const String &p_string) {
|
||||||
put_u32(cs.length());
|
put_u32(cs.length());
|
||||||
put_data((const uint8_t *)cs.get_data(), 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;
|
int len = 0;
|
||||||
Vector<uint8_t> buf;
|
Vector<uint8_t> buf;
|
||||||
encode_variant(p_variant, NULL, len);
|
encode_variant(p_variant, NULL, len, p_full_objects);
|
||||||
buf.resize(len);
|
buf.resize(len);
|
||||||
put_32(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());
|
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());
|
ret.parse_utf8((const char *)buf.ptr(), buf.size());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
Variant StreamPeer::get_var() {
|
Variant StreamPeer::get_var(bool p_allow_objects) {
|
||||||
|
|
||||||
int len = get_32();
|
int len = get_32();
|
||||||
Vector<uint8_t> var;
|
Vector<uint8_t> var;
|
||||||
|
@ -369,7 +369,7 @@ Variant StreamPeer::get_var() {
|
||||||
ERR_FAIL_COND_V(err != OK, Variant());
|
ERR_FAIL_COND_V(err != OK, Variant());
|
||||||
|
|
||||||
Variant ret;
|
Variant ret;
|
||||||
decode_variant(ret, var.ptr(), len);
|
decode_variant(ret, var.ptr(), len, NULL, p_allow_objects);
|
||||||
return ret;
|
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_double", "value"), &StreamPeer::put_double);
|
||||||
ClassDB::bind_method(D_METHOD("put_string", "value"), &StreamPeer::put_string);
|
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_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_8"), &StreamPeer::get_8);
|
||||||
ClassDB::bind_method(D_METHOD("get_u8"), &StreamPeer::get_u8);
|
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_double"), &StreamPeer::get_double);
|
||||||
ClassDB::bind_method(D_METHOD("get_string", "bytes"), &StreamPeer::get_string, DEFVAL(-1));
|
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_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");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian_enabled");
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
void put_double(double p_val);
|
void put_double(double p_val);
|
||||||
void put_string(const String &p_string);
|
void put_string(const String &p_string);
|
||||||
void put_utf8_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();
|
uint8_t get_u8();
|
||||||
int8_t get_8();
|
int8_t get_8();
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
double get_double();
|
double get_double();
|
||||||
String get_string(int p_bytes = -1);
|
String get_string(int p_bytes = -1);
|
||||||
String get_utf8_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; }
|
StreamPeer() { big_endian = false; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -164,10 +164,10 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
|
||||||
case TEXT_PRINTRAW:
|
case TEXT_PRINTRAW:
|
||||||
case VAR_TO_STR:
|
case VAR_TO_STR:
|
||||||
case STR_TO_VAR:
|
case STR_TO_VAR:
|
||||||
case VAR_TO_BYTES:
|
|
||||||
case BYTES_TO_VAR:
|
|
||||||
case TYPE_EXISTS:
|
case TYPE_EXISTS:
|
||||||
return 1;
|
return 1;
|
||||||
|
case VAR_TO_BYTES:
|
||||||
|
case BYTES_TO_VAR:
|
||||||
case MATH_ATAN2:
|
case MATH_ATAN2:
|
||||||
case MATH_FMOD:
|
case MATH_FMOD:
|
||||||
case MATH_FPOSMOD:
|
case MATH_FPOSMOD:
|
||||||
|
@ -696,8 +696,9 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
|
||||||
case VAR_TO_BYTES: {
|
case VAR_TO_BYTES: {
|
||||||
|
|
||||||
PoolByteArray barr;
|
PoolByteArray barr;
|
||||||
|
bool full_objects = *p_inputs[1];
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(*p_inputs[0], NULL, len);
|
Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
|
||||||
if (err) {
|
if (err) {
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = 0;
|
r_error.argument = 0;
|
||||||
|
@ -709,7 +710,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
|
||||||
barr.resize(len);
|
barr.resize(len);
|
||||||
{
|
{
|
||||||
PoolByteArray::Write w = barr.write();
|
PoolByteArray::Write w = barr.write();
|
||||||
encode_variant(*p_inputs[0], w.ptr(), len);
|
encode_variant(*p_inputs[0], w.ptr(), len, full_objects);
|
||||||
}
|
}
|
||||||
*r_return = barr;
|
*r_return = barr;
|
||||||
} break;
|
} break;
|
||||||
|
@ -724,10 +725,11 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolByteArray varr = *p_inputs[0];
|
PoolByteArray varr = *p_inputs[0];
|
||||||
|
bool allow_objects = *p_inputs[1];
|
||||||
Variant ret;
|
Variant ret;
|
||||||
{
|
{
|
||||||
PoolByteArray::Read r = varr.read();
|
PoolByteArray::Read r = varr.read();
|
||||||
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL);
|
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
|
@ -114,7 +114,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Variant v;
|
Variant v;
|
||||||
Error rerr = decode_variant(v, p_buf + p_ofs, datalen - p_ofs, NULL);
|
Error rerr = decode_variant(v, p_buf + p_ofs, datalen - p_ofs, NULL, false);
|
||||||
|
|
||||||
if (rerr != OK) {
|
if (rerr != OK) {
|
||||||
|
|
||||||
|
@ -249,9 +249,9 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
|
||||||
|
|
||||||
uint32_t pos = tmpdata.size();
|
uint32_t pos = tmpdata.size();
|
||||||
int len;
|
int len;
|
||||||
encode_variant(p_data, NULL, len);
|
encode_variant(p_data, NULL, len, false);
|
||||||
tmpdata.resize(tmpdata.size() + len);
|
tmpdata.resize(tmpdata.size() + len);
|
||||||
encode_variant(p_data, &tmpdata.write[pos], len);
|
encode_variant(p_data, &tmpdata.write[pos], len, false);
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -501,7 +501,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) {
|
||||||
d.resize(vlen);
|
d.resize(vlen);
|
||||||
f->get_buffer(d.ptrw(), vlen);
|
f->get_buffer(d.ptrw(), vlen);
|
||||||
Variant value;
|
Variant value;
|
||||||
err = decode_variant(value, d.ptr(), d.size());
|
err = decode_variant(value, d.ptr(), d.size(), NULL, false);
|
||||||
ERR_EXPLAIN("Error decoding property: " + key);
|
ERR_EXPLAIN("Error decoding property: " + key);
|
||||||
ERR_CONTINUE(err != OK);
|
ERR_CONTINUE(err != OK);
|
||||||
set(key, value);
|
set(key, value);
|
||||||
|
@ -656,7 +656,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
|
||||||
file->store_string(key);
|
file->store_string(key);
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
err = encode_variant(p_custom_features, NULL, len);
|
err = encode_variant(p_custom_features, NULL, len, false);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
memdelete(file);
|
memdelete(file);
|
||||||
ERR_FAIL_V(err);
|
ERR_FAIL_V(err);
|
||||||
|
@ -665,7 +665,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
|
||||||
Vector<uint8_t> buff;
|
Vector<uint8_t> buff;
|
||||||
buff.resize(len);
|
buff.resize(len);
|
||||||
|
|
||||||
err = encode_variant(p_custom_features, buff.ptrw(), len);
|
err = encode_variant(p_custom_features, buff.ptrw(), len, false);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
memdelete(file);
|
memdelete(file);
|
||||||
ERR_FAIL_V(err);
|
ERR_FAIL_V(err);
|
||||||
|
@ -694,7 +694,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
|
||||||
file->store_string(key);
|
file->store_string(key);
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
err = encode_variant(value, NULL, len);
|
err = encode_variant(value, NULL, len, false);
|
||||||
if (err != OK)
|
if (err != OK)
|
||||||
memdelete(file);
|
memdelete(file);
|
||||||
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
|
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
|
||||||
|
@ -702,7 +702,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
|
||||||
Vector<uint8_t> buff;
|
Vector<uint8_t> buff;
|
||||||
buff.resize(len);
|
buff.resize(len);
|
||||||
|
|
||||||
err = encode_variant(value, buff.ptrw(), len);
|
err = encode_variant(value, buff.ptrw(), len, false);
|
||||||
if (err != OK)
|
if (err != OK)
|
||||||
memdelete(file);
|
memdelete(file);
|
||||||
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
|
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
|
||||||
|
|
|
@ -134,8 +134,11 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="bytes" type="PoolByteArray">
|
<argument index="0" name="bytes" type="PoolByteArray">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="allow_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Decodes a byte array back to a value.
|
Decodes a byte array back to a value. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="cartesian2polar">
|
<method name="cartesian2polar">
|
||||||
|
@ -1110,8 +1113,10 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="var" type="Variant">
|
<argument index="0" name="var" type="Variant">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="full_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Encodes a variable value to a byte array.
|
Encodes a variable value to a byte array. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="var2str">
|
<method name="var2str">
|
||||||
|
|
|
@ -206,8 +206,11 @@
|
||||||
<method name="get_var" qualifiers="const">
|
<method name="get_var" qualifiers="const">
|
||||||
<return type="Variant">
|
<return type="Variant">
|
||||||
</return>
|
</return>
|
||||||
|
<argument index="0" name="allow_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Returns the next [Variant] value from the file.
|
Returns the next [Variant] value from the file. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="is_open" qualifiers="const">
|
<method name="is_open" qualifiers="const">
|
||||||
|
@ -404,8 +407,10 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="value" type="Variant">
|
<argument index="0" name="value" type="Variant">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="full_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Stores any Variant value in the file.
|
Stores any Variant value in the file. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -32,8 +32,11 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="base64_str" type="String">
|
<argument index="0" name="base64_str" type="String">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="allow_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Return [Variant] of a given base64 encoded String.
|
Return [Variant] of a given base64 encoded String. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="raw_to_base64">
|
<method name="raw_to_base64">
|
||||||
|
@ -59,8 +62,10 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="variant" type="Variant">
|
<argument index="0" name="variant" type="Variant">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="full_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Return base64 encoded String of a given [Variant].
|
Return base64 encoded String of a given [Variant]. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -87,6 +87,10 @@
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed">
|
||||||
|
If [code]true[/code] (or if the [member network_peer] [member PacketPeer.allow_object_decoding] the MultiplayerAPI will allow encoding and decoding of object during RPCs/RSETs.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
|
</member>
|
||||||
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
|
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
|
||||||
The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
|
The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -33,8 +33,11 @@
|
||||||
<method name="get_var">
|
<method name="get_var">
|
||||||
<return type="Variant">
|
<return type="Variant">
|
||||||
</return>
|
</return>
|
||||||
|
<argument index="0" name="allow_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Get a Variant.
|
Get a Variant. When [code]allow_objects[/code] (or [member allow_object_decoding]) is [code]true[/code] decoding objects is allowed.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="put_packet">
|
<method name="put_packet">
|
||||||
|
@ -51,13 +54,16 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="var" type="Variant">
|
<argument index="0" name="var" type="Variant">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="full_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Send a Variant as a packet.
|
Send a Variant as a packet. When [code]full_objects[/code] (or [member allow_object_decoding]) is [code]true[/code] encoding objects is allowed (and can potentially include code).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
<member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed">
|
<member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed">
|
||||||
|
Deprecated. Use [code]get_var[/code] and [code]put_var[/code] parameters instead.
|
||||||
If [code]true[/code] the PacketPeer will allow encoding and decoding of object via [method get_var] and [method put_var].
|
If [code]true[/code] the PacketPeer will allow encoding and decoding of object via [method get_var] and [method put_var].
|
||||||
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -125,8 +125,11 @@
|
||||||
<method name="get_var">
|
<method name="get_var">
|
||||||
<return type="Variant">
|
<return type="Variant">
|
||||||
</return>
|
</return>
|
||||||
|
<argument index="0" name="allow_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Get a Variant from the stream.
|
Get a Variant from the stream. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed.
|
||||||
|
[b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="put_16">
|
<method name="put_16">
|
||||||
|
@ -260,8 +263,10 @@
|
||||||
</return>
|
</return>
|
||||||
<argument index="0" name="value" type="Variant">
|
<argument index="0" name="value" type="Variant">
|
||||||
</argument>
|
</argument>
|
||||||
|
<argument index="1" name="full_objects" type="bool" default="false">
|
||||||
|
</argument>
|
||||||
<description>
|
<description>
|
||||||
Put a Variant into the stream.
|
Put a Variant into the stream. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -768,11 +768,30 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
|
||||||
(void)VariantParser::parse(&ss, r_ret, errs, line);
|
(void)VariantParser::parse(&ss, r_ret, errs, line);
|
||||||
} break;
|
} break;
|
||||||
case VAR_TO_BYTES: {
|
case VAR_TO_BYTES: {
|
||||||
VALIDATE_ARG_COUNT(1);
|
bool full_objects = false;
|
||||||
|
if (p_arg_count < 1) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_ret = Variant();
|
||||||
|
return;
|
||||||
|
} else if (p_arg_count > 2) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||||
|
r_error.argument = 2;
|
||||||
|
r_ret = Variant();
|
||||||
|
} else if (p_arg_count == 2) {
|
||||||
|
if (p_args[1]->get_type() != Variant::BOOL) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_error.expected = Variant::BOOL;
|
||||||
|
r_ret = Variant();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
full_objects = *p_args[1];
|
||||||
|
}
|
||||||
|
|
||||||
PoolByteArray barr;
|
PoolByteArray barr;
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(*p_args[0], NULL, len);
|
Error err = encode_variant(*p_args[0], NULL, len, full_objects);
|
||||||
if (err) {
|
if (err) {
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = 0;
|
r_error.argument = 0;
|
||||||
|
@ -784,15 +803,35 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
|
||||||
barr.resize(len);
|
barr.resize(len);
|
||||||
{
|
{
|
||||||
PoolByteArray::Write w = barr.write();
|
PoolByteArray::Write w = barr.write();
|
||||||
encode_variant(*p_args[0], w.ptr(), len);
|
encode_variant(*p_args[0], w.ptr(), len, full_objects);
|
||||||
}
|
}
|
||||||
r_ret = barr;
|
r_ret = barr;
|
||||||
} break;
|
} break;
|
||||||
case BYTES_TO_VAR: {
|
case BYTES_TO_VAR: {
|
||||||
VALIDATE_ARG_COUNT(1);
|
bool allow_objects = false;
|
||||||
|
if (p_arg_count < 1) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_ret = Variant();
|
||||||
|
return;
|
||||||
|
} else if (p_arg_count > 2) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||||
|
r_error.argument = 2;
|
||||||
|
r_ret = Variant();
|
||||||
|
} else if (p_arg_count == 2) {
|
||||||
|
if (p_args[1]->get_type() != Variant::BOOL) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_error.expected = Variant::BOOL;
|
||||||
|
r_ret = Variant();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
allow_objects = *p_args[1];
|
||||||
|
}
|
||||||
|
|
||||||
if (p_args[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
|
if (p_args[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = 0;
|
r_error.argument = 1;
|
||||||
r_error.expected = Variant::POOL_BYTE_ARRAY;
|
r_error.expected = Variant::POOL_BYTE_ARRAY;
|
||||||
r_ret = Variant();
|
r_ret = Variant();
|
||||||
return;
|
return;
|
||||||
|
@ -802,7 +841,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
|
||||||
Variant ret;
|
Variant ret;
|
||||||
{
|
{
|
||||||
PoolByteArray::Read r = varr.read();
|
PoolByteArray::Read r = varr.read();
|
||||||
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL);
|
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
r_ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
r_ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
@ -1805,13 +1844,15 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
|
||||||
} break;
|
} break;
|
||||||
case VAR_TO_BYTES: {
|
case VAR_TO_BYTES: {
|
||||||
|
|
||||||
MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
|
MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "full_objects"));
|
||||||
|
mi.default_arguments.push_back(false);
|
||||||
mi.return_val.type = Variant::POOL_BYTE_ARRAY;
|
mi.return_val.type = Variant::POOL_BYTE_ARRAY;
|
||||||
return mi;
|
return mi;
|
||||||
} break;
|
} break;
|
||||||
case BYTES_TO_VAR: {
|
case BYTES_TO_VAR: {
|
||||||
|
|
||||||
MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"));
|
MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects"));
|
||||||
|
mi.default_arguments.push_back(false);
|
||||||
mi.return_val.type = Variant::NIL;
|
mi.return_val.type = Variant::NIL;
|
||||||
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
|
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
|
||||||
return mi;
|
return mi;
|
||||||
|
|
|
@ -1200,7 +1200,8 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
|
||||||
|
|
||||||
Variant v;
|
Variant v;
|
||||||
int len;
|
int len;
|
||||||
Error err = decode_variant(v, b, total_len, &len);
|
// An object cannot be constant, never decode objects
|
||||||
|
Error err = decode_variant(v, b, total_len, &len, false);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
b += len;
|
b += len;
|
||||||
|
@ -1368,11 +1369,12 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
|
||||||
for (Map<int, Variant>::Element *E = rev_constant_map.front(); E; E = E->next()) {
|
for (Map<int, Variant>::Element *E = rev_constant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(E->get(), NULL, len);
|
// Objects cannot be constant, never encode objects
|
||||||
|
Error err = encode_variant(E->get(), NULL, len, false);
|
||||||
ERR_FAIL_COND_V(err != OK, Vector<uint8_t>());
|
ERR_FAIL_COND_V(err != OK, Vector<uint8_t>());
|
||||||
int pos = buf.size();
|
int pos = buf.size();
|
||||||
buf.resize(pos + len);
|
buf.resize(pos + len);
|
||||||
encode_variant(E->get(), &buf.write[pos], len);
|
encode_variant(E->get(), &buf.write[pos], len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map<int, uint32_t>::Element *E = rev_line_map.front(); E; E = E->next()) {
|
for (Map<int, uint32_t>::Element *E = rev_line_map.front(); E; E = E->next()) {
|
||||||
|
|
|
@ -13,9 +13,9 @@ namespace Godot
|
||||||
{
|
{
|
||||||
public static partial class GD
|
public static partial class GD
|
||||||
{
|
{
|
||||||
public static object Bytes2Var(byte[] bytes)
|
public static object Bytes2Var(byte[] bytes, bool allow_objects = false)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_bytes2var(bytes);
|
return godot_icall_GD_bytes2var(bytes, allow_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object Convert(object what, Variant.Type type)
|
public static object Convert(object what, Variant.Type type)
|
||||||
|
@ -186,9 +186,9 @@ namespace Godot
|
||||||
return godot_icall_GD_type_exists(type);
|
return godot_icall_GD_type_exists(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] Var2Bytes(object var)
|
public static byte[] Var2Bytes(object var, bool full_objects = false)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_var2bytes(var);
|
return godot_icall_GD_var2bytes(var, full_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Var2Str(object var)
|
public static string Var2Str(object var)
|
||||||
|
@ -197,7 +197,7 @@ namespace Godot
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal extern static object godot_icall_GD_bytes2var(byte[] bytes);
|
internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allow_objects);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal extern static object godot_icall_GD_convert(object what, Variant.Type type);
|
internal extern static object godot_icall_GD_convert(object what, Variant.Type type);
|
||||||
|
@ -251,7 +251,7 @@ namespace Godot
|
||||||
internal extern static bool godot_icall_GD_type_exists(string type);
|
internal extern static bool godot_icall_GD_type_exists(string type);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal extern static byte[] godot_icall_GD_var2bytes(object what);
|
internal extern static byte[] godot_icall_GD_var2bytes(object what, bool full_objects);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal extern static string godot_icall_GD_var2str(object var);
|
internal extern static string godot_icall_GD_var2str(object var);
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
|
|
||||||
#include "../mono_gd/gd_mono_utils.h"
|
#include "../mono_gd/gd_mono_utils.h"
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes) {
|
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) {
|
||||||
Variant ret;
|
Variant ret;
|
||||||
PoolByteArray varr = GDMonoMarshal::mono_array_to_PoolByteArray(p_bytes);
|
PoolByteArray varr = GDMonoMarshal::mono_array_to_PoolByteArray(p_bytes);
|
||||||
PoolByteArray::Read r = varr.read();
|
PoolByteArray::Read r = varr.read();
|
||||||
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL);
|
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, p_allow_objects);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
||||||
}
|
}
|
||||||
|
@ -187,19 +187,19 @@ void godot_icall_GD_pushwarning(MonoString *p_str) {
|
||||||
WARN_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str));
|
WARN_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var) {
|
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects) {
|
||||||
Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
|
Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
|
||||||
|
|
||||||
PoolByteArray barr;
|
PoolByteArray barr;
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(var, NULL, len);
|
Error err = encode_variant(var, NULL, len, p_full_objects);
|
||||||
ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
|
ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
|
||||||
ERR_FAIL_COND_V(err != OK, NULL);
|
ERR_FAIL_COND_V(err != OK, NULL);
|
||||||
|
|
||||||
barr.resize(len);
|
barr.resize(len);
|
||||||
{
|
{
|
||||||
PoolByteArray::Write w = barr.write();
|
PoolByteArray::Write w = barr.write();
|
||||||
encode_variant(var, w.ptr(), len);
|
encode_variant(var, w.ptr(), len, p_full_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GDMonoMarshal::PoolByteArray_to_mono_array(barr);
|
return GDMonoMarshal::PoolByteArray_to_mono_array(barr);
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#include "../mono_gd/gd_mono_marshal.h"
|
#include "../mono_gd/gd_mono_marshal.h"
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes);
|
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects);
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type);
|
MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str);
|
||||||
|
|
||||||
MonoBoolean godot_icall_GD_type_exists(MonoString *p_type);
|
MonoBoolean godot_icall_GD_type_exists(MonoString *p_type);
|
||||||
|
|
||||||
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var);
|
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects);
|
||||||
|
|
||||||
MonoString *godot_icall_GD_var2str(MonoObject *p_var);
|
MonoString *godot_icall_GD_var2str(MonoObject *p_var);
|
||||||
|
|
||||||
|
|
|
@ -183,10 +183,10 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
|
||||||
case TEXT_PRINTRAW:
|
case TEXT_PRINTRAW:
|
||||||
case VAR_TO_STR:
|
case VAR_TO_STR:
|
||||||
case STR_TO_VAR:
|
case STR_TO_VAR:
|
||||||
case VAR_TO_BYTES:
|
|
||||||
case BYTES_TO_VAR:
|
|
||||||
case TYPE_EXISTS:
|
case TYPE_EXISTS:
|
||||||
return 1;
|
return 1;
|
||||||
|
case VAR_TO_BYTES:
|
||||||
|
case BYTES_TO_VAR:
|
||||||
case MATH_ATAN2:
|
case MATH_ATAN2:
|
||||||
case MATH_FMOD:
|
case MATH_FMOD:
|
||||||
case MATH_FPOSMOD:
|
case MATH_FPOSMOD:
|
||||||
|
@ -491,12 +491,18 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
|
||||||
return PropertyInfo(Variant::STRING, "string");
|
return PropertyInfo(Variant::STRING, "string");
|
||||||
} break;
|
} break;
|
||||||
case VAR_TO_BYTES: {
|
case VAR_TO_BYTES: {
|
||||||
|
if (p_idx == 0)
|
||||||
return PropertyInfo(Variant::NIL, "var");
|
return PropertyInfo(Variant::NIL, "var");
|
||||||
|
else
|
||||||
|
return PropertyInfo(Variant::BOOL, "full_objects");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case BYTES_TO_VAR: {
|
case BYTES_TO_VAR: {
|
||||||
|
|
||||||
|
if (p_idx == 0)
|
||||||
return PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes");
|
return PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes");
|
||||||
|
else
|
||||||
|
return PropertyInfo(Variant::BOOL, "allow_objects");
|
||||||
} break;
|
} break;
|
||||||
case COLORN: {
|
case COLORN: {
|
||||||
|
|
||||||
|
@ -655,11 +661,15 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case VAR_TO_BYTES: {
|
case VAR_TO_BYTES: {
|
||||||
|
if (p_idx == 0)
|
||||||
t = Variant::POOL_BYTE_ARRAY;
|
t = Variant::POOL_BYTE_ARRAY;
|
||||||
|
else
|
||||||
|
t = Variant::BOOL;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case BYTES_TO_VAR: {
|
case BYTES_TO_VAR: {
|
||||||
|
if (p_idx == 1)
|
||||||
|
t = Variant::BOOL;
|
||||||
} break;
|
} break;
|
||||||
case COLORN: {
|
case COLORN: {
|
||||||
t = Variant::COLOR;
|
t = Variant::COLOR;
|
||||||
|
@ -1192,9 +1202,16 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
|
||||||
} break;
|
} break;
|
||||||
case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
|
case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
|
||||||
|
|
||||||
|
if (p_inputs[1]->get_type() != Variant::BOOL) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_error.expected = Variant::BOOL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
PoolByteArray barr;
|
PoolByteArray barr;
|
||||||
int len;
|
int len;
|
||||||
Error err = encode_variant(*p_inputs[0], NULL, len);
|
bool full_objects = *p_inputs[1];
|
||||||
|
Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
|
||||||
if (err) {
|
if (err) {
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = 0;
|
r_error.argument = 0;
|
||||||
|
@ -1206,7 +1223,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
|
||||||
barr.resize(len);
|
barr.resize(len);
|
||||||
{
|
{
|
||||||
PoolByteArray::Write w = barr.write();
|
PoolByteArray::Write w = barr.write();
|
||||||
encode_variant(*p_inputs[0], w.ptr(), len);
|
encode_variant(*p_inputs[0], w.ptr(), len, full_objects);
|
||||||
}
|
}
|
||||||
*r_return = barr;
|
*r_return = barr;
|
||||||
} break;
|
} break;
|
||||||
|
@ -1216,15 +1233,21 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = 0;
|
r_error.argument = 0;
|
||||||
r_error.expected = Variant::POOL_BYTE_ARRAY;
|
r_error.expected = Variant::POOL_BYTE_ARRAY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (p_inputs[1]->get_type() != Variant::BOOL) {
|
||||||
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
r_error.argument = 1;
|
||||||
|
r_error.expected = Variant::BOOL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolByteArray varr = *p_inputs[0];
|
PoolByteArray varr = *p_inputs[0];
|
||||||
|
bool allow_objects = *p_inputs[1];
|
||||||
Variant ret;
|
Variant ret;
|
||||||
{
|
{
|
||||||
PoolByteArray::Read r = varr.read();
|
PoolByteArray::Read r = varr.read();
|
||||||
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL);
|
Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
||||||
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
Loading…
Reference in New Issue