summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/http_request.cpp49
-rw-r--r--scene/main/multiplayer_api.cpp2
-rw-r--r--scene/main/node.cpp22
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/main/scene_tree.cpp21
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp16
-rw-r--r--scene/main/window.cpp2
8 files changed, 74 insertions, 42 deletions
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 2c395ec07d..62f362553f 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -276,10 +276,10 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
}
if (content_encoding == "gzip") {
decompressor.instantiate();
- decompressor->start_decompression(false, get_download_chunk_size() * 2);
+ decompressor->start_decompression(false, get_download_chunk_size());
} else if (content_encoding == "deflate") {
decompressor.instantiate();
- decompressor->start_decompression(true, get_download_chunk_size() * 2);
+ decompressor->start_decompression(true, get_download_chunk_size());
}
return false;
@@ -390,19 +390,38 @@ bool HTTPRequest::_update_connection() {
return false;
}
- PackedByteArray chunk = client->read_response_body_chunk();
- downloaded.add(chunk.size());
-
- // Decompress chunk if needed.
- if (decompressor.is_valid()) {
- Error err = decompressor->put_data(chunk.ptr(), chunk.size());
- if (err == OK) {
- chunk.resize(decompressor->get_available_bytes());
- err = decompressor->get_data(chunk.ptrw(), chunk.size());
- }
- if (err != OK) {
- _defer_done(RESULT_BODY_DECOMPRESS_FAILED, response_code, response_headers, PackedByteArray());
- return true;
+ PackedByteArray chunk;
+ if (decompressor.is_null()) {
+ // Chunk can be read directly.
+ chunk = client->read_response_body_chunk();
+ downloaded.add(chunk.size());
+ } else {
+ // Chunk is the result of decompression.
+ PackedByteArray compressed = client->read_response_body_chunk();
+ downloaded.add(compressed.size());
+
+ int pos = 0;
+ int left = compressed.size();
+ while (left) {
+ int w = 0;
+ Error err = decompressor->put_partial_data(compressed.ptr() + pos, left, w);
+ if (err == OK) {
+ PackedByteArray dc;
+ dc.resize(decompressor->get_available_bytes());
+ err = decompressor->get_data(dc.ptrw(), dc.size());
+ chunk.append_array(dc);
+ }
+ if (err != OK) {
+ _defer_done(RESULT_BODY_DECOMPRESS_FAILED, response_code, response_headers, PackedByteArray());
+ return true;
+ }
+ // We need this check here because a "zip bomb" could result in a chunk of few kilos decompressing into gigabytes of data.
+ if (body_size_limit >= 0 && final_body_size.get() + chunk.size() > body_size_limit) {
+ _defer_done(RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
+ return true;
+ }
+ pos += w;
+ left -= w;
}
}
final_body_size.add(chunk.size());
diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp
index 946929aa89..8b4b98c172 100644
--- a/scene/main/multiplayer_api.cpp
+++ b/scene/main/multiplayer_api.cpp
@@ -39,7 +39,7 @@
#include "core/os/os.h"
#endif
-StringName MultiplayerAPI::default_interface = StringName();
+StringName MultiplayerAPI::default_interface;
void MultiplayerAPI::set_default_interface(const StringName &p_interface) {
ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_interface, MultiplayerAPI::get_class_static()), vformat("Can't make %s the default multiplayer interface since it does not extend MultiplayerAPI.", p_interface));
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 304504a82e..f88fdb3ac1 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1759,11 +1759,11 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
}
void Node::remove_from_group(const StringName &p_identifier) {
- ERR_FAIL_COND(!data.grouped.has(p_identifier));
-
HashMap<StringName, GroupData>::Iterator E = data.grouped.find(p_identifier);
- ERR_FAIL_COND(!E);
+ if (!E) {
+ return;
+ }
if (data.tree) {
data.tree->remove_from_group(E->key, this);
@@ -2060,7 +2060,7 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c
nip->set_instance_path(ip->get_instance_path());
node = nip;
- } else if ((p_flags & DUPLICATE_USE_INSTANCING) && !get_scene_file_path().is_empty()) {
+ } else if ((p_flags & DUPLICATE_USE_INSTANTIATION) && !get_scene_file_path().is_empty()) {
Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path());
ERR_FAIL_COND_V(res.is_null(), nullptr);
PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED;
@@ -2246,7 +2246,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) con
}
Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const {
- Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap);
+ Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap);
// This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
if (!p_resource_remap.is_empty()) {
@@ -2581,10 +2581,14 @@ void Node::print_orphan_nodes() {
}
void Node::queue_free() {
+ // There are users which instantiate multiple scene trees for their games.
+ // Use the node's own tree to handle its deletion when relevant.
if (is_inside_tree()) {
get_tree()->queue_delete(this);
} else {
- SceneTree::get_singleton()->queue_delete(this);
+ SceneTree *tree = SceneTree::get_singleton();
+ ERR_FAIL_NULL_MSG(tree, "Can't queue free a node when no SceneTree is available.");
+ tree->queue_delete(this);
}
}
@@ -2652,7 +2656,7 @@ PackedStringArray Node::get_configuration_warnings() const {
String Node::get_configuration_warnings_as_string() const {
PackedStringArray warnings = get_configuration_warnings();
- String all_warnings = String();
+ String all_warnings;
for (int i = 0; i < warnings.size(); i++) {
if (i > 0) {
all_warnings += "\n\n";
@@ -2812,7 +2816,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree);
ClassDB::bind_method(D_METHOD("create_tween"), &Node::create_tween);
- ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS));
+ ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANTIATION | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS));
ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder);
@@ -2918,7 +2922,7 @@ void Node::_bind_methods() {
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS);
- BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANCING);
+ BIND_ENUM_CONSTANT(DUPLICATE_USE_INSTANTIATION);
BIND_ENUM_CONSTANT(INTERNAL_MODE_DISABLED);
BIND_ENUM_CONSTANT(INTERNAL_MODE_FRONT);
diff --git a/scene/main/node.h b/scene/main/node.h
index 4a3ec253b1..5e51ec6b0e 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -57,7 +57,7 @@ public:
DUPLICATE_SIGNALS = 1,
DUPLICATE_GROUPS = 2,
DUPLICATE_SCRIPTS = 4,
- DUPLICATE_USE_INSTANCING = 8,
+ DUPLICATE_USE_INSTANTIATION = 8,
#ifdef TOOLS_ENABLED
DUPLICATE_FROM_EDITOR = 16,
#endif
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 41eefe0f85..81a4e3073b 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -123,6 +123,9 @@ void SceneTree::tree_changed() {
void SceneTree::node_added(Node *p_node) {
emit_signal(node_added_name, p_node);
+ if (call_lock > 0) {
+ call_skip.erase(p_node->get_instance_id());
+ }
}
void SceneTree::node_removed(Node *p_node) {
@@ -131,7 +134,7 @@ void SceneTree::node_removed(Node *p_node) {
}
emit_signal(node_removed_name, p_node);
if (call_lock > 0) {
- call_skip.insert(p_node);
+ call_skip.insert(p_node->get_instance_id());
}
}
@@ -261,7 +264,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -275,7 +278,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -314,7 +317,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -327,7 +330,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -365,7 +368,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -378,7 +381,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -854,7 +857,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
for (int i = 0; i < gr_node_count; i++) {
Node *n = gr_nodes[i];
- if (call_lock && call_skip.has(n)) {
+ if (call_lock && call_skip.has(n->get_instance_id())) {
continue;
}
@@ -904,7 +907,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_cal
}
Node *n = gr_nodes[i];
- if (call_lock && call_skip.has(n)) {
+ if (call_lock && call_skip.has(n->get_instance_id())) {
continue;
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index a460e40597..d4fcb288ae 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -135,7 +135,7 @@ private:
// Safety for when a node is deleted while a group is being called.
int call_lock = 0;
- HashSet<Node *> call_skip; // Skip erased nodes.
+ HashSet<ObjectID> call_skip; // Skip erased nodes. Store ID instead of pointer to avoid false positives when node is freed and a new node is allocated at the pointed address.
List<ObjectID> delete_queue;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 43a2c9473e..9e440405af 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1623,7 +1623,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *control = Object::cast_to<Control>(ci);
if (control) {
gui.dragging = true;
- gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos) - gui.drag_accum);
+ gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos - gui.drag_accum));
if (gui.drag_data.get_type() != Variant::NIL) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
@@ -1669,6 +1669,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_cancel_tooltip();
if (over) {
+ if (!gui.mouse_over) {
+ _drop_physics_mouseover();
+ }
_gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER);
gui.mouse_over = over;
}
@@ -2660,6 +2663,11 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
} else {
gui.subwindow_resize_mode = _sub_window_get_resize_margin(sw.window, mb->get_position());
if (gui.subwindow_resize_mode != SUB_WINDOW_RESIZE_DISABLED) {
+ if (gui.subwindow_focused != sw.window) {
+ // Refocus.
+ _sub_window_grab_focus(sw.window);
+ }
+
gui.subwindow_resize_from_rect = r;
gui.subwindow_drag_from = mb->get_position();
gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
@@ -3039,8 +3047,6 @@ bool Viewport::gui_is_drag_successful() const {
}
void Viewport::set_input_as_handled() {
- _drop_physics_mouseover();
-
if (!handle_input_locally) {
ERR_FAIL_COND(!is_inside_tree());
Viewport *vp = this;
@@ -4159,7 +4165,7 @@ DisplayServer::WindowID SubViewport::get_window_id() const {
}
Transform2D SubViewport::_stretch_transform() {
- Transform2D transform = Transform2D();
+ Transform2D transform;
Size2i view_size_2d_override = _get_size_2d_override();
if (size_2d_override_stretch && view_size_2d_override.width > 0 && view_size_2d_override.height > 0) {
Size2 scale = Size2(_get_size()) / Size2(view_size_2d_override);
@@ -4170,7 +4176,7 @@ Transform2D SubViewport::_stretch_transform() {
}
Transform2D SubViewport::get_screen_transform() const {
- Transform2D container_transform = Transform2D();
+ Transform2D container_transform;
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
if (c) {
if (c->is_stretch_enabled()) {
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index ebb11ecee8..aff2c594d9 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1633,7 +1633,7 @@ void Window::_validate_property(PropertyInfo &p_property) const {
}
Transform2D Window::get_screen_transform() const {
- Transform2D embedder_transform = Transform2D();
+ Transform2D embedder_transform;
if (_get_embedder()) {
embedder_transform.translate_local(get_position());
embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform;