]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/script/cpp_api/s_env.cpp
Use LuaErrors in security check macros
[dragonfireclient.git] / src / script / cpp_api / s_env.cpp
index b8717597a8f46f207b519c54fc784910c428505b..a1b11bfe16b727c07878b4a768edf0ecc0d425fc 100644 (file)
@@ -157,3 +157,42 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
        }
        lua_pop(L, 1);
 }
+
+void ScriptApiEnv::on_emerge_area_completion(
+       v3s16 blockpos, int action, ScriptCallbackState *state)
+{
+       Server *server = getServer();
+
+       // Note that the order of these locks is important!  Envlock must *ALWAYS*
+       // be acquired before attempting to acquire scriptlock, or else ServerThread
+       // will try to acquire scriptlock after it already owns envlock, thus
+       // deadlocking EmergeThread and ServerThread
+       MutexAutoLock envlock(server->m_env_mutex);
+
+       SCRIPTAPI_PRECHECKHEADER
+
+       int error_handler = PUSH_ERROR_HANDLER(L);
+
+       lua_rawgeti(L, LUA_REGISTRYINDEX, state->callback_ref);
+       luaL_checktype(L, -1, LUA_TFUNCTION);
+
+       push_v3s16(L, blockpos);
+       lua_pushinteger(L, action);
+       lua_pushinteger(L, state->refcount);
+       lua_rawgeti(L, LUA_REGISTRYINDEX, state->args_ref);
+
+       setOriginDirect(state->origin.c_str());
+
+       try {
+               PCALL_RES(lua_pcall(L, 4, 0, error_handler));
+       } catch (LuaError &e) {
+               server->setAsyncFatalError(e.what());
+       }
+
+       lua_pop(L, 1); // Pop error handler
+
+       if (state->refcount == 0) {
+               luaL_unref(L, LUA_REGISTRYINDEX, state->callback_ref);
+               luaL_unref(L, LUA_REGISTRYINDEX, state->args_ref);
+       }
+}