diff options
Diffstat (limited to 'core')
58 files changed, 741 insertions, 361 deletions
diff --git a/core/SCsub b/core/SCsub index abd985fb79..85e5f1b089 100644 --- a/core/SCsub +++ b/core/SCsub @@ -47,15 +47,11 @@ env_thirdparty.disable_warnings() thirdparty_misc_dir = "#thirdparty/misc/" thirdparty_misc_sources = [ # C sources - "base64.c", "fastlz.c", - "sha256.c", "smaz.c", # C++ sources - "aes256.cpp", "hq2x.cpp", - "md5.cpp", "pcg.cpp", "triangulator.cpp", "clipper.cpp", @@ -130,10 +126,10 @@ if env['builtin_zstd']: thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) - env_thirdparty.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") + env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) env.Prepend(CPPPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings - env.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") + env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources) diff --git a/core/array.cpp b/core/array.cpp index 65934d6ec9..a334af2c04 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -133,12 +133,18 @@ void Array::erase(const Variant &p_value) { } Variant Array::front() const { - ERR_FAIL_COND_V(_p->array.size() == 0, Variant()); + if (_p->array.size() == 0) { + ERR_EXPLAIN("Can't take value from empty array"); + ERR_FAIL_V(Variant()); + } return operator[](0); } Variant Array::back() const { - ERR_FAIL_COND_V(_p->array.size() == 0, Variant()); + if (_p->array.size() == 0) { + ERR_EXPLAIN("Can't take value from empty array"); + ERR_FAIL_V(Variant()); + } return operator[](_p->array.size() - 1); } @@ -165,8 +171,8 @@ int Array::rfind(const Variant &p_value, int p_from) const { if (_p->array[i] == p_value) { return i; - }; - }; + } + } return -1; } @@ -186,8 +192,8 @@ int Array::count(const Variant &p_value) const { if (_p->array[i] == p_value) { amount++; - }; - }; + } + } return amount; } diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 44573a0d97..34bbdb2c75 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -34,13 +34,12 @@ #include "core/io/file_access_encrypted.h" #include "core/io/json.h" #include "core/io/marshalls.h" +#include "core/math/crypto_core.h" #include "core/math/geometry.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "thirdparty/misc/base64.h" - /** * Time constants borrowed from loc_time.h */ @@ -149,8 +148,10 @@ _ResourceLoader::_ResourceLoader() { } Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) { - - ERR_FAIL_COND_V(p_resource.is_null(), ERR_INVALID_PARAMETER); + if (p_resource.is_null()) { + ERR_EXPLAIN("Can't save empty resource to path: " + String(p_path)) + ERR_FAIL_V(ERR_INVALID_PARAMETER); + } return ResourceSaver::save(p_path, p_resource, p_flags); } @@ -246,11 +247,11 @@ PoolStringArray _OS::get_connected_midi_inputs() { } void _OS::open_midi_inputs() { - return OS::get_singleton()->open_midi_inputs(); + OS::get_singleton()->open_midi_inputs(); } void _OS::close_midi_inputs() { - return OS::get_singleton()->close_midi_inputs(); + OS::get_singleton()->close_midi_inputs(); } void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) { @@ -1317,6 +1318,26 @@ void _OS::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_position"), "set_window_position", "get_window_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_size"), "set_window_size", "get_window_size"); + // Those default values need to be specified for the docs generator, + // to avoid using values from the documentation writer's own OS instance. + ADD_PROPERTY_DEFAULT("clipboard", ""); + ADD_PROPERTY_DEFAULT("current_screen", 0); + ADD_PROPERTY_DEFAULT("exit_code", 0); + ADD_PROPERTY_DEFAULT("vsync_enabled", true); + ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false); + ADD_PROPERTY_DEFAULT("keep_screen_on", true); + ADD_PROPERTY_DEFAULT("min_window_size", Vector2()); + ADD_PROPERTY_DEFAULT("max_window_size", Vector2()); + ADD_PROPERTY_DEFAULT("screen_orientation", 0); + ADD_PROPERTY_DEFAULT("window_borderless", false); + ADD_PROPERTY_DEFAULT("window_per_pixel_transparency_enabled", false); + ADD_PROPERTY_DEFAULT("window_fullscreen", false); + ADD_PROPERTY_DEFAULT("window_maximized", false); + ADD_PROPERTY_DEFAULT("window_minimized", false); + ADD_PROPERTY_DEFAULT("window_resizable", true); + ADD_PROPERTY_DEFAULT("window_position", Vector2()); + ADD_PROPERTY_DEFAULT("window_size", Vector2()); + BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2); BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES3); @@ -1911,13 +1932,15 @@ PoolVector<uint8_t> _File::get_buffer(int p_length) const { ERR_FAIL_COND_V(p_length < 0, data); if (p_length == 0) return data; + Error err = data.resize(p_length); ERR_FAIL_COND_V(err != OK, data); + PoolVector<uint8_t>::Write w = data.write(); int len = f->get_buffer(&w[0], p_length); ERR_FAIL_COND_V(len < 0, PoolVector<uint8_t>()); - w = PoolVector<uint8_t>::Write(); + w.release(); if (len < p_length) data.resize(p_length); @@ -2092,11 +2115,11 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) { PoolVector<uint8_t> buff; buff.resize(len); - PoolVector<uint8_t>::Write w = buff.write(); + PoolVector<uint8_t>::Write w = buff.write(); err = encode_variant(p_var, &w[0], len, p_full_objects); ERR_FAIL_COND(err != OK); - w = PoolVector<uint8_t>::Write(); + w.release(); store_32(len); store_buffer(buff); @@ -2246,7 +2269,7 @@ bool _Directory::current_is_dir() const { void _Directory::list_dir_end() { ERR_FAIL_COND(!d); - return d->list_dir_end(); + d->list_dir_end(); } int _Directory::get_drive_count() { @@ -2411,15 +2434,8 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) err = encode_variant(p_var, &w[0], len, p_full_objects); ERR_FAIL_COND_V(err != OK, ""); - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)(&w[0]), len); - //OS::get_singleton()->print("len is %i, vector size is %i\n", b64len, strlen); - w64[strlen] = 0; - String ret = (char *)&w64[0]; + String ret = CryptoCore::b64_encode_str(&w[0], len); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2433,7 +2449,8 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) buf.resize(strlen / 4 * 3 + 1); PoolVector<uint8_t>::Write w = buf.write(); - int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); + size_t len = 0; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, Variant()); Variant v; Error err = decode_variant(v, &w[0], len, NULL, p_allow_objects); @@ -2444,18 +2461,8 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) String _Marshalls::raw_to_base64(const PoolVector<uint8_t> &p_arr) { - int len = p_arr.size(); - PoolVector<uint8_t>::Read r = p_arr.read(); - - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)(&r[0]), len); - w64[strlen] = 0; - String ret = (char *)&w64[0]; - + String ret = CryptoCore::b64_encode_str(p_arr.read().ptr(), p_arr.size()); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2464,35 +2471,24 @@ PoolVector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) { int strlen = p_str.length(); CharString cstr = p_str.ascii(); - int arr_len; + size_t arr_len = 0; PoolVector<uint8_t> buf; { buf.resize(strlen / 4 * 3 + 1); PoolVector<uint8_t>::Write w = buf.write(); - arr_len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); - }; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen) != OK, PoolVector<uint8_t>()); + } buf.resize(arr_len); - // conversion from PoolVector<uint8_t> to raw array? return buf; }; String _Marshalls::utf8_to_base64(const String &p_str) { CharString cstr = p_str.utf8(); - int len = cstr.length(); - - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)cstr.get_data(), len); - - w64[strlen] = 0; - String ret = (char *)&w64[0]; - + String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length()); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2505,7 +2501,8 @@ String _Marshalls::base64_to_utf8(const String &p_str) { buf.resize(strlen / 4 * 3 + 1 + 1); PoolVector<uint8_t>::Write w = buf.write(); - int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); + size_t len = 0; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, String()); w[len] = 0; String ret = String::utf8((char *)&w[0]); @@ -2680,6 +2677,8 @@ Variant _Thread::wait_to_finish() { target_method = StringName(); target_instance = NULL; userdata = Variant(); + if (thread) + memdelete(thread); thread = NULL; return r; diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 2885e7c0e0..3be5a08752 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -805,6 +805,9 @@ public: void set_result(const Variant &p_result); Variant get_result() const; + + JSONParseResult() : + error_line(-1) {} }; class _JSON : public Object { diff --git a/core/class_db.cpp b/core/class_db.cpp index c9527e3c8f..2cbf53ba0b 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -545,6 +545,11 @@ bool ClassDB::can_instance(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); ERR_FAIL_COND_V(!ti, false); +#ifdef TOOLS_ENABLED + if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) { + return false; + } +#endif return (!ti->disabled && ti->creation_func != NULL); } @@ -920,7 +925,7 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons #ifdef DEBUG_METHODS_ENABLED if (!mb_set) { ERR_EXPLAIN("Invalid Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name); - ERR_FAIL_COND(!mb_set); + ERR_FAIL(); } else { int exp_args = 1 + (p_index >= 0 ? 1 : 0); if (mb_set->get_argument_count() != exp_args) { @@ -939,7 +944,7 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons if (!mb_get) { ERR_EXPLAIN("Invalid Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name); - ERR_FAIL_COND(!mb_get); + ERR_FAIL(); } else { int exp_args = 0 + (p_index >= 0 ? 1 : 0); @@ -980,6 +985,13 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons type->property_setget[p_pinfo.name] = psg; } +void ClassDB::set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default) { + if (!default_values.has(p_class)) { + default_values[p_class] = HashMap<StringName, Variant>(); + } + default_values[p_class][p_name] = p_default; +} + void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) { OBJTYPE_RLOCK; @@ -1383,37 +1395,60 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p } HashMap<StringName, HashMap<StringName, Variant> > ClassDB::default_values; +Set<StringName> ClassDB::default_values_cached; -Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property) { +Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) { - if (!default_values.has(p_class)) { + if (!default_values_cached.has(p_class)) { - default_values[p_class] = HashMap<StringName, Variant>(); + if (!default_values.has(p_class)) { + default_values[p_class] = HashMap<StringName, Variant>(); + } + + Object *c = NULL; + bool cleanup_c = false; - if (ClassDB::can_instance(p_class)) { + if (Engine::get_singleton()->has_singleton(p_class)) { + c = Engine::get_singleton()->get_singleton_object(p_class); + cleanup_c = false; + } else if (ClassDB::can_instance(p_class)) { + c = ClassDB::instance(p_class); + cleanup_c = true; + } + + if (c) { - Object *c = ClassDB::instance(p_class); List<PropertyInfo> plist; c->get_property_list(&plist); for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) { - Variant v = c->get(E->get().name); - default_values[p_class][E->get().name] = v; + if (!default_values[p_class].has(E->get().name)) { + Variant v = c->get(E->get().name); + default_values[p_class][E->get().name] = v; + } } } - memdelete(c); + + if (cleanup_c) { + memdelete(c); + } } + + default_values_cached.insert(p_class); } if (!default_values.has(p_class)) { + if (r_valid != NULL) *r_valid = false; return Variant(); } if (!default_values[p_class].has(p_property)) { + if (r_valid != NULL) *r_valid = false; return Variant(); } + if (r_valid != NULL) *r_valid = true; return default_values[p_class][p_property]; } @@ -1424,6 +1459,12 @@ void ClassDB::init() { lock = RWLock::create(); } +void ClassDB::cleanup_defaults() { + + default_values.clear(); + default_values_cached.clear(); +} + void ClassDB::cleanup() { //OBJTYPE_LOCK; hah not here @@ -1443,7 +1484,6 @@ void ClassDB::cleanup() { classes.clear(); resource_base_extensions.clear(); compat_classes.clear(); - default_values.clear(); memdelete(lock); } diff --git a/core/class_db.h b/core/class_db.h index efa1a46866..237ae9b806 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -162,6 +162,7 @@ public: static void _add_class2(const StringName &p_class, const StringName &p_inherits); static HashMap<StringName, HashMap<StringName, Variant> > default_values; + static Set<StringName> default_values_cached; public: // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! @@ -329,6 +330,7 @@ public: static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = ""); static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); + static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default); static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = NULL); static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = NULL); static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value); @@ -355,7 +357,7 @@ public: static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false); static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false); - static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property); + static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = NULL); static StringName get_category(const StringName &p_node); @@ -373,6 +375,7 @@ public: static void set_current_api(APIType p_api); static APIType get_current_api(); + static void cleanup_defaults(); static void cleanup(); }; diff --git a/core/color.cpp b/core/color.cpp index 8959fce4e3..1843532124 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -388,9 +388,8 @@ bool Color::html_is_valid(const String &p_color) { return false; } - int a = 255; if (alpha) { - a = _parse_col(color, 0); + int a = _parse_col(color, 0); if (a < 0) { return false; } diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index 798fa4394d..3789eda5db 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -346,7 +346,7 @@ class CommandQueueMT { } return NULL; } - } else if (write_ptr >= dealloc_ptr) { + } else { // ahead of dealloc_ptr, check that there is room if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + sizeof(uint32_t)) { diff --git a/core/engine.cpp b/core/engine.cpp index 50822244cf..2d8473fbd9 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -197,8 +197,10 @@ void Engine::add_singleton(const Singleton &p_singleton) { Object *Engine::get_singleton_object(const String &p_name) const { const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name); - ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'"); - ERR_FAIL_COND_V(!E, NULL); + if (!E) { + ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'"); + ERR_FAIL_V(NULL); + } return E->get(); }; diff --git a/core/hash_map.h b/core/hash_map.h index 31332991de..1513d7a65b 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -208,7 +208,10 @@ private: /* if element doesn't exist, create it */ Element *e = memnew(Element); - ERR_FAIL_COND_V(!e, NULL); /* out of memory */ + if (!e) { + ERR_EXPLAIN("Out of memory"); + ERR_FAIL_V(NULL); + } uint32_t hash = Hasher::hash(p_key); uint32_t index = hash & ((1 << hash_table_power) - 1); e->next = hash_table[index]; @@ -495,8 +498,10 @@ public: } else { /* get the next key */ const Element *e = get_element(*p_key); - ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */ - + if (!e) { + ERR_EXPLAIN("Invalid key supplied") + ERR_FAIL_V(NULL); + } if (e->next) { /* if there is a "next" in the list, return that */ return &e->next->pair.key; diff --git a/core/image.cpp b/core/image.cpp index dd8f2b9bac..a88395204a 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -495,8 +495,8 @@ void Image::convert(Format p_new_format) { case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break; } - r = PoolVector<uint8_t>::Read(); - w = PoolVector<uint8_t>::Write(); + r.release(); + w.release(); bool gen_mipmaps = mipmaps; @@ -1091,8 +1091,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } break; } - r = PoolVector<uint8_t>::Read(); - w = PoolVector<uint8_t>::Write(); + r.release(); + w.release(); if (interpolate_mipmaps) { dst._copy_internals_from(dst2); @@ -1372,6 +1372,7 @@ void Image::shrink_x2() { int new_size = data.size() - ofs; new_img.resize(new_size); + ERR_FAIL_COND(new_img.size() == 0); { PoolVector<uint8_t>::Write w = new_img.write(); @@ -1391,6 +1392,7 @@ void Image::shrink_x2() { ERR_FAIL_COND(!_can_modify(format)); int ps = get_format_pixel_size(format); new_img.resize((width / 2) * (height / 2) * ps); + ERR_FAIL_COND(new_img.size() == 0); { PoolVector<uint8_t>::Write w = new_img.write(); @@ -1464,7 +1466,10 @@ Error Image::generate_mipmaps(bool p_renormalize) { ERR_FAIL_V(ERR_UNAVAILABLE); } - ERR_FAIL_COND_V(width == 0 || height == 0, ERR_UNCONFIGURED); + if (width == 0 || height == 0) { + ERR_EXPLAIN("Cannot generate mipmaps with width or height equal to 0."); + ERR_FAIL_V(ERR_UNCONFIGURED); + } int mmcount; @@ -2389,7 +2394,7 @@ void Image::lock() { void Image::unlock() { - write_lock = PoolVector<uint8_t>::Write(); + write_lock.release(); } Color Image::get_pixelv(const Point2 &p_src) const { @@ -2532,7 +2537,7 @@ Color Image::get_pixel(int p_x, int p_y) const { } void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) { - return set_pixel(p_dst.x, p_dst.y, p_color); + set_pixel(p_dst.x, p_dst.y, p_color); } void Image::set_pixel(int p_x, int p_y, const Color &p_color) { diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp index 93eaeb08c5..15523a49a9 100644 --- a/core/io/file_access_buffered.cpp +++ b/core/io/file_access_buffered.cpp @@ -35,79 +35,79 @@ Error FileAccessBuffered::set_error(Error p_error) const { return (last_error = p_error); -}; +} void FileAccessBuffered::set_cache_size(int p_size) { cache_size = p_size; -}; +} int FileAccessBuffered::get_cache_size() { return cache_size; -}; +} int FileAccessBuffered::cache_data_left() const { if (file.offset >= file.size) { return 0; - }; + } if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) { return read_data_block(file.offset, cache_size); + } - } else { - - return cache.buffer.size() - (file.offset - cache.offset); - }; - - return 0; -}; + return cache.buffer.size() - (file.offset - cache.offset); +} void FileAccessBuffered::seek(size_t p_position) { file.offset = p_position; -}; +} void FileAccessBuffered::seek_end(int64_t p_position) { file.offset = file.size + p_position; -}; +} size_t FileAccessBuffered::get_position() const { return file.offset; -}; +} size_t FileAccessBuffered::get_len() const { return file.size; -}; +} bool FileAccessBuffered::eof_reached() const { return file.offset > file.size; -}; +} uint8_t FileAccessBuffered::get_8() const { - - ERR_FAIL_COND_V(!file.open, 0); + if (!file.open) { + ERR_EXPLAIN("Can't get data, when file is not opened."); + ERR_FAIL_V(0); + } uint8_t byte = 0; if (cache_data_left() >= 1) { byte = cache.buffer[file.offset - cache.offset]; - }; + } ++file.offset; return byte; -}; +} int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const { - - ERR_FAIL_COND_V(!file.open, -1); + if (!file.open) { + ERR_EXPLAIN("Can't get buffer, when file is not opened."); + ERR_FAIL_V(-1); + } if (p_length > cache_size) { @@ -124,16 +124,16 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const { p_length -= size; file.offset += size; total_read += size; - }; + } int err = read_data_block(file.offset, p_length, p_dest); if (err >= 0) { total_read += err; file.offset += err; - }; + } return total_read; - }; + } int to_read = p_length; int total_read = 0; @@ -143,10 +143,10 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const { if (left == 0) { file.offset += to_read; return total_read; - }; + } if (left < 0) { return left; - }; + } int r = MIN(left, to_read); //PoolVector<uint8_t>::Read read = cache.buffer.read(); @@ -156,25 +156,25 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const { file.offset += r; total_read += r; to_read -= r; - }; + } return p_length; -}; +} bool FileAccessBuffered::is_open() const { return file.open; -}; +} Error FileAccessBuffered::get_error() const { return last_error; -}; +} FileAccessBuffered::FileAccessBuffered() { cache_size = DEFAULT_CACHE_SIZE; -}; +} FileAccessBuffered::~FileAccessBuffered() { } diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 24b40cbce8..6e806e7b3f 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -40,7 +40,10 @@ class FileAccessBufferedFA : public FileAccessBuffered { int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const { - ERR_FAIL_COND_V(!f.is_open(), -1); + if (!f.is_open()) { + ERR_EXPLAIN("Can't read data block, when file is not opened."); + ERR_FAIL_V(-1); + } ((T *)&f)->seek(p_offset); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 7dea749a43..ccee6aeb15 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -30,13 +30,11 @@ #include "file_access_encrypted.h" +#include "core/math/crypto_core.h" #include "core/os/copymem.h" #include "core/print_string.h" #include "core/variant.h" -#include "thirdparty/misc/aes256.h" -#include "thirdparty/misc/md5.h" - #include <stdio.h> #define COMP_MAGIC 0x43454447 @@ -83,25 +81,21 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 uint32_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); - aes256_context ctx; - aes256_init(&ctx, key.ptrw()); + CryptoCore::AESContext ctx; + ctx.set_decode_key(key.ptrw(), 256); for (size_t i = 0; i < ds; i += 16) { - aes256_decrypt_ecb(&ctx, &data.write[i]); + ctx.decrypt_ecb(&data.write[i], &data.write[i]); } - aes256_done(&ctx); - data.resize(length); - MD5_CTX md5; - MD5Init(&md5); - MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); - MD5Final(&md5); + unsigned char hash[16]; + ERR_FAIL_COND_V(CryptoCore::md5(data.ptr(), data.size(), hash) != OK, ERR_BUG); ERR_EXPLAIN("The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid."); - ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT); file = p_base; } @@ -140,10 +134,8 @@ void FileAccessEncrypted::close() { len += 16 - (len % 16); } - MD5_CTX md5; - MD5Init(&md5); - MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); - MD5Final(&md5); + unsigned char hash[16]; + ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug? compressed.resize(len); zeromem(compressed.ptrw(), len); @@ -151,20 +143,18 @@ void FileAccessEncrypted::close() { compressed.write[i] = data[i]; } - aes256_context ctx; - aes256_init(&ctx, key.ptrw()); + CryptoCore::AESContext ctx; + ctx.set_encode_key(key.ptrw(), 256); for (size_t i = 0; i < len; i += 16) { - aes256_encrypt_ecb(&ctx, &compressed.write[i]); + ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]); } - aes256_done(&ctx); - file->store_32(COMP_MAGIC); file->store_32(mode); - file->store_buffer(md5.digest, 16); + file->store_buffer(hash, 16); file->store_64(data.size()); file->store_buffer(compressed.ptr(), compressed.size()); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index d38d09c6bb..ca66b34e17 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -144,7 +144,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) { uint32_t magic = f->get_32(); if (magic != 0x43504447) { - //maybe at he end.... self contained exe + //maybe at the end.... self contained exe f->seek_end(); f->seek(f->get_position() - 4); magic = f->get_32(); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index c3626bfe31..170bef4430 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -482,8 +482,6 @@ Error HTTPClient::poll() { return OK; } } - // Wait for response - return OK; } break; case STATUS_DISCONNECTED: { return ERR_UNCONFIGURED; diff --git a/core/io/json.cpp b/core/io/json.cpp index c211ca2ed4..4e729cb355 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -347,8 +347,6 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in r_err_str = "Expected value, got " + String(tk_name[token.type]) + "."; return ERR_PARSE_ERROR; } - - return ERR_PARSE_ERROR; } Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 17a3f52a65..dc5581ea01 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -558,8 +558,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = buf[i]; } - - w = PoolVector<uint8_t>::Write(); } r_variant = data; @@ -590,8 +588,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = decode_uint32(&buf[i * 4]); } - - w = PoolVector<int>::Write(); } r_variant = Variant(data); if (r_len) { @@ -618,8 +614,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = decode_float(&buf[i * 4]); } - - w = PoolVector<float>::Write(); } r_variant = data; diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 2779837190..33dc4dbde4 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -874,6 +874,7 @@ void MultiplayerAPI::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer"); + ADD_PROPERTY_DEFAULT("refuse_new_network_connections", false); ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id"))); diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 55685a2d9a..c16d89d695 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -63,10 +63,11 @@ void PCKPacker::_bind_methods() { Error PCKPacker::pck_start(const String &p_file, int p_alignment) { file = FileAccess::open(p_file, FileAccess::WRITE); - if (file == NULL) { - return ERR_CANT_CREATE; - }; + if (!file) { + ERR_EXPLAIN("Can't open file to write: " + String(p_file)); + ERR_FAIL_V(ERR_CANT_CREATE); + } alignment = p_alignment; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 688dfc21e5..861e34e415 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -410,7 +410,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<uint8_t>::Write w = array.write(); f->get_buffer(w.ptr(), len); _advance_padding(len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_v = array; } break; @@ -432,7 +432,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { } #endif - w = PoolVector<int>::Write(); + w.release(); r_v = array; } break; case VARIANT_REAL_ARRAY: { @@ -454,7 +454,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { #endif - w = PoolVector<real_t>::Write(); + w.release(); r_v = array; } break; case VARIANT_STRING_ARRAY: { @@ -465,7 +465,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<String>::Write w = array.write(); for (uint32_t i = 0; i < len; i++) w[i] = get_unicode_string(); - w = PoolVector<String>::Write(); + w.release(); r_v = array; } break; @@ -493,7 +493,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Vector2 size is NOT 8!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Vector2>::Write(); + w.release(); r_v = array; } break; @@ -521,7 +521,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Vector3 size is NOT 12!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Vector3>::Write(); + w.release(); r_v = array; } break; @@ -549,7 +549,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Color size is NOT 16!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Color>::Write(); + w.release(); r_v = array; } break; #ifndef DISABLE_DEPRECATED @@ -584,7 +584,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<uint8_t>::Write w = imgdata.write(); f->get_buffer(w.ptr(), datalen); _advance_padding(datalen); - w = PoolVector<uint8_t>::Write(); + w.release(); Ref<Image> image; image.instance(); @@ -597,7 +597,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { data.resize(f->get_32()); PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), data.size()); - w = PoolVector<uint8_t>::Write(); + w.release(); Ref<Image> image; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 4a58d37ca5..63d7ba547c 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -161,7 +161,8 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { if (p_type == "") { - return get_recognized_extensions(p_extensions); + get_recognized_extensions(p_extensions); + return; } Set<String> found; @@ -347,7 +348,7 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> return; } - return ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types); + ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types); } Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 56d3b8b133..a29b9d1ddb 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -207,8 +207,6 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa ERR_FAIL_COND_V(err != OK, RES()); } - - return RES(); } void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { @@ -283,7 +281,6 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c ERR_EXPLAIN("No loader found for resource: " + p_path); } ERR_FAIL_V(RES()); - return RES(); } bool ResourceLoader::_add_to_loading_map(const String &p_path) { @@ -543,7 +540,6 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(Ref<ResourceInteractiveLoader>()); - return Ref<ResourceInteractiveLoader>(); } void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) { diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 6ad24a5f3a..acf72dbba5 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -79,7 +79,7 @@ Array StreamPeer::_get_data(int p_bytes) { PoolVector<uint8_t>::Write w = data.write(); Error err = get_data(&w[0], p_bytes); - w = PoolVector<uint8_t>::Write(); + w.release(); ret.push_back(err); ret.push_back(data); return ret; @@ -101,7 +101,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) { PoolVector<uint8_t>::Write w = data.write(); int received; Error err = get_partial_data(&w[0], p_bytes, received); - w = PoolVector<uint8_t>::Write(); + w.release(); if (err != OK) { data.resize(0); diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 254ae84bf5..ccce48ccd7 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -39,7 +39,9 @@ StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL; StreamPeerSSL *StreamPeerSSL::create() { - return _create(); + if (_create) + return _create(); + return NULL; } StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index bcdae343b8..310bb12bc0 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,6 +30,8 @@ #include "stream_peer_tcp.h" +#include "core/project_settings.h" + Error StreamPeerTCP::_poll_connection() { ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED); @@ -40,6 +42,12 @@ Error StreamPeerTCP::_poll_connection() { status = STATUS_CONNECTED; return OK; } else if (err == ERR_BUSY) { + // Check for connect timeout + if (OS::get_singleton()->get_ticks_msec() > timeout) { + disconnect_from_host(); + status = STATUS_ERROR; + return ERR_CONNECTION_ERROR; + } // Still trying to connect return OK; } @@ -54,6 +62,7 @@ void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint _sock = p_sock; _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); status = STATUS_CONNECTING; peer_host = p_host; @@ -74,6 +83,7 @@ Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); err = _sock->connect_to_host(p_host, p_port); if (err == OK) { @@ -217,6 +227,11 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool to_read -= read; total_read += read; + + if (!p_block) { + r_received = total_read; + return OK; + } } } @@ -276,6 +291,7 @@ void StreamPeerTCP::disconnect_from_host() { if (_sock.is_valid() && _sock->is_open()) _sock->close(); + timeout = 0; status = STATUS_NONE; peer_host = IP_Address(); peer_port = 0; @@ -351,6 +367,7 @@ void StreamPeerTCP::_bind_methods() { StreamPeerTCP::StreamPeerTCP() : _sock(Ref<NetSocket>(NetSocket::create())), + timeout(0), status(STATUS_NONE), peer_port(0) { } diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 1ca39375aa..321fb3a6c8 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -52,6 +52,7 @@ public: protected: Ref<NetSocket> _sock; + uint64_t timeout; Status status; IP_Address peer_host; uint16_t peer_port; diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index be87f47d50..a2756164bc 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -34,6 +34,7 @@ void TCP_Server::_bind_methods() { ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*")); ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available); + ClassDB::bind_method(D_METHOD("is_listening"), &TCP_Server::is_listening); ClassDB::bind_method(D_METHOD("take_connection"), &TCP_Server::take_connection); ClassDB::bind_method(D_METHOD("stop"), &TCP_Server::stop); } @@ -75,6 +76,12 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) { return OK; } +bool TCP_Server::is_listening() const { + ERR_FAIL_COND_V(!_sock.is_valid(), false); + + return _sock->is_open(); +} + bool TCP_Server::is_connection_available() const { ERR_FAIL_COND_V(!_sock.is_valid(), false); diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 538db175ad..ef64044599 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -50,6 +50,7 @@ protected: public: Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*")); + bool is_listening() const; bool is_connection_available() const; Ref<StreamPeerTCP> take_connection(); diff --git a/core/math/SCsub b/core/math/SCsub index 1c5f954470..0995298a4b 100644 --- a/core/math/SCsub +++ b/core/math/SCsub @@ -2,4 +2,37 @@ Import('env') -env.add_source_files(env.core_sources, "*.cpp") +env_math = env.Clone() # Maybe make one specific for crypto? + +is_builtin = env["builtin_mbedtls"] +has_module = env["module_mbedtls_enabled"] + +if is_builtin or not has_module: + # Use our headers for builtin or if the module is not going to be compiled. + # We decided not to depend on system mbedtls just for these few files that can + # be easily extracted. + env_math.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) + +# MbedTLS core functions (for CryptoCore). +# If the mbedtls module is compiled we don't need to add the .c files with our +# custom config since they will be built by the module itself. +# Only if the module is not enabled, we must compile here the required sources +# to make a "light" build with only the necessary mbedtls files. +if not has_module: + env_thirdparty = env_math.Clone() + env_thirdparty.disable_warnings() + # Custom config file + env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')]) + thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/" + thirdparty_mbedtls_sources = [ + "aes.c", + "base64.c", + "md5.c", + "sha1.c", + "sha256.c", + "godot_core_mbedtls_platform.c" + ] + thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources] + env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources) + +env_math.add_source_files(env.core_sources, "*.cpp") diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 7ce3824505..b61119d8df 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -216,6 +216,8 @@ int AStar::get_closest_point(const Vector3 &p_point) const { for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { + if (!E->get()->enabled) + continue; //Disabled points should not be considered real_t d = p_point.distance_squared_to(E->get()->pos); if (closest_id < 0 || d < closest_dist) { closest_dist = d; @@ -234,6 +236,10 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const { for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) { + if (!(E->get().from_point->enabled && E->get().to_point->enabled)) { + continue; + } + Vector3 segment[2] = { E->get().from_point->pos, E->get().to_point->pos, diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index d7e6e82cd9..a12f9fee2e 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -142,7 +142,7 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind } return _get_points_inside(node->over, p_points, p_indices, p_center, p_half_extents, p_indices_count); - } else if (dist_min <= 0) { //all points behind plane + } else { //all points behind plane if (node->under == UNDER_LEAF) { @@ -150,8 +150,6 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind } return _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, p_indices_count); } - - return 0; } int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const { @@ -271,8 +269,6 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const { ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false); #endif } - - return false; } static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_indices, real_t p_tolerance) { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index f615cc8c65..8b3b6c82f3 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -507,21 +507,21 @@ void CameraMatrix::set_light_bias() { real_t *m = &matrix[0][0]; - m[0] = 0.5, - m[1] = 0.0, - m[2] = 0.0, - m[3] = 0.0, - m[4] = 0.0, - m[5] = 0.5, - m[6] = 0.0, - m[7] = 0.0, - m[8] = 0.0, - m[9] = 0.0, - m[10] = 0.5, - m[11] = 0.0, - m[12] = 0.5, - m[13] = 0.5, - m[14] = 0.5, + m[0] = 0.5; + m[1] = 0.0; + m[2] = 0.0; + m[3] = 0.0; + m[4] = 0.0; + m[5] = 0.5; + m[6] = 0.0; + m[7] = 0.0; + m[8] = 0.0; + m[9] = 0.0; + m[10] = 0.5; + m[11] = 0.0; + m[12] = 0.5; + m[13] = 0.5; + m[14] = 0.5; m[15] = 1.0; } @@ -529,21 +529,21 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { real_t *m = &matrix[0][0]; - m[0] = p_rect.size.width, - m[1] = 0.0, - m[2] = 0.0, - m[3] = 0.0, - m[4] = 0.0, - m[5] = p_rect.size.height, - m[6] = 0.0, - m[7] = 0.0, - m[8] = 0.0, - m[9] = 0.0, - m[10] = 1.0, - m[11] = 0.0, - m[12] = p_rect.position.x, - m[13] = p_rect.position.y, - m[14] = 0.0, + m[0] = p_rect.size.width; + m[1] = 0.0; + m[2] = 0.0; + m[3] = 0.0; + m[4] = 0.0; + m[5] = p_rect.size.height; + m[6] = 0.0; + m[7] = 0.0; + m[8] = 0.0; + m[9] = 0.0; + m[10] = 1.0; + m[11] = 0.0; + m[12] = p_rect.position.x; + m[13] = p_rect.position.y; + m[14] = 0.0; m[15] = 1.0; } diff --git a/core/math/crypto_core.cpp b/core/math/crypto_core.cpp new file mode 100644 index 0000000000..d7ba54e469 --- /dev/null +++ b/core/math/crypto_core.cpp @@ -0,0 +1,157 @@ +/*************************************************************************/ +/* crypto_core.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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. */ +/*************************************************************************/ + +#include "crypto_core.h" + +#include <mbedtls/aes.h> +#include <mbedtls/base64.h> +#include <mbedtls/md5.h> +#include <mbedtls/sha1.h> +#include <mbedtls/sha256.h> + +// MD5 +CryptoCore::MD5Context::MD5Context() { + ctx = memalloc(sizeof(mbedtls_md5_context)); + mbedtls_md5_init((mbedtls_md5_context *)ctx); +} + +CryptoCore::MD5Context::~MD5Context() { + mbedtls_md5_free((mbedtls_md5_context *)ctx); + memfree((mbedtls_md5_context *)ctx); +} + +Error CryptoCore::MD5Context::start() { + int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx); + return ret ? FAILED : OK; +} + +Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) { + int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) { + int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash); + return ret ? FAILED : OK; +} + +// SHA256 +CryptoCore::SHA256Context::SHA256Context() { + ctx = memalloc(sizeof(mbedtls_sha256_context)); + mbedtls_sha256_init((mbedtls_sha256_context *)ctx); +} + +CryptoCore::SHA256Context::~SHA256Context() { + mbedtls_sha256_free((mbedtls_sha256_context *)ctx); + memfree((mbedtls_sha256_context *)ctx); +} + +Error CryptoCore::SHA256Context::start() { + int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0); + return ret ? FAILED : OK; +} + +Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) { + int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::SHA256Context::finish(unsigned char r_hash[16]) { + int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash); + return ret ? FAILED : OK; +} + +// AES256 +CryptoCore::AESContext::AESContext() { + ctx = memalloc(sizeof(mbedtls_aes_context)); + mbedtls_aes_init((mbedtls_aes_context *)ctx); +} + +CryptoCore::AESContext::~AESContext() { + mbedtls_aes_free((mbedtls_aes_context *)ctx); + memfree((mbedtls_aes_context *)ctx); +} + +Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) { + int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) { + int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { + int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { + int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst); + return ret ? FAILED : OK; +} + +// CryptoCore +String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { + int b64len = p_src_len / 3 * 4 + 4 + 1; + PoolVector<uint8_t> b64buff; + b64buff.resize(b64len); + PoolVector<uint8_t>::Write w64 = b64buff.write(); + size_t strlen = 0; + int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len); + w64[strlen] = 0; + return ret ? String() : (const char *)&w64[0]; +} + +Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { + int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { + int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { + int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); + return ret ? FAILED : OK; +} + +Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { + int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); + return ret ? FAILED : OK; +} + +Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { + int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); + return ret ? FAILED : OK; +} diff --git a/core/math/crypto_core.h b/core/math/crypto_core.h new file mode 100644 index 0000000000..e28cb5a792 --- /dev/null +++ b/core/math/crypto_core.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* crypto_core.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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. */ +/*************************************************************************/ + +#ifndef CRYPTO_CORE_H +#define CRYPTO_CORE_H + +#include "core/reference.h" + +class CryptoCore { + +public: + class MD5Context { + + private: + void *ctx; // To include, or not to include... + + public: + MD5Context(); + ~MD5Context(); + + Error start(); + Error update(uint8_t *p_src, size_t p_len); + Error finish(unsigned char r_hash[16]); + }; + + class SHA256Context { + + private: + void *ctx; // To include, or not to include... + + public: + SHA256Context(); + ~SHA256Context(); + + Error start(); + Error update(uint8_t *p_src, size_t p_len); + Error finish(unsigned char r_hash[16]); + }; + + class AESContext { + + private: + void *ctx; // To include, or not to include... + + public: + AESContext(); + ~AESContext(); + + Error set_encode_key(const uint8_t *p_key, size_t p_bits); + Error set_decode_key(const uint8_t *p_key, size_t p_bits); + Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); + Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); + }; + + static String b64_encode_str(const uint8_t *p_src, int p_src_len); + static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + + static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); + static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); + static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); +}; +#endif // CRYPTO_CORE_H diff --git a/core/math/geometry.h b/core/math/geometry.h index 0e144e491f..e4f3ff799e 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -455,16 +455,15 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -474,12 +473,11 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } @@ -488,16 +486,15 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -521,12 +518,11 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 5b5fd8e283..7a2e74a413 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -161,8 +161,6 @@ uint32_t Math::larger_prime(uint32_t p_val) { return primes[idx]; idx++; } - - return 0; } double Math::random(double from, double to) { diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index a6182a4b33..9b54ea9b2e 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -47,7 +47,7 @@ public: _FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); } - _FORCE_INLINE_ void randomize() { return randbase.randomize(); } + _FORCE_INLINE_ void randomize() { randbase.randomize(); } _FORCE_INLINE_ uint32_t randi() { return randbase.rand(); } diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 83784a1fa7..546981be44 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -182,7 +182,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { int max_alloc = fc; _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); - bw = PoolVector<BVH>::Write(); //clearup + bw.release(); //clearup bvh.resize(max_alloc); //resize back valid = true; @@ -751,7 +751,7 @@ PoolVector<Face3> TriangleMesh::get_faces() const { } } - w = PoolVector<Face3>::Write(); + w.release(); return faces; } diff --git a/core/object.cpp b/core/object.cpp index ee512ff23c..3367d6b6c3 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -742,13 +742,11 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args, if (Object::cast_to<Reference>(this)) { ERR_EXPLAIN("Can't 'free' a reference."); ERR_FAIL(); - return; } if (_lock_index.get() > 1) { ERR_EXPLAIN("Object is locked and can't be freed."); ERR_FAIL(); - return; } #endif @@ -1467,7 +1465,7 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str if (!signal_is_valid) { ERR_EXPLAIN("In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'"); - ERR_FAIL_COND_V(!signal_is_valid, ERR_INVALID_PARAMETER); + ERR_FAIL_V(ERR_INVALID_PARAMETER); } signal_map[p_signal] = Signal(); s = &signal_map[p_signal]; @@ -1517,7 +1515,7 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const return false; ERR_EXPLAIN("Nonexistent signal: " + p_signal); - ERR_FAIL_COND_V(!s, false); + ERR_FAIL_V(false); } Signal::Target target(p_to_object->get_instance_id(), p_to_method); diff --git a/core/object.h b/core/object.h index 4394c1c3da..1e0b22c086 100644 --- a/core/object.h +++ b/core/object.h @@ -130,6 +130,7 @@ enum PropertyUsageFlags { #define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal) #define ADD_PROPERTY(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter)) #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) +#define ADD_PROPERTY_DEFAULT(m_property, m_default) ClassDB::set_property_default_value(get_class_static(), m_property, m_default) #define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix) struct PropertyInfo { diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 1c57bfdf3d..0cdb5b41b7 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -43,8 +43,6 @@ String DirAccess::_get_root_path() const { case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir(); default: return ""; } - - return ""; } String DirAccess::_get_root_string() const { @@ -54,8 +52,6 @@ String DirAccess::_get_root_string() const { case ACCESS_USERDATA: return "user://"; default: return ""; } - - return ""; } int DirAccess::get_current_drive() { @@ -378,7 +374,7 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag list_dir_end(); return ERR_BUG; } - Error err = copy(get_current_dir() + "/" + n, p_to + rel_path, p_chmod_flags); + Error err = copy(get_current_dir().plus_file(n), p_to + rel_path, p_chmod_flags); if (err) { list_dir_end(); return err; diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index b5580b5c6e..7509050b2b 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -32,12 +32,10 @@ #include "core/io/file_access_pack.h" #include "core/io/marshalls.h" +#include "core/math/crypto_core.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "thirdparty/misc/md5.h" -#include "thirdparty/misc/sha256.h" - FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { 0, 0 }; FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = NULL; @@ -637,8 +635,8 @@ String FileAccess::get_md5(const String &p_file) { if (!f) return String(); - MD5_CTX md5; - MD5Init(&md5); + CryptoCore::MD5Context ctx; + ctx.start(); unsigned char step[32768]; @@ -647,24 +645,24 @@ String FileAccess::get_md5(const String &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - MD5Update(&md5, step, br); + ctx.update(step, br); } if (br < 4096) break; } - MD5Final(&md5); - - String ret = String::md5(md5.digest); + unsigned char hash[16]; + ctx.finish(hash); memdelete(f); - return ret; + + return String::md5(hash); } String FileAccess::get_multiple_md5(const Vector<String> &p_file) { - MD5_CTX md5; - MD5Init(&md5); + CryptoCore::MD5Context ctx; + ctx.start(); for (int i = 0; i < p_file.size(); i++) { FileAccess *f = FileAccess::open(p_file[i], READ); @@ -677,7 +675,7 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - MD5Update(&md5, step, br); + ctx.update(step, br); } if (br < 4096) break; @@ -685,11 +683,10 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { memdelete(f); } - MD5Final(&md5); + unsigned char hash[16]; + ctx.finish(hash); - String ret = String::md5(md5.digest); - - return ret; + return String::md5(hash); } String FileAccess::get_sha256(const String &p_file) { @@ -698,8 +695,8 @@ String FileAccess::get_sha256(const String &p_file) { if (!f) return String(); - sha256_context sha256; - sha256_init(&sha256); + CryptoCore::SHA256Context ctx; + ctx.start(); unsigned char step[32768]; @@ -708,15 +705,14 @@ String FileAccess::get_sha256(const String &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - sha256_hash(&sha256, step, br); + ctx.update(step, br); } if (br < 4096) break; } unsigned char hash[32]; - - sha256_done(&sha256, hash); + ctx.finish(hash); memdelete(f); return String::hex_encode_buffer(hash, 32); diff --git a/core/os/memory.h b/core/os/memory.h index f3ca9fc614..e073b11e76 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -66,7 +66,7 @@ public: class DefaultAllocator { public: _FORCE_INLINE_ static void *alloc(size_t p_memory) { return Memory::alloc_static(p_memory, false); } - _FORCE_INLINE_ static void free(void *p_ptr) { return Memory::free_static(p_ptr, false); } + _FORCE_INLINE_ static void free(void *p_ptr) { Memory::free_static(p_ptr, false); } }; void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool diff --git a/core/os/os.cpp b/core/os/os.cpp index 08067385ab..925154af7d 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -51,6 +51,35 @@ uint32_t OS::get_ticks_msec() const { return get_ticks_usec() / 1000; } +String OS::get_iso_date_time(bool local) const { + OS::Date date = get_date(local); + OS::Time time = get_time(local); + + String timezone; + if (!local) { + TimeZoneInfo zone = get_time_zone_info(); + if (zone.bias >= 0) { + timezone = "+"; + } + timezone = timezone + itos(zone.bias / 60).pad_zeros(2) + itos(zone.bias % 60).pad_zeros(2); + } else { + timezone = "Z"; + } + + return itos(date.year).pad_zeros(2) + + "-" + + itos(date.month).pad_zeros(2) + + "-" + + itos(date.day).pad_zeros(2) + + "T" + + itos(time.hour).pad_zeros(2) + + ":" + + itos(time.min).pad_zeros(2) + + ":" + + itos(time.sec).pad_zeros(2) + + timezone; +} + uint64_t OS::get_splash_tick_msec() const { return _msec_splash; } diff --git a/core/os/os.h b/core/os/os.h index 1b19ddff26..2224d3b006 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -336,6 +336,7 @@ public: virtual Date get_date(bool local = false) const = 0; virtual Time get_time(bool local = false) const = 0; virtual TimeZoneInfo get_time_zone_info() const = 0; + virtual String get_iso_date_time(bool local = false) const; virtual uint64_t get_unix_time() const; virtual uint64_t get_system_time_secs() const; virtual uint64_t get_system_time_msecs() const; diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp index fa60be64a7..54bf12b314 100644 --- a/core/packed_data_container.cpp +++ b/core/packed_data_container.cpp @@ -224,7 +224,8 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd string_cache[s] = tmpdata.size(); - }; //fallthrough + FALLTHROUGH; + }; case Variant::NIL: case Variant::BOOL: case Variant::INT: diff --git a/core/pool_vector.h b/core/pool_vector.h index 338de966f6..98a52c6938 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -301,6 +301,10 @@ public: virtual ~Access() { _unref(); } + + void release() { + _unref(); + } }; class Read : public Access { @@ -484,9 +488,7 @@ T PoolVector<T>::get(int p_index) const { template <class T> void PoolVector<T>::set(int p_index, const T &p_val) { - if (p_index < 0 || p_index >= size()) { - ERR_FAIL_COND(p_index < 0 || p_index >= size()); - } + ERR_FAIL_INDEX(p_index, size()); Write w = write(); w[p_index] = p_val; diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 983b2a2576..3597e2b818 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -83,6 +83,10 @@ String ProjectSettings::localize_path(const String &p_path) const { // `plus_file("")` is an easy way to ensure we have a trailing '/'. const String res_path = resource_path.plus_file(""); + // DirAccess::get_current_dir() is not guaranteed to return a path that with a trailing '/', + // so we must make sure we have it as well in order to compare with 'res_path'. + cwd = cwd.plus_file(""); + if (!cwd.begins_with(res_path)) { return p_path; }; @@ -343,17 +347,17 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b return err; } - // Attempt with exec_name.pck - // (This is the usual case when distributing a Godot game.) - - // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) - // or the exec path's basename + '.pck' (Windows). - // We need to test both possibilities as extensions for Linux binaries are optional - // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). - String exec_path = OS::get_singleton()->get_executable_path(); if (exec_path != "") { + // Attempt with exec_name.pck + // (This is the usual case when distributing a Godot game.) + + // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) + // or the exec path's basename + '.pck' (Windows). + // We need to test both possibilities as extensions for Linux binaries are optional + // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). + bool found = false; String exec_dir = exec_path.get_base_dir(); @@ -375,6 +379,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b } } + // Attempt with PCK bundled into executable + + if (!found) { + if (_load_resource_pack(exec_path)) { + found = true; + } + } + // If we opened our package, try and load our project if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); @@ -863,8 +875,6 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust ERR_EXPLAIN("Unknown config file format: " + p_path); ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); } - - return OK; } Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed) { diff --git a/core/reference.cpp b/core/reference.cpp index 7b5145184a..1984af9a34 100644 --- a/core/reference.cpp +++ b/core/reference.cpp @@ -70,7 +70,7 @@ bool Reference::reference() { if (get_script_instance()) { get_script_instance()->refcount_incremented(); } - if (instance_binding_count > 0) { + if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { ScriptServer::get_language(i)->refcount_incremented_instance_binding(this); @@ -91,7 +91,7 @@ bool Reference::unreference() { bool script_ret = get_script_instance()->refcount_decremented(); die = die && script_ret; } - if (instance_binding_count > 0) { + if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 135df4e5bd..e442546124 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -190,6 +190,8 @@ void register_core_types() { ClassDB::register_class<JSONParseResult>(); + ClassDB::register_virtual_class<ResourceImporter>(); + ip = IP::create(); _geometry = memnew(_Geometry); @@ -205,6 +207,8 @@ void register_core_types() { void register_core_settings() { //since in register core types, globals may not e present + GLOBAL_DEF("network/limits/tcp/connect_timeout_seconds", (30)); + ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1")); GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16)); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater")); } @@ -273,6 +277,7 @@ void unregister_core_types() { ResourceLoader::finalize(); + ClassDB::cleanup_defaults(); ObjectDB::cleanup(); unregister_variant_methods(); diff --git a/core/script_language.h b/core/script_language.h index b0c60b4e90..87f103bb33 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -200,6 +200,35 @@ public: virtual ~ScriptInstance(); }; +struct ScriptCodeCompletionOption { + enum Kind { + KIND_CLASS, + KIND_FUNCTION, + KIND_SIGNAL, + KIND_VARIABLE, + KIND_MEMBER, + KIND_ENUM, + KIND_CONSTANT, + KIND_NODE_PATH, + KIND_FILE_PATH, + KIND_PLAIN_TEXT, + }; + Kind kind; + String display; + String insert_text; + RES icon; + + ScriptCodeCompletionOption() { + kind = KIND_PLAIN_TEXT; + } + + ScriptCodeCompletionOption(const String &p_text, Kind p_kind) { + display = p_text; + insert_text = p_text; + kind = p_kind; + } +}; + class ScriptCodeCompletionCache { static ScriptCodeCompletionCache *singleton; @@ -250,7 +279,7 @@ public: virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } virtual bool overrides_external_editor() { return false; } - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } struct LookupResult { enum Type { diff --git a/core/ustring.cpp b/core/ustring.cpp index ff28fa420d..75e3b6f22e 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -31,6 +31,7 @@ #include "ustring.h" #include "core/color.h" +#include "core/math/crypto_core.h" #include "core/math/math_funcs.h" #include "core/os/memory.h" #include "core/print_string.h" @@ -38,9 +39,6 @@ #include "core/ucaps.h" #include "core/variant.h" -#include "thirdparty/misc/md5.h" -#include "thirdparty/misc/sha256.h" - #include <wchar.h> #ifndef NO_USE_STDLIB @@ -481,8 +479,6 @@ signed char String::nocasecmp_to(const String &p_str) const { this_str++; that_str++; } - - return 0; //should never reach anyway } signed char String::casecmp_to(const String &p_str) const { @@ -513,8 +509,6 @@ signed char String::casecmp_to(const String &p_str) const { this_str++; that_str++; } - - return 0; //should never reach anyway } signed char String::naturalnocasecmp_to(const String &p_str) const { @@ -731,8 +725,6 @@ String String::get_slicec(CharType p_splitter, int p_slice) const { i++; } - - return String(); //no find! } Vector<String> String::split_spaces() const { @@ -786,7 +778,7 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p if (p_allow_empty || (end > from)) { if (p_maxsplit <= 0) ret.push_back(substr(from, end - from)); - else if (p_maxsplit > 0) { + else { // Put rest of the string and leave cycle. if (p_maxsplit == ret.size()) { @@ -2260,54 +2252,63 @@ uint64_t String::hash64() const { String String::md5_text() const { CharString cs = utf8(); - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length()); - MD5Final(&ctx); - return String::md5(ctx.digest); + unsigned char hash[16]; + CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash); + return String::hex_encode_buffer(hash, 16); +} + +String String::sha1_text() const { + CharString cs = utf8(); + unsigned char hash[20]; + CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash); + return String::hex_encode_buffer(hash, 20); } String String::sha256_text() const { CharString cs = utf8(); unsigned char hash[32]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length()); - sha256_done(&ctx, hash); + CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash); return String::hex_encode_buffer(hash, 32); } Vector<uint8_t> String::md5_buffer() const { CharString cs = utf8(); - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length()); - MD5Final(&ctx); + unsigned char hash[16]; + CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash); Vector<uint8_t> ret; ret.resize(16); for (int i = 0; i < 16; i++) { - ret.write[i] = ctx.digest[i]; - }; - + ret.write[i] = hash[i]; + } return ret; }; +Vector<uint8_t> String::sha1_buffer() const { + CharString cs = utf8(); + unsigned char hash[20]; + CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash); + + Vector<uint8_t> ret; + ret.resize(20); + for (int i = 0; i < 20; i++) { + ret.write[i] = hash[i]; + } + + return ret; +} + Vector<uint8_t> String::sha256_buffer() const { CharString cs = utf8(); unsigned char hash[32]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length()); - sha256_done(&ctx, hash); + CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash); Vector<uint8_t> ret; ret.resize(32); for (int i = 0; i < 32; i++) { ret.write[i] = hash[i]; } - return ret; } @@ -3337,7 +3338,7 @@ String String::http_unescape() const { if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) { CharType ord2 = ord_at(i + 2); if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) { - char bytes[2] = { (char)ord1, (char)ord2 }; + char bytes[3] = { (char)ord1, (char)ord2, 0 }; res += (char)strtol(bytes, NULL, 16); i += 2; } diff --git a/core/ustring.h b/core/ustring.h index a32daabb91..8a52c53238 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -305,8 +305,10 @@ public: uint32_t hash() const; /* hash the string */ uint64_t hash64() const; /* hash the string */ String md5_text() const; + String sha1_text() const; String sha256_text() const; Vector<uint8_t> md5_buffer() const; + Vector<uint8_t> sha1_buffer() const; Vector<uint8_t> sha256_buffer() const; _FORCE_INLINE_ bool empty() const { return length() == 0; } diff --git a/core/variant.cpp b/core/variant.cpp index 9306867ac7..fe9623d068 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1171,8 +1171,6 @@ Variant::operator signed int() const { return 0; } } - - return 0; } Variant::operator unsigned int() const { @@ -1188,8 +1186,6 @@ Variant::operator unsigned int() const { return 0; } } - - return 0; } Variant::operator int64_t() const { @@ -1206,8 +1202,6 @@ Variant::operator int64_t() const { return 0; } } - - return 0; } /* @@ -1244,8 +1238,6 @@ Variant::operator uint64_t() const { return 0; } } - - return 0; } #ifdef NEED_LONG_INT @@ -1300,8 +1292,6 @@ Variant::operator signed short() const { return 0; } } - - return 0; } Variant::operator unsigned short() const { @@ -1317,8 +1307,6 @@ Variant::operator unsigned short() const { return 0; } } - - return 0; } Variant::operator signed char() const { @@ -1334,8 +1322,6 @@ Variant::operator signed char() const { return 0; } } - - return 0; } Variant::operator unsigned char() const { @@ -1351,8 +1337,6 @@ Variant::operator unsigned char() const { return 0; } } - - return 0; } Variant::operator CharType() const { @@ -1374,8 +1358,6 @@ Variant::operator float() const { return 0; } } - - return 0; } Variant::operator double() const { @@ -1391,8 +1373,6 @@ Variant::operator double() const { return 0; } } - - return true; } Variant::operator StringName() const { @@ -2438,9 +2418,6 @@ Variant::Variant(const PoolVector<Face3> &p_face_array) { for (int j = 0; j < 3; j++) w[i * 3 + j] = r[i].vertex[j]; } - - r = PoolVector<Face3>::Read(); - w = PoolVector<Vector3>::Write(); } type = NIL; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index dc28f1ca02..3fdd18a630 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -33,10 +33,10 @@ #include "core/color_names.inc" #include "core/core_string_names.h" #include "core/io/compression.h" +#include "core/math/crypto_core.h" #include "core/object.h" #include "core/os/os.h" #include "core/script_language.h" -#include "thirdparty/misc/sha256.h" typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); @@ -275,8 +275,10 @@ struct _VariantCall { VCALL_LOCALMEM2(String, erase); VCALL_LOCALMEM0R(String, hash); VCALL_LOCALMEM0R(String, md5_text); + VCALL_LOCALMEM0R(String, sha1_text); VCALL_LOCALMEM0R(String, sha256_text); VCALL_LOCALMEM0R(String, md5_buffer); + VCALL_LOCALMEM0R(String, sha1_buffer); VCALL_LOCALMEM0R(String, sha256_buffer); VCALL_LOCALMEM0R(String, empty); VCALL_LOCALMEM0R(String, is_abs_path); @@ -317,7 +319,7 @@ struct _VariantCall { retval.resize(len); PoolByteArray::Write w = retval.write(); copymem(w.ptr(), charstr.ptr(), len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_ret = retval; } @@ -332,7 +334,7 @@ struct _VariantCall { retval.resize(len); PoolByteArray::Write w = retval.write(); copymem(w.ptr(), charstr.ptr(), len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_ret = retval; } @@ -598,10 +600,7 @@ struct _VariantCall { PoolByteArray::Read r = ba->read(); String s; unsigned char hash[32]; - sha256_context sha256; - sha256_init(&sha256); - sha256_hash(&sha256, (unsigned char *)r.ptr(), ba->size()); - sha256_done(&sha256, hash); + CryptoCore::sha256((unsigned char *)r.ptr(), ba->size(), hash); s = String::hex_encode_buffer(hash, 32); r_ret = s; } @@ -1542,8 +1541,10 @@ void register_variant_methods() { ADDFUNC2(STRING, NIL, String, erase, INT, "position", INT, "chars", varray()); ADDFUNC0R(STRING, INT, String, hash, varray()); ADDFUNC0R(STRING, STRING, String, md5_text, varray()); + ADDFUNC0R(STRING, STRING, String, sha1_text, varray()); ADDFUNC0R(STRING, STRING, String, sha256_text, varray()); ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, md5_buffer, varray()); + ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha1_buffer, varray()); ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha256_buffer, varray()); ADDFUNC0R(STRING, BOOL, String, empty, varray()); ADDFUNC0R(STRING, BOOL, String, is_abs_path, varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index f3c9bcaa7e..d677c7776a 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2183,7 +2183,8 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) return; } - return obj->set(p_index, p_value, r_valid); + obj->set(p_index, p_value, r_valid); + return; } } break; case DICTIONARY: { diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index d7371b0434..d5513bc2d7 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -436,8 +436,6 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings, line++; } } - - return OK; } template <class T> @@ -799,8 +797,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } } - return OK; - } else if (id == "Resource" || id == "SubResource" || id == "ExtResource") { get_token(p_stream, token, line, r_err_str); @@ -864,8 +860,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return ERR_PARSE_ERROR; } } - - return OK; #ifndef DISABLE_DEPRECATED } else if (id == "InputEvent") { @@ -1256,8 +1250,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, r_err_str = "Expected value, got " + String(tk_name[token.type]) + "."; return ERR_PARSE_ERROR; } - - return ERR_PARSE_ERROR; } Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) { @@ -1301,8 +1293,6 @@ Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, Str array.push_back(v); need_comma = true; } - - return OK; } Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) { @@ -1372,8 +1362,6 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int at_key = true; } } - - return OK; } Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, String &r_err_str, Tag &r_tag, ResourceParser *p_res_parser, bool p_simple_tag) { @@ -1557,8 +1545,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r line++; } } - - return OK; } Error VariantParser::parse(Stream *p_stream, Variant &r_ret, String &r_err_str, int &r_err_line, ResourceParser *p_res_parser) { |