1
0
Fork 0

Compare commits

...

4 Commits

Author SHA1 Message Date
Ryan a6977f33e7
Merge 14fb9358fc into 15ff450680 2025-02-28 01:35:38 +01:00
Rémi Verschelde 15ff450680
Merge pull request #103371 from m4gr3d/add_checks_for_game_menu_utils_jni
Add checks to prevent crashes when accessing the GameMenu api
2025-02-28 01:12:11 +01:00
Fredia Huya-Kouadio 7fb37a088b Add checks to prevent crashes when accessing the GameMenu api
This should address crashes reported on the Play store. Note that those crashes lack debug symbols which reduces our ability to narrow down the exact cause of the crash. We aim to resolve that in Godot 4.5.
2025-02-27 13:20:23 -08:00
Ryan 14fb9358fc Expose ResourceLoader::get_resource_type and ResourceLoader::get_resource_script_class
Co-Authored-By: Pedro J. Estébanez <RandomShaper@users.noreply.github.com>
2024-12-04 14:31:44 -05:00
4 changed files with 46 additions and 10 deletions

View File

@ -130,6 +130,14 @@ ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) {
return ::ResourceLoader::get_resource_uid(p_path);
}
String ResourceLoader::get_resource_type(const String &p_path) {
return ::ResourceLoader::get_resource_type(p_path);
}
String ResourceLoader::get_resource_script_class(const String &p_path) {
return ::ResourceLoader::get_resource_script_class(p_path);
}
Vector<String> ResourceLoader::list_directory(const String &p_directory) {
return ::ResourceLoader::list_directory(p_directory);
}
@ -149,6 +157,8 @@ void ResourceLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cached_ref", "path"), &ResourceLoader::get_cached_ref);
ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &ResourceLoader::exists, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_resource_uid", "path"), &ResourceLoader::get_resource_uid);
ClassDB::bind_method(D_METHOD("get_resource_type", "path"), &ResourceLoader::get_resource_type);
ClassDB::bind_method(D_METHOD("get_resource_script_class", "path"), &ResourceLoader::get_resource_script_class);
ClassDB::bind_method(D_METHOD("list_directory", "directory_path"), &ResourceLoader::list_directory);
BIND_ENUM_CONSTANT(THREAD_LOAD_INVALID_RESOURCE);

View File

@ -83,6 +83,8 @@ public:
Ref<Resource> get_cached_ref(const String &p_path);
bool exists(const String &p_path, const String &p_type_hint = "");
ResourceUID::ID get_resource_uid(const String &p_path);
String get_resource_type(const String &p_path);
String get_resource_script_class(const String &p_path);
Vector<String> list_directory(const String &p_directory);

View File

@ -60,6 +60,21 @@
Returns the list of recognized extensions for a resource type.
</description>
</method>
<method name="get_resource_script_class">
<return type="String" />
<param index="0" name="path" type="String" />
<description>
Returns the global script class name a given [param path], as set by the [code]class_name[/code] keyword in GDScript or the [code][GlobalClass][/code] attribute in C#.
If there is none, it returns an empty string.
</description>
</method>
<method name="get_resource_type">
<return type="String" />
<param index="0" name="path" type="String" />
<description>
Returns the type of the resource at the given [param path].
</description>
</method>
<method name="get_resource_uid">
<return type="int" />
<param index="0" name="path" type="String" />

View File

@ -34,13 +34,20 @@
#include "editor/editor_interface.h"
#include "editor/editor_node.h"
#include "editor/plugins/game_view_plugin.h"
static GameViewPlugin *_get_game_view_plugin() {
ERR_FAIL_NULL_V(EditorNode::get_singleton(), nullptr);
ERR_FAIL_NULL_V(EditorNode::get_singleton()->get_editor_main_screen(), nullptr);
return Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
}
#endif
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend(JNIEnv *env, jclass clazz, jboolean enabled) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_suspend(enabled);
}
@ -49,7 +56,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->next_frame();
}
@ -58,7 +65,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeType(JNIEnv *env, jclass clazz, jint type) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_node_type(type);
}
@ -67,7 +74,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeTyp
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectMode(JNIEnv *env, jclass clazz, jint mode) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_select_mode(mode);
}
@ -76,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectM
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectionVisible(JNIEnv *env, jclass clazz, jboolean visible) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_selection_visible(visible);
}
@ -85,7 +92,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelecti
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraOverride(JNIEnv *env, jclass clazz, jboolean enabled) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_camera_override(enabled);
}
@ -94,7 +101,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraO
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraManipulateMode(JNIEnv *env, jclass clazz, jint mode) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->set_camera_manipulate_mode(static_cast<EditorDebuggerNode::CameraOverride>(mode));
}
@ -103,7 +110,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraM
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera2DPosition(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->reset_camera_2d_position();
}
@ -112,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera3DPosition(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
game_view_plugin->get_debugger()->reset_camera_3d_position();
}
@ -121,7 +128,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_playMainScene(JNIEnv *env, jclass clazz) {
#ifdef TOOLS_ENABLED
EditorInterface::get_singleton()->play_main_scene();
if (EditorInterface::get_singleton()) {
EditorInterface::get_singleton()->play_main_scene();
}
#endif
}
}