Skip to content

Commit 7fb37a0

Browse files
committed
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.
1 parent a9c5c4d commit 7fb37a0

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

platform/android/game_menu_utils_jni.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,20 @@
3434
#include "editor/editor_interface.h"
3535
#include "editor/editor_node.h"
3636
#include "editor/plugins/game_view_plugin.h"
37+
38+
static GameViewPlugin *_get_game_view_plugin() {
39+
ERR_FAIL_NULL_V(EditorNode::get_singleton(), nullptr);
40+
ERR_FAIL_NULL_V(EditorNode::get_singleton()->get_editor_main_screen(), nullptr);
41+
return Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
42+
}
43+
3744
#endif
3845

3946
extern "C" {
4047

4148
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend(JNIEnv *env, jclass clazz, jboolean enabled) {
4249
#ifdef TOOLS_ENABLED
43-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
50+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
4451
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
4552
game_view_plugin->get_debugger()->set_suspend(enabled);
4653
}
@@ -49,7 +56,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSuspend
4956

5057
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(JNIEnv *env, jclass clazz) {
5158
#ifdef TOOLS_ENABLED
52-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
59+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
5360
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
5461
game_view_plugin->get_debugger()->next_frame();
5562
}
@@ -58,7 +65,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_nextFrame(
5865

5966
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeType(JNIEnv *env, jclass clazz, jint type) {
6067
#ifdef TOOLS_ENABLED
61-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
68+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
6269
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
6370
game_view_plugin->get_debugger()->set_node_type(type);
6471
}
@@ -67,7 +74,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setNodeTyp
6774

6875
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectMode(JNIEnv *env, jclass clazz, jint mode) {
6976
#ifdef TOOLS_ENABLED
70-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
77+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
7178
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
7279
game_view_plugin->get_debugger()->set_select_mode(mode);
7380
}
@@ -76,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectM
7683

7784
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelectionVisible(JNIEnv *env, jclass clazz, jboolean visible) {
7885
#ifdef TOOLS_ENABLED
79-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
86+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
8087
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
8188
game_view_plugin->get_debugger()->set_selection_visible(visible);
8289
}
@@ -85,7 +92,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setSelecti
8592

8693
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraOverride(JNIEnv *env, jclass clazz, jboolean enabled) {
8794
#ifdef TOOLS_ENABLED
88-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
95+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
8996
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
9097
game_view_plugin->get_debugger()->set_camera_override(enabled);
9198
}
@@ -94,7 +101,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraO
94101

95102
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraManipulateMode(JNIEnv *env, jclass clazz, jint mode) {
96103
#ifdef TOOLS_ENABLED
97-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
104+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
98105
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
99106
game_view_plugin->get_debugger()->set_camera_manipulate_mode(static_cast<EditorDebuggerNode::CameraOverride>(mode));
100107
}
@@ -103,7 +110,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_setCameraM
103110

104111
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera2DPosition(JNIEnv *env, jclass clazz) {
105112
#ifdef TOOLS_ENABLED
106-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
113+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
107114
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
108115
game_view_plugin->get_debugger()->reset_camera_2d_position();
109116
}
@@ -112,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
112119

113120
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamera3DPosition(JNIEnv *env, jclass clazz) {
114121
#ifdef TOOLS_ENABLED
115-
GameViewPlugin *game_view_plugin = Object::cast_to<GameViewPlugin>(EditorNode::get_singleton()->get_editor_main_screen()->get_plugin_by_name("Game"));
122+
GameViewPlugin *game_view_plugin = _get_game_view_plugin();
116123
if (game_view_plugin != nullptr && game_view_plugin->get_debugger().is_valid()) {
117124
game_view_plugin->get_debugger()->reset_camera_3d_position();
118125
}
@@ -121,7 +128,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_resetCamer
121128

122129
JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_GameMenuUtils_playMainScene(JNIEnv *env, jclass clazz) {
123130
#ifdef TOOLS_ENABLED
124-
EditorInterface::get_singleton()->play_main_scene();
131+
if (EditorInterface::get_singleton()) {
132+
EditorInterface::get_singleton()->play_main_scene();
133+
}
125134
#endif
126135
}
127136
}

0 commit comments

Comments
 (0)