summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Texture2D.xml2
-rw-r--r--doc/classes/TextureLayered.xml2
-rw-r--r--doc/classes/VisualServer.xml42
-rw-r--r--editor/code_editor.cpp10
-rw-r--r--editor/connections_dialog.cpp16
-rw-r--r--editor/connections_dialog.h1
-rw-r--r--misc/dist/shell/godot.fish91
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp86
-rw-r--r--modules/websocket/emws_client.cpp22
-rw-r--r--modules/websocket/emws_peer.cpp15
-rw-r--r--scene/2d/audio_stream_player_2d.cpp2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp2
-rw-r--r--scene/audio/audio_stream_player.cpp2
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--scene/resources/texture.h4
-rw-r--r--servers/visual/shader_language.cpp8
-rw-r--r--servers/visual_server.cpp6
-rw-r--r--servers/visual_server.h2
18 files changed, 223 insertions, 92 deletions
diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml
index 2ccb469eb1..63cdb0d90a 100644
--- a/doc/classes/Texture2D.xml
+++ b/doc/classes/Texture2D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Texture2D" inherits="Resource" version="4.0">
+<class name="Texture2D" inherits="Texture" version="4.0">
<brief_description>
Texture for 2D and 3D.
</brief_description>
diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml
index f9ecdb02f0..66e5b69ab4 100644
--- a/doc/classes/TextureLayered.xml
+++ b/doc/classes/TextureLayered.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="TextureLayered" inherits="Resource" version="4.0">
+<class name="TextureLayered" inherits="Texture" version="4.0">
<brief_description>
Base class for 3D texture types.
</brief_description>
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index 1634db2484..c51811397a 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -801,6 +801,30 @@
Sets the rotation of the background [Sky] expressed as a [Basis]. Equivalent to [member Environment.sky_rotation], where the rotation vector is used to construct the [Basis].
</description>
</method>
+ <method name="environment_set_ssao">
+ <return type="void">
+ </return>
+ <argument index="0" name="env" type="RID">
+ </argument>
+ <argument index="1" name="enable" type="bool">
+ </argument>
+ <argument index="2" name="radius" type="float">
+ </argument>
+ <argument index="3" name="intensity" type="float">
+ </argument>
+ <argument index="4" name="bias" type="float">
+ </argument>
+ <argument index="5" name="light_affect" type="float">
+ </argument>
+ <argument index="6" name="ao_channel_affect" type="float">
+ </argument>
+ <argument index="7" name="blur" type="int" enum="VisualServer.EnvironmentSSAOBlur">
+ </argument>
+ <argument index="8" name="bilateral_sharpness" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="environment_set_ssr">
<return type="void">
</return>
@@ -3497,15 +3521,6 @@
<constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper">
Use the ACES tonemapper.
</constant>
- <constant name="ENV_SSAO_QUALITY_LOW" value="0" enum="EnvironmentSSAOQuality">
- Lowest quality of screen space ambient occlusion.
- </constant>
- <constant name="ENV_SSAO_QUALITY_MEDIUM" value="1" enum="EnvironmentSSAOQuality">
- Medium quality screen space ambient occlusion.
- </constant>
- <constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality">
- Highest quality screen space ambient occlusion.
- </constant>
<constant name="ENV_SSAO_BLUR_DISABLED" value="0" enum="EnvironmentSSAOBlur">
Disables the blur set for SSAO. Will make SSAO look noisier.
</constant>
@@ -3518,6 +3533,15 @@
<constant name="ENV_SSAO_BLUR_3x3" value="3" enum="EnvironmentSSAOBlur">
Performs a 3x3 blur on the SSAO output. Use this for smoothest SSAO.
</constant>
+ <constant name="ENV_SSAO_QUALITY_LOW" value="0" enum="EnvironmentSSAOQuality">
+ Lowest quality of screen space ambient occlusion.
+ </constant>
+ <constant name="ENV_SSAO_QUALITY_MEDIUM" value="1" enum="EnvironmentSSAOQuality">
+ Medium quality screen space ambient occlusion.
+ </constant>
+ <constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality">
+ Highest quality screen space ambient occlusion.
+ </constant>
<constant name="ENV_SSAO_QUALITY_ULTRA" value="3" enum="EnvironmentSSAOQuality">
</constant>
<constant name="DOF_BLUR_QUALITY_VERY_LOW" value="0" enum="DOFBlurQuality">
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index e898bc54dd..ca0ac70ff7 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -691,6 +691,16 @@ void CodeTextEditor::_input(const Ref<InputEvent> &event) {
accept_event();
return;
}
+ if (ED_IS_SHORTCUT("script_text_editor/delete_line", key_event)) {
+ delete_lines();
+ accept_event();
+ return;
+ }
+ if (ED_IS_SHORTCUT("script_text_editor/clone_down", key_event)) {
+ clone_lines_down();
+ accept_event();
+ return;
+ }
}
void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 7e283bb27f..deabb06e1a 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -119,6 +119,9 @@ void ConnectDialog::ok_pressed() {
return;
}
Node *target = tree->get_selected();
+ if (!target) {
+ return; // Nothing selected in the tree, not an error.
+ }
if (target->get_script().is_null()) {
if (!target->has_method(dst_method->get_text())) {
error->set_text(TTR("Target method not found. Specify a valid method or attach a script to the target node."));
@@ -150,16 +153,6 @@ void ConnectDialog::_tree_node_selected() {
}
/*
- * Called each time a target node is activated within the target node tree.
- */
-void ConnectDialog::_tree_item_activated() {
-
- if (!get_ok()->is_disabled()) {
- get_ok()->emit_signal("pressed");
- }
-}
-
-/*
* Adds a new parameter bind to connection.
*/
void ConnectDialog::_add_bind() {
@@ -243,7 +236,6 @@ void ConnectDialog::_bind_methods() {
ClassDB::bind_method("_advanced_pressed", &ConnectDialog::_advanced_pressed);
ClassDB::bind_method("_cancel", &ConnectDialog::_cancel_pressed);
ClassDB::bind_method("_tree_node_selected", &ConnectDialog::_tree_node_selected);
- ClassDB::bind_method("_tree_item_activated", &ConnectDialog::_tree_item_activated);
ClassDB::bind_method("_add_bind", &ConnectDialog::_add_bind);
ClassDB::bind_method("_remove_bind", &ConnectDialog::_remove_bind);
ClassDB::bind_method("_update_ok_enabled", &ConnectDialog::_update_ok_enabled);
@@ -397,7 +389,7 @@ ConnectDialog::ConnectDialog() {
tree = memnew(SceneTreeEditor(false));
tree->set_connecting_signal(true);
- tree->get_scene_tree()->connect("item_activated", this, "_tree_item_activated");
+ tree->get_scene_tree()->connect("item_activated", this, "_ok");
tree->connect("node_selected", this, "_tree_node_selected");
tree->set_connect_to_script_mode(true);
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index c30413953a..7e39d7d904 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -76,7 +76,6 @@ class ConnectDialog : public ConfirmationDialog {
void ok_pressed();
void _cancel_pressed();
void _tree_node_selected();
- void _tree_item_activated();
void _add_bind();
void _remove_bind();
void _advanced_pressed();
diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish
new file mode 100644
index 0000000000..3cffcfa3b8
--- /dev/null
+++ b/misc/dist/shell/godot.fish
@@ -0,0 +1,91 @@
+# Fish completion for the Godot editor
+# To use it, install this file in `~/.config/fish/completions` then restart your shell.
+# You can also `source` this file directly in your shell startup file.
+#
+# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+function godot_video_driver_args
+ # Use a function instead of a fixed string to customize the argument descriptions.
+ echo -e "Vulkan\tVulkan renderer"
+ echo -e "GLES2\tOpenGL ES 2.0 renderer"
+end
+
+# Erase existing completions for Godot.
+complete -c godot -e
+
+# General options:
+complete -c godot -s h -l help -d "Display the full help message"
+complete -c godot -l version -d "Display the version string"
+complete -c godot -s v -l verbose -d "Use verbose stdout mode"
+complete -c godot -l quiet -d "Quiet mode, silences stdout messages (errors are still displayed)"
+
+# Run options:
+complete -c godot -s e -l editor -d "Start the editor instead of running the scene"
+complete -c godot -s p -l project-manager -d "Start the project manager, even if a project is auto-detected"
+complete -c godot -s q -l quit -d "Quit after the first iteration"
+complete -c godot -s l -l language -d "Use a specific locale (<locale> being a two-letter code)" -x
+complete -c godot -l path -d "Path to a project (<directory> must contain a 'project.godot' file)" -r
+complete -c godot -s u -l upwards -d "Scan folders upwards for project.godot file"
+complete -c godot -l main-pack -d "Path to a pack (.pck) file to load" -r
+complete -c godot -l render-thread -d "Set the render thread mode" -x -a "unsafe safe separate"
+complete -c godot -l remote-fs -d "Use a remote filesystem (<host/IP>[:<port>] address)" -x
+complete -c godot -l remote-fs-password -d "Password for remote filesystem" -x
+complete -c godot -l audio-driver -d "Set the audio driver" -x
+complete -c godot -l video-driver -d "Set the video driver" -x -a "(godot_video_driver_args)"
+
+# Display options:
+complete -c godot -s f -l fullscreen -d "Request fullscreen mode"
+complete -c godot -s m -l maximized -d "Request a maximized window"
+complete -c godot -s w -l windowed -d "Request windowed mode"
+complete -c godot -s t -l always-on-top -d "Request an always-on-top window"
+complete -c godot -l resolution -d "Request window resolution" -x
+complete -c godot -l position -d "Request window position" -x
+complete -c godot -l low-dpi -d "Force low-DPI mode (macOS and Windows only)"
+complete -c godot -l no-window -d "Disable window creation (Windows only), useful together with --script"
+complete -c godot -l enable-vsync-via-compositor -d "When Vsync is enabled, Vsync via the OS' window compositor (Windows only)"
+complete -c godot -l disable-vsync-via-compositor -d "Disable Vsync via the OS' window compositor (Windows only)"
+
+# Debug options:
+complete -c godot -s d -l debug -d "Debug (local stdout debugger)"
+complete -c godot -s b -l breakpoints -d "Specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)" -x
+complete -c godot -l profiling -d "Enable profiling in the script debugger"
+complete -c godot -l remote-debug -d "Enable remote debugging"
+complete -c godot -l debug-collisions -d "Show collision shapes when running the scene"
+complete -c godot -l debug-navigation -d "Show navigation polygons when running the scene"
+complete -c godot -l frame-delay -d "Simulate high CPU load (delay each frame by the given number of milliseconds)" -x
+complete -c godot -l time-scale -d "Force time scale (higher values are faster, 1.0 is normal speed)" -x
+complete -c godot -l disable-render-loop -d "Disable render loop so rendering only occurs when called explicitly from script"
+complete -c godot -l disable-crash-handler -d "Disable crash handler when supported by the platform code"
+complete -c godot -l fixed-fps -d "Force a fixed number of frames per second (this setting disables real-time synchronization)" -x
+complete -c godot -l print-fps -d "Print the frames per second to the stdout"
+
+# Standalone tools:
+complete -c godot -s s -l script -d "Run a script" -r
+complete -c godot -l check-only -d "Only parse for errors and quit (use with --script)"
+complete -c godot -l export -d "Export the project using the given preset and matching release template" -x
+complete -c godot -l export-debug -d "Same as --export, but using the debug template" -x
+complete -c godot -l export-pack -d "Same as --export, but only export the game pack for the given preset" -x
+complete -c godot -l doctool -d "Dump the engine API reference to the given path in XML format, merging if existing files are found" -r
+complete -c godot -l no-docbase -d "Disallow dumping the base types (used with --doctool)"
+complete -c godot -l build-solutions -d "Build the scripting solutions (e.g. for C# projects)"
+complete -c godot -l gdnative-generate-json-api -d "Generate JSON dump of the Godot API for GDNative bindings"
+complete -c godot -l test -d "Run a unit test" -x
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 21dd758391..ca134824f7 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -49,7 +49,7 @@ void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
int NetworkedMultiplayerENet::get_packet_peer() const {
- ERR_FAIL_COND_V(!active, 1);
+ ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
return incoming_packets.front()->get().from;
@@ -57,7 +57,7 @@ int NetworkedMultiplayerENet::get_packet_peer() const {
int NetworkedMultiplayerENet::get_packet_channel() const {
- ERR_FAIL_COND_V(!active, -1);
+ ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
return incoming_packets.front()->get().channel;
@@ -65,7 +65,7 @@ int NetworkedMultiplayerENet::get_packet_channel() const {
int NetworkedMultiplayerENet::get_last_packet_channel() const {
- ERR_FAIL_COND_V(!active, -1);
+ ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(!current_packet.packet, -1);
return current_packet.channel;
@@ -73,11 +73,11 @@ int NetworkedMultiplayerENet::get_last_packet_channel() const {
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
- ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_in_bandwidth < 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_out_bandwidth < 0, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
+ ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
+ ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
ENetAddress address;
memset(&address, 0, sizeof(address));
@@ -104,7 +104,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
- ERR_FAIL_COND_V(!host, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create an ENet multiplayer server.");
_setup_compressor();
active = true;
@@ -116,11 +116,11 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
}
Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
- ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_in_bandwidth < 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_out_bandwidth < 0, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
+ ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The server port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER, "The client port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
+ ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
if (p_client_port != 0) {
ENetAddress c_client;
@@ -135,7 +135,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
if (bind_ip.is_wildcard()) {
c_client.host = 0;
} else {
- ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER, "Wildcard IP addresses are only permitted in IPv4, not IPv6.");
c_client.host = *(uint32_t *)bind_ip.get_ipv4();
}
#endif
@@ -155,7 +155,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
}
- ERR_FAIL_COND_V(!host, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create the ENet client host.");
_setup_compressor();
@@ -169,14 +169,14 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
ip = IP::get_singleton()->resolve_hostname(p_address, IP::TYPE_IPV4);
#endif
- ERR_FAIL_COND_V(!ip.is_valid(), ERR_CANT_RESOLVE);
+ ERR_FAIL_COND_V_MSG(!ip.is_valid(), ERR_CANT_RESOLVE, "Couldn't resolve the server IP address or domain name.");
}
ENetAddress address;
#ifdef GODOT_ENET
enet_address_set_ip(&address, ip.get_ipv6(), 16);
#else
- ERR_FAIL_COND_V(!ip.is_ipv4(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(!ip.is_ipv4(), ERR_INVALID_PARAMETER, "Connecting to an IPv6 server isn't supported when using vanilla ENet. Recompile Godot with the bundled ENet library.");
address.host = *(uint32_t *)ip.get_ipv4();
#endif
address.port = p_port;
@@ -188,7 +188,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
if (peer == NULL) {
enet_host_destroy(host);
- ERR_FAIL_COND_V(!peer, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!peer, ERR_CANT_CREATE, "Couldn't connect to the ENet multiplayer server.");
}
// Technically safe to ignore the peer or anything else.
@@ -203,7 +203,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
void NetworkedMultiplayerENet::poll() {
- ERR_FAIL_COND(!active);
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -435,14 +435,14 @@ void NetworkedMultiplayerENet::poll() {
}
bool NetworkedMultiplayerENet::is_server() const {
- ERR_FAIL_COND_V(!active, false);
+ ERR_FAIL_COND_V_MSG(!active, false, "The multiplayer instance isn't currently active.");
return server;
}
void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
- ERR_FAIL_COND(!active);
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -474,9 +474,9 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
- ERR_FAIL_COND(!active);
- ERR_FAIL_COND(!is_server());
- ERR_FAIL_COND(!peer_map.has(p_peer));
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
+ ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
+ ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
if (now) {
int *id = (int *)peer_map[p_peer]->data;
@@ -515,7 +515,7 @@ int NetworkedMultiplayerENet::get_available_packet_count() const {
Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V(incoming_packets.size() == 0, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
_pop_current_packet();
@@ -530,8 +530,8 @@ Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buff
Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(!active, ERR_UNCONFIGURED);
- ERR_FAIL_COND_V(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
+ ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
int packet_flags = 0;
int channel = SYSCH_RELIABLE;
@@ -562,7 +562,7 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
if (target_peer != 0) {
E = peer_map.find(ABS(target_peer));
- ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer '" + itos(target_peer) + "'.");
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, vformat("Invalid target peer: %d", target_peer));
}
ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 8, packet_flags);
@@ -650,7 +650,7 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
int NetworkedMultiplayerENet::get_unique_id() const {
- ERR_FAIL_COND_V(!active, 0);
+ ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
return unique_id;
}
@@ -706,7 +706,7 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
mode = Compression::MODE_ZSTD;
} break;
default: {
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, vformat("Invalid ENet compression mode: %d", enet->compression_mode));
}
}
@@ -781,9 +781,9 @@ void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) {
IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
- ERR_FAIL_COND_V(!peer_map.has(p_peer_id), IP_Address());
- ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, IP_Address());
- ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, IP_Address());
+ ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IP_Address(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
+ ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IP_Address(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
+ ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, IP_Address(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
IP_Address out;
#ifdef GODOT_ENET
@@ -797,9 +797,9 @@ IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
- ERR_FAIL_COND_V(!peer_map.has(p_peer_id), 0);
- ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, 0);
- ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, 0);
+ ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
+ ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
+ ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == NULL, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
#ifdef GODOT_ENET
return peer_map[p_peer_id]->address.port;
#else
@@ -809,8 +809,8 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
- ERR_FAIL_COND(p_channel < -1 || p_channel >= channel_count);
- ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, "Channel " + itos(SYSCH_CONFIG) + " is reserved.");
+ ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
+ ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
transfer_channel = p_channel;
}
@@ -820,8 +820,8 @@ int NetworkedMultiplayerENet::get_transfer_channel() const {
void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
- ERR_FAIL_COND(active);
- ERR_FAIL_COND(p_channel < SYSCH_MAX);
+ ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
+ ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
channel_count = p_channel;
}
@@ -838,7 +838,7 @@ bool NetworkedMultiplayerENet::is_always_ordered() const {
}
void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) {
- ERR_FAIL_COND(active);
+ ERR_FAIL_COND_MSG(active, "Server relaying can't be toggled while the multiplayer instance is active.");
server_relay = p_enabled;
}
@@ -916,7 +916,7 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
// Sets IP for ENet to bind when using create_server or create_client
// if no IP is set, then ENet bind to ENET_HOST_ANY
void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
- ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard());
+ ERR_FAIL_COND_MSG(!p_ip.is_valid() && !p_ip.is_wildcard(), vformat("Invalid bind IP address: %s", String(p_ip)));
bind_ip = p_ip;
}
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index 7e68936fc3..e5680ce2e9 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -91,10 +91,14 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
int peer_sock = EM_ASM_INT({
var proto_str = UTF8ToString($2);
var socket = null;
- if (proto_str) {
- socket = new WebSocket(UTF8ToString($1), proto_str.split(","));
- } else {
- socket = new WebSocket(UTF8ToString($1));
+ try {
+ if (proto_str) {
+ socket = new WebSocket(UTF8ToString($1), proto_str.split(","));
+ } else {
+ socket = new WebSocket(UTF8ToString($1));
+ }
+ } catch (e) {
+ return -1;
}
var c_ptr = Module.IDHandler.get($0);
socket.binaryType = "arraybuffer";
@@ -174,6 +178,8 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
return Module.IDHandler.add(socket);
}, _js_id, str.utf8().get_data(), proto_string.utf8().get_data());
/* clang-format on */
+ if (peer_sock == -1)
+ return FAILED;
static_cast<Ref<EMWSPeer> >(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size);
@@ -190,11 +196,11 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const {
NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
- if (_peer->is_connected_to_host())
+ if (_peer->is_connected_to_host()) {
+ if (_is_connecting)
+ return CONNECTION_CONNECTING;
return CONNECTION_CONNECTED;
-
- if (_is_connecting)
- return CONNECTION_CONNECTING;
+ }
return CONNECTION_DISCONNECTED;
};
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index effed8e4d9..588f38cffd 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -68,12 +68,17 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
bytes_array[i] = getValue($1+i, 'i8');
}
- if ($3) {
- sock.send(bytes_array.buffer);
- } else {
- var string = new TextDecoder("utf-8").decode(bytes_array);
- sock.send(string);
+ try {
+ if ($3) {
+ sock.send(bytes_array.buffer);
+ } else {
+ var string = new TextDecoder("utf-8").decode(bytes_array);
+ sock.send(string);
+ }
+ } catch (e) {
+ return 1;
}
+ return 0;
}, peer_sock, p_buffer, p_buffer_size, is_bin);
/* clang-format on */
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 4f0f681a01..fd654cbf60 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -516,7 +516,7 @@ void AudioStreamPlayer2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 596ef78fb5..189ac1d1b3 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -1007,7 +1007,7 @@ void AudioStreamPlayer3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 3a0169f065..03d96d41fa 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -412,7 +412,7 @@ void AudioStreamPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4ddceed58e..ff9c786b4c 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -588,6 +588,8 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
image = load_image_from_file(f, p_size_limit);
+ memdelete(f);
+
if (image.is_null() || image->empty()) {
return ERR_CANT_OPEN;
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index b42b770903..cd8576539b 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -52,7 +52,7 @@ public:
class Texture2D : public Texture {
- GDCLASS(Texture2D, Resource);
+ GDCLASS(Texture2D, Texture);
OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
protected:
@@ -350,7 +350,7 @@ public:
class TextureLayered : public Texture {
- GDCLASS(TextureLayered, Resource);
+ GDCLASS(TextureLayered, Texture);
VS::TextureLayeredType layered_type;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 734abd7365..a7c18f184d 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -5675,7 +5675,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
st.shader_struct = st_node;
int member_count = 0;
-
+ Set<String> member_names;
while (true) { // variables list
tk = _get_token();
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
@@ -5732,6 +5732,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
member->struct_name = struct_name;
member->name = tk.text;
+ if (member_names.has(member->name)) {
+ _set_error("Redefinition of '" + String(member->name) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ member_names.insert(member->name);
+
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
tk = _get_token();
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 83efbabc36..508d5ec1f8 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1819,7 +1819,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white", "auto_exposure", "min_luminance", "max_luminance", "auto_exp_speed", "auto_exp_grey"), &VisualServer::environment_set_tonemap);
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &VisualServer::environment_set_adjustment);
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance", "roughness"), &VisualServer::environment_set_ssr);
- ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "radius2", "intensity2", "bias", "light_affect", "ao_channel_affect", "color", "blur", "bilateral_sharpness"), &VisualServer::environment_set_ssao);
+ ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "bias", "light_affect", "ao_channel_affect", "blur", "bilateral_sharpness"), &VisualServer::environment_set_ssao);
ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "color", "sun_color", "sun_amount"), &VisualServer::environment_set_fog);
ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_end", "depth_curve", "transmit", "transmit_curve"), &VisualServer::environment_set_fog_depth);
@@ -2141,10 +2141,6 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);
- BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_LOW);
- BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_MEDIUM);
- BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH);
-
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 9b7a3ffa76..09fc1aaba2 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -753,7 +753,7 @@ public:
ENV_SSAO_BLUR_3x3,
};
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
enum EnvironmentSSAOQuality {
ENV_SSAO_QUALITY_LOW,