summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/io/net_socket.h2
-rw-r--r--core/io/packet_peer_udp.cpp11
-rw-r--r--core/io/packet_peer_udp.h2
-rw-r--r--core/math/basis.cpp12
-rw-r--r--core/math/bsp_tree.cpp4
-rw-r--r--core/math/geometry.cpp2
-rw-r--r--core/math/geometry.h9
-rw-r--r--core/message_queue.cpp3
-rw-r--r--core/object.cpp9
-rw-r--r--core/project_settings.cpp5
-rw-r--r--core/ustring.cpp22
-rw-r--r--core/ustring.h2
-rw-r--r--core/variant_call.cpp51
-rw-r--r--core/variant_op.cpp4
-rw-r--r--core/variant_parser.cpp3
15 files changed, 81 insertions, 60 deletions
diff --git a/core/io/net_socket.h b/core/io/net_socket.h
index 3bc1369487..914e243b65 100644
--- a/core/io/net_socket.h
+++ b/core/io/net_socket.h
@@ -69,7 +69,7 @@ public:
virtual bool is_open() const = 0;
virtual int get_available_bytes() const = 0;
- virtual void set_broadcasting_enabled(bool p_enabled) = 0;
+ virtual Error set_broadcasting_enabled(bool p_enabled) = 0; // Returns OK if the socket option has been set successfully.
virtual void set_blocking_enabled(bool p_enabled) = 0;
virtual void set_ipv6_only_enabled(bool p_enabled) = 0;
virtual void set_tcp_no_delay_enabled(bool p_enabled) = 0;
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index 7e9471c053..80a070cf1c 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -37,6 +37,12 @@ void PacketPeerUDP::set_blocking_mode(bool p_enable) {
blocking = p_enable;
}
+void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
+ broadcast = p_enabled;
+ if (_sock.is_valid() && _sock->is_open())
+ _sock->set_broadcasting_enabled(p_enabled);
+}
+
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
@@ -47,6 +53,7 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
Error err = _sock->open(NetSocket::TYPE_UDP, ip_type);
ERR_FAIL_COND_V(err != OK, err);
_sock->set_blocking_enabled(false);
+ _sock->set_broadcasting_enabled(broadcast);
}
return _sock->join_multicast_group(p_multi_address, p_if_name);
}
@@ -122,6 +129,7 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
err = _sock->open(NetSocket::TYPE_UDP, ip_type);
ERR_FAIL_COND_V(err != OK, err);
_sock->set_blocking_enabled(false);
+ _sock->set_broadcasting_enabled(broadcast);
}
do {
@@ -165,6 +173,7 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
_sock->set_blocking_enabled(false);
_sock->set_reuse_address_enabled(true);
+ _sock->set_broadcasting_enabled(broadcast);
err = _sock->bind(p_bind_address, p_port);
if (err != OK) {
@@ -258,6 +267,7 @@ void PacketPeerUDP::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address);
+ ClassDB::bind_method(D_METHOD("set_broadcast_enabled", "enabled"), &PacketPeerUDP::set_broadcast_enabled);
ClassDB::bind_method(D_METHOD("join_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::join_multicast_group);
ClassDB::bind_method(D_METHOD("leave_multicast_group", "multicast_address", "interface_name"), &PacketPeerUDP::leave_multicast_group);
}
@@ -267,6 +277,7 @@ PacketPeerUDP::PacketPeerUDP() :
queue_count(0),
peer_port(0),
blocking(true),
+ broadcast(false),
_sock(Ref<NetSocket>(NetSocket::create())) {
rb.resize(16);
}
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index 068bd5cd5a..dc89e129dd 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -53,6 +53,7 @@ protected:
IP_Address peer_addr;
int peer_port;
bool blocking;
+ bool broadcast;
Ref<NetSocket> _sock;
static void _bind_methods();
@@ -77,6 +78,7 @@ public:
Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
int get_available_packet_count() const;
int get_max_packet_size() const;
+ void set_broadcast_enabled(bool p_enabled);
Error join_multicast_group(IP_Address p_multi_address, String p_if_name);
Error leave_multicast_group(IP_Address p_multi_address, String p_if_name);
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index d77501c0f6..09d04a8a2a 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -739,8 +739,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
if ((xx > yy) && (xx > zz)) { // elements[0][0] is the largest diagonal term
if (xx < epsilon) {
x = 0;
- y = 0.7071;
- z = 0.7071;
+ y = Math_SQRT12;
+ z = Math_SQRT12;
} else {
x = Math::sqrt(xx);
y = xy / x;
@@ -748,9 +748,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
} else if (yy > zz) { // elements[1][1] is the largest diagonal term
if (yy < epsilon) {
- x = 0.7071;
+ x = Math_SQRT12;
y = 0;
- z = 0.7071;
+ z = Math_SQRT12;
} else {
y = Math::sqrt(yy);
x = xy / y;
@@ -758,8 +758,8 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
} else { // elements[2][2] is the largest diagonal term so base result on this
if (zz < epsilon) {
- x = 0.7071;
- y = 0.7071;
+ x = Math_SQRT12;
+ y = Math_SQRT12;
z = 0;
} else {
z = Math::sqrt(zz);
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index ece293d036..f1d4505c35 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -192,14 +192,14 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
#ifdef DEBUG_ENABLED
int plane_count = planes.size();
uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
+ ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, 0);
#endif
idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under;
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false);
+ ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, 0);
#endif
}
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index ada5107a2c..ee7feba19e 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -97,8 +97,6 @@ void Geometry::MeshData::optimize_vertices() {
vertices = new_vertices;
}
-Vector<Vector<Vector2> > (*Geometry::_decompose_func)(const Vector<Vector2> &p_polygon) = NULL;
-
struct _FaceClassify {
struct _Link {
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 8b0a51c651..db4b82e8ce 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -853,15 +853,6 @@ public:
return triangles;
}
- static Vector<Vector<Vector2> > (*_decompose_func)(const Vector<Vector2> &p_polygon);
- static Vector<Vector<Vector2> > decompose_polygon(const Vector<Vector2> &p_polygon) {
-
- if (_decompose_func)
- return _decompose_func(p_polygon);
-
- return Vector<Vector<Vector2> >();
- }
-
static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
int c = p_polygon.size();
if (c < 3)
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index a76b5167b6..a254da89c6 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -129,9 +129,6 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
uint8_t room_needed = sizeof(Message);
if ((buffer_end + room_needed) >= buffer_size) {
- String type;
- if (ObjectDB::get_instance(p_id))
- type = ObjectDB::get_instance(p_id)->get_class();
print_line("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id));
statistics();
ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
diff --git a/core/object.cpp b/core/object.cpp
index ed3ae4f25d..b643aecdd8 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1215,7 +1215,9 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
MessageQueue::get_singleton()->push_call(target->get_instance_id(), c.method, args, argc, true);
} else {
Variant::CallError ce;
+ s->lock++;
target->call(c.method, args, argc, ce);
+ s->lock--;
if (ce.error != Variant::CallError::CALL_OK) {
#ifdef DEBUG_ENABLED
@@ -1517,7 +1519,7 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
Signal *s = signal_map.getptr(p_signal);
ERR_FAIL_COND_MSG(!s, "Nonexistent signal: " + p_signal + ".");
- ERR_FAIL_COND_MSG(s->lock > 0, "Attempt to disconnect signal '" + p_signal + "' while emitting (locks: " + itos(s->lock) + ").");
+ ERR_FAIL_COND_MSG(s->lock > 0, "Attempt to disconnect signal '" + p_signal + "' while in emission callback. Use CONNECT_DEFERRED (to be able to safely disconnect) or CONNECT_ONESHOT (for automatic disconnection) as connection flags.");
Signal::Target target(p_to_object->get_instance_id(), p_to_method);
@@ -1948,7 +1950,10 @@ Object::~Object() {
Signal *s = &signal_map[*S];
- ERR_CONTINUE_MSG(s->lock > 0, "Attempt to delete an object in the middle of a signal emission from it.");
+ if (s->lock > 0) {
+ //@todo this may need to actually reach the debugger prioritarily somehow because it may crash before
+ ERR_PRINTS("Object was freed or unreferenced while signal '" + String(*S) + "' is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes.");
+ }
//brute force disconnect for performance
int slot_count = s->slot_map.size();
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 067578e354..52087df548 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -769,10 +769,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
String vstr;
VariantWriter::write_to_string(value, vstr);
- if (F->get().find(" ") != -1)
- file->store_string(F->get().quote() + "=" + vstr + "\n");
- else
- file->store_string(F->get() + "=" + vstr + "\n");
+ file->store_string(F->get().property_name_encode() + "=" + vstr + "\n");
}
}
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 25930db201..09a02a09be 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -28,6 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS // to disable build-time warning which suggested to use strcpy_s instead strcpy
+#endif
+
#include "ustring.h"
#include "core/color.h"
@@ -1917,7 +1921,7 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
1.0e256
};
- int sign, expSign = false;
+ bool sign, expSign = false;
double fraction, dblExp;
const double *d;
const C *p;
@@ -3792,7 +3796,8 @@ bool String::is_valid_float() const {
String String::path_to_file(const String &p_path) const {
- String src = this->replace("\\", "/").get_base_dir();
+ // Don't get base dir for src, this is expected to be a dir already.
+ String src = this->replace("\\", "/");
String dst = p_path.replace("\\", "/").get_base_dir();
String rel = src.path_to(dst);
if (rel == dst) // failed
@@ -4054,6 +4059,19 @@ String String::percent_decode() const {
return String::utf8(pe.ptr());
}
+String String::property_name_encode() const {
+ // Escape and quote strings with extended ASCII or further Unicode characters
+ // as well as '"', '=' or ' ' (32)
+ const CharType *cstr = c_str();
+ for (int i = 0; cstr[i]; i++) {
+ if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) {
+ return "\"" + c_escape_multiline() + "\"";
+ }
+ }
+ // Keep as is
+ return *this;
+}
+
String String::get_basename() const {
int pos = find_last(".");
diff --git a/core/ustring.h b/core/ustring.h
index dfc5044942..c20f659c59 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -338,6 +338,8 @@ public:
String percent_encode() const;
String percent_decode() const;
+ String property_name_encode() const;
+
bool is_valid_identifier() const;
bool is_valid_integer() const;
bool is_valid_float() const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 6e593a308d..8aae2d8490 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -1187,31 +1187,6 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
default: return Variant();
}
- } else if (p_argcount > 1) {
-
- _VariantCall::ConstructFunc &c = _VariantCall::construct_funcs[p_type];
-
- for (List<_VariantCall::ConstructData>::Element *E = c.constructors.front(); E; E = E->next()) {
- const _VariantCall::ConstructData &cd = E->get();
-
- if (cd.arg_count != p_argcount)
- continue;
-
- //validate parameters
- for (int i = 0; i < cd.arg_count; i++) {
- if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
- r_error.argument = i;
- r_error.expected = cd.arg_types[i];
- return Variant();
- }
- }
-
- Variant v;
- cd.func(v, p_args);
- return v;
- }
-
} else if (p_argcount == 1 && p_args[0]->type == p_type) {
return *p_args[0]; //copy construct
} else if (p_argcount == 1 && (!p_strict || Variant::can_convert(p_args[0]->type, p_type))) {
@@ -1268,6 +1243,30 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
case POOL_COLOR_ARRAY: return (PoolColorArray(*p_args[0]));
default: return Variant();
}
+ } else if (p_argcount >= 1) {
+
+ _VariantCall::ConstructFunc &c = _VariantCall::construct_funcs[p_type];
+
+ for (List<_VariantCall::ConstructData>::Element *E = c.constructors.front(); E; E = E->next()) {
+ const _VariantCall::ConstructData &cd = E->get();
+
+ if (cd.arg_count != p_argcount)
+ continue;
+
+ //validate parameters
+ for (int i = 0; i < cd.arg_count; i++) {
+ if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) {
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
+ r_error.argument = i;
+ r_error.expected = cd.arg_types[i];
+ return Variant();
+ }
+ }
+
+ Variant v;
+ cd.func(v, p_args);
+ return v;
+ }
}
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor
return Variant();
@@ -1951,7 +1950,7 @@ void register_variant_methods() {
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, orthonormalized, varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, rotated, VECTOR3, "axis", REAL, "phi", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, scaled, VECTOR3, "scale", varray());
- ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated, VECTOR3, "ofs", varray());
+ ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated, VECTOR3, "offset", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, interpolate_with, TRANSFORM, "transform", REAL, "weight", varray());
ADDFUNC1R(TRANSFORM, BOOL, Transform, is_equal_approx, TRANSFORM, "transform", varray());
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index ea9e29e744..ae47397558 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -1118,6 +1118,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_SHIFT_LEFT, INT) {
if (p_b.type != INT)
_RETURN_FAIL;
+ if (p_b._data._int < 0 || p_b._data._int >= 64)
+ _RETURN_FAIL;
_RETURN(p_a._data._int << p_b._data._int);
}
@@ -1129,6 +1131,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_SHIFT_RIGHT, INT) {
if (p_b.type != INT)
_RETURN_FAIL;
+ if (p_b._data._int < 0 || p_b._data._int >= 64)
+ _RETURN_FAIL;
_RETURN(p_a._data._int >> p_b._data._int);
}
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index fe2c981c3c..9a5f9c9ede 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -1530,9 +1530,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
} else if (c != '=') {
what += String::chr(c);
} else {
- if (p_stream->is_utf8()) {
- what.parse_utf8(what.ascii(true).get_data());
- }
r_assign = what;
Token token;
get_token(p_stream, token, line, r_err_str);