diff options
-rw-r--r-- | doc/classes/Texture2D.xml | 2 | ||||
-rw-r--r-- | doc/classes/TextureLayered.xml | 2 | ||||
-rw-r--r-- | doc/classes/VisualServer.xml | 42 | ||||
-rw-r--r-- | editor/code_editor.cpp | 10 | ||||
-rw-r--r-- | editor/connections_dialog.cpp | 16 | ||||
-rw-r--r-- | editor/connections_dialog.h | 1 | ||||
-rw-r--r-- | misc/dist/shell/godot.fish | 91 | ||||
-rw-r--r-- | modules/enet/networked_multiplayer_enet.cpp | 86 | ||||
-rw-r--r-- | modules/websocket/emws_client.cpp | 22 | ||||
-rw-r--r-- | modules/websocket/emws_peer.cpp | 15 | ||||
-rw-r--r-- | scene/2d/audio_stream_player_2d.cpp | 2 | ||||
-rw-r--r-- | scene/3d/audio_stream_player_3d.cpp | 2 | ||||
-rw-r--r-- | scene/audio/audio_stream_player.cpp | 2 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 2 | ||||
-rw-r--r-- | scene/resources/texture.h | 4 | ||||
-rw-r--r-- | servers/visual/shader_language.cpp | 8 | ||||
-rw-r--r-- | servers/visual_server.cpp | 6 | ||||
-rw-r--r-- | servers/visual_server.h | 2 |
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, |