diff options
-rw-r--r-- | clientmods/preview/init.lua | 7 | ||||
-rw-r--r-- | doc/client_lua_api.md | 3 | ||||
-rw-r--r-- | src/client.cpp | 10 | ||||
-rw-r--r-- | src/client.h | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_client.cpp | 18 | ||||
-rw-r--r-- | src/script/lua_api/l_client.h | 3 |
6 files changed, 37 insertions, 5 deletions
diff --git a/clientmods/preview/init.lua b/clientmods/preview/init.lua index c57a62155..07464e927 100644 --- a/clientmods/preview/init.lua +++ b/clientmods/preview/init.lua @@ -127,3 +127,10 @@ core.register_chatcommand("list_players", { core.display_chat_message(dump(core.get_player_names())) end }) + +core.register_chatcommand("disconnect", { + description = "Exit to main menu", + func = function(param) + core.disconnect() + end, +}) diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index d5ccef5d3..deb5bfb13 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -698,6 +698,9 @@ Call these functions only at load time! ### Client Environment * `minetest.get_player_names()` * Returns list of player names on server +* `minetest.disconnect()` + * Disconnect from the server and exit to main menu. + * Returns `false` if the client is already disconnecting otherwise returns `true`. ### Misc. * `minetest.parse_json(string[, nullvalue])`: returns something diff --git a/src/client.cpp b/src/client.cpp index 8bbaa83bd..e710624d5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -260,7 +260,8 @@ Client::Client( m_localdb(NULL), m_script(NULL), m_mod_storage_save_timer(10.0f), - m_game_ui_flags(game_ui_flags) + m_game_ui_flags(game_ui_flags), + m_shutdown(false) { // Add local player m_env.setLocalPlayer(new LocalPlayer(this, playername)); @@ -346,6 +347,7 @@ const ModSpec* Client::getModSpec(const std::string &modname) const void Client::Stop() { + m_shutdown = true; // Don't disable this part when modding is disabled, it's used in builtin m_script->on_shutdown(); //request all client managed threads to stop @@ -361,14 +363,12 @@ void Client::Stop() bool Client::isShutdown() { - - if (!m_mesh_update_thread.isRunning()) return true; - - return false; + return m_shutdown || !m_mesh_update_thread.isRunning(); } Client::~Client() { + m_shutdown = true; m_con.Disconnect(); m_mesh_update_thread.stop(); diff --git a/src/client.h b/src/client.h index 84adf81d8..e565acd93 100644 --- a/src/client.h +++ b/src/client.h @@ -737,6 +737,7 @@ private: float m_mod_storage_save_timer; GameUIFlags *m_game_ui_flags; + bool m_shutdown; DISABLE_CLASS_COPY(Client); }; diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 7cb89188d..5f9474702 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -25,8 +25,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "l_internal.h" #include "lua_api/l_item.h" +#include "mainmenumanager.h" #include "util/string.h" +extern MainGameCallback *g_gamecallback; + int ModApiClient::l_get_current_modname(lua_State *L) { lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); @@ -107,6 +110,20 @@ int ModApiClient::l_send_respawn(lua_State *L) return 0; } +// disconnect() +int ModApiClient::l_disconnect(lua_State *L) +{ + // Stops badly written Lua code form causing boot loops + if (getClient(L)->isShutdown()) { + lua_pushboolean(L, false); + return 1; + } + + g_gamecallback->disconnect(); + lua_pushboolean(L, true); + return 1; +} + // gettext(text) int ModApiClient::l_gettext(lua_State *L) { @@ -178,4 +195,5 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(get_node); API_FCT(get_node_or_nil); API_FCT(get_wielded_item); + API_FCT(disconnect); } diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index b79cc670d..d7f92ac1c 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -41,6 +41,9 @@ private: // send_respawn() static int l_send_respawn(lua_State *L); + // disconnect() + static int l_disconnect(lua_State *L); + // gettext(text) static int l_gettext(lua_State *L); |