summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp2
-rw-r--r--core/input/input_event.cpp2
-rw-r--r--core/input/input_map.cpp4
-rw-r--r--core/input/input_map.h4
-rw-r--r--core/io/file_access.compat.inc43
-rw-r--r--core/io/file_access.cpp7
-rw-r--r--core/io/file_access.h8
-rw-r--r--core/io/file_access_encrypted.cpp29
-rw-r--r--core/io/file_access_encrypted.h5
-rw-r--r--core/io/file_access_pack.h2
-rw-r--r--core/io/image.cpp14
-rw-r--r--core/io/resource_uid.cpp16
-rw-r--r--core/io/resource_uid.h4
-rw-r--r--core/templates/a_hash_map.h5
14 files changed, 113 insertions, 32 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 08ce6c0e07..fa5c30c4ec 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1410,7 +1410,7 @@ void ProjectSettings::_add_builtin_input_map() {
}
Dictionary action;
- action["deadzone"] = Variant(0.2f);
+ action["deadzone"] = Variant(InputMap::DEFAULT_DEADZONE);
action["events"] = events;
String action_name = "input/" + E.key;
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 248b5a8bf7..e580ea185d 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -1099,7 +1099,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const {
void InputEventJoypadMotion::set_axis_value(float p_value) {
axis_value = p_value;
- pressed = Math::abs(axis_value) >= 0.5f;
+ pressed = Math::abs(axis_value) >= InputMap::DEFAULT_DEADZONE;
emit_changed();
}
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 553de4af9c..3073935f96 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -44,7 +44,7 @@ InputMap *InputMap::singleton = nullptr;
void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
- ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.2f));
+ ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(DEFAULT_DEADZONE));
ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action);
ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone);
@@ -307,7 +307,7 @@ void InputMap::load_from_project_settings() {
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
Dictionary action = GLOBAL_GET(pi.name);
- float deadzone = action.has("deadzone") ? (float)action["deadzone"] : 0.2f;
+ float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE;
Array events = action["events"];
add_action(name, deadzone);
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 1a2e378d79..319ce98ebd 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -51,6 +51,8 @@ public:
List<Ref<InputEvent>> inputs;
};
+ static constexpr float DEFAULT_DEADZONE = 0.2f;
+
private:
static InputMap *singleton;
@@ -76,7 +78,7 @@ public:
bool has_action(const StringName &p_action) const;
List<StringName> get_actions() const;
- void add_action(const StringName &p_action, float p_deadzone = 0.2);
+ void add_action(const StringName &p_action, float p_deadzone = DEFAULT_DEADZONE);
void erase_action(const StringName &p_action);
float action_get_deadzone(const StringName &p_action);
diff --git a/core/io/file_access.compat.inc b/core/io/file_access.compat.inc
new file mode 100644
index 0000000000..0ecafb7d9d
--- /dev/null
+++ b/core/io/file_access.compat.inc
@@ -0,0 +1,43 @@
+/**************************************************************************/
+/* file_access.compat.inc */
+/**************************************************************************/
+/* This file is part of: */
+/* REDOT ENGINE */
+/* https://redotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2024-present Redot Engine contributors */
+/* (see REDOT_AUTHORS.md) */
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 DISABLE_DEPRECATED
+
+Ref<FileAccess> FileAccess::_open_encrypted_bind_compat_98918(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) {
+ return open_encrypted(p_path, p_mode_flags, p_key, Vector<uint8_t>());
+}
+
+void FileAccess::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key"), &FileAccess::_open_encrypted_bind_compat_98918);
+}
+
+#endif // DISABLE_DEPRECATED
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index e10462adcd..0b004ce1e3 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -31,6 +31,7 @@
/**************************************************************************/
#include "file_access.h"
+#include "file_access.compat.inc"
#include "core/config/project_settings.h"
#include "core/crypto/crypto_core.h"
@@ -126,7 +127,7 @@ Ref<FileAccess> FileAccess::_open(const String &p_path, ModeFlags p_mode_flags)
return fa;
}
-Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) {
+Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key, const Vector<uint8_t> &p_iv) {
Ref<FileAccess> fa = _open(p_path, p_mode_flags);
if (fa.is_null()) {
return fa;
@@ -134,7 +135,7 @@ Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mod
Ref<FileAccessEncrypted> fae;
fae.instantiate();
- Error err = fae->open_and_parse(fa, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ);
+ Error err = fae->open_and_parse(fa, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ, true, p_iv);
last_file_open_error = err;
if (err) {
return Ref<FileAccess>();
@@ -808,7 +809,7 @@ String FileAccess::get_sha256(const String &p_file) {
void FileAccess::_bind_methods() {
ClassDB::bind_static_method("FileAccess", D_METHOD("open", "path", "flags"), &FileAccess::_open);
- ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key"), &FileAccess::open_encrypted);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key", "iv"), &FileAccess::open_encrypted, DEFVAL(Vector<uint8_t>()));
ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &FileAccess::open_encrypted_pass);
ClassDB::bind_static_method("FileAccess", D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &FileAccess::open_compressed, DEFVAL(0));
ClassDB::bind_static_method("FileAccess", D_METHOD("get_open_error"), &FileAccess::get_open_error);
diff --git a/core/io/file_access.h b/core/io/file_access.h
index 61970b2d1a..20b5f26d9f 100644
--- a/core/io/file_access.h
+++ b/core/io/file_access.h
@@ -111,6 +111,12 @@ protected:
static FileCloseFailNotify close_fail_notify;
+#ifndef DISABLE_DEPRECATED
+ static Ref<FileAccess> _open_encrypted_bind_compat_98918(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key);
+
+ static void _bind_compatibility_methods();
+#endif
+
private:
static bool backup_save;
thread_local static Error last_file_open_error;
@@ -201,7 +207,7 @@ public:
static Ref<FileAccess> create_for_path(const String &p_path);
static Ref<FileAccess> open(const String &p_path, int p_mode_flags, Error *r_error = nullptr); /// Create a file access (for the current platform) this is the only portable way of accessing files.
- static Ref<FileAccess> open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key);
+ static Ref<FileAccess> open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
static Ref<FileAccess> open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass);
static Ref<FileAccess> open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ);
static Error get_open_error();
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index a84aa4c800..5fe7d99c1c 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -38,7 +38,7 @@
#include <stdio.h>
-Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) {
+Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &p_iv) {
ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute()));
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
@@ -51,6 +51,16 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
writing = true;
file = p_base;
key = p_key;
+ if (p_iv.is_empty()) {
+ iv.resize(16);
+ CryptoCore::RandomGenerator rng;
+ ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator.");
+ Error err = rng.get_random_bytes(iv.ptrw(), 16);
+ ERR_FAIL_COND_V(err != OK, err);
+ } else {
+ ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER);
+ iv = p_iv;
+ }
} else if (p_mode == MODE_READ) {
writing = false;
@@ -65,10 +75,8 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
- unsigned char iv[16];
- for (int i = 0; i < 16; i++) {
- iv[i] = p_base->get_8();
- }
+ iv.resize(16);
+ p_base->get_buffer(iv.ptrw(), 16);
base = p_base->get_position();
ERR_FAIL_COND_V(p_base->get_length() < base + length, ERR_FILE_CORRUPT);
@@ -85,7 +93,7 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
CryptoCore::AESContext ctx;
ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!
- ctx.decrypt_cfb(ds, iv, data.ptrw(), data.ptrw());
+ ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw());
}
data.resize(length);
@@ -147,14 +155,9 @@ void FileAccessEncrypted::_close() {
file->store_buffer(hash, 16);
file->store_64(data.size());
+ file->store_buffer(iv.ptr(), 16);
- unsigned char iv[16];
- for (int i = 0; i < 16; i++) {
- iv[i] = Math::rand() % 256;
- file->store_8(iv[i]);
- }
-
- ctx.encrypt_cfb(len, iv, compressed.ptrw(), compressed.ptrw());
+ ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptrw(), compressed.ptrw());
file->store_buffer(compressed.ptr(), compressed.size());
data.clear();
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index c9d0c458c1..0a8c19ea37 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -46,6 +46,7 @@ public:
};
private:
+ Vector<uint8_t> iv;
Vector<uint8_t> key;
bool writing = false;
Ref<FileAccess> file;
@@ -59,9 +60,11 @@ private:
void _close();
public:
- Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true);
+ Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>());
Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode);
+ Vector<uint8_t> get_iv() const { return iv; }
+
virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
virtual bool is_open() const override; ///< true when file is open
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 124c08fe07..ff02d3f6fa 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -207,7 +207,7 @@ Ref<FileAccess> PackedData::try_open_path(const String &p_path) {
}
bool PackedData::has_path(const String &p_path) {
- return files.has(PathMD5(p_path.simplify_path().md5_buffer()));
+ return files.has(PathMD5(p_path.simplify_path().trim_prefix("res://").md5_buffer()));
}
bool PackedData::has_directory(const String &p_path) {
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 3e5ae837f5..a69794c931 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -2613,23 +2613,25 @@ Image::AlphaMode Image::detect_alpha() const {
}
Error Image::load(const String &p_path) {
+ String path = ResourceUID::ensure_path(p_path);
#ifdef DEBUG_ENABLED
- if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) {
- WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", p_path));
+ if (path.begins_with("res://") && ResourceLoader::exists(path)) {
+ WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", path));
}
#endif
- return ImageLoader::load_image(p_path, this);
+ return ImageLoader::load_image(ResourceUID::ensure_path(p_path), this);
}
Ref<Image> Image::load_from_file(const String &p_path) {
+ String path = ResourceUID::ensure_path(p_path);
#ifdef DEBUG_ENABLED
- if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) {
- WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", p_path));
+ if (path.begins_with("res://") && ResourceLoader::exists(path)) {
+ WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", path));
}
#endif
Ref<Image> image;
image.instantiate();
- Error err = ImageLoader::load_image(p_path, image);
+ Error err = ImageLoader::load_image(path, image);
if (err != OK) {
ERR_FAIL_V_MSG(Ref<Image>(), vformat("Failed to load image. Error %d", err));
}
diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp
index 0c564ce33b..83cde97331 100644
--- a/core/io/resource_uid.cpp
+++ b/core/io/resource_uid.cpp
@@ -36,6 +36,7 @@
#include "core/crypto/crypto_core.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
+#include "core/io/resource_loader.h"
// These constants are off by 1, causing the 'z' and '9' characters never to be used.
// This cannot be fixed without breaking compatibility; see GH-83843.
@@ -141,6 +142,21 @@ void ResourceUID::remove_id(ID p_id) {
unique_ids.erase(p_id);
}
+String ResourceUID::uid_to_path(const String &p_uid) {
+ return singleton->get_id_path(singleton->text_to_id(p_uid));
+}
+
+String ResourceUID::path_to_uid(const String &p_path) {
+ return singleton->id_to_text(ResourceLoader::get_resource_uid(p_path));
+}
+
+String ResourceUID::ensure_path(const String &p_uid_or_path) {
+ if (p_uid_or_path.begins_with("uid://")) {
+ return uid_to_path(p_uid_or_path);
+ }
+ return p_uid_or_path;
+}
+
Error ResourceUID::save_to_cache() {
String cache_file = get_cache_file();
if (!FileAccess::exists(cache_file)) {
diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h
index 19ccf90e8c..3ab25cb9d4 100644
--- a/core/io/resource_uid.h
+++ b/core/io/resource_uid.h
@@ -75,6 +75,10 @@ public:
String get_id_path(ID p_id) const;
void remove_id(ID p_id);
+ static String uid_to_path(const String &p_uid);
+ static String path_to_uid(const String &p_path);
+ static String ensure_path(const String &p_uid_or_path);
+
Error load_from_cache(bool p_reset);
Error save_to_cache();
Error update_cache();
diff --git a/core/templates/a_hash_map.h b/core/templates/a_hash_map.h
index 81b061deb4..e831a65c67 100644
--- a/core/templates/a_hash_map.h
+++ b/core/templates/a_hash_map.h
@@ -624,10 +624,11 @@ public:
}
// Inserts an element without checking if it already exists.
- void insert_new(const TKey &p_key, const TValue &p_value) {
+ Iterator insert_new(const TKey &p_key, const TValue &p_value) {
DEV_ASSERT(!has(p_key));
uint32_t hash = _hash(p_key);
- _insert_element(p_key, p_value, hash);
+ uint32_t pos = _insert_element(p_key, p_value, hash);
+ return Iterator(elements + pos, elements, elements + num_elements);
}
/* Array methods. */