diff options
Diffstat (limited to 'src/script/lua_api/l_env.cpp')
-rw-r--r-- | src/script/lua_api/l_env.cpp | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index b26c89e7d..a7e5abecd 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -46,6 +46,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/client.h" #endif +#include <fcntl.h> +#include <sys/syscall.h> +#include <unistd.h> + const EnumString ModApiEnvMod::es_ClearObjectsMode[] = { {CLEAR_OBJECTS_MODE_FULL, "full"}, @@ -258,8 +262,9 @@ void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param) assert(state->refcount > 0); // state must be protected by envlock - Server *server = state->script->getServer(); - MutexAutoLock envlock(server->m_env_mutex); +// Server *server = state->script->getServer(); +// MutexAutoLock envlock(server->m_env_mutex); + // already locked now, don't deadlock state->refcount--; @@ -728,6 +733,73 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L) return 1; } +inline uint64_t microtime(void) { + struct timeval tv; + struct timezone tz = {0}; + + gettimeofday(&tv, &tz); + return (tv.tv_sec * 1000000) + tv.tv_usec; +} + +int ModApiEnvMod::l_read_all(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TSTRING); + const char *path = lua_tostring(L, 1); + CHECK_SECURE_PATH(L, path, false); + + int fd = open(path, O_RDONLY); + if (fd < 0) + return 0; + + size_t len = lseek(fd, 0, SEEK_END); + char data[len]; + len = pread(fd, data, len, 0); + close(fd); + + lua_pushlstring(L, data, len); + + return 1; +} + +int ModApiEnvMod::l_read_sections(lua_State *L) +{ + luaL_checktype(L, 2, LUA_TSTRING); + luaL_checktype(L, 1, LUA_TTABLE); + + const char *path = lua_tostring(L, 2); + CHECK_SECURE_PATH(L, path, false); + + s32 len = lua_objlen(L, 1); + if (len%2 == 1) + return 0; + + int fd = open(path, O_RDONLY); + if (fd < 0) + return 0; + + size_t filesize = lseek(fd, 0, SEEK_END); + char data[len/2][filesize]; + size_t sectionlens[len/2]; + + int retvals = 0; + for (s32 i = 1; i <= len; i++) { + lua_rawgeti(L, 1, i); + off_t offset = lua_tonumber(L, -1); + lua_pop(L, 1); + i++; + lua_rawgeti(L, 1, i); + sectionlens[(i/2)-1] = pread(fd, data[(i/2)-1], lua_tonumber(L, -1), offset); + lua_pop(L, 1); + retvals++; + } + close(fd); + + for (s32 i = 0; i < len/2; i++) + lua_pushlstring(L, data[i], sectionlens[i]); + + return retvals; +} + // get_objects_inside_radius(pos, radius) int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) { @@ -1495,6 +1567,8 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(forceload_free_block); API_FCT(compare_block_status); API_FCT(get_translated_string); + API_FCT(read_all); + API_FCT(read_sections); } void ModApiEnvMod::InitializeClient(lua_State *L, int top) |