diff options
Diffstat (limited to 'core')
52 files changed, 725 insertions, 264 deletions
diff --git a/core/SCsub b/core/SCsub index 166b7083e4..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) @@ -146,7 +142,7 @@ env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificat env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header)) # Make binders -env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run)) +env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc', 'method_bind_free_func.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run)) # Authors env.Depends('#core/authors.gen.h', "../AUTHORS.md") diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index f9fb7d7695..b41b84ab1e 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 */ @@ -1933,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); @@ -2114,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); @@ -2433,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; }; @@ -2455,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); @@ -2466,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; }; @@ -2486,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; }; @@ -2527,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]); @@ -2702,6 +2677,8 @@ Variant _Thread::wait_to_finish() { target_method = StringName(); target_instance = NULL; userdata = Variant(); + if (thread) + memdelete(thread); thread = NULL; return r; @@ -2964,6 +2941,10 @@ float _Engine::get_physics_jitter_fix() const { return Engine::get_singleton()->get_physics_jitter_fix(); } +float _Engine::get_physics_interpolation_fraction() const { + return Engine::get_singleton()->get_physics_interpolation_fraction(); +} + void _Engine::set_target_fps(int p_fps) { Engine::get_singleton()->set_target_fps(p_fps); } @@ -3052,6 +3033,7 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second); ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix); ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix); + ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &_Engine::get_physics_interpolation_fraction); ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps); ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 3be5a08752..f0f86e003f 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -746,6 +746,7 @@ public: void set_physics_jitter_fix(float p_threshold); float get_physics_jitter_fix() const; + float get_physics_interpolation_fraction() const; void set_target_fps(int p_fps); int get_target_fps() const; diff --git a/core/class_db.cpp b/core/class_db.cpp index 2cbf53ba0b..794d990083 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -1148,7 +1148,7 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String return Variant::NIL; } -StringName ClassDB::get_property_setter(StringName p_class, const StringName p_property) { +StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -1165,7 +1165,7 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName p_p return StringName(); } -StringName ClassDB::get_property_getter(StringName p_class, const StringName p_property) { +StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; diff --git a/core/class_db.h b/core/class_db.h index 237ae9b806..3d9a695f02 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -337,8 +337,8 @@ public: static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false); static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL); static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL); - static StringName get_property_setter(StringName p_class, const StringName p_property); - static StringName get_property_getter(StringName p_class, const StringName p_property); + static StringName get_property_setter(StringName p_class, const StringName &p_property); + static StringName get_property_getter(StringName p_class, const StringName &p_property); static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false); static void set_method_flags(StringName p_class, StringName p_method, int p_flags); diff --git a/core/engine.cpp b/core/engine.cpp index 2d8473fbd9..0dd0459403 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -227,6 +227,7 @@ Engine::Engine() { frames_drawn = 0; ips = 60; physics_jitter_fix = 0.5; + _physics_interpolation_fraction = 0.0f; _frame_delay = 0; _fps = 1; _target_fps = 0; diff --git a/core/engine.h b/core/engine.h index 15665fee29..192e8e67a0 100644 --- a/core/engine.h +++ b/core/engine.h @@ -63,6 +63,7 @@ private: float _time_scale; bool _pixel_snap; uint64_t _physics_frames; + float _physics_interpolation_fraction; uint64_t _idle_frames; bool _in_physics; @@ -95,6 +96,7 @@ public: bool is_in_physics_frame() const { return _in_physics; } uint64_t get_idle_frame_ticks() const { return _frame_ticks; } float get_idle_frame_step() const { return _frame_step; } + float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; } void set_time_scale(float p_scale); float get_time_scale() const; diff --git a/core/image.cpp b/core/image.cpp index 18a3aae88f..10778eced6 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -240,27 +240,27 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: return 4; - } break; + } case FORMAT_PVRTC2: case FORMAT_PVRTC2A: { return 4; - } break; + } case FORMAT_PVRTC4A: case FORMAT_PVRTC4: { return 4; - } break; + } case FORMAT_ETC: { return 4; - } break; + } case FORMAT_BPTC_RGBA: case FORMAT_BPTC_RGBF: case FORMAT_BPTC_RGBFU: { return 4; - } break; + } case FORMAT_ETC2_R11: //etc2 case FORMAT_ETC2_R11S: //signed: NOT srgb. case FORMAT_ETC2_RG11: @@ -270,7 +270,7 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_ETC2_RGB8A1: { return 4; - } break; + } default: { } } @@ -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; @@ -852,7 +852,7 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, float p_alpha, uint32_t p_width, uint32_t p_height, uint32_t p_pixel_size) { - uint16_t alpha = CLAMP((uint16_t)(p_alpha * 256.0f), 0, 256); + uint16_t alpha = MIN((uint16_t)(p_alpha * 256.0f), 256); for (uint32_t i = 0; i < p_width * p_height * p_pixel_size; i++) { @@ -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); @@ -2394,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 { @@ -2421,38 +2421,36 @@ Color Image::get_pixel(int p_x, int p_y) const { case FORMAT_L8: { float l = ptr[ofs] / 255.0; return Color(l, l, l, 1); - } break; + } case FORMAT_LA8: { float l = ptr[ofs * 2 + 0] / 255.0; float a = ptr[ofs * 2 + 1] / 255.0; return Color(l, l, l, a); - } break; + } case FORMAT_R8: { float r = ptr[ofs] / 255.0; return Color(r, 0, 0, 1); - } break; + } case FORMAT_RG8: { float r = ptr[ofs * 2 + 0] / 255.0; float g = ptr[ofs * 2 + 1] / 255.0; return Color(r, g, 0, 1); - } break; + } case FORMAT_RGB8: { float r = ptr[ofs * 3 + 0] / 255.0; float g = ptr[ofs * 3 + 1] / 255.0; float b = ptr[ofs * 3 + 2] / 255.0; return Color(r, g, b, 1); - - } break; + } case FORMAT_RGBA8: { float r = ptr[ofs * 4 + 0] / 255.0; float g = ptr[ofs * 4 + 1] / 255.0; float b = ptr[ofs * 4 + 2] / 255.0; float a = ptr[ofs * 4 + 3] / 255.0; return Color(r, g, b, a); - - } break; + } case FORMAT_RGBA4444: { uint16_t u = ((uint16_t *)ptr)[ofs]; float r = (u & 0xF) / 15.0; @@ -2460,8 +2458,7 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((u >> 8) & 0xF) / 15.0; float a = ((u >> 12) & 0xF) / 15.0; return Color(r, g, b, a); - - } break; + } case FORMAT_RGBA5551: { uint16_t u = ((uint16_t *)ptr)[ofs]; @@ -2470,25 +2467,25 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((u >> 10) & 0x1F) / 15.0; float a = ((u >> 15) & 0x1) / 1.0; return Color(r, g, b, a); - } break; + } case FORMAT_RF: { float r = ((float *)ptr)[ofs]; return Color(r, 0, 0, 1); - } break; + } case FORMAT_RGF: { float r = ((float *)ptr)[ofs * 2 + 0]; float g = ((float *)ptr)[ofs * 2 + 1]; return Color(r, g, 0, 1); - } break; + } case FORMAT_RGBF: { float r = ((float *)ptr)[ofs * 3 + 0]; float g = ((float *)ptr)[ofs * 3 + 1]; float b = ((float *)ptr)[ofs * 3 + 2]; return Color(r, g, b, 1); - } break; + } case FORMAT_RGBAF: { float r = ((float *)ptr)[ofs * 4 + 0]; @@ -2496,25 +2493,25 @@ Color Image::get_pixel(int p_x, int p_y) const { float b = ((float *)ptr)[ofs * 4 + 2]; float a = ((float *)ptr)[ofs * 4 + 3]; return Color(r, g, b, a); - } break; + } case FORMAT_RH: { uint16_t r = ((uint16_t *)ptr)[ofs]; return Color(Math::half_to_float(r), 0, 0, 1); - } break; + } case FORMAT_RGH: { uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0]; uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1]; return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1); - } break; + } case FORMAT_RGBH: { uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0]; uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1]; uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2]; return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1); - } break; + } case FORMAT_RGBAH: { uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0]; @@ -2522,18 +2519,15 @@ Color Image::get_pixel(int p_x, int p_y) const { uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2]; uint16_t a = ((uint16_t *)ptr)[ofs * 4 + 3]; return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a)); - } break; + } case FORMAT_RGBE9995: { return Color::from_rgbe9995(((uint32_t *)ptr)[ofs]); - - } break; + } default: { ERR_EXPLAIN("Can't get_pixel() on compressed image, sorry."); ERR_FAIL_V(Color()); } } - - return Color(); } void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) { diff --git a/core/input_map.cpp b/core/input_map.cpp index 04911787a8..165999f081 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -202,7 +202,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str if (p_pressed != NULL) *p_pressed = input_event_action->is_pressed(); if (p_strength != NULL) - *p_strength = (*p_pressed) ? input_event_action->get_strength() : 0.0f; + *p_strength = (p_pressed != NULL && *p_pressed) ? input_event_action->get_strength() : 0.0f; return input_event_action->get_action() == p_action; } 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/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/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 688dfc21e5..38bef2768e 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; @@ -712,8 +712,8 @@ Error ResourceInteractiveLoaderBinary::poll() { if (!obj) { error = ERR_FILE_CORRUPT; ERR_EXPLAIN(local_path + ":Resource of unrecognized type in file: " + t); + ERR_FAIL_V(ERR_FILE_CORRUPT); } - ERR_FAIL_COND_V(!obj, ERR_FILE_CORRUPT); Resource *r = Object::cast_to<Resource>(obj); if (!r) { diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 0cecca904d..e2c1c3402a 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -137,7 +137,6 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t save_callback(p_resource, p_path); return OK; - } else { } } diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 6ad24a5f3a..84b8554d54 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); @@ -369,7 +369,9 @@ Variant StreamPeer::get_var(bool p_allow_objects) { ERR_FAIL_COND_V(err != OK, Variant()); Variant ret; - decode_variant(ret, var.ptr(), len, NULL, p_allow_objects); + err = decode_variant(ret, var.ptr(), len, NULL, p_allow_objects); + ERR_FAIL_COND_V(err != OK, Variant()); + return ret; } 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/make_binders.py b/core/make_binders.py index 5c1c66cab6..24901c42a1 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -191,6 +191,96 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$ """ +template_typed_free_func = """ +#ifdef TYPED_METHOD_BIND +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +class FunctionBind$argc$$ifret R$$ifconst C$ : public MethodBind { +public: + + $ifret R$ $ifnoret void$ (*method) ($ifconst const$ T *$ifargs , $$arg, P@$); +#ifdef DEBUG_METHODS_ENABLED + virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } + virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { + $ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$ + $arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA; + $ + return GodotTypeInfo::METADATA_NONE; + } + Variant::Type _get_argument_type(int p_argument) const { + $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$ + $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE; + $ + return Variant::NIL; + } + virtual PropertyInfo _gen_argument_type_info(int p_argument) const { + $ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$ + $arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info(); + $ + return PropertyInfo(); + } +#endif + virtual String get_instance_class() const { + return T::get_class_static(); + } + + virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) { + + T *instance=Object::cast_to<T>(p_object); + r_error.error=Variant::CallError::CALL_OK; +#ifdef DEBUG_METHODS_ENABLED + + ERR_FAIL_COND_V(!instance,Variant()); + if (p_arg_count>get_argument_count()) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=get_argument_count(); + return Variant(); + + } + if (p_arg_count<(get_argument_count()-get_default_argument_count())) { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=get_argument_count()-get_default_argument_count(); + return Variant(); + } + $arg CHECK_ARG(@); + $ +#endif + $ifret Variant ret = $(method)(instance$ifargs , $$arg, _VC(@)$); + $ifret return Variant(ret);$ + $ifnoret return Variant();$ + } + +#ifdef PTRCALL_ENABLED + virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) { + + T *instance=Object::cast_to<T>(p_object); + $ifret PtrToArg<R>::encode( $ (method)(instance$ifargs , $$arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret)$ ; + } +#endif + FunctionBind$argc$$ifret R$$ifconst C$ () { +#ifdef DEBUG_METHODS_ENABLED + _set_const($ifconst true$$ifnoconst false$); + _generate_argument_types($argc$); +#else + set_argument_count($argc$); +#endif + + $ifret _set_returns(true); $ + }; +}; + +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +MethodBind* create_method_bind($ifret R$ $ifnoret void$ (*p_method)($ifconst const$ T *$ifargs , $$arg, P@$) ) { + + FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) ); + a->method=p_method; + return a; +} +#endif +""" + + + def make_version(template, nargs, argmax, const, ret): intext = template @@ -259,6 +349,9 @@ def run(target, source, env): versions_ext = 6 text = "" text_ext = "" + text_free_func = "#ifndef METHOD_BIND_FREE_FUNC_H\n#define METHOD_BIND_FREE_FUNC_H\n" + text_free_func += "\n//including this header file allows method binding to use free functions\n" + text_free_func += "//note that the free function must have a pointer to an instance of the class as its first parameter\n" for i in range(0, versions + 1): @@ -276,12 +369,22 @@ def run(target, source, env): else: text += t + text_free_func += make_version(template_typed_free_func, i, versions, False, False) + text_free_func += make_version(template_typed_free_func, i, versions, False, True) + text_free_func += make_version(template_typed_free_func, i, versions, True, False) + text_free_func += make_version(template_typed_free_func, i, versions, True, True) + + text_free_func += "#endif" + with open(target[0], "w") as f: f.write(text) with open(target[1], "w") as f: f.write(text_ext) + with open(target[2], "w") as f: + f.write(text_free_func) + if __name__ == '__main__': from platform_methods import subprocess_main 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/basis.cpp b/core/math/basis.cpp index 1540bc8fe1..400f342018 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -852,7 +852,7 @@ void Basis::set_quat_scale(const Quat &p_quat, const Vector3 &p_scale) { rotate(p_quat); } -void Basis::set_diagonal(const Vector3 p_diag) { +void Basis::set_diagonal(const Vector3 &p_diag) { elements[0][0] = p_diag.x; elements[0][1] = 0; elements[0][2] = 0; diff --git a/core/math/basis.h b/core/math/basis.h index 75037c2c52..d3adad3d90 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -153,7 +153,7 @@ public: int get_orthogonal_index() const; void set_orthogonal_index(int p_index); - void set_diagonal(const Vector3 p_diag); + void set_diagonal(const Vector3 &p_diag); bool is_orthogonal() const; bool is_diagonal() const; diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index a12f9fee2e..cfa698282e 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -192,7 +192,7 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons #ifdef DEBUG_ENABLED int plane_count = planes.size(); uint16_t plane = nodesptr[idx].plane; - ERR_FAIL_INDEX_V(plane, plane_count, false); + ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false); #endif idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under; @@ -258,7 +258,7 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const { #ifdef DEBUG_ENABLED int plane_count = planes.size(); uint16_t plane = nodesptr[idx].plane; - ERR_FAIL_INDEX_V(plane, plane_count, false); + ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false); #endif bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point); 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/expression.cpp b/core/math/expression.cpp index b52658e2cf..25a40c70bf 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -52,6 +52,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = { "sqrt", "fmod", "fposmod", + "posmod", "floor", "ceil", "round", @@ -175,6 +176,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) { case MATH_ATAN2: case MATH_FMOD: case MATH_FPOSMOD: + case MATH_POSMOD: case MATH_POW: case MATH_EASE: case MATH_STEPIFY: @@ -283,6 +285,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant VALIDATE_ARG_NUM(1); *r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]); } break; + case MATH_POSMOD: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]); + } break; case MATH_FLOOR: { VALIDATE_ARG_NUM(0); @@ -793,17 +801,13 @@ Error Expression::_get_token(Token &r_token) { #define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) CharType cchar = GET_CHAR(); - if (cchar == 0) { - r_token.type = TK_EOF; - return OK; - } switch (cchar) { case 0: { r_token.type = TK_EOF; return OK; - } break; + }; case '{': { r_token.type = TK_CURLY_BRACKET_OPEN; diff --git a/core/math/expression.h b/core/math/expression.h index 1113bb6587..03a2bb70e6 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -51,6 +51,7 @@ public: MATH_SQRT, MATH_FMOD, MATH_FPOSMOD, + MATH_POSMOD, MATH_FLOOR, MATH_CEIL, MATH_ROUND, 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.h b/core/math/math_funcs.h index 0e3bd8a318..b6398712e4 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -198,6 +198,13 @@ public: value += 0.0; return value; } + static _ALWAYS_INLINE_ int posmod(int p_x, int p_y) { + int value = p_x % p_y; + if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) { + value += p_y; + } + return value; + } static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; } static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; } 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/math/vector3.h b/core/math/vector3.h index 811a207138..45bdfee487 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -219,10 +219,6 @@ Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const { } Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(!is_normalized(), Vector3()); -#endif - real_t theta = angle_to(p_b); return rotated(cross(p_b).normalized(), theta * p_t); } diff --git a/core/object.cpp b/core/object.cpp index 3367d6b6c3..67ab27c190 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -635,9 +635,12 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons #endif p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT)); } - if (!metadata.empty()) { - p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); - } + +#ifdef TOOLS_ENABLED + p_list->push_back(PropertyInfo(Variant::NIL, "Metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); +#endif + p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT)); + if (script_instance && !p_reversed) { p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); diff --git a/core/object.h b/core/object.h index 1e0b22c086..e6c5b7c5b9 100644 --- a/core/object.h +++ b/core/object.h @@ -179,6 +179,15 @@ struct PropertyInfo { usage(PROPERTY_USAGE_DEFAULT) { } + bool operator==(const PropertyInfo &p_info) const { + return ((type == p_info.type) && + (name == p_info.name) && + (class_name == p_info.class_name) && + (hint == p_info.hint) && + (hint_string == p_info.hint_string) && + (usage == p_info.usage)); + } + bool operator<(const PropertyInfo &p_info) const { return name < p_info.name; } 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/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/pool_allocator.cpp b/core/pool_allocator.cpp index 094352b5cc..9b342ef913 100644 --- a/core/pool_allocator.cpp +++ b/core/pool_allocator.cpp @@ -611,7 +611,7 @@ PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_ PoolAllocator::PoolAllocator(int p_align, int p_size, bool p_needs_locking, int p_max_entries) { ERR_FAIL_COND(p_align < 1); - mem_ptr = Memory::alloc_static(p_size + p_align, "PoolAllocator()"); + mem_ptr = Memory::alloc_static(p_size + p_align, true); uint8_t *mem8 = (uint8_t *)mem_ptr; uint64_t ofs = (uint64_t)mem8; if (ofs % p_align) diff --git a/core/pool_vector.h b/core/pool_vector.h index 338de966f6..3d28d86803 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 { @@ -454,7 +458,7 @@ public: bool is_locked() const { return alloc && alloc->lock > 0; } - inline const T operator[](int p_index) const; + inline T operator[](int p_index) const; Error resize(int p_size); @@ -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; @@ -500,7 +502,7 @@ void PoolVector<T>::push_back(const T &p_val) { } template <class T> -const T PoolVector<T>::operator[](int p_index) const { +T PoolVector<T>::operator[](int p_index) const { CRASH_BAD_INDEX(p_index, size()); diff --git a/core/project_settings.cpp b/core/project_settings.cpp index fc1a74801d..c1d4967f55 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"); @@ -475,7 +487,7 @@ void ProjectSettings::set_registering_order(bool p_enable) { registering_order = p_enable; } -Error ProjectSettings::_load_settings_binary(const String p_path) { +Error ProjectSettings::_load_settings_binary(const String &p_path) { Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -518,7 +530,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) { return OK; } -Error ProjectSettings::_load_settings_text(const String p_path) { +Error ProjectSettings::_load_settings_text(const String &p_path) { Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -581,7 +593,7 @@ Error ProjectSettings::_load_settings_text(const String p_path) { } } -Error ProjectSettings::_load_settings_text_or_binary(const String p_text_path, const String p_bin_path) { +Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path) { // Attempt first to load the text-based project.godot file Error err_text = _load_settings_text(p_text_path); diff --git a/core/project_settings.h b/core/project_settings.h index 0ff18ab3f5..d7651417d5 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -97,9 +97,9 @@ protected: static ProjectSettings *singleton; - Error _load_settings_text(const String p_path); - Error _load_settings_binary(const String p_path); - Error _load_settings_text_or_binary(const String p_text_path, const String p_bin_path); + Error _load_settings_text(const String &p_path); + Error _load_settings_binary(const String &p_path); + Error _load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path); Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); 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 af863dd385..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")); } 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/string_name.cpp b/core/string_name.cpp index 10b71ad3ac..b1a8bfb849 100644 --- a/core/string_name.cpp +++ b/core/string_name.cpp @@ -205,7 +205,6 @@ StringName::StringName(const char *p_name) { // exists lock->unlock(); return; - } else { } } @@ -253,7 +252,6 @@ StringName::StringName(const StaticCString &p_static_string) { // exists lock->unlock(); return; - } else { } } @@ -301,7 +299,6 @@ StringName::StringName(const String &p_name) { // exists lock->unlock(); return; - } else { } } diff --git a/core/ustring.cpp b/core/ustring.cpp index 18c48b4dad..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 @@ -780,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()) { @@ -2254,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; } @@ -3331,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 5b51a4e513..1574af5239 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1834,8 +1834,6 @@ inline DA _convert_array_from_variant(const Variant &p_variant) { return DA(); } } - - return DA(); } Variant::operator Array() const { @@ -2299,7 +2297,7 @@ Variant::Variant(const Object *p_object) { Variant::Variant(const Dictionary &p_dictionary) { type = DICTIONARY; - memnew_placement(_data._mem, (Dictionary)(p_dictionary)); + memnew_placement(_data._mem, Dictionary(p_dictionary)); } Variant::Variant(const Array &p_array) { @@ -2418,9 +2416,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..b637e745af 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); @@ -70,7 +70,7 @@ struct _VariantCall { for (int i = 0; i < arg_count; i++) { - if (!tptr[i] || tptr[i] == p_args[i]->type) + if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type) continue; // all good if (!Variant::can_convert(p_args[i]->type, tptr[i])) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; @@ -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 d677c7776a..ea9e29e744 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2613,7 +2613,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const { if (r_valid) { *r_valid = false; } - return "Attempted get on stray pointer."; + return true; // Attempted get on stray pointer. } } #endif diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index d5513bc2d7..07212ec669 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1537,8 +1537,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r Token token; get_token(p_stream, token, line, r_err_str); Error err = parse_value(token, r_value, p_stream, line, r_err_str, p_res_parser); - if (err) { - } return err; } } else if (c == '\n') { |