summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub1
-rw-r--r--core/bind/core_bind.cpp2
-rw-r--r--core/crypto/SCsub38
-rw-r--r--core/crypto/crypto.cpp170
-rw-r--r--core/crypto/crypto.h105
-rw-r--r--core/crypto/crypto_core.cpp (renamed from core/math/crypto_core.cpp)32
-rw-r--r--core/crypto/crypto_core.h (renamed from core/math/crypto_core.h)20
-rw-r--r--core/crypto/hashing_context.cpp137
-rw-r--r--core/crypto/hashing_context.h66
-rw-r--r--core/io/config_file.cpp2
-rw-r--r--core/io/file_access_encrypted.cpp2
-rw-r--r--core/io/file_access_pack.cpp6
-rw-r--r--core/io/stream_peer_ssl.cpp68
-rw-r--r--core/io/stream_peer_ssl.h13
-rw-r--r--core/math/SCsub33
-rw-r--r--core/math/a_star.cpp239
-rw-r--r--core/math/a_star.h26
-rw-r--r--core/math/delaunay.h4
-rw-r--r--core/oa_hash_map.h34
-rw-r--r--core/object.cpp11
-rw-r--r--core/object.h2
-rw-r--r--core/os/file_access.cpp2
-rw-r--r--core/register_core_types.cpp24
-rw-r--r--core/ustring.cpp2
-rw-r--r--core/variant_call.cpp10
25 files changed, 807 insertions, 242 deletions
diff --git a/core/SCsub b/core/SCsub
index 85e5f1b089..ed9a0a231d 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -159,6 +159,7 @@ env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]
# Chain load SCsubs
SConscript('os/SCsub')
SConscript('math/SCsub')
+SConscript('crypto/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 56369a3cc6..8e0d156438 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -30,11 +30,11 @@
#include "core_bind.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/file_access_compressed.h"
#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"
diff --git a/core/crypto/SCsub b/core/crypto/SCsub
new file mode 100644
index 0000000000..0a3f05d87a
--- /dev/null
+++ b/core/crypto/SCsub
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env_crypto = env.Clone()
+
+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_crypto.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_crypto.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_crypto.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
new file mode 100644
index 0000000000..925a01b36a
--- /dev/null
+++ b/core/crypto/crypto.cpp
@@ -0,0 +1,170 @@
+/*************************************************************************/
+/* crypto.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.h"
+
+#include "core/engine.h"
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
+
+/// Resources
+
+CryptoKey *(*CryptoKey::_create)() = NULL;
+CryptoKey *CryptoKey::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void CryptoKey::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
+}
+
+X509Certificate *(*X509Certificate::_create)() = NULL;
+X509Certificate *X509Certificate::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void X509Certificate::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
+}
+
+/// Crypto
+
+void (*Crypto::_load_default_certificates)(String p_path) = NULL;
+Crypto *(*Crypto::_create)() = NULL;
+Crypto *Crypto::create() {
+ if (_create)
+ return _create();
+ return memnew(Crypto);
+}
+
+void Crypto::load_default_certificates(String p_path) {
+
+ if (_load_default_certificates)
+ _load_default_certificates(p_path);
+}
+
+void Crypto::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
+ ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa);
+ ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
+}
+
+PoolByteArray Crypto::generate_random_bytes(int p_bytes) {
+ ERR_FAIL_V_MSG(PoolByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
+}
+
+Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) {
+ ERR_FAIL_V_MSG(NULL, "generate_rsa is not available when mbedtls module is disabled.");
+}
+
+Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
+ ERR_FAIL_V_MSG(NULL, "generate_self_signed_certificate is not available when mbedtls module is disabled.");
+}
+
+Crypto::Crypto() {
+}
+
+/// Resource loader/saver
+
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "crt") {
+ X509Certificate *cert = X509Certificate::create();
+ if (cert)
+ cert->load(p_path);
+ return cert;
+ } else if (el == "key") {
+ CryptoKey *key = CryptoKey::create();
+ if (key)
+ key->load(p_path);
+ return key;
+ }
+ return NULL;
+}
+
+void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("crt");
+ p_extensions->push_back("key");
+}
+
+bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
+
+ return p_type == "X509Certificate" || p_type == "CryptoKey";
+}
+
+String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "crt")
+ return "X509Certificate";
+ else if (el == "key")
+ return "CryptoKey";
+ return "";
+}
+
+Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+
+ Error err;
+ Ref<X509Certificate> cert = p_resource;
+ Ref<CryptoKey> key = p_resource;
+ if (cert.is_valid()) {
+ err = cert->save(p_path);
+ } else if (key.is_valid()) {
+ err = key->save(p_path);
+ } else {
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ }
+ ERR_FAIL_COND_V(err != OK, err);
+ return OK;
+}
+
+void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+
+ const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
+ const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
+ if (cert) {
+ p_extensions->push_back("crt");
+ }
+ if (key) {
+ p_extensions->push_back("key");
+ }
+}
+bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
+
+ return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
+}
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
new file mode 100644
index 0000000000..2de81f5b57
--- /dev/null
+++ b/core/crypto/crypto.h
@@ -0,0 +1,105 @@
+/*************************************************************************/
+/* crypto.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_H
+#define CRYPTO_H
+
+#include "core/reference.h"
+#include "core/resource.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+
+class CryptoKey : public Resource {
+ GDCLASS(CryptoKey, Resource);
+
+protected:
+ static void _bind_methods();
+ static CryptoKey *(*_create)();
+
+public:
+ static CryptoKey *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class X509Certificate : public Resource {
+ GDCLASS(X509Certificate, Resource);
+
+protected:
+ static void _bind_methods();
+ static X509Certificate *(*_create)();
+
+public:
+ static X509Certificate *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class Crypto : public Reference {
+ GDCLASS(Crypto, Reference);
+
+protected:
+ static void _bind_methods();
+ static Crypto *(*_create)();
+ static void (*_load_default_certificates)(String p_path);
+
+public:
+ static Crypto *create();
+ static void load_default_certificates(String p_path);
+
+ virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual Ref<CryptoKey> generate_rsa(int p_bytes);
+ virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
+
+ Crypto();
+};
+
+class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
+
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverCrypto : public ResourceFormatSaver {
+ GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
+
+public:
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+ virtual bool recognize(const RES &p_resource) const;
+};
+
+#endif // CRYPTO_H
diff --git a/core/math/crypto_core.cpp b/core/crypto/crypto_core.cpp
index d7ba54e469..51c2e3c9e5 100644
--- a/core/math/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -52,7 +52,7 @@ Error CryptoCore::MD5Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::MD5Context::update(const 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;
}
@@ -62,6 +62,32 @@ Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
return ret ? FAILED : OK;
}
+// SHA1
+CryptoCore::SHA1Context::SHA1Context() {
+ ctx = memalloc(sizeof(mbedtls_sha1_context));
+ mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
+}
+
+CryptoCore::SHA1Context::~SHA1Context() {
+ mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
+ memfree((mbedtls_sha1_context *)ctx);
+}
+
+Error CryptoCore::SHA1Context::start() {
+ int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
+ int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
+ int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
+ return ret ? FAILED : OK;
+}
+
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
@@ -78,12 +104,12 @@ Error CryptoCore::SHA256Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::SHA256Context::update(const 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]) {
+Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
diff --git a/core/math/crypto_core.h b/core/crypto/crypto_core.h
index e28cb5a792..c859d612d4 100644
--- a/core/math/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -46,10 +46,24 @@ public:
~MD5Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
+ Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
+ class SHA1Context {
+
+ private:
+ void *ctx; // To include, or not to include...
+
+ public:
+ SHA1Context();
+ ~SHA1Context();
+
+ Error start();
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[20]);
+ };
+
class SHA256Context {
private:
@@ -60,8 +74,8 @@ public:
~SHA256Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
- Error finish(unsigned char r_hash[16]);
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[32]);
};
class AESContext {
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
new file mode 100644
index 0000000000..bdccb258dd
--- /dev/null
+++ b/core/crypto/hashing_context.cpp
@@ -0,0 +1,137 @@
+/*************************************************************************/
+/* hashing_context.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 "hashing_context.h"
+
+#include "core/crypto/crypto_core.h"
+
+Error HashingContext::start(HashType p_type) {
+ ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
+ _create_ctx(p_type);
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNAVAILABLE);
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->start();
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->start();
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->start();
+ }
+ return ERR_UNAVAILABLE;
+}
+
+Error HashingContext::update(PoolByteArray p_chunk) {
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
+ size_t len = p_chunk.size();
+ PoolByteArray::Read r = p_chunk.read();
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
+ }
+ return ERR_UNAVAILABLE;
+}
+
+PoolByteArray HashingContext::finish() {
+ ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
+ PoolByteArray out;
+ Error err = FAILED;
+ switch (type) {
+ case HASH_MD5:
+ out.resize(16);
+ err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA1:
+ out.resize(20);
+ err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA256:
+ out.resize(32);
+ err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
+ break;
+ }
+ _delete_ctx();
+ ERR_FAIL_COND_V(err != OK, PoolByteArray());
+ return out;
+}
+
+void HashingContext::_create_ctx(HashType p_type) {
+ type = p_type;
+ switch (type) {
+ case HASH_MD5:
+ ctx = memnew(CryptoCore::MD5Context);
+ break;
+ case HASH_SHA1:
+ ctx = memnew(CryptoCore::SHA1Context);
+ break;
+ case HASH_SHA256:
+ ctx = memnew(CryptoCore::SHA256Context);
+ break;
+ default:
+ ctx = NULL;
+ }
+}
+
+void HashingContext::_delete_ctx() {
+ return;
+ switch (type) {
+ case HASH_MD5:
+ memdelete((CryptoCore::MD5Context *)ctx);
+ break;
+ case HASH_SHA1:
+ memdelete((CryptoCore::SHA1Context *)ctx);
+ break;
+ case HASH_SHA256:
+ memdelete((CryptoCore::SHA256Context *)ctx);
+ break;
+ }
+ ctx = NULL;
+}
+
+void HashingContext::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
+ ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
+ ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
+ BIND_ENUM_CONSTANT(HASH_MD5);
+ BIND_ENUM_CONSTANT(HASH_SHA1);
+ BIND_ENUM_CONSTANT(HASH_SHA256);
+}
+
+HashingContext::HashingContext() {
+ ctx = NULL;
+}
+
+HashingContext::~HashingContext() {
+ if (ctx != NULL)
+ _delete_ctx();
+}
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
new file mode 100644
index 0000000000..aa69636f2c
--- /dev/null
+++ b/core/crypto/hashing_context.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* hashing_context.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 HASHING_CONTEXT_H
+#define HASHING_CONTEXT_H
+
+#include "core/reference.h"
+
+class HashingContext : public Reference {
+ GDCLASS(HashingContext, Reference);
+
+public:
+ enum HashType {
+ HASH_MD5,
+ HASH_SHA1,
+ HASH_SHA256
+ };
+
+private:
+ void *ctx;
+ HashType type;
+
+protected:
+ static void _bind_methods();
+ void _create_ctx(HashType p_type);
+ void _delete_ctx();
+
+public:
+ Error start(HashType p_type);
+ Error update(PoolByteArray p_chunk);
+ PoolByteArray finish();
+
+ HashingContext();
+ ~HashingContext();
+};
+
+VARIANT_ENUM_CAST(HashingContext::HashType);
+
+#endif // HASHING_CONTEXT_H
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 70bb816acd..9063e028be 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -201,7 +201,7 @@ Error ConfigFile::load(const String &p_path) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f)
- return ERR_CANT_OPEN;
+ return err;
return _internal_load(p_path, f);
}
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 1452c61d1a..77decc107d 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -30,7 +30,7 @@
#include "file_access_encrypted.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/os/copymem.h"
#include "core/print_string.h"
#include "core/variant.h"
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 6b683759f8..d49d36c2b9 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -90,7 +90,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
}
String filename = path.get_file();
- // Don't add as a file if the path points to a directoryy
+ // Don't add as a file if the path points to a directory
if (!filename.empty()) {
cd->files.insert(filename);
}
@@ -460,11 +460,15 @@ String DirAccessPack::get_current_dir() {
bool DirAccessPack::file_exists(String p_file) {
+ p_file = fix_path(p_file);
+
return current->files.has(p_file);
}
bool DirAccessPack::dir_exists(String p_dir) {
+ p_dir = fix_path(p_dir);
+
return current->subdirs.has(p_dir);
}
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index ccce48ccd7..f2eaf57acc 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -30,10 +30,7 @@
#include "stream_peer_ssl.h"
-#include "core/io/certs_compressed.gen.h"
-#include "core/io/compression.h"
-#include "core/os/file_access.h"
-#include "core/project_settings.h"
+#include "core/engine.h"
StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL;
@@ -44,22 +41,8 @@ StreamPeerSSL *StreamPeerSSL::create() {
return NULL;
}
-StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
-void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
- if (load_certs_func)
- load_certs_func(p_memory);
-}
-
-void StreamPeerSSL::load_certs_from_file(String p_path) {
- if (p_path != "") {
- PoolByteArray certs = get_cert_file_as_array(p_path);
- if (certs.size() > 0)
- load_certs_func(certs);
- }
-}
-
bool StreamPeerSSL::is_available() {
return available;
}
@@ -72,56 +55,11 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake;
}
-PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
-
- PoolByteArray out;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (f) {
- int flen = f->get_len();
- out.resize(flen + 1);
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; // Make sure it ends with string terminator
- memdelete(f);
-#ifdef DEBUG_ENABLED
- print_verbose(vformat("Loaded certs from '%s'.", p_path));
-#endif
- }
-
- return out;
-}
-
-PoolByteArray StreamPeerSSL::get_project_cert_array() {
-
- PoolByteArray out;
- String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
-
- if (certs_path != "") {
- // Use certs defined in project settings.
- return get_cert_file_as_array(certs_path);
- }
-#ifdef BUILTIN_CERTS_ENABLED
- else {
- // Use builtin certs only if user did not override it in project settings.
- out.resize(_certs_uncompressed_size + 1);
- PoolByteArray::Write w = out.write();
- Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
- w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
-#ifdef DEBUG_ENABLED
- print_verbose("Loaded builtin certs");
-#endif
- }
-#endif
-
- return out;
-}
-
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream", "base"), &StreamPeerSSL::accept_stream);
- ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("accept_stream", "stream", "private_key", "certificate", "chain"), &StreamPeerSSL::accept_stream, DEFVAL(Ref<X509Certificate>()));
+ ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname", "valid_certificate"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
ClassDB::bind_method(D_METHOD("set_blocking_handshake_enabled", "enabled"), &StreamPeerSSL::set_blocking_handshake_enabled);
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 482576c4c6..dedc35b9ac 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -31,19 +31,16 @@
#ifndef STREAM_PEER_SSL_H
#define STREAM_PEER_SSL_H
+#include "core/crypto/crypto.h"
#include "core/io/stream_peer.h"
class StreamPeerSSL : public StreamPeer {
GDCLASS(StreamPeerSSL, StreamPeer);
-public:
- typedef void (*LoadCertsFromMemory)(const PoolByteArray &p_certs);
-
protected:
static StreamPeerSSL *(*_create)();
static void _bind_methods();
- static LoadCertsFromMemory load_certs_func;
static bool available;
bool blocking_handshake;
@@ -61,18 +58,14 @@ public:
bool is_blocking_handshake_enabled() const;
virtual void poll() = 0;
- virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
- virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
+ virtual Error accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
+ virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref<X509Certificate> p_valid_cert = Ref<X509Certificate>()) = 0;
virtual Status get_status() const = 0;
virtual void disconnect_from_stream() = 0;
static StreamPeerSSL *create();
- static PoolByteArray get_cert_file_as_array(String p_path);
- static PoolByteArray get_project_cert_array();
- static void load_certs_from_file(String p_path);
- static void load_certs_from_memory(const PoolByteArray &p_memory);
static bool is_available();
StreamPeerSSL();
diff --git a/core/math/SCsub b/core/math/SCsub
index 0995298a4b..be438fcfbe 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -2,37 +2,6 @@
Import('env')
-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 = env.Clone()
env_math.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index b61119d8df..aea42a1edf 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -40,7 +40,17 @@ int AStar::get_available_point_id() const {
return 1;
}
- return points.back()->key() + 1;
+ // calculate our new next available point id if bigger than before or next id already contained in set of points.
+ if (points.has(last_free_id)) {
+ int cur_new_id = last_free_id;
+ while (points.has(cur_new_id)) {
+ cur_new_id++;
+ }
+ int &non_const = const_cast<int &>(last_free_id);
+ non_const = cur_new_id;
+ }
+
+ return last_free_id;
}
void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
@@ -48,7 +58,10 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
ERR_FAIL_COND(p_id < 0);
ERR_FAIL_COND(p_weight_scale < 1);
- if (!points.has(p_id)) {
+ Point *found_pt;
+ bool p_exists = points.lookup(p_id, found_pt);
+
+ if (!p_exists) {
Point *pt = memnew(Point);
pt->id = p_id;
pt->pos = p_pos;
@@ -57,84 +70,98 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
pt->open_pass = 0;
pt->closed_pass = 0;
pt->enabled = true;
- points[p_id] = pt;
+ points.set(p_id, pt);
} else {
- points[p_id]->pos = p_pos;
- points[p_id]->weight_scale = p_weight_scale;
+ found_pt->pos = p_pos;
+ found_pt->weight_scale = p_weight_scale;
}
}
Vector3 AStar::get_point_position(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), Vector3());
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, Vector3());
- return points[p_id]->pos;
+ return p->pos;
}
void AStar::set_point_position(int p_id, const Vector3 &p_pos) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- points[p_id]->pos = p_pos;
+ p->pos = p_pos;
}
real_t AStar::get_point_weight_scale(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), 0);
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, 0);
- return points[p_id]->weight_scale;
+ return p->weight_scale;
}
void AStar::set_point_weight_scale(int p_id, real_t p_weight_scale) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
ERR_FAIL_COND(p_weight_scale < 1);
- points[p_id]->weight_scale = p_weight_scale;
+ p->weight_scale = p_weight_scale;
}
void AStar::remove_point(int p_id) {
- ERR_FAIL_COND(!points.has(p_id));
-
- Point *p = points[p_id];
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
- Segment s(p_id, E->get()->id);
+ Segment s(p_id, (*it.key));
segments.erase(s);
- E->get()->neighbours.erase(p);
- E->get()->unlinked_neighbours.erase(p);
+ (*it.value)->neighbours.remove(p->id);
+ (*it.value)->unlinked_neighbours.remove(p->id);
}
- for (Set<Point *>::Element *E = p->unlinked_neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) {
- Segment s(p_id, E->get()->id);
+ Segment s(p_id, (*it.key));
segments.erase(s);
- E->get()->neighbours.erase(p);
- E->get()->unlinked_neighbours.erase(p);
+ (*it.value)->neighbours.remove(p->id);
+ (*it.value)->unlinked_neighbours.remove(p->id);
}
memdelete(p);
- points.erase(p_id);
+ points.remove(p_id);
+ last_free_id = p_id;
}
void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
- ERR_FAIL_COND(!points.has(p_id));
- ERR_FAIL_COND(!points.has(p_with_id));
ERR_FAIL_COND(p_id == p_with_id);
- Point *a = points[p_id];
- Point *b = points[p_with_id];
- a->neighbours.insert(b);
+ Point *a;
+ bool from_exists = points.lookup(p_id, a);
+ ERR_FAIL_COND(!from_exists);
- if (bidirectional)
- b->neighbours.insert(a);
- else
- b->unlinked_neighbours.insert(a);
+ Point *b;
+ bool to_exists = points.lookup(p_with_id, b);
+ ERR_FAIL_COND(!to_exists);
+
+ a->neighbours.set(b->id, b);
+
+ if (bidirectional) {
+ b->neighbours.set(a->id, a);
+ } else {
+ b->unlinked_neighbours.set(a->id, a);
+ }
Segment s(p_id, p_with_id);
if (s.from == p_id) {
@@ -147,6 +174,7 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
segments.insert(s);
}
+
void AStar::disconnect_points(int p_id, int p_with_id) {
Segment s(p_id, p_with_id);
@@ -154,12 +182,18 @@ void AStar::disconnect_points(int p_id, int p_with_id) {
segments.erase(s);
- Point *a = points[p_id];
- Point *b = points[p_with_id];
- a->neighbours.erase(b);
- a->unlinked_neighbours.erase(b);
- b->neighbours.erase(a);
- b->unlinked_neighbours.erase(a);
+ Point *a;
+ bool a_exists = points.lookup(p_id, a);
+ CRASH_COND(!a_exists);
+
+ Point *b;
+ bool b_exists = points.lookup(p_with_id, b);
+ CRASH_COND(!b_exists);
+
+ a->neighbours.remove(b->id);
+ a->unlinked_neighbours.remove(b->id);
+ b->neighbours.remove(a->id);
+ b->unlinked_neighbours.remove(a->id);
}
bool AStar::has_point(int p_id) const {
@@ -171,8 +205,8 @@ Array AStar::get_points() {
Array point_list;
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
- point_list.push_back(E->key());
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+ point_list.push_back(*(it.key));
}
return point_list;
@@ -180,14 +214,14 @@ Array AStar::get_points() {
PoolVector<int> AStar::get_point_connections(int p_id) {
- ERR_FAIL_COND_V(!points.has(p_id), PoolVector<int>());
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, PoolVector<int>());
PoolVector<int> point_list;
- Point *p = points[p_id];
-
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
- point_list.push_back(E->get()->id);
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+ point_list.push_back((*it.key));
}
return point_list;
@@ -201,9 +235,9 @@ bool AStar::are_points_connected(int p_id, int p_with_id) const {
void AStar::clear() {
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
-
- memdelete(E->get());
+ last_free_id = 0;
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+ memdelete(*(it.value));
}
segments.clear();
points.clear();
@@ -214,14 +248,14 @@ int AStar::get_closest_point(const Vector3 &p_point) const {
int closest_id = -1;
real_t closest_dist = 1e20;
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+
+ if (!(*it.value)->enabled) continue; // Disabled points should not be considered.
- if (!E->get()->enabled)
- continue; //Disabled points should not be considered
- real_t d = p_point.distance_squared_to(E->get()->pos);
+ real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) {
closest_dist = d;
- closest_id = E->key();
+ closest_id = *(it.key);
}
}
@@ -230,8 +264,8 @@ int AStar::get_closest_point(const Vector3 &p_point) const {
Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
- real_t closest_dist = 1e20;
bool found = false;
+ real_t closest_dist = 1e20;
Vector3 closest_point;
for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) {
@@ -262,8 +296,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
pass++;
- if (!end_point->enabled)
- return false;
+ if (!end_point->enabled) return false;
bool found_route = false;
@@ -272,13 +305,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
begin_point->g_score = 0;
begin_point->f_score = _estimate_cost(begin_point->id, end_point->id);
-
open_list.push_back(begin_point);
- while (true) {
-
- if (open_list.size() == 0) // No path found
- break;
+ while (!open_list.empty()) {
Point *p = open_list[0]; // The currently processed point
@@ -291,24 +320,23 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
open_list.remove(open_list.size() - 1);
p->closed_pass = pass; // Mark the point as closed
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
- Point *e = E->get(); // The neighbour point
+ Point *e = *(it.value); // The neighbour point
- if (!e->enabled || e->closed_pass == pass)
+ if (!e->enabled || e->closed_pass == pass) {
continue;
+ }
real_t tentative_g_score = p->g_score + _compute_cost(p->id, e->id) * e->weight_scale;
bool new_point = false;
- if (e->open_pass != pass) { // The point wasn't inside the open list
-
+ if (e->open_pass != pass) { // The point wasn't inside the open list.
e->open_pass = pass;
open_list.push_back(e);
new_point = true;
- } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous
-
+ } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous.
continue;
}
@@ -316,10 +344,11 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
e->g_score = tentative_g_score;
e->f_score = e->g_score + _estimate_cost(e->id, end_point->id);
- if (new_point) // The position of the new points is already known
+ if (new_point) { // The position of the new points is already known.
sorter.push_heap(0, open_list.size() - 1, 0, e, open_list.ptrw());
- else
+ } else {
sorter.push_heap(0, open_list.find(e), 0, e, open_list.ptrw());
+ }
}
}
@@ -331,7 +360,15 @@ float AStar::_estimate_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost))
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
- return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+ Point *from_point;
+ bool from_exists = points.lookup(p_from_id, from_point);
+ CRASH_COND(!from_exists);
+
+ Point *to_point;
+ bool to_exists = points.lookup(p_to_id, to_point);
+ CRASH_COND(!to_exists);
+
+ return from_point->pos.distance_to(to_point->pos);
}
float AStar::_compute_cost(int p_from_id, int p_to_id) {
@@ -339,16 +376,26 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost))
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
- return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+ Point *from_point;
+ bool from_exists = points.lookup(p_from_id, from_point);
+ CRASH_COND(!from_exists);
+
+ Point *to_point;
+ bool to_exists = points.lookup(p_to_id, to_point);
+ CRASH_COND(!to_exists);
+
+ return from_point->pos.distance_to(to_point->pos);
}
PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
- ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<Vector3>());
- ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<Vector3>());
+ Point *a;
+ bool from_exists = points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, PoolVector<Vector3>());
- Point *a = points[p_from_id];
- Point *b = points[p_to_id];
+ Point *b;
+ bool to_exists = points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, PoolVector<Vector3>());
if (a == b) {
PoolVector<Vector3> ret;
@@ -360,11 +407,8 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return PoolVector<Vector3>();
- if (!found_route)
- return PoolVector<Vector3>();
-
- // Midpoints
Point *p = end_point;
int pc = 1; // Begin point
while (p != begin_point) {
@@ -393,11 +437,13 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
- ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<int>());
- ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<int>());
+ Point *a;
+ bool from_exists = points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, PoolVector<int>());
- Point *a = points[p_from_id];
- Point *b = points[p_to_id];
+ Point *b;
+ bool to_exists = points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, PoolVector<int>());
if (a == b) {
PoolVector<int> ret;
@@ -409,11 +455,8 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return PoolVector<int>();
- if (!found_route)
- return PoolVector<int>();
-
- // Midpoints
Point *p = end_point;
int pc = 1; // Begin point
while (p != begin_point) {
@@ -442,16 +485,20 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
void AStar::set_point_disabled(int p_id, bool p_disabled) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- points[p_id]->enabled = !p_disabled;
+ p->enabled = !p_disabled;
}
bool AStar::is_point_disabled(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), false);
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, false);
- return !points[p_id]->enabled;
+ return !p->enabled;
}
void AStar::_bind_methods() {
@@ -487,13 +534,11 @@ void AStar::_bind_methods() {
}
AStar::AStar() {
-
+ last_free_id = 0;
pass = 1;
}
AStar::~AStar() {
-
- pass = 1;
clear();
}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index cbabcce974..53aaaa1f6c 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -31,6 +31,7 @@
#ifndef ASTAR_H
#define ASTAR_H
+#include "core/oa_hash_map.h"
#include "core/reference.h"
/**
@@ -43,8 +44,6 @@ class AStar : public Reference {
GDCLASS(AStar, Reference);
- uint64_t pass;
-
struct Point {
int id;
@@ -52,10 +51,10 @@ class AStar : public Reference {
real_t weight_scale;
bool enabled;
- Set<Point *> neighbours;
- Set<Point *> unlinked_neighbours;
+ OAHashMap<int, Point *> neighbours;
+ OAHashMap<int, Point *> unlinked_neighbours;
- // Used for pathfinding
+ // Used for pathfinding.
Point *prev_point;
real_t g_score;
real_t f_score;
@@ -63,16 +62,15 @@ class AStar : public Reference {
uint64_t closed_pass;
};
- Map<int, Point *> points;
-
struct SortPoints {
- _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B
- if (A->f_score > B->f_score)
+ _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B.
+ if (A->f_score > B->f_score) {
return true;
- else if (A->f_score < B->f_score)
+ } else if (A->f_score < B->f_score) {
return false;
- else
- return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start
+ } else {
+ return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start.
+ }
}
};
@@ -100,6 +98,10 @@ class AStar : public Reference {
}
};
+ int last_free_id;
+ uint64_t pass;
+
+ OAHashMap<int, Point *> points;
Set<Segment> segments;
bool _solve(Point *begin_point, Point *end_point);
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index ed52c506db..3f8013a3e6 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -80,11 +80,11 @@ public:
}
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) {
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) {
return true;
}
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) {
return true;
}
diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h
index e52d36a859..83621bec14 100644
--- a/core/oa_hash_map.h
+++ b/core/oa_hash_map.h
@@ -62,7 +62,7 @@ private:
static const uint32_t EMPTY_HASH = 0;
static const uint32_t DELETED_HASH_BIT = 1 << 31;
- _FORCE_INLINE_ uint32_t _hash(const TKey &p_key) {
+ _FORCE_INLINE_ uint32_t _hash(const TKey &p_key) const {
uint32_t hash = Hasher::hash(p_key);
if (hash == EMPTY_HASH) {
@@ -74,7 +74,7 @@ private:
return hash;
}
- _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash) {
+ _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash) const {
p_hash = p_hash & ~DELETED_HASH_BIT; // we don't care if it was deleted or not
uint32_t original_pos = p_hash % capacity;
@@ -90,7 +90,7 @@ private:
num_elements++;
}
- bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) {
+ bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const {
uint32_t hash = _hash(p_key);
uint32_t pos = hash % capacity;
uint32_t distance = 0;
@@ -151,6 +151,7 @@ private:
distance++;
}
}
+
void _resize_and_rehash() {
TKey *old_keys = keys;
@@ -190,6 +191,26 @@ public:
_FORCE_INLINE_ uint32_t get_capacity() const { return capacity; }
_FORCE_INLINE_ uint32_t get_num_elements() const { return num_elements; }
+ bool empty() const {
+ return num_elements == 0;
+ }
+
+ void clear() {
+
+ for (uint32_t i = 0; i < capacity; i++) {
+
+ if (hashes[i] & DELETED_HASH_BIT) {
+ continue;
+ }
+
+ hashes[i] |= DELETED_HASH_BIT;
+ values[i].~TValue();
+ keys[i].~TKey();
+ }
+
+ num_elements = 0;
+ }
+
void insert(const TKey &p_key, const TValue &p_value) {
if ((float)num_elements / (float)capacity > 0.9) {
@@ -219,7 +240,7 @@ public:
* if r_data is not NULL then the value will be written to the object
* it points to.
*/
- bool lookup(const TKey &p_key, TValue &r_data) {
+ bool lookup(const TKey &p_key, TValue &r_data) const {
uint32_t pos = 0;
bool exists = _lookup_pos(p_key, pos);
@@ -232,7 +253,7 @@ public:
return false;
}
- _FORCE_INLINE_ bool has(const TKey &p_key) {
+ _FORCE_INLINE_ bool has(const TKey &p_key) const {
uint32_t _pos = 0;
return _lookup_pos(p_key, _pos);
}
@@ -302,6 +323,9 @@ public:
return it;
}
+ OAHashMap(const OAHashMap &) = delete; // Delete the copy constructor so we don't get unexpected copies and dangling pointers.
+ OAHashMap &operator=(const OAHashMap &) = delete; // Same for assignment operator.
+
OAHashMap(uint32_t p_initial_capacity = 64) {
capacity = p_initial_capacity;
diff --git a/core/object.cpp b/core/object.cpp
index 5875a46ea2..62bfa31480 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1400,8 +1400,9 @@ void Object::get_signal_connection_list(const StringName &p_signal, List<Connect
p_connections->push_back(s->slot_map.getv(i).conn);
}
-bool Object::has_persistent_signal_connections() const {
+int Object::get_persistent_signal_connection_count() const {
+ int count = 0;
const StringName *S = NULL;
while ((S = signal_map.next(S))) {
@@ -1409,13 +1410,13 @@ bool Object::has_persistent_signal_connections() const {
const Signal *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
-
- if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST)
- return true;
+ if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
+ count += 1;
+ }
}
}
- return false;
+ return count;
}
void Object::get_signals_connected_to_this(List<Connection> *p_connections) const {
diff --git a/core/object.h b/core/object.h
index 15c3ab94c5..ac8620757c 100644
--- a/core/object.h
+++ b/core/object.h
@@ -707,7 +707,7 @@ public:
void get_signal_list(List<MethodInfo> *p_signals) const;
void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
void get_all_signal_connections(List<Connection> *p_connections) const;
- bool has_persistent_signal_connections() const;
+ int get_persistent_signal_connection_count() const;
void get_signals_connected_to_this(List<Connection> *p_connections) const;
Error connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index ba94e87da6..9a8315a3bb 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -30,9 +30,9 @@
#include "file_access.h"
+#include "core/crypto/crypto_core.h"
#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"
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e442546124..efc77bde48 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -34,6 +34,8 @@
#include "core/class_db.h"
#include "core/compressed_translation.h"
#include "core/core_string_names.h"
+#include "core/crypto/crypto.h"
+#include "core/crypto/hashing_context.h"
#include "core/engine.h"
#include "core/func_ref.h"
#include "core/input_map.h"
@@ -70,6 +72,8 @@ static Ref<ResourceFormatLoaderBinary> resource_loader_binary;
static Ref<ResourceFormatImporter> resource_format_importer;
static Ref<ResourceFormatLoaderImage> resource_format_image;
static Ref<TranslationLoaderPO> resource_format_po;
+static Ref<ResourceFormatSaverCrypto> resource_format_saver_crypto;
+static Ref<ResourceFormatLoaderCrypto> resource_format_loader_crypto;
static _ResourceLoader *_resource_loader = NULL;
static _ResourceSaver *_resource_saver = NULL;
@@ -151,7 +155,19 @@ void register_core_types() {
ClassDB::register_class<StreamPeerTCP>();
ClassDB::register_class<TCP_Server>();
ClassDB::register_class<PacketPeerUDP>();
+
+ // Crypto
+ ClassDB::register_class<HashingContext>();
+ ClassDB::register_custom_instance_class<X509Certificate>();
+ ClassDB::register_custom_instance_class<CryptoKey>();
+ ClassDB::register_custom_instance_class<Crypto>();
ClassDB::register_custom_instance_class<StreamPeerSSL>();
+
+ resource_format_saver_crypto.instance();
+ ResourceSaver::add_resource_format_saver(resource_format_saver_crypto);
+ resource_format_loader_crypto.instance();
+ ResourceLoader::add_resource_format_loader(resource_format_loader_crypto);
+
ClassDB::register_virtual_class<IP>();
ClassDB::register_virtual_class<PacketPeer>();
ClassDB::register_class<PacketPeerStream>();
@@ -211,6 +227,9 @@ void register_core_settings() {
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"));
+
+ GLOBAL_DEF("network/ssl/certificates", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
}
void register_core_singletons() {
@@ -272,6 +291,11 @@ void unregister_core_types() {
ResourceLoader::remove_resource_format_loader(resource_format_po);
resource_format_po.unref();
+ ResourceSaver::remove_resource_format_saver(resource_format_saver_crypto);
+ resource_format_saver_crypto.unref();
+ ResourceLoader::remove_resource_format_loader(resource_format_loader_crypto);
+ resource_format_loader_crypto.unref();
+
if (ip)
memdelete(ip);
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ed401c3763..4e9ab7be6b 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -31,7 +31,7 @@
#include "ustring.h"
#include "core/color.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/print_string.h"
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 9ea2fed5ae..02c6cd73d8 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -32,8 +32,8 @@
#include "core/color_names.inc"
#include "core/core_string_names.h"
+#include "core/crypto/crypto_core.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"
@@ -606,6 +606,13 @@ struct _VariantCall {
r_ret = s;
}
+ static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PoolByteArray::Read r = ba->read();
+ String s = String::hex_encode_buffer(&r[0], ba->size());
+ r_ret = s;
+ }
+
VCALL_LOCALMEM0R(PoolByteArray, size);
VCALL_LOCALMEM2(PoolByteArray, set);
VCALL_LOCALMEM1R(PoolByteArray, get);
@@ -1763,6 +1770,7 @@ void register_variant_methods() {
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, sha256_string, varray());
+ ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, hex_encode, varray());
ADDFUNC1R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));