diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/debugger/remote_debugger_peer.cpp | 6 | ||||
-rw-r--r-- | core/io/file_access_pack.cpp | 68 | ||||
-rw-r--r-- | core/io/http_client_tcp.cpp | 3 | ||||
-rw-r--r-- | core/io/packet_peer_udp.cpp | 4 | ||||
-rw-r--r-- | core/io/packet_peer_udp.h | 2 | ||||
-rw-r--r-- | core/io/stream_peer_tcp.cpp | 85 | ||||
-rw-r--r-- | core/io/stream_peer_tcp.h | 11 | ||||
-rw-r--r-- | core/os/os.cpp | 5 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/variant/variant.cpp | 59 |
10 files changed, 114 insertions, 131 deletions
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 950500884e..e9362b4ea4 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -93,7 +93,7 @@ RemoteDebuggerPeerTCP::~RemoteDebuggerPeerTCP() { } void RemoteDebuggerPeerTCP::_write_out() { - while (tcp_client->poll(NetSocket::POLL_TYPE_OUT) == OK) { + while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_OUT) == OK) { uint8_t *buf = out_buf.ptrw(); if (out_left <= 0) { if (out_queue.size() == 0) { @@ -119,7 +119,7 @@ void RemoteDebuggerPeerTCP::_write_out() { } void RemoteDebuggerPeerTCP::_read_in() { - while (tcp_client->poll(NetSocket::POLL_TYPE_IN) == OK) { + while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_IN) == OK) { uint8_t *buf = in_buf.ptrw(); if (in_left <= 0) { if (in_queue.size() > max_queued_messages) { @@ -167,6 +167,7 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po tcp_client->connect_to_host(ip, port); for (int i = 0; i < tries; i++) { + tcp_client->poll(); if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) { print_verbose("Remote Debugger: Connected!"); break; @@ -213,6 +214,7 @@ void RemoteDebuggerPeerTCP::poll() { } void RemoteDebuggerPeerTCP::_poll() { + tcp_client->poll(); if (connected) { _write_out(); _read_in(); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index c6e14ffee7..ba120de68b 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -32,6 +32,7 @@ #include "core/io/file_access_encrypted.h" #include "core/object/script_language.h" +#include "core/os/os.h" #include "core/version.h" #include <stdio.h> @@ -131,32 +132,69 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, return false; } - f->seek(p_offset); + bool pck_header_found = false; + // Search for the header at the start offset - standalone PCK file. + f->seek(p_offset); uint32_t magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { + pck_header_found = true; + } - if (magic != PACK_HEADER_MAGIC) { - // loading with offset feature not supported for self contained exe files - ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Loading self-contained executable with offset not supported."); + // Search for the header in the executable "pck" section - self contained executable. + if (!pck_header_found) { + // Loading with offset feature not supported for self contained exe files. + if (p_offset != 0) { + ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported."); + } - //maybe at the end.... self contained exe - f->seek_end(); - f->seek(f->get_position() - 4); - magic = f->get_32(); - if (magic != PACK_HEADER_MAGIC) { - return false; + int64_t pck_off = OS::get_singleton()->get_embedded_pck_offset(); + if (pck_off != 0) { + // Search for the header, in case PCK start and section have different alignment. + for (int i = 0; i < 8; i++) { + f->seek(pck_off); + magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { +#ifdef DEBUG_ENABLED + print_verbose("PCK header found in executable pck section, loading from offset 0x" + String::num_int64(pck_off - 4, 16)); +#endif + pck_header_found = true; + break; + } + pck_off++; + } } - f->seek(f->get_position() - 12); + } - uint64_t ds = f->get_64(); - f->seek(f->get_position() - ds - 8); + // Search for the header at the end of file - self contained executable. + if (!pck_header_found) { + // Loading with offset feature not supported for self contained exe files. + if (p_offset != 0) { + ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported."); + } + f->seek_end(); + f->seek(f->get_position() - 4); magic = f->get_32(); - if (magic != PACK_HEADER_MAGIC) { - return false; + + if (magic == PACK_HEADER_MAGIC) { + f->seek(f->get_position() - 12); + uint64_t ds = f->get_64(); + f->seek(f->get_position() - ds - 8); + magic = f->get_32(); + if (magic == PACK_HEADER_MAGIC) { +#ifdef DEBUG_ENABLED + print_verbose("PCK header found at the end of executable, loading from offset 0x" + String::num_int64(f->get_position() - 4, 16)); +#endif + pck_header_found = true; + } } } + if (!pck_header_found) { + return false; + } + uint32_t version = f->get_32(); uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp index f920799677..d983d86b99 100644 --- a/core/io/http_client_tcp.cpp +++ b/core/io/http_client_tcp.cpp @@ -264,6 +264,9 @@ void HTTPClientTCP::close() { } Error HTTPClientTCP::poll() { + if (tcp_connection.is_valid()) { + tcp_connection->poll(); + } switch (status) { case STATUS_RESOLVING: { ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG); diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 503eb17cae..84d1f3ebd4 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -242,7 +242,7 @@ Error PacketPeerUDP::connect_to_host(const IPAddress &p_host, int p_port) { return OK; } -bool PacketPeerUDP::is_connected_to_host() const { +bool PacketPeerUDP::is_socket_connected() const { return connected; } @@ -348,7 +348,7 @@ void PacketPeerUDP::_bind_methods() { ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait); ClassDB::bind_method(D_METHOD("is_bound"), &PacketPeerUDP::is_bound); ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &PacketPeerUDP::connect_to_host); - ClassDB::bind_method(D_METHOD("is_connected_to_host"), &PacketPeerUDP::is_connected_to_host); + ClassDB::bind_method(D_METHOD("is_socket_connected"), &PacketPeerUDP::is_socket_connected); 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("get_local_port"), &PacketPeerUDP::get_local_port); diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 444a6dd5ba..a174cf5347 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -79,7 +79,7 @@ public: void disconnect_shared_socket(); // Used by UDPServer Error store_packet(IPAddress p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer Error connect_to_host(const IPAddress &p_host, int p_port); - bool is_connected_to_host() const; + bool is_socket_connected() const; IPAddress get_packet_address() const; int get_packet_port() const; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 6d5784a8ab..c5c2021e6e 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -32,8 +32,28 @@ #include "core/config/project_settings.h" -Error StreamPeerTCP::_poll_connection() { - ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED); +Error StreamPeerTCP::poll() { + if (status == STATUS_CONNECTED) { + Error err; + err = _sock->poll(NetSocket::POLL_TYPE_IN, 0); + if (err == OK) { + // FIN received + if (_sock->get_available_bytes() == 0) { + disconnect_from_host(); + return OK; + } + } + // Also poll write + err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0); + if (err != OK && err != ERR_BUSY) { + // Got an error + disconnect_from_host(); + status = STATUS_ERROR; + return err; + } + } else if (status != STATUS_CONNECTING) { + return OK; + } Error err = _sock->connect_to_host(peer_host, peer_port); @@ -121,22 +141,7 @@ Error StreamPeerTCP::connect_to_host(const IPAddress &p_host, int p_port) { Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) { ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE); - if (status == STATUS_NONE || status == STATUS_ERROR) { - return FAILED; - } - if (status != STATUS_CONNECTED) { - if (_poll_connection() != OK) { - return FAILED; - } - - if (status != STATUS_CONNECTED) { - r_sent = 0; - return OK; - } - } - - if (!_sock->is_open()) { return FAILED; } @@ -179,21 +184,10 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool } Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) { - if (!is_connected_to_host()) { + if (status != STATUS_CONNECTED) { return FAILED; } - if (status == STATUS_CONNECTING) { - if (_poll_connection() != OK) { - return FAILED; - } - - if (status != STATUS_CONNECTED) { - r_received = 0; - return OK; - } - } - Error err; int to_read = p_bytes; int total_read = 0; @@ -243,36 +237,11 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool } void StreamPeerTCP::set_no_delay(bool p_enabled) { - ERR_FAIL_COND(!is_connected_to_host()); + ERR_FAIL_COND(!_sock.is_valid() || !_sock->is_open()); _sock->set_tcp_no_delay_enabled(p_enabled); } -bool StreamPeerTCP::is_connected_to_host() const { - return _sock.is_valid() && _sock->is_open() && (status == STATUS_CONNECTED || status == STATUS_CONNECTING); -} - -StreamPeerTCP::Status StreamPeerTCP::get_status() { - if (status == STATUS_CONNECTING) { - _poll_connection(); - } else if (status == STATUS_CONNECTED) { - Error err; - err = _sock->poll(NetSocket::POLL_TYPE_IN, 0); - if (err == OK) { - // FIN received - if (_sock->get_available_bytes() == 0) { - disconnect_from_host(); - return status; - } - } - // Also poll write - err = _sock->poll(NetSocket::POLL_TYPE_IN_OUT, 0); - if (err != OK && err != ERR_BUSY) { - // Got an error - disconnect_from_host(); - status = STATUS_ERROR; - } - } - +StreamPeerTCP::Status StreamPeerTCP::get_status() const { return status; } @@ -287,7 +256,7 @@ void StreamPeerTCP::disconnect_from_host() { peer_port = 0; } -Error StreamPeerTCP::poll(NetSocket::PollType p_type, int timeout) { +Error StreamPeerTCP::wait(NetSocket::PollType p_type, int timeout) { ERR_FAIL_COND_V(_sock.is_null() || !_sock->is_open(), ERR_UNAVAILABLE); return _sock->poll(p_type, timeout); } @@ -346,7 +315,7 @@ Error StreamPeerTCP::_connect(const String &p_address, int p_port) { void StreamPeerTCP::_bind_methods() { ClassDB::bind_method(D_METHOD("bind", "port", "host"), &StreamPeerTCP::bind, DEFVAL("*")); ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &StreamPeerTCP::_connect); - ClassDB::bind_method(D_METHOD("is_connected_to_host"), &StreamPeerTCP::is_connected_to_host); + ClassDB::bind_method(D_METHOD("poll"), &StreamPeerTCP::poll); ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerTCP::get_status); ClassDB::bind_method(D_METHOD("get_connected_host"), &StreamPeerTCP::get_connected_host); ClassDB::bind_method(D_METHOD("get_connected_port"), &StreamPeerTCP::get_connected_port); diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index bf49cc8a5f..39c2e84346 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -55,7 +55,6 @@ protected: uint16_t peer_port = 0; Error _connect(const String &p_address, int p_port); - Error _poll_connection(); Error write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block); Error read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block); @@ -66,19 +65,21 @@ public: Error bind(int p_port, const IPAddress &p_host); Error connect_to_host(const IPAddress &p_host, int p_port); - bool is_connected_to_host() const; IPAddress get_connected_host() const; int get_connected_port() const; int get_local_port() const; void disconnect_from_host(); int get_available_bytes() const override; - Status get_status(); + Status get_status() const; void set_no_delay(bool p_enabled); - // Poll functions (wait or check for writable, readable) - Error poll(NetSocket::PollType p_type, int timeout = 0); + // Poll socket updating its state. + Error poll(); + + // Wait or check for writable, readable. + Error wait(NetSocket::PollType p_type, int timeout = 0); // Read/Write from StreamPeer Error put_data(const uint8_t *p_data, int p_bytes) override; diff --git a/core/os/os.cpp b/core/os/os.cpp index 846aeb16c5..4f7095b0fc 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -237,6 +237,11 @@ String OS::get_locale_language() const { return get_locale().left(3).replace("_", ""); } +// Embedded PCK offset. +uint64_t OS::get_embedded_pck_offset() const { + return 0; +} + // Helper function to ensure that a dir name/path will be valid on the OS String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const { Vector<String> invalid_chars = String(": * ? \" < > |").split(" "); diff --git a/core/os/os.h b/core/os/os.h index b3c66ff18c..9ec0dd7728 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -264,6 +264,8 @@ public: virtual String get_locale() const; String get_locale_language() const; + virtual uint64_t get_embedded_pck_offset() const; + String get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator = false) const; virtual String get_godot_dir_name() const; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index da5d73d519..0eb93a72b4 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3341,27 +3341,7 @@ String Variant::get_construct_string() const { } String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - return "'" + String(p_method) + "': " + err_text; + return get_call_error_text(nullptr, p_method, p_argptrs, p_argcount, ce); } String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { @@ -3386,37 +3366,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, return "Call OK"; } - String class_name = p_base->get_class(); - Ref<Resource> script = p_base->get_script(); - if (script.is_valid() && script->get_path().is_resource_file()) { - class_name += "(" + script->get_path().get_file() + ")"; + String base_text; + if (p_base) { + base_text = p_base->get_class(); + Ref<Resource> script = p_base->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { + base_text += "(" + script->get_path().get_file() + ")"; + } + base_text += "::"; } - return "'" + class_name + "::" + String(p_method) + "': " + err_text; + return "'" + base_text + String(p_method) + "': " + err_text; } String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - - return String(p_callable) + " : " + err_text; + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce); } String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { |