diff --git a/core/io/compression.cpp b/core/io/compression.cpp index e04d1d16297..652f60966a5 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -104,19 +104,21 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) { ERR_FAIL_V(-1); } -void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) { +int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_FASTLZ: { + int ret_size=0; + if (p_dst_max_size < 16) { uint8_t dst[16]; - fastlz_decompress(p_src, p_src_size, dst, 16); + ret_size = fastlz_decompress(p_src, p_src_size, dst, 16); copymem(p_dst, dst, p_dst_max_size); } else { - fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size); + ret_size = fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size); } - return; + return ret_size; } break; case MODE_DEFLATE: { @@ -127,7 +129,7 @@ void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t * strm.avail_in = 0; strm.next_in = Z_NULL; int err = inflateInit(&strm); - ERR_FAIL_COND(err != Z_OK); + ERR_FAIL_COND_V(err != Z_OK, -1); strm.avail_in = p_src_size; strm.avail_out = p_dst_max_size; @@ -135,11 +137,12 @@ void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t * strm.next_out = p_dst; err = inflate(&strm, Z_FINISH); + int total = strm.total_out; inflateEnd(&strm); - ERR_FAIL_COND(err != Z_STREAM_END); - return; + ERR_FAIL_COND_V(err != Z_STREAM_END, -1); + return total; } break; } - ERR_FAIL(); + ERR_FAIL_V(-1); } diff --git a/core/io/compression.h b/core/io/compression.h index b5f0db9e968..a982a074b1a 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -41,7 +41,7 @@ public: static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ); static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_FASTLZ); - static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ); + static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ); Compression(); }; diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 0ef6722f967..a1b7e6b5e02 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -32,6 +32,11 @@ PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL; +void PacketPeerUDP::set_blocking_mode(bool p_enable) { + + blocking = p_enable; +} + String PacketPeerUDP::_get_packet_ip() const { return get_packet_address(); @@ -79,4 +84,6 @@ PacketPeerUDP *PacketPeerUDP::create() { } PacketPeerUDP::PacketPeerUDP() { + + blocking = true; } diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 5a8edab0183..9b2901e4d43 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -37,6 +37,8 @@ class PacketPeerUDP : public PacketPeer { OBJ_TYPE(PacketPeerUDP, PacketPeer); protected: + bool blocking; + static PacketPeerUDP *(*_create)(); static void _bind_methods(); @@ -45,6 +47,8 @@ protected: Error _set_send_address(const String &p_address, int p_port); public: + void set_blocking_mode(bool p_enable); + virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0; virtual void close() = 0; virtual Error wait() = 0; diff --git a/core/message_queue.cpp b/core/message_queue.cpp index 171f9fbfc4c..821414be07e 100644 --- a/core/message_queue.cpp +++ b/core/message_queue.cpp @@ -49,9 +49,10 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V type = ObjectDB::get_instance(p_id)->get_type(); print_line("failed method: " + type + ":" + p_method + " target ID: " + itos(p_id)); statistics(); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_FAIL_V(ERR_OUT_OF_MEMORY); } - ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY); Message *msg = memnew_placement(&buffer[buffer_end], Message); msg->args = p_argcount; msg->instance_ID = p_id; @@ -99,10 +100,10 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari type = ObjectDB::get_instance(p_id)->get_type(); print_line("failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id)); statistics(); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_FAIL_V(ERR_OUT_OF_MEMORY); } - ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY); - Message *msg = memnew_placement(&buffer[buffer_end], Message); msg->args = 1; msg->instance_ID = p_id; @@ -132,9 +133,10 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) { type = ObjectDB::get_instance(p_id)->get_type(); print_line("failed notification: " + itos(p_notification) + " target ID: " + itos(p_id)); statistics(); + ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings"); + ERR_FAIL_V(ERR_OUT_OF_MEMORY); } - ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY); Message *msg = memnew_placement(&buffer[buffer_end], Message); msg->type = TYPE_NOTIFICATION; diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 4ac91bea1b2..8d46495e15d 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -77,7 +77,7 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_addr) { if (p_addr->sa_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *)p_addr; ip.set_ipv4((uint8_t *)&(addr->sin_addr)); - } else { + } else if (p_addr->sa_family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; ip.set_ipv6(addr6->sin6_addr.s6_addr); }; @@ -180,15 +180,16 @@ void IP_Unix::get_local_addresses(List *r_addresses) const { SOCKADDR_IN *ipv4 = reinterpret_cast(address->Address.lpSockaddr); ip.set_ipv4((uint8_t *)&(ipv4->sin_addr)); - } else { // ipv6 + r_addresses->push_back(ip); + + } else if (address->Address.lpSockaddr->sa_family == AF_INET6) { // ipv6 SOCKADDR_IN6 *ipv6 = reinterpret_cast(address->Address.lpSockaddr); ip.set_ipv6(ipv6->sin6_addr.s6_addr); + r_addresses->push_back(ip); }; - r_addresses->push_back(ip); - address = address->Next; }; adapter = adapter->Next; @@ -205,6 +206,7 @@ void IP_Unix::get_local_addresses(List *r_addresses) const { struct ifaddrs *ifAddrStruct = NULL; struct ifaddrs *ifa = NULL; + int family; getifaddrs(&ifAddrStruct); @@ -212,6 +214,11 @@ void IP_Unix::get_local_addresses(List *r_addresses) const { if (!ifa->ifa_addr) continue; + family = ifa->ifa_addr->sa_family; + + if (family != AF_INET && family != AF_INET6) + continue; + IP_Address ip = _sockaddr2ip(ifa->ifa_addr); r_addresses->push_back(ip); } diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index b9293dc651e..afabe9dea99 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -108,10 +108,14 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer, int p_buffer_size) errno = 0; int err; + _set_sock_blocking(blocking); + while ((err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr *)&addr, addr_size)) != p_buffer_size) { if (errno != EAGAIN) { return FAILED; + } else if (!blocking) { + return ERR_UNAVAILABLE; } } @@ -174,10 +178,12 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { return FAILED; } + _set_sock_blocking(p_wait); + struct sockaddr_storage from = { 0 }; socklen_t len = sizeof(struct sockaddr_storage); int ret; - while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), p_wait ? 0 : MSG_DONTWAIT, (struct sockaddr *)&from, &len)) > 0) { + while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), 0, (struct sockaddr *)&from, &len)) > 0) { uint32_t port = 0; @@ -210,6 +216,8 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { len = sizeof(struct sockaddr_storage); ++queue_count; + if (p_wait) + break; }; // TODO: Should ECONNRESET be handled here? @@ -244,9 +252,35 @@ int PacketPeerUDPPosix::_get_socket() { sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd != -1) + _set_sock_blocking(false); + return sockfd; } +void PacketPeerUDPPosix::_set_sock_blocking(bool p_blocking) { + + if (sock_blocking == p_blocking) + return; + + sock_blocking = p_blocking; + +#ifndef NO_FCNTL + int opts = fcntl(sockfd, F_GETFL); + int ret = 0; + if (sock_blocking) + ret = fcntl(sockfd, F_SETFL, opts & ~O_NONBLOCK); + else + ret = fcntl(sockfd, F_SETFL, opts | O_NONBLOCK); + if (ret == -1) + perror("setting non-block mode"); +#else + int bval = sock_blocking ? 0 : 1; + if (ioctl(sockfd, FIONBIO, &bval) == -1) + perror("setting non-block mode"); +#endif +} + void PacketPeerUDPPosix::set_send_address(const IP_Address &p_address, int p_port) { peer_addr = p_address; @@ -265,6 +299,8 @@ void PacketPeerUDPPosix::make_default() { PacketPeerUDPPosix::PacketPeerUDPPosix() { + blocking = true; + sock_blocking = true; sockfd = -1; packet_port = 0; queue_count = 0; diff --git a/drivers/unix/packet_peer_udp_posix.h b/drivers/unix/packet_peer_udp_posix.h index 237773e28dd..f987da18f85 100644 --- a/drivers/unix/packet_peer_udp_posix.h +++ b/drivers/unix/packet_peer_udp_posix.h @@ -48,6 +48,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP { mutable int packet_port; mutable int queue_count; int sockfd; + bool sock_blocking; IP::Type sock_type; IP_Address peer_addr; @@ -56,6 +57,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP { _FORCE_INLINE_ int _get_socket(); static PacketPeerUDP *_create(); + void _set_sock_blocking(bool p_blocking); virtual Error _poll(bool p_block); public: diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index b3b0d4e5315..03617c01fe0 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -71,13 +71,21 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage *p_addr, int p_port, }; }; -static int _socket_create(IP::Type p_type, int type, int protocol) { +static int _socket_create(IP::Type &p_type, int type, int protocol) { ERR_FAIL_COND_V(p_type > IP::TYPE_ANY || p_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); int family = p_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; int sockfd = socket(family, type, protocol); + if (sockfd == -1 && p_type == IP::TYPE_ANY) { + // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket + // in place of a dual stack one, and further calls to _set_sock_addr will work as expected. + p_type = IP::TYPE_IPV4; + family = AF_INET; + sockfd = socket(family, type, protocol); + } + ERR_FAIL_COND_V(sockfd == -1, -1); if (family == AF_INET6) { diff --git a/editor/editor_import_export.cpp b/editor/editor_import_export.cpp index 5bd3cf29eb4..82400336070 100644 --- a/editor/editor_import_export.cpp +++ b/editor/editor_import_export.cpp @@ -1047,7 +1047,7 @@ void EditorExportPlatform::gen_export_flags(Vector &r_flags, int p_flags r_flags.push_back("-rdebug"); - r_flags.push_back(host + ":" + String::num(GLOBAL_DEF("debug/debug_port", 6007))); + r_flags.push_back(host + ":" + String::num(GLOBAL_DEF("network/debug_port", 6007))); List breakpoints; ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index d4616d380dc..c7f15145590 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -40,6 +40,7 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li List args; String resource_path = Globals::get_singleton()->get_resource_path(); + String remote_host = EditorSettings::get_singleton()->get("network/debug_host"); if (resource_path != "") { args.push_back("-path"); @@ -48,13 +49,7 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li if (true) { args.push_back("-rdebug"); -#ifdef WINDOWS_ENABLED - // Avoid failing DNS lookup on disconnected Windows machines. - const char *debug_host = "127.0.0.1:"; -#else - const char *debug_host = "localhost:"; -#endif - args.push_back(debug_host + String::num(GLOBAL_DEF("debug/debug_port", 6007))); + args.push_back(remote_host + ":" + String::num(GLOBAL_DEF("network/debug_port", 6007))); } args.push_back("-epid"); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5d695ce7ec2..2a6fe312507 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -413,12 +413,11 @@ void EditorSettings::setup_network() { String lip; String hint; String current = get("network/debug_host"); + int port = has("network/debug_port") ? (int)get("network/debug_port") : 6007; for (List::Element *E = local_ip.front(); E; E = E->next()) { String ip = E->get(); - if (ip == "127.0.0.1") - continue; if (lip == "") lip = ip; @@ -431,6 +430,9 @@ void EditorSettings::setup_network() { set("network/debug_host", lip); add_property_hint(PropertyInfo(Variant::STRING, "network/debug_host", PROPERTY_HINT_ENUM, hint)); + + set("network/debug_port", port); + add_property_hint(PropertyInfo(Variant::INT, "network/debug_port", PROPERTY_HINT_RANGE, "1,65535,1")); } void EditorSettings::save() { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 997ab501597..4696c1167c5 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -37,7 +37,6 @@ #include "os/file_access.h" #include "os/input.h" #include "os/keyboard.h" -#include "os/keyboard.h" #include "os/os.h" #include "scene/main/viewport.h" @@ -2158,8 +2157,6 @@ void ScriptEditor::_editor_play() { debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_STEP), true); debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_BREAK), false); debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true); - - //debugger_gui->start_listening(Globals::get_singleton()->get("debug/debug_port")); } void ScriptEditor::_editor_pause() { diff --git a/main/main.cpp b/main/main.cpp index df79aab1b82..972d0739fb7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -564,8 +564,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph ScriptDebuggerRemote *sdr = memnew(ScriptDebuggerRemote); uint16_t debug_port = GLOBAL_DEF("debug/remote_port", 6007); if (debug_host.find(":") != -1) { - debug_port = debug_host.get_slicec(':', 1).to_int(); - debug_host = debug_host.get_slicec(':', 0); + int sep_pos = debug_host.find_last(":"); + debug_port = debug_host.substr(sep_pos + 1, debug_host.length()).to_int(); + debug_host = debug_host.substr(0, sep_pos); } Error derr = sdr->connect_to_host(debug_host, debug_port); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 944840de759..a94241ff99e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1651,7 +1651,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) { args.push_back("--remove-all"); err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); - int port = Globals::get_singleton()->get("debug/debug_port"); + int port = Globals::get_singleton()->get("network/debug_port"); args.clear(); args.push_back("reverse"); args.push_back("tcp:" + itos(port)); diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 468c3ffff8c..b59056a3d06 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -83,7 +83,7 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz struct sockaddr_storage addr; size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type); - _set_blocking(true); + _set_sock_blocking(blocking); errno = 0; int err; @@ -91,7 +91,9 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz if (WSAGetLastError() != WSAEWOULDBLOCK) { return FAILED; - }; + } else if (!blocking) { + return ERR_UNAVAILABLE; + } } return OK; @@ -102,15 +104,13 @@ int PacketPeerUDPWinsock::get_max_packet_size() const { return 512; // uhm maybe not } -void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) { - //am no windows expert - //hope this is the right thing +void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) { - if (blocking == p_blocking) + if (sock_blocking == p_blocking) return; - blocking = p_blocking; - unsigned long par = blocking ? 0 : 1; + sock_blocking = p_blocking; + unsigned long par = sock_blocking ? 0 : 1; if (ioctlsocket(sockfd, FIONBIO, &par)) { perror("setting non-block mode"); //close(); @@ -140,8 +140,6 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_ return ERR_UNAVAILABLE; } - blocking = true; - printf("UDP Connection listening on port %i\n", p_port); rb.resize(nearest_shift(p_recv_buffer_size)); return OK; @@ -167,7 +165,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { return FAILED; } - _set_blocking(p_wait); + _set_sock_blocking(p_wait); struct sockaddr_storage from = { 0 }; int len = sizeof(struct sockaddr_storage); @@ -205,6 +203,8 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { len = sizeof(struct sockaddr_storage); ++queue_count; + if (p_wait) + break; }; if (ret == SOCKET_ERROR) { @@ -253,6 +253,9 @@ int PacketPeerUDPWinsock::_get_socket() { sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd != -1) + _set_sock_blocking(false); + return sockfd; } @@ -274,6 +277,8 @@ PacketPeerUDP *PacketPeerUDPWinsock::_create() { PacketPeerUDPWinsock::PacketPeerUDPWinsock() { + blocking = true; + sock_blocking = true; sockfd = -1; packet_port = 0; queue_count = 0; diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h index cff232307cd..37860b42690 100644 --- a/platform/windows/packet_peer_udp_winsock.h +++ b/platform/windows/packet_peer_udp_winsock.h @@ -46,6 +46,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { mutable int packet_port; mutable int queue_count; int sockfd; + bool sock_blocking; IP::Type sock_type; IP_Address peer_addr; @@ -55,8 +56,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { static PacketPeerUDP *_create(); - bool blocking; - void _set_blocking(bool p_blocking); + void _set_sock_blocking(bool p_blocking); Error _poll(bool p_wait); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 3817bc25f21..4345bc564ee 100755 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -382,7 +382,7 @@ Node::PauseMode Node::get_pause_mode() const { void Node::_propagate_pause_owner(Node *p_owner) { - if (data.pause_mode != PAUSE_MODE_INHERIT) + if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) return; data.pause_owner = p_owner; for (int i = 0; i < data.children.size(); i++) {