From 664f5ce9605b580b9500547fff1e54eac553f295 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 19 Dec 2020 13:27:15 +0000 Subject: Add open user data button to main menu (#10579) --- src/script/lua_api/l_mainmenu.cpp | 21 ++++++++++++++++++++- src/script/lua_api/l_mainmenu.h | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/script') diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 0aa2760e9..0b0b2de3b 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -686,6 +686,14 @@ int ModApiMainMenu::l_get_mapgen_names(lua_State *L) } +/******************************************************************************/ +int ModApiMainMenu::l_get_user_path(lua_State *L) +{ + std::string path = fs::RemoveRelativePathComponents(porting::path_user); + lua_pushstring(L, path.c_str()); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_get_modpath(lua_State *L) { @@ -1067,7 +1075,15 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L) int ModApiMainMenu::l_open_url(lua_State *L) { std::string url = luaL_checkstring(L, 1); - lua_pushboolean(L, porting::openURL(url)); + lua_pushboolean(L, porting::open_url(url)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_open_dir(lua_State *L) +{ + std::string path = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::open_directory(path)); return 1; } @@ -1113,6 +1129,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(set_background); API_FCT(set_topleft_text); API_FCT(get_mapgen_names); + API_FCT(get_user_path); API_FCT(get_modpath); API_FCT(get_clientmodpath); API_FCT(get_gamepath); @@ -1134,6 +1151,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_min_supp_proto); API_FCT(get_max_supp_proto); API_FCT(open_url); + API_FCT(open_dir); API_FCT(do_async_callback); } @@ -1144,6 +1162,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(get_games); API_FCT(get_favorites); API_FCT(get_mapgen_names); + API_FCT(get_user_path); API_FCT(get_modpath); API_FCT(get_clientmodpath); API_FCT(get_gamepath); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 5a16b3bfe..faa2bf273 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -112,6 +112,8 @@ private: static int l_get_mainmenu_path(lua_State *L); + static int l_get_user_path(lua_State *L); + static int l_get_modpath(lua_State *L); static int l_get_clientmodpath(lua_State *L); @@ -148,6 +150,8 @@ private: // other static int l_open_url(lua_State *L); + static int l_open_dir(lua_State *L); + // async static int l_do_async_callback(lua_State *L); -- cgit v1.2.3 From 2c3593b51eef193eb543a08eb1e83c37e2fafe72 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 23 Dec 2020 16:39:29 +0000 Subject: Fix unsafe cast in l_object --- src/script/lua_api/l_object.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/script') diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index bc59bd55c..4d7a1bc41 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1409,7 +1409,7 @@ int ObjectRef::l_set_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *) getobject(ref); + PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1449,7 +1449,7 @@ int ObjectRef::l_get_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *)getobject(ref); + PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; -- cgit v1.2.3 From 74762470b2aa11a5271b846549ff14b86c1705d2 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 23 Dec 2020 22:03:49 +0100 Subject: Fix some minor code issues all over the place --- CMakeLists.txt | 8 +------- lib/lua/CMakeLists.txt | 13 ++----------- src/CMakeLists.txt | 23 ----------------------- src/client/content_cao.cpp | 4 ++-- src/client/game.cpp | 36 +++++------------------------------- src/client/hud.cpp | 6 +++--- src/client/mapblock_mesh.cpp | 4 ++-- src/client/tile.cpp | 7 +++++++ src/filesys.cpp | 22 ++++++++-------------- src/gui/touchscreengui.cpp | 3 +-- src/irrlicht_changes/CGUITTFont.h | 2 +- src/irrlicht_changes/irrUString.h | 4 ++-- src/mapgen/mapgen_v7.cpp | 2 +- src/mapgen/treegen.cpp | 3 ++- src/network/serverpackethandler.cpp | 2 +- src/nodedef.cpp | 2 +- src/script/cpp_api/s_security.cpp | 7 +++---- src/util/srp.cpp | 4 ++-- src/util/string.cpp | 2 +- 19 files changed, 45 insertions(+), 109 deletions(-) (limited to 'src/script') diff --git a/CMakeLists.txt b/CMakeLists.txt index 78d551168..1d53fcffd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,9 @@ -cmake_minimum_required(VERSION 2.6) - -if(${CMAKE_VERSION} STREQUAL "2.8.2") - # Bug http://vtk.org/Bug/view.php?id=11020 - message(WARNING "CMake/CPack version 2.8.2 will not create working .deb packages!") -endif() +cmake_minimum_required(VERSION 3.5) # This can be read from ${PROJECT_NAME} after project() is called project(minetest) set(PROJECT_NAME_CAPITALIZED "Minetest") -# Works only for cmake 3.1 and greater set(CMAKE_CXX_STANDARD 11) set(GCC_MINIMUM_VERSION "4.8") set(CLANG_MINIMUM_VERSION "3.4") diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt index 119dd6302..5d0dc0f70 100644 --- a/lib/lua/CMakeLists.txt +++ b/lib/lua/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 2.4 FATAL_ERROR) - project(lua C) set(LUA_VERSION_MAJOR 5) @@ -15,9 +13,8 @@ set(LIBS) if(APPLE) set(DEFAULT_POSIX TRUE) - set(DEFAULT_DLOPEN ON) - # use this on Mac OS X 10.3- - option(LUA_USE_MACOSX "Mac OS X 10.3-" OFF) + set(DEFAULT_DLOPEN OFF) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX") elseif(UNIX OR CYGWIN) set(DEFAULT_POSIX TRUE) elseif(WIN32) @@ -32,12 +29,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(DEFAULT_DLOPEN ON) endif() -# For "Mac OS X 10.3-" -if(LUA_USE_MACOSX) - set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX") - set(LUA_USE_DLOPEN FALSE) -endif(LUA_USE_MACOSX) - option(LUA_USE_DLOPEN "Enable dlopen support." ${DEFAULT_DLOPEN}) mark_as_advanced(LUA_USE_DLOPEN) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8ce69f1d..b6bba6e8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 2.6) - project(minetest) INCLUDE(CheckIncludeFiles) @@ -124,27 +122,6 @@ option(ENABLE_FREETYPE "Enable FreeType2 (TrueType fonts and basic unicode suppo set(USE_FREETYPE FALSE) if(ENABLE_FREETYPE) -## -## Note: FindFreetype.cmake seems to have been fixed in recent versions of -## CMake. If issues persist, re-enable this workaround specificially for the -## failing platforms. -## -# if(UNIX) -# include(FindPkgConfig) -# if(PKG_CONFIG_FOUND) -# pkg_check_modules(FREETYPE QUIET freetype2) -# if(FREETYPE_FOUND) -# SET(FREETYPE_PKGCONFIG_FOUND TRUE) -# SET(FREETYPE_LIBRARY ${FREETYPE_LIBRARIES}) -# # Because CMake is idiotic -# string(REPLACE ";" " " FREETYPE_CFLAGS_STR ${FREETYPE_CFLAGS}) -# string(REPLACE ";" " " FREETYPE_LDFLAGS_STR ${FREETYPE_LDFLAGS}) -# endif(FREETYPE_FOUND) -# endif(PKG_CONFIG_FOUND) -# endif(UNIX) -# if(NOT FREETYPE_FOUND) -# find_package(Freetype) -# endif() find_package(Freetype) if(FREETYPE_FOUND) message(STATUS "Freetype enabled.") diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index c645900aa..c65977b44 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1165,7 +1165,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } } - if (!getParent() && std::fabs(m_prop.automatic_rotate) > 0.001) { + if (!getParent() && node && fabs(m_prop.automatic_rotate) > 0.001f) { // This is the child node's rotation. It is only used for automatic_rotate. v3f local_rot = node->getRotation(); local_rot.Y = modulo360f(local_rot.Y - dtime * core::RADTODEG * @@ -1174,7 +1174,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } if (!getParent() && m_prop.automatic_face_movement_dir && - (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)) { + (fabs(m_velocity.Z) > 0.001f || fabs(m_velocity.X) > 0.001f)) { float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI + m_prop.automatic_face_movement_dir_offset; float max_rotation_per_sec = diff --git a/src/client/game.cpp b/src/client/game.cpp index 6151d2aa6..9e942f47a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -186,7 +186,7 @@ struct LocalFormspecHandler : public TextDest return; } - if (m_client && m_client->modsLoaded()) + if (m_client->modsLoaded()) m_client->getScript()->on_formspec_input(m_formname, fields); } @@ -583,7 +583,7 @@ public: virtual IShaderConstantSetter* create() { - GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter( + auto *scs = new GameGlobalShaderConstantSetter( m_sky, m_force_fog_off, m_fog_range, m_client); if (!m_sky) created_nosky.push_back(scs); @@ -1338,7 +1338,7 @@ bool Game::createClient(const GameStartData &start_data) return false; } - GameGlobalShaderConstantSetterFactory *scsf = new GameGlobalShaderConstantSetterFactory( + auto *scsf = new GameGlobalShaderConstantSetterFactory( &m_flags.force_fog_off, &runData.fog_range, client); shader_src->addShaderConstantSetterFactory(scsf); @@ -1348,20 +1348,14 @@ bool Game::createClient(const GameStartData &start_data) /* Camera */ camera = new Camera(*draw_control, client); - if (!camera || !camera->successfullyCreated(*error_message)) + if (!camera->successfullyCreated(*error_message)) return false; client->setCamera(camera); /* Clouds */ - if (m_cache_enable_clouds) { + if (m_cache_enable_clouds) clouds = new Clouds(smgr, -1, time(0)); - if (!clouds) { - *error_message = "Memory allocation error (clouds)"; - errorstream << *error_message << std::endl; - return false; - } - } /* Skybox */ @@ -1369,12 +1363,6 @@ bool Game::createClient(const GameStartData &start_data) scsf->setSky(sky); skybox = NULL; // This is used/set later on in the main run loop - if (!sky) { - *error_message = "Memory allocation error sky"; - errorstream << *error_message << std::endl; - return false; - } - /* Pre-calculated values */ video::ITexture *t = texture_src->getTexture("crack_anylength.png"); @@ -1404,12 +1392,6 @@ bool Game::createClient(const GameStartData &start_data) hud = new Hud(guienv, client, player, &player->inventory); - if (!hud) { - *error_message = "Memory error: could not create HUD"; - errorstream << *error_message << std::endl; - return false; - } - mapper = client->getMinimap(); if (mapper && client->modsLoaded()) @@ -1431,11 +1413,6 @@ bool Game::initGui() // Chat backend and console gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(), -1, chat_backend, client, &g_menumgr); - if (!gui_chat_console) { - *error_message = "Could not allocate memory for chat console"; - errorstream << *error_message << std::endl; - return false; - } #ifdef HAVE_TOUCHSCREENGUI @@ -1492,9 +1469,6 @@ bool Game::connectToServer(const GameStartData &start_data, itemdef_manager, nodedef_manager, sound, eventmgr, connect_address.isIPv6(), m_game_ui.get()); - if (!client) - return false; - client->m_simple_singleplayer_mode = simple_singleplayer_mode; infostream << "Connecting to server at "; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 8d8411ca1..e956c2738 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1055,9 +1055,9 @@ void drawItemStack( if (def.type == ITEM_TOOL && item.wear != 0) { // Draw a progressbar - float barheight = rect.getHeight() / 16; - float barpad_x = rect.getWidth() / 16; - float barpad_y = rect.getHeight() / 16; + float barheight = static_cast(rect.getHeight()) / 16; + float barpad_x = static_cast(rect.getWidth()) / 16; + float barpad_y = static_cast(rect.getHeight()) / 16; core::rect progressrect( rect.UpperLeftCorner.X + barpad_x, diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index dac25a066..4c43fcb61 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -1201,13 +1201,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): MapBlockMesh::~MapBlockMesh() { for (scene::IMesh *m : m_mesh) { - if (m_enable_vbo && m) + if (m_enable_vbo) { for (u32 i = 0; i < m->getMeshBufferCount(); i++) { scene::IMeshBuffer *buf = m->getMeshBuffer(i); RenderingEngine::get_video_driver()->removeHardwareBuffer(buf); } + } m->drop(); - m = NULL; } delete m_minimap_mapblock; } diff --git a/src/client/tile.cpp b/src/client/tile.cpp index d03588b2b..37836d0df 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -1633,6 +1633,13 @@ bool TextureSource::generateImagePart(std::string part_of_name, /* IMPORTANT: When changing this, getTextureForMesh() needs to be * updated too. */ + if (!baseimg) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + // Apply the "clean transparent" filter, if configured. if (g_settings->getBool("texture_clean_transparent")) imageCleanTransparent(baseimg, 127); diff --git a/src/filesys.cpp b/src/filesys.cpp index 2470b1b64..28a33f4d0 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -295,31 +295,26 @@ bool RecursiveDelete(const std::string &path) infostream<<"Removing \""<(argv)); // Execv shouldn't return. Failed. _exit(1); @@ -331,7 +326,6 @@ bool RecursiveDelete(const std::string &path) pid_t tpid; do{ tpid = wait(&child_status); - //if(tpid != child_pid) process_terminated(tpid); }while(tpid != child_pid); return (child_status == 0); } diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp index 0d64aa618..e1a971462 100644 --- a/src/gui/touchscreengui.cpp +++ b/src/gui/touchscreengui.cpp @@ -881,8 +881,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event) s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f; bool inside_joystick = (dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5); - if (m_joystick_has_really_moved || - (!m_joystick_has_really_moved && inside_joystick) || + if (m_joystick_has_really_moved || inside_joystick || (!m_fixed_joystick && distance_sq > m_touchscreen_threshold * m_touchscreen_threshold)) { m_joystick_has_really_moved = true; diff --git a/src/irrlicht_changes/CGUITTFont.h b/src/irrlicht_changes/CGUITTFont.h index cf64934a2..310f74f67 100644 --- a/src/irrlicht_changes/CGUITTFont.h +++ b/src/irrlicht_changes/CGUITTFont.h @@ -356,7 +356,7 @@ namespace gui load_flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER; if (!useHinting()) load_flags |= FT_LOAD_NO_HINTING; if (!useAutoHinting()) load_flags |= FT_LOAD_NO_AUTOHINT; - if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO | FT_RENDER_MODE_MONO; + if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO; else load_flags |= FT_LOAD_TARGET_NORMAL; } u32 getWidthFromCharacter(wchar_t c) const; diff --git a/src/irrlicht_changes/irrUString.h b/src/irrlicht_changes/irrUString.h index b628c092c..09172ee6d 100644 --- a/src/irrlicht_changes/irrUString.h +++ b/src/irrlicht_changes/irrUString.h @@ -1331,7 +1331,7 @@ public: { u32 i; const uchar16_t* oa = other.c_str(); - for(i=0; array[i] && oa[i] && i < n; ++i) + for(i=0; i < n && array[i] && oa[i]; ++i) if (array[i] != oa[i]) return false; @@ -1350,7 +1350,7 @@ public: if (!str) return false; u32 i; - for(i=0; array[i] && str[i] && i < n; ++i) + for(i=0; i < n && array[i] && str[i]; ++i) if (array[i] != str[i]) return false; diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp index cc5f5726d..91f004518 100644 --- a/src/mapgen/mapgen_v7.cpp +++ b/src/mapgen/mapgen_v7.cpp @@ -297,7 +297,7 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p) int iters = 256; while (iters > 0 && y <= max_spawn_y) { if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { - if (y <= water_level || y > max_spawn_y) + if (y <= water_level) return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point // y + 1 due to biome 'dust' diff --git a/src/mapgen/treegen.cpp b/src/mapgen/treegen.cpp index e633d800a..ec7771439 100644 --- a/src/mapgen/treegen.cpp +++ b/src/mapgen/treegen.cpp @@ -406,7 +406,8 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, v3f(position.X, position.Y, position.Z - 1), tree_definition ); - } if (!stack_orientation.empty()) { + } + if (!stack_orientation.empty()) { s16 size = 1; for (x = -size; x <= size; x++) for (y = -size; y <= size; y++) diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 3db4eb286..c636d01e1 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -316,7 +316,7 @@ void Server::handleCommand_Init2(NetworkPacket* pkt) // Send active objects { PlayerSAO *sao = getPlayerSAO(peer_id); - if (client && sao) + if (sao) SendActiveObjectRemoveAdd(client, sao); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 80013192d..f9d15a9f6 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -617,7 +617,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer, bool has_scale = tiledef.scale > 0; bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE || (tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale); - if (use_autoscale && layer->texture) { + if (use_autoscale) { auto texture_size = layer->texture->getOriginalSize(); float base_size = tsettings.node_texture_size; float size = std::fmin(texture_size.Width, texture_size.Height); diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 01333b941..63058d7c3 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -398,10 +398,9 @@ bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char lua_pushfstring(L, "%s: %s", path, strerror(errno)); return false; } - chunk_name = new char[strlen(display_name) + 2]; - chunk_name[0] = '@'; - chunk_name[1] = '\0'; - strcat(chunk_name, display_name); + size_t len = strlen(display_name) + 2; + chunk_name = new char[len]; + snprintf(chunk_name, len, "@%s", display_name); } size_t start = 0; diff --git a/src/util/srp.cpp b/src/util/srp.cpp index f4d369d68..ceb2fef9e 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -1015,10 +1015,10 @@ void srp_user_process_challenge(struct SRPUser *usr, goto cleanup_and_exit; *bytes_M = usr->M; - if (len_M) *len_M = hash_length(usr->hash_alg); + *len_M = hash_length(usr->hash_alg); } else { *bytes_M = NULL; - if (len_M) *len_M = 0; + *len_M = 0; } cleanup_and_exit: diff --git a/src/util/string.cpp b/src/util/string.cpp index 8381a29c5..3ac3b8cf0 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -633,7 +633,7 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color color_name = value; } - color_name = lowercase(value); + color_name = lowercase(color_name); std::map::const_iterator it; it = named_colors.colors.find(color_name); -- cgit v1.2.3 From 8f72d4b2940f0bd5486e38bd58127d14a1762be8 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Thu, 24 Dec 2020 14:48:05 +0100 Subject: Fix minetest.is_nan --- builtin/common/misc_helpers.lua | 4 ++++ src/script/lua_api/l_util.cpp | 11 ----------- src/script/lua_api/l_util.h | 3 --- 3 files changed, 4 insertions(+), 14 deletions(-) (limited to 'src/script') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index e29a9f422..0f3897f47 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -697,3 +697,7 @@ function core.privs_to_string(privs, delim) end return table.concat(list, delim) end + +function core.is_nan(number) + return number ~= number +end diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index cd63e20c2..6490eb578 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -239,15 +239,6 @@ int ModApiUtil::l_is_yes(lua_State *L) return 1; } -// is_nan(arg) -int ModApiUtil::l_is_nan(lua_State *L) -{ - NO_MAP_LOCK_REQUIRED; - - lua_pushboolean(L, isNaN(L, 1)); - return 1; -} - // get_builtin_path() int ModApiUtil::l_get_builtin_path(lua_State *L) { @@ -493,7 +484,6 @@ void ModApiUtil::Initialize(lua_State *L, int top) API_FCT(get_password_hash); API_FCT(is_yes); - API_FCT(is_nan); API_FCT(get_builtin_path); @@ -526,7 +516,6 @@ void ModApiUtil::InitializeClient(lua_State *L, int top) API_FCT(write_json); API_FCT(is_yes); - API_FCT(is_nan); API_FCT(compress); API_FCT(decompress); diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index 9ff91bb53..b6c1b58af 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -65,9 +65,6 @@ private: // is_yes(arg) static int l_is_yes(lua_State *L); - // is_nan(arg) - static int l_is_nan(lua_State *L); - // get_builtin_path() static int l_get_builtin_path(lua_State *L); -- cgit v1.2.3 From 9250b5205a6c627dfa18b7870b454d74f8d9dae6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein <54945686+EliasFleckenstein03@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:50:09 +0100 Subject: Add minetest.get_objects_in_area (#10668) --- doc/lua_api.txt | 3 +++ src/script/lua_api/l_env.cpp | 26 ++++++++++++++++++++++++++ src/script/lua_api/l_env.h | 3 +++ src/server/activeobjectmgr.cpp | 15 +++++++++++++++ src/server/activeobjectmgr.h | 3 +++ src/serverenvironment.h | 7 +++++++ 6 files changed, 57 insertions(+) (limited to 'src/script') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 708d6b0bc..800fc0c24 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4891,6 +4891,9 @@ Environment access * `minetest.get_objects_inside_radius(pos, radius)`: returns a list of ObjectRefs. * `radius`: using an euclidean metric +* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of + ObjectRefs. + * `pos1` and `pos2` are the min and max positions of the area to search. * `minetest.set_timeofday(val)` * `val` is between `0` and `1`; `0` for midnight, `0.5` for midday * `minetest.get_timeofday()` diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 021ef2ea7..c75fc8dc7 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -743,6 +743,31 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) return 1; } +// get_objects_in_area(pos, minp, maxp) +int ModApiEnvMod::l_get_objects_in_area(lua_State *L) +{ + GET_ENV_PTR; + ScriptApiBase *script = getScriptApiBase(L); + + v3f minp = read_v3f(L, 1) * BS; + v3f maxp = read_v3f(L, 2) * BS; + aabb3f box(minp, maxp); + box.repair(); + std::vector objs; + + auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); }; + env->getObjectsInArea(objs, box, include_obj_cb); + + int i = 0; + lua_createtable(L, objs.size(), 0); + for (const auto obj : objs) { + // Insert object reference into table + script->objectrefGetOrCreate(L, obj); + lua_rawseti(L, -2, ++i); + } + return 1; +} + // set_timeofday(val) // val = 0...1 int ModApiEnvMod::l_set_timeofday(lua_State *L) @@ -1413,6 +1438,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(get_node_timer); API_FCT(get_connected_players); API_FCT(get_player_by_name); + API_FCT(get_objects_in_area); API_FCT(get_objects_inside_radius); API_FCT(set_timeofday); API_FCT(get_timeofday); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 7f212b5fc..42c2d64f8 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -114,6 +114,9 @@ private: // get_objects_inside_radius(pos, radius) static int l_get_objects_inside_radius(lua_State *L); + + // get_objects_in_area(pos, minp, maxp) + static int l_get_objects_in_area(lua_State *L); // set_timeofday(val) // val = 0...1 diff --git a/src/server/activeobjectmgr.cpp b/src/server/activeobjectmgr.cpp index 1b8e31409..acd6611f4 100644 --- a/src/server/activeobjectmgr.cpp +++ b/src/server/activeobjectmgr.cpp @@ -127,6 +127,21 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius, } } +void ActiveObjectMgr::getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb) +{ + for (auto &activeObject : m_active_objects) { + ServerActiveObject *obj = activeObject.second; + const v3f &objectpos = obj->getBasePosition(); + if (!box.isPointInside(objectpos)) + continue; + + if (!include_obj_cb || include_obj_cb(obj)) + result.push_back(obj); + } +} + void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, std::queue &added_objects) diff --git a/src/server/activeobjectmgr.h b/src/server/activeobjectmgr.h index bc2085499..d43f5643c 100644 --- a/src/server/activeobjectmgr.h +++ b/src/server/activeobjectmgr.h @@ -38,6 +38,9 @@ public: void getObjectsInsideRadius(const v3f &pos, float radius, std::vector &result, std::function include_obj_cb); + void getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb); void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, diff --git a/src/serverenvironment.h b/src/serverenvironment.h index cfd5b8f3e..c76d34a37 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -331,6 +331,13 @@ public: { return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); } + + // Find all active objects inside a box + void getObjectsInArea(std::vector &objects, const aabb3f &box, + std::function include_obj_cb) + { + return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb); + } // Clear objects, loading and going through every MapBlock void clearObjects(ClearObjectsMode mode); -- cgit v1.2.3 From dd5a732fa90550066bb96305b64b6648903cc822 Mon Sep 17 00:00:00 2001 From: hecks <42101236+hecktest@users.noreply.github.com> Date: Sat, 2 Jan 2021 15:14:29 +0100 Subject: Add on_deactivate callback for luaentities (#10723) --- builtin/profiler/instrumentation.lua | 1 + doc/lua_api.txt | 2 ++ games/devtest/mods/testentities/callbacks.lua | 3 ++ src/script/cpp_api/s_entity.cpp | 26 ++++++++++++++ src/script/cpp_api/s_entity.h | 1 + src/script/lua_api/l_object.cpp | 2 +- src/server/luaentity_sao.cpp | 13 +++++-- src/server/luaentity_sao.h | 5 +++ src/server/player_sao.cpp | 2 +- src/server/serveractiveobject.cpp | 16 +++++++++ src/server/serveractiveobject.h | 50 +++++++++++++++++---------- src/serverenvironment.cpp | 12 ++++--- 12 files changed, 106 insertions(+), 27 deletions(-) (limited to 'src/script') diff --git a/builtin/profiler/instrumentation.lua b/builtin/profiler/instrumentation.lua index 237f048fb..6b951a2c2 100644 --- a/builtin/profiler/instrumentation.lua +++ b/builtin/profiler/instrumentation.lua @@ -160,6 +160,7 @@ local function init() -- Simple iteration would ignore lookup via __index. local entity_instrumentation = { "on_activate", + "on_deactivate", "on_step", "on_punch", "on_rightclick", diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 8bf6ade69..47c2776e6 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4207,6 +4207,8 @@ Callbacks: * Called when the object is instantiated. * `dtime_s` is the time passed since the object was unloaded, which can be used for updating the entity state. +* `on_deactivate(self) + * Called when the object is about to get removed or unloaded. * `on_step(self, dtime)` * Called on every server tick, after movement and collision processing. `dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting diff --git a/games/devtest/mods/testentities/callbacks.lua b/games/devtest/mods/testentities/callbacks.lua index 711079f87..320690b39 100644 --- a/games/devtest/mods/testentities/callbacks.lua +++ b/games/devtest/mods/testentities/callbacks.lua @@ -31,6 +31,9 @@ minetest.register_entity("testentities:callback", { on_activate = function(self, staticdata, dtime_s) message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s) end, + on_deactivate = function(self) + message("Callback entity: on_deactivate! pos="..spos(self)) + end, on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) local name = get_object_name(puncher) message( diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index ea9320051..746f7013e 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -103,6 +103,32 @@ void ScriptApiEntity::luaentity_Activate(u16 id, lua_pop(L, 2); // Pop object and error handler } +void ScriptApiEntity::luaentity_Deactivate(u16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "scriptapi_luaentity_deactivate: id=" << id << std::endl; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get the entity + luaentity_get(L, id); + int object = lua_gettop(L); + + // Get on_deactivate + lua_getfield(L, -1, "on_deactivate"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + } else { + lua_pop(L, 1); + } + lua_pop(L, 2); // Pop object and error handler +} + void ScriptApiEntity::luaentity_Remove(u16 id) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_entity.h b/src/script/cpp_api/s_entity.h index b5f7a6586..b52f6e447 100644 --- a/src/script/cpp_api/s_entity.h +++ b/src/script/cpp_api/s_entity.h @@ -33,6 +33,7 @@ public: bool luaentity_Add(u16 id, const char *name); void luaentity_Activate(u16 id, const std::string &staticdata, u32 dtime_s); + void luaentity_Deactivate(u16 id); void luaentity_Remove(u16 id); std::string luaentity_GetStaticdata(u16 id); void luaentity_GetProperties(u16 id, diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 4d7a1bc41..f52e4892e 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -110,7 +110,7 @@ int ObjectRef::l_remove(lua_State *L) sao->clearParentAttachment(); verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl; - sao->m_pending_removal = true; + sao->markForRemoval(); return 0; } diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index b39797531..c7277491a 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -112,6 +112,15 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) } } +void LuaEntitySAO::dispatchScriptDeactivate() +{ + // Ensure that this is in fact a registered entity, + // and that it isn't already gone. + // The latter also prevents this from ever being called twice. + if (m_registered && !isGone()) + m_env->getScriptIface()->luaentity_Deactivate(m_id); +} + void LuaEntitySAO::step(float dtime, bool send_recommended) { if(!m_properties_sent) @@ -302,7 +311,7 @@ u16 LuaEntitySAO::punch(v3f dir, { if (!m_registered) { // Delete unknown LuaEntities when punched - m_pending_removal = true; + markForRemoval(); return 0; } @@ -335,7 +344,7 @@ u16 LuaEntitySAO::punch(v3f dir, clearParentAttachment(); clearChildAttachments(); m_env->getScriptIface()->luaentity_on_death(m_id, puncher); - m_pending_removal = true; + markForRemoval(); } actionstream << puncher->getDescription() << " (id=" << puncher->getId() << diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index e060aa06d..6883ae1b9 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -71,6 +71,11 @@ public: bool getSelectionBox(aabb3f *toset) const; bool collideWithObjects() const; +protected: + void dispatchScriptDeactivate(); + virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(); } + virtual void onMarkedForRemoval() { dispatchScriptDeactivate(); } + private: std::string getPropertyPacket(); void sendPosition(bool do_interpolate, bool is_movement_end); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 62515d1c9..232c6a01d 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -531,7 +531,7 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item) void PlayerSAO::disconnected() { m_peer_id = PEER_ID_INEXISTENT; - m_pending_removal = true; + markForRemoval(); } void PlayerSAO::unlinkPlayerSessionAndSave() diff --git a/src/server/serveractiveobject.cpp b/src/server/serveractiveobject.cpp index 8cb59b2d6..96b433d1d 100644 --- a/src/server/serveractiveobject.cpp +++ b/src/server/serveractiveobject.cpp @@ -73,3 +73,19 @@ void ServerActiveObject::dumpAOMessagesToQueue(std::queue & m_messages_out.pop(); } } + +void ServerActiveObject::markForRemoval() +{ + if (!m_pending_removal) { + onMarkedForRemoval(); + m_pending_removal = true; + } +} + +void ServerActiveObject::markForDeactivation() +{ + if (!m_pending_deactivation) { + onMarkedForDeactivation(); + m_pending_deactivation = true; + } +} diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 2764d159e..25653a1ad 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -70,6 +70,10 @@ public: virtual bool environmentDeletes() const { return true; } + // Safely mark the object for removal or deactivation + void markForRemoval(); + void markForDeactivation(); + // Create a certain type of ServerActiveObject static ServerActiveObject* create(ActiveObjectType type, ServerEnvironment *env, u16 id, v3f pos, @@ -213,25 +217,6 @@ public: */ u16 m_known_by_count = 0; - /* - - Whether this object is to be removed when nobody knows about - it anymore. - - Removal is delayed to preserve the id for the time during which - it could be confused to some other object by some client. - - This is usually set to true by the step() method when the object wants - to be deleted but can be set by anything else too. - */ - bool m_pending_removal = false; - - /* - Same purpose as m_pending_removal but for deactivation. - deactvation = save static data in block, remove active object - - If this is set alongside with m_pending_removal, removal takes - priority. - */ - bool m_pending_deactivation = false; - /* A getter that unifies the above to answer the question: "Can the environment still interact with this object?" @@ -239,6 +224,9 @@ public: inline bool isGone() const { return m_pending_removal || m_pending_deactivation; } + inline bool isPendingRemoval() const + { return m_pending_removal; } + /* Whether the object's static data has been stored to a block */ @@ -250,6 +238,9 @@ public: v3s16 m_static_block = v3s16(1337,1337,1337); protected: + virtual void onMarkedForDeactivation() {} + virtual void onMarkedForRemoval() {} + virtual void onAttach(int parent_id) {} virtual void onDetach(int parent_id) {} @@ -257,6 +248,27 @@ protected: v3f m_base_position; std::unordered_set m_attached_particle_spawners; + /* + Same purpose as m_pending_removal but for deactivation. + deactvation = save static data in block, remove active object + + If this is set alongside with m_pending_removal, removal takes + priority. + Note: Do not assign this directly, use markForDeactivation() instead. + */ + bool m_pending_deactivation = false; + + /* + - Whether this object is to be removed when nobody knows about + it anymore. + - Removal is delayed to preserve the id for the time during which + it could be confused to some other object by some client. + - This is usually set to true by the step() method when the object wants + to be deleted but can be set by anything else too. + Note: Do not assign this directly, use markForRemoval() instead. + */ + bool m_pending_removal = false; + /* Queue of messages to be sent to the client */ diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index d044b003d..56dbb0632 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -1164,7 +1164,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode) // If known by some client, don't delete immediately if (obj->m_known_by_count > 0) { - obj->m_pending_removal = true; + obj->markForRemoval(); return false; } @@ -1792,7 +1792,7 @@ void ServerEnvironment::removeRemovedObjects() /* Delete static data from block if removed */ - if (obj->m_pending_removal) + if (obj->isPendingRemoval()) deleteStaticFromBlock(obj, id, MOD_REASON_REMOVE_OBJECTS_REMOVE, false); // If still known by clients, don't actually remove. On some future @@ -1803,7 +1803,7 @@ void ServerEnvironment::removeRemovedObjects() /* Move static data from active to stored if deactivated */ - if (!obj->m_pending_removal && obj->m_static_exists) { + if (!obj->isPendingRemoval() && obj->m_static_exists) { MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); if (block) { const auto i = block->m_static_objects.m_active.find(id); @@ -1991,6 +1991,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) if (!force_delete && obj->m_static_exists && !m_active_blocks.contains(obj->m_static_block) && m_active_blocks.contains(blockpos_o)) { + // Delete from block where object was located deleteStaticFromBlock(obj, id, MOD_REASON_STATIC_DATA_REMOVED, false); @@ -2068,6 +2069,10 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) force_delete = true; } + // Regardless of what happens to the object at this point, deactivate it first. + // This ensures that LuaEntity on_deactivate is always called. + obj->markForDeactivation(); + /* If known by some client, set pending deactivation. Otherwise delete it immediately. @@ -2077,7 +2082,6 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) << "object id=" << id << " is known by clients" << "; not deleting yet" << std::endl; - obj->m_pending_deactivation = true; return false; } -- cgit v1.2.3 From edd083601173c1b67a2e5cd88e23122f46b88bbf Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 4 Jan 2021 15:18:31 +0000 Subject: ContentDB: Add overwrite dialog when content is already installed (#10768) --- builtin/mainmenu/dlg_contentstore.lua | 74 ++++++++++++++++++++++++++++++++--- doc/menu_lua_api.txt | 2 + src/script/lua_api/l_mainmenu.cpp | 11 ++++++ src/script/lua_api/l_mainmenu.h | 2 + 4 files changed, 84 insertions(+), 5 deletions(-) (limited to 'src/script') diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 7f6b4b7e4..b5f71e753 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -437,12 +437,53 @@ function install_dialog.create(package, raw_deps) install_dialog.package = package install_dialog.raw_deps = raw_deps install_dialog.will_install_deps = true - return dialog_create("package_view", + return dialog_create("install_dialog", install_dialog.get_formspec, install_dialog.handle_submit, nil) end + +local confirm_overwrite = {} +function confirm_overwrite.get_formspec() + local package = confirm_overwrite.package + + return "size[11.5,4.5,true]" .. + "label[2,2;" .. + fgettext("\"$1\" already exists. Would you like to overwrite it?", package.name) .. "]".. + "style[install;bgcolor=red]" .. + "button[3.25,3.5;2.5,0.5;install;" .. fgettext("Overwrite") .. "]" .. + "button[5.75,3.5;2.5,0.5;cancel;" .. fgettext("Cancel") .. "]" +end + +function confirm_overwrite.handle_submit(this, fields) + if fields.cancel then + this:delete() + return true + end + + if fields.install then + this:delete() + confirm_overwrite.callback() + return true + end + + return false +end + +function confirm_overwrite.create(package, callback) + assert(type(package) == "table") + assert(type(callback) == "function") + + confirm_overwrite.package = package + confirm_overwrite.callback = callback + return dialog_create("confirm_overwrite", + confirm_overwrite.get_formspec, + confirm_overwrite.handle_submit, + nil) +end + + local function get_file_extension(path) local parts = path:split(".") return parts[#parts] @@ -858,14 +899,37 @@ function store.handle_submit(this, fields) assert(package) if fields["install_" .. i] then - local deps = get_raw_dependencies(package) - if deps and has_hard_deps(deps) then - local dlg = install_dialog.create(package, deps) + local install_parent + if package.type == "mod" then + install_parent = core.get_modpath() + elseif package.type == "game" then + install_parent = core.get_gamepath() + elseif package.type == "txp" then + install_parent = core.get_texturepath() + else + error("Unknown package type: " .. package.type) + end + + + local function on_confirm() + local deps = get_raw_dependencies(package) + if deps and has_hard_deps(deps) then + local dlg = install_dialog.create(package, deps) + dlg:set_parent(this) + this:hide() + dlg:show() + else + queue_download(package) + end + end + + if not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then + local dlg = confirm_overwrite.create(package, on_confirm) dlg:set_parent(this) this:hide() dlg:show() else - queue_download(package) + on_confirm() end return true diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 8908552d5..1bcf697e9 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -67,6 +67,8 @@ core.copy_dir(source,destination,keep_soure) (possible in async calls) ^ destination folder ^ keep_source DEFAULT true --> if set to false source is deleted after copying ^ returns true/false +core.is_dir(path) (possible in async calls) +^ returns true if path is a valid dir core.extract_zip(zipfile,destination) [unzip within path required] ^ zipfile to extract ^ destination folder to extract to diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 0b0b2de3b..5070ec7d4 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -803,6 +803,15 @@ int ModApiMainMenu::l_copy_dir(lua_State *L) return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_is_dir(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + + lua_pushboolean(L, fs::IsDir(path)); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_extract_zip(lua_State *L) { @@ -1139,6 +1148,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); + API_FCT(is_dir); API_FCT(extract_zip); API_FCT(may_modify_path); API_FCT(get_mainmenu_path); @@ -1172,6 +1182,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); + API_FCT(is_dir); //API_FCT(extract_zip); //TODO remove dependency to GuiEngine API_FCT(may_modify_path); API_FCT(download_file); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index faa2bf273..0b02ed892 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -132,6 +132,8 @@ private: static int l_copy_dir(lua_State *L); + static int l_is_dir(lua_State *L); + static int l_extract_zip(lua_State *L); static int l_may_modify_path(lua_State *L); -- cgit v1.2.3