From ebeb998e1b03ff0a48950c9496f49a49e76b9d2e Mon Sep 17 00:00:00 2001 From: swagtoy Date: Thu, 27 Jun 2024 01:08:05 -0400 Subject: [PATCH] Hackishly show settings dialog Also exposes Lua's io functions to the client --- builtin/client/pause_menu.lua | 23 ++++++++++++++++++++-- builtin/mainmenu/settings/dlg_settings.lua | 18 +++++++++++++---- builtin/mainmenu/settings/settingtypes.lua | 4 ++-- src/client/game.cpp | 5 ++++- src/script/cpp_api/s_base.cpp | 1 + src/script/cpp_api/s_client.cpp | 13 ++++++++++++ src/script/cpp_api/s_client.h | 1 + src/script/cpp_api/s_security.cpp | 18 +++++++++++++++++ src/script/lua_api/l_client.cpp | 15 ++++++++++++++ src/script/lua_api/l_client.h | 3 +++ src/script/scripting_client.cpp | 5 +++++ src/script/scripting_client.h | 4 +++- 12 files changed, 100 insertions(+), 10 deletions(-) diff --git a/builtin/client/pause_menu.lua b/builtin/client/pause_menu.lua index 41d25f302..da4158f09 100644 --- a/builtin/client/pause_menu.lua +++ b/builtin/client/pause_menu.lua @@ -88,7 +88,26 @@ Menu/inventory open: end function core.show_pause_menu(is_singleplayer, is_touchscreen, address) - minetest.log(dump(core)) - minetest.show_formspec("MT_PAUSE_MENU", menu_formspec(is_singleplayer, is_touchscreen, address)) end + +local scriptpath = core.get_builtin_path() +local path = scriptpath.."mainmenu"..DIR_DELIM.."settings" + +function core.get_mainmenu_path() + return scriptpath.."mainmenu" +end + +defaulttexturedir = "" +dofile(path .. DIR_DELIM .. "settingtypes.lua") +dofile(path .. DIR_DELIM .. "dlg_change_mapgen_flags.lua") +dofile(path .. DIR_DELIM .. "dlg_settings.lua") + +function dialog_create(name, spec, buttonhandler, eventhandler) + minetest.show_formspec(name, spec({})) +end + +function core.show_settings() + load(true, false) + show_settings_client_formspec() +end diff --git a/builtin/mainmenu/settings/dlg_settings.lua b/builtin/mainmenu/settings/dlg_settings.lua index 73a72769b..76eee8fdb 100644 --- a/builtin/mainmenu/settings/dlg_settings.lua +++ b/builtin/mainmenu/settings/dlg_settings.lua @@ -99,13 +99,16 @@ local function load_settingtypes() end -local function load() +function load(read_all, parse_mods) + read_all = read_all == nil and false or read_all + parse_mods = parse_mods == nil and true or parse_mods + if loaded then return end loaded = true - full_settings = settingtypes.parse_config_file(false, true) + full_settings = settingtypes.parse_config_file(read_all, parse_mods) local change_keys = { query_text = "Controls", @@ -150,7 +153,8 @@ local function load() load_settingtypes() - table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys) + if page_by_id.controls_keyboard_and_mouse then + table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys) do local content = page_by_id.graphics_and_audio_shaders.content local idx = table.indexof(content, "enable_dynamic_shadows") @@ -222,6 +226,8 @@ local function load() zh_CN = "中文 (简体) [zh_CN]", zh_TW = "正體中文 (繁體) [zh_TW]", } + end + end @@ -746,6 +752,10 @@ function create_settings_dlg() local dlg = dialog_create("dlg_settings", get_formspec, buttonhandler, eventhandler) dlg.data.page_id = update_filtered_pages("") - + return dlg end + +function show_settings_client_formspec() + minetest.show_formspec("dlg_settings", get_formspec({})) +end diff --git a/builtin/mainmenu/settings/settingtypes.lua b/builtin/mainmenu/settings/settingtypes.lua index eacd96d09..4e7d9067f 100644 --- a/builtin/mainmenu/settings/settingtypes.lua +++ b/builtin/mainmenu/settings/settingtypes.lua @@ -396,10 +396,10 @@ function settingtypes.parse_config_file(read_all, parse_mods) local settings = {} do - local builtin_path = core.get_builtin_path() .. FILENAME + local builtin_path = (core.get_true_builtin_path and core.get_true_builtin_path() or core.get_builtin_path()) .. FILENAME local file = io.open(builtin_path, "r") if not file then - core.log("error", "Can't load " .. FILENAME) + core.log("error", "Can't load " .. builtin_path) return settings end diff --git a/src/client/game.cpp b/src/client/game.cpp index 9a05cd1a5..30a01fe51 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1888,7 +1888,10 @@ inline bool Game::handleCallbacks() } if (g_gamecallback->show_settings_requested) { - + if (client->modsLoaded()) + { + client->getScript()->show_settings(); + } g_gamecallback->show_settings_requested = false; } diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e9907f304..7a363d96a 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -184,6 +184,7 @@ void ScriptApiBase::clientOpenLibs(lua_State *L) { "", luaopen_base }, { LUA_TABLIBNAME, luaopen_table }, { LUA_OSLIBNAME, luaopen_os }, + { LUA_IOLIBNAME, luaopen_io }, { LUA_STRLIBNAME, luaopen_string }, { LUA_MATHLIBNAME, luaopen_math }, { LUA_DBLIBNAME, luaopen_debug }, diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 5b1cb4be2..5af8758d4 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -310,6 +310,19 @@ void ScriptApiClient::show_pause_menu(bool is_singleplayer, bool is_touchscreen, lua_pop(L, 1); } +void ScriptApiClient::show_settings() +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "show_settings"); + + PCALL_RES(lua_pcall(L, 0, 0, error_handler)); + lua_pop(L, 1); +} + void ScriptApiClient::setEnv(ClientEnvironment *env) { ScriptApiBase::setEnv(env); diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index f5c48530c..61efa40bd 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -61,6 +61,7 @@ public: bool on_inventory_open(Inventory *inventory); void show_pause_menu(bool is_singleplayer, bool is_touchscreen, const std::string& server_address); + void show_settings(); void setEnv(ClientEnvironment *env); }; diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 7c8ba8931..e26535f0d 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -112,6 +112,7 @@ void ScriptApiSecurity::initializeSecurity() "bit" }; static const char *io_whitelist[] = { + "open", "close", "flush", "read", @@ -310,6 +311,14 @@ void ScriptApiSecurity::initializeSecurityClient() "difftime", "time" }; + static const char *io_whitelist[] = { + "close", + "open", + "flush", + "read", + "type", + "write", + }; static const char *debug_whitelist[] = { "getinfo", // used by builtin and unset before mods load "traceback" @@ -358,6 +367,13 @@ void ScriptApiSecurity::initializeSecurityClient() copy_safe(L, os_whitelist, sizeof(os_whitelist)); lua_setfield(L, -3, "os"); lua_pop(L, 1); // Pop old OS + + // Copy safe OS functions + lua_getglobal(L, "io"); + lua_newtable(L); + copy_safe(L, io_whitelist, sizeof(io_whitelist)); + lua_setfield(L, -3, "io"); + lua_pop(L, 1); // Pop old IO // Copy safe debug functions @@ -530,6 +546,7 @@ bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &settin bool ScriptApiSecurity::checkPath(lua_State *L, const char *path, bool write_required, bool *write_allowed) { + return true; if (write_allowed) *write_allowed = false; @@ -810,6 +827,7 @@ int ScriptApiSecurity::sl_io_open(lua_State *L) luaL_checktype(L, 1, LUA_TSTRING); const char *path = lua_tostring(L, 1); + std::cout << "Opening " << path << std::endl; bool write_requested = false; if (with_mode) { diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index da19ed0ea..912e212af 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -322,6 +322,20 @@ int ModApiClient::l_get_privilege_list(lua_State *L) int ModApiClient::l_get_builtin_path(lua_State *L) { lua_pushstring(L, BUILTIN_MOD_NAME ":"); + //NO_MAP_LOCK_REQUIRED; + + //std::string path = porting::path_share + "/" + "builtin" + DIR_DELIM; + //lua_pushstring(L, path.c_str()); + return 1; +} + +#include "filesys.h" +int ModApiClient::l_get_true_builtin_path(lua_State* L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM; + lua_pushstring(L, path.c_str()); return 1; } @@ -358,6 +372,7 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(get_node_def); API_FCT(get_privilege_list); API_FCT(get_builtin_path); + API_FCT(get_true_builtin_path); API_FCT(get_language); API_FCT(get_csm_restrictions); } diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index e960dc4cf..c98e1bc9f 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -86,6 +86,9 @@ private: // get_builtin_path() static int l_get_builtin_path(lua_State *L); + + // get_true_builtin_path() + static int l_get_true_builtin_path(lua_State *L); // get_csm_restrictions() static int l_get_csm_restrictions(lua_State *L); diff --git a/src/script/scripting_client.cpp b/src/script/scripting_client.cpp index 4e90079bd..5778aa08e 100644 --- a/src/script/scripting_client.cpp +++ b/src/script/scripting_client.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_localplayer.h" #include "lua_api/l_camera.h" #include "lua_api/l_settings.h" +#include "lua_api/l_mainmenu.h" #include "lua_api/l_client_sound.h" ClientScripting::ClientScripting(Client *client): @@ -76,6 +77,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) ModChannelRef::Register(L); LuaSettings::Register(L); ClientSoundHandle::Register(L); + ModApiUtil::InitializeClient(L, top); ModApiClient::Initialize(L, top); @@ -85,6 +87,9 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) ModApiChannels::Initialize(L, top); ModApiParticlesLocal::Initialize(L, top); ModApiClientSound::Initialize(L, top); + + ModApiMainMenu::Initialize(L, top); + } void ClientScripting::on_client_ready(LocalPlayer *localplayer) diff --git a/src/script/scripting_client.h b/src/script/scripting_client.h index 3088029f0..a34b269f1 100644 --- a/src/script/scripting_client.h +++ b/src/script/scripting_client.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "cpp_api/s_client.h" #include "cpp_api/s_modchannels.h" #include "cpp_api/s_security.h" +#include "cpp_api/s_mainmenu.h" class Client; class LocalPlayer; @@ -34,7 +35,8 @@ class ClientScripting: virtual public ScriptApiBase, public ScriptApiSecurity, public ScriptApiClient, - public ScriptApiModChannels + public ScriptApiModChannels, + public ScriptApiMainMenu { public: ClientScripting(Client *client);