Modernize lua read (part 2 & 3): C++ templating assurance (#7410)

* Modernize lua read (part 2 & 3): C++ templating assurance

Implement the boolean reader
Implement the string reader
Also remove unused & unimplemented script_error_handler
Add a reader with default value
This commit is contained in:
Loïc Blot 2018-06-30 17:11:38 +02:00 committed by GitHub
parent 227c71eb76
commit eef62c82a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 247 additions and 154 deletions

@ -316,6 +316,7 @@ LOCAL_SRC_FILES += \
jni/src/script/common/c_converter.cpp \
jni/src/script/common/c_internal.cpp \
jni/src/script/common/c_types.cpp \
jni/src/script/common/helper.cpp \
jni/src/script/cpp_api/s_async.cpp \
jni/src/script/cpp_api/s_base.cpp \
jni/src/script/cpp_api/s_client.cpp \

@ -3,6 +3,7 @@ set(common_SCRIPT_COMMON_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
${CMAKE_CURRENT_SOURCE_DIR}/helper.cpp
PARENT_SCOPE)
set(client_SCRIPT_COMMON_SRCS

@ -95,11 +95,10 @@ enum RunCallbacksMode
// after seeing the first true value
RUN_CALLBACKS_MODE_OR_SC,
// Note: "a true value" and "a false value" refer to values that
// are converted by lua_toboolean to true or false, respectively.
// are converted by readParam<bool> to true or false, respectively.
};
std::string script_get_backtrace(lua_State *L);
int script_error_handler(lua_State *L);
int script_exception_wrapper(lua_State *L, lua_CFunction f);
void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
void script_run_callbacks_f(lua_State *L, int nargs,

@ -0,0 +1,73 @@
/*
Minetest
Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "helper.h"
#include <cmath>
#include <sstream>
#include "c_types.h"
bool LuaHelper::isNaN(lua_State *L, int idx)
{
return lua_type(L, idx) == LUA_TNUMBER && std::isnan(lua_tonumber(L, idx));
}
/*
* Read template functions
*/
template <> bool LuaHelper::readParam(lua_State *L, int index)
{
return lua_toboolean(L, index) != 0;
}
template <> bool LuaHelper::readParam(lua_State *L, int index, const bool &default_value)
{
if (lua_isnil(L, index))
return default_value;
return lua_toboolean(L, index) != 0;
}
template <> float LuaHelper::readParam(lua_State *L, int index)
{
if (isNaN(L, index))
throw LuaError("NaN value is not allowed.");
return (float)luaL_checknumber(L, index);
}
template <> std::string LuaHelper::readParam(lua_State *L, int index)
{
std::string result;
const char *str = luaL_checkstring(L, index);
result.append(str);
return result;
}
template <>
std::string LuaHelper::readParam(
lua_State *L, int index, const std::string &default_value)
{
std::string result;
const char *str = lua_tostring(L, index);
if (str)
result.append(str);
else
result = default_value;
return result;
}

@ -0,0 +1,54 @@
/*
Minetest
Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
extern "C" {
#include <lua.h>
#include <lauxlib.h>
}
class LuaHelper
{
protected:
static bool isNaN(lua_State *L, int idx);
/**
* Read a value using a template type T from Lua State L and index
*
*
* @tparam T type to read from Lua
* @param L Lua state
* @param index Lua Index to read
* @return read value from Lua
*/
template <typename T> static T readParam(lua_State *L, int index);
/**
* Read a value using a template type T from Lua State L and index
*
* @tparam T type to read from Lua
* @param L Lua state
* @param index Lua Index to read
* @param default_value default value to apply if nil
* @return read value from Lua or default value if nil
*/
template <typename T>
static T readParam(lua_State *L, int index, const T &default_value);
};

@ -133,7 +133,7 @@ int ScriptApiBase::luaPanic(lua_State *L)
{
std::ostringstream oss;
oss << "LUA PANIC: unprotected error in call to Lua API ("
<< lua_tostring(L, -1) << ")";
<< readParam<std::string>(L, -1) << ")";
FATAL_ERROR(oss.str().c_str());
// NOTREACHED
return 0;
@ -184,7 +184,7 @@ void ScriptApiBase::loadScript(const std::string &script_path)
}
ok = ok && !lua_pcall(L, 0, 0, error_handler);
if (!ok) {
std::string error_msg = lua_tostring(L, -1);
std::string error_msg = readParam<std::string>(L, -1);
lua_pop(L, 2); // Pop error message and error handler
throw ModError("Failed to load and run script from " +
script_path + ":\n" + error_msg);
@ -286,10 +286,10 @@ void ScriptApiBase::stackDump(std::ostream &o)
int t = lua_type(m_luastack, i);
switch (t) {
case LUA_TSTRING: /* strings */
o << "\"" << lua_tostring(m_luastack, i) << "\"";
o << "\"" << readParam<std::string>(m_luastack, i) << "\"";
break;
case LUA_TBOOLEAN: /* booleans */
o << (lua_toboolean(m_luastack, i) ? "true" : "false");
o << (readParam<bool>(m_luastack, i) ? "true" : "false");
break;
case LUA_TNUMBER: /* numbers */ {
char buf[10];

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <thread>
#include <mutex>
#include <unordered_map>
#include "common/helper.h"
#include "util/basic_macros.h"
extern "C" {
@ -74,7 +75,7 @@ class GUIEngine;
class ServerActiveObject;
struct PlayerHPChangeReason;
class ScriptApiBase {
class ScriptApiBase : protected LuaHelper {
public:
ScriptApiBase(ScriptingType type);
// fake constructor to allow script API classes (e.g ScriptApiEnv) to virtually inherit from this one.

@ -57,8 +57,7 @@ bool ScriptApiClient::on_sending_message(const std::string &message)
// Call callbacks
lua_pushstring(L, message.c_str());
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
bool ate = lua_toboolean(L, -1);
return ate;
return readParam<bool>(L, -1);
}
bool ScriptApiClient::on_receiving_message(const std::string &message)
@ -71,8 +70,7 @@ bool ScriptApiClient::on_receiving_message(const std::string &message)
// Call callbacks
lua_pushstring(L, message.c_str());
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
bool ate = lua_toboolean(L, -1);
return ate;
return readParam<bool>(L, -1);
}
void ScriptApiClient::on_damage_taken(int32_t damage_amount)
@ -186,8 +184,7 @@ bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
bool blocked = lua_toboolean(L, -1);
return blocked;
return readParam<bool>(L, -1);
}
bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item)
@ -204,7 +201,7 @@ bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefini
// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
return lua_toboolean(L, -1);
return readParam<bool>(L, -1);
}
bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed)
@ -221,7 +218,7 @@ bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &poi
// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
return lua_toboolean(L, -1);
return readParam<bool>(L, -1);
}
bool ScriptApiClient::on_inventory_open(Inventory *inventory)
@ -242,7 +239,7 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory)
}
runCallbacks(1, RUN_CALLBACKS_MODE_OR);
return lua_toboolean(L, -1);
return readParam<bool>(L, -1);
}
void ScriptApiClient::setEnv(ClientEnvironment *env)

@ -257,7 +257,7 @@ bool ScriptApiEntity::luaentity_Punch(u16 id,
setOriginFromTable(object);
PCALL_RES(lua_pcall(L, 6, 1, error_handler));
bool retval = lua_toboolean(L, -1);
bool retval = readParam<bool>(L, -1);
lua_pop(L, 2); // Pop object and error handler
return retval;
}
@ -287,7 +287,7 @@ bool ScriptApiEntity::luaentity_run_simple_callback(u16 id,
setOriginFromTable(object);
PCALL_RES(lua_pcall(L, 2, 1, error_handler));
bool retval = lua_toboolean(L, -1);
bool retval = readParam<bool>(L, -1);
lua_pop(L, 2); // Pop object and error handler
return retval;
}

@ -116,12 +116,12 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
while (lua_next(L, table)) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
trigger_contents.emplace_back(lua_tostring(L, -1));
trigger_contents.emplace_back(readParam<std::string>(L, -1));
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, -1)) {
trigger_contents.emplace_back(lua_tostring(L, -1));
trigger_contents.emplace_back(readParam<std::string>(L, -1));
}
lua_pop(L, 1);
@ -133,12 +133,12 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
while (lua_next(L, table)) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
required_neighbors.emplace_back(lua_tostring(L, -1));
required_neighbors.emplace_back(readParam<std::string>(L, -1));
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, -1)) {
required_neighbors.emplace_back(lua_tostring(L, -1));
required_neighbors.emplace_back(readParam<std::string>(L, -1));
}
lua_pop(L, 1);
@ -185,12 +185,12 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
while (lua_next(L, table)) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
trigger_contents.insert(lua_tostring(L, -1));
trigger_contents.insert(readParam<std::string>(L, -1));
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, -1)) {
trigger_contents.insert(lua_tostring(L, -1));
trigger_contents.insert(readParam<std::string>(L, -1));
}
lua_pop(L, 1);

@ -192,7 +192,7 @@ bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
pushnode(L, newnode, ndef);
PCALL_RES(lua_pcall(L, 3, 1, error_handler));
lua_remove(L, error_handler);
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1);
return readParam<bool>(L, -1, false);
}
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
@ -231,7 +231,7 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
lua_pushnumber(L,dtime);
PCALL_RES(lua_pcall(L, 2, 1, error_handler));
lua_remove(L, error_handler);
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1);
return readParam<bool>(L, -1, false);
}
void ScriptApiNode::node_on_receive_fields(v3s16 p,

@ -74,7 +74,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
push_v3f(L, dir);
lua_pushnumber(L, damage);
runCallbacks(6, RUN_CALLBACKS_MODE_OR);
return lua_toboolean(L, -1);
return readParam<bool>(L, -1);
}
s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
@ -111,8 +111,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
// Call callbacks
objectrefGetOrCreate(L, player);
runCallbacks(1, RUN_CALLBACKS_MODE_OR);
bool positioning_handled_by_some = lua_toboolean(L, -1);
return positioning_handled_by_some;
return readParam<bool>(L, -1);
}
bool ScriptApiPlayer::on_prejoinplayer(
@ -129,7 +128,7 @@ bool ScriptApiPlayer::on_prejoinplayer(
lua_pushstring(L, ip.c_str());
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
if (lua_isstring(L, -1)) {
reason->assign(lua_tostring(L, -1));
reason->assign(readParam<std::string>(L, -1));
return true;
}
return false;

@ -524,7 +524,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
// Get mod name
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
if (lua_isstring(L, -1)) {
std::string mod_name = lua_tostring(L, -1);
std::string mod_name = readParam<std::string>(L, -1);
// Builtin can access anything
if (mod_name == BUILTIN_MOD_NAME) {
@ -649,7 +649,7 @@ int ScriptApiSecurity::sl_g_loadfile(lua_State *L)
lua_pop(L, 1);
if (script->getType() == ScriptingType::Client) {
std:: string display_path = lua_tostring(L, 1);
std::string display_path = readParam<std::string>(L, 1);
const std::string *path = script->getClient()->getModFile(display_path);
if (!path) {
std::string error_msg = "Coudln't find script called:" + display_path;

@ -88,7 +88,7 @@ void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
while (lua_next(L, index) != 0) {
// key at index -2 and value at index -1
std::string key = luaL_checkstring(L, -2);
bool value = lua_toboolean(L, -1);
bool value = readParam<bool>(L, -1);
if (value)
result.insert(key);
// removes value, keeps key for next iteration
@ -143,8 +143,7 @@ bool ScriptApiServer::on_chat_message(const std::string &name,
lua_pushstring(L, name.c_str());
lua_pushstring(L, message.c_str());
runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
bool ate = lua_toboolean(L, -1);
return ate;
return readParam<bool>(L, -1);
}
void ScriptApiServer::on_mods_loaded()

@ -156,7 +156,7 @@ int LuaAreaStore::l_get_areas_in_area(lua_State *L)
bool include_data = false;
bool accept_overlap = false;
if (lua_isboolean(L, 4)) {
accept_overlap = lua_toboolean(L, 4);
accept_overlap = readParam<bool>(L, 4);
get_data_and_border_flags(L, 5, &include_borders, &include_data);
}
std::vector<Area *> res;
@ -328,7 +328,7 @@ int LuaAreaStore::create_object(lua_State *L)
NO_MAP_LOCK_REQUIRED;
LuaAreaStore *o = (lua_isstring(L, 1)) ?
new LuaAreaStore(lua_tostring(L, 1)) :
new LuaAreaStore(readParam<std::string>(L, 1)) :
new LuaAreaStore();
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;

@ -63,8 +63,8 @@ GUIEngine *ModApiBase::getGuiEngine(lua_State *L)
std::string ModApiBase::getCurrentModPath(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
const char *current_mod_name = lua_tostring(L, -1);
if (!current_mod_name)
std::string current_mod_name = readParam<std::string>(L, -1, "");
if (current_mod_name.empty())
return ".";
const ModSpec *mod = getServer(L)->getModSpec(current_mod_name);
@ -85,20 +85,3 @@ bool ModApiBase::registerFunction(lua_State *L, const char *name,
return true;
}
bool ModApiBase::isNaN(lua_State *L, int idx)
{
return lua_type(L, idx) == LUA_TNUMBER && std::isnan(lua_tonumber(L, idx));
}
/*
* Read template functions
*/
template<>
float ModApiBase::readParam(lua_State *L, int index)
{
if (isNaN(L, index))
throw LuaError("NaN value is not allowed.");
return (float) luaL_checknumber(L, index);
}

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_types.h"
#include "common/c_internal.h"
#include "common/helper.h"
#include "gamedef.h"
extern "C" {
@ -37,7 +38,7 @@ class Server;
class Environment;
class GUIEngine;
class ModApiBase {
class ModApiBase : protected LuaHelper {
public:
static ScriptApiBase* getScriptApiBase(lua_State *L);
@ -69,17 +70,4 @@ public:
const char* name,
lua_CFunction func,
int top);
static bool isNaN(lua_State *L, int idx);
/**
* Read a value using a template type T from Lua State L and index
*
* @tparam T type to read from Lua
* @param L Lua state
* @param index Lua Index to read
* @return read value from Lua
*/
template<typename T>
static T readParam(lua_State *L, int index);
};

@ -46,8 +46,8 @@ int ModApiClient::l_get_current_modname(lua_State *L)
int ModApiClient::l_get_last_run_mod(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
const char *current_mod = lua_tostring(L, -1);
if (current_mod == NULL || current_mod[0] == '\0') {
std::string current_mod = readParam<std::string>(L, -1, "");
if (current_mod.empty()) {
lua_pop(L, 1);
lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str());
}
@ -303,7 +303,7 @@ int ModApiClient::l_get_item_def(lua_State *L)
if (!lua_isstring(L, 1))
return 0;
const std::string &name(lua_tostring(L, 1));
std::string name = readParam<std::string>(L, 1);
if (!idef->isKnown(name))
return 0;
const ItemDefinition &def = idef->get(name);
@ -331,7 +331,7 @@ int ModApiClient::l_get_node_def(lua_State *L)
return 0;
// clang-format on
const std::string &name = lua_tostring(L, 1);
std::string name = readParam<std::string>(L, 1);
const ContentFeatures &cf = ndef->get(ndef->getId(name));
if (cf.name != name) // Unknown node. | name = <whatever>, cf.name = ignore
return 0;

@ -57,7 +57,7 @@ bool ModApiCraft::readCraftRecipeShaped(lua_State *L, int index,
// key at index -2 and value at index -1
if(!lua_isstring(L, -1))
return false;
recipe.emplace_back(lua_tostring(L, -1));
recipe.emplace_back(readParam<std::string>(L, -1));
// removes value, keeps key for next iteration
lua_pop(L, 1);
colcount++;
@ -90,7 +90,7 @@ bool ModApiCraft::readCraftRecipeShapeless(lua_State *L, int index,
// key at index -2 and value at index -1
if(!lua_isstring(L, -1))
return false;
recipe.emplace_back(lua_tostring(L, -1));
recipe.emplace_back(readParam<std::string>(L, -1));
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
@ -115,12 +115,12 @@ bool ModApiCraft::readCraftReplacements(lua_State *L, int index,
lua_rawgeti(L, -1, 1);
if(!lua_isstring(L, -1))
return false;
std::string replace_from = lua_tostring(L, -1);
std::string replace_from = readParam<std::string>(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, -1, 2);
if(!lua_isstring(L, -1))
return false;
std::string replace_to = lua_tostring(L, -1);
std::string replace_to = readParam<std::string>(L, -1);
lua_pop(L, 1);
replacements.pairs.emplace_back(replace_from, replace_to);
// removes value, keeps key for next iteration

@ -165,10 +165,10 @@ int LuaRaycast::create_object(lua_State *L)
v3f pos1 = checkFloatPos(L, 1);
v3f pos2 = checkFloatPos(L, 2);
if (lua_isboolean(L, 3)) {
objects = lua_toboolean(L, 3);
objects = readParam<bool>(L, 3);
}
if (lua_isboolean(L, 4)) {
liquids = lua_toboolean(L, 4);
liquids = readParam<bool>(L, 4);
}
LuaRaycast *o = new LuaRaycast(core::line3d<f32>(pos1, pos2),
@ -757,15 +757,15 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
while (lua_next(L, 3) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
ndef->getIds(lua_tostring(L, -1), filter);
ndef->getIds(readParam<std::string>(L, -1), filter);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, 3)) {
ndef->getIds(lua_tostring(L, 3), filter);
ndef->getIds(readParam<std::string>(L, 3), filter);
}
int start_radius = (lua_toboolean(L, 4)) ? 0 : 1;
int start_radius = (lua_isboolean(L, 4) && readParam<bool>(L, 4)) ? 0 : 1;
#ifndef SERVER
// Client API limitations
@ -815,12 +815,12 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
while (lua_next(L, 3) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
ndef->getIds(lua_tostring(L, -1), filter);
ndef->getIds(readParam<std::string>(L, -1), filter);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, 3)) {
ndef->getIds(lua_tostring(L, 3), filter);
ndef->getIds(readParam<std::string>(L, 3), filter);
}
std::vector<u32> individual_count;
@ -884,12 +884,12 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
while (lua_next(L, 3) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
ndef->getIds(lua_tostring(L, -1), filter);
ndef->getIds(readParam<std::string>(L, -1), filter);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, 3)) {
ndef->getIds(lua_tostring(L, 3), filter);
ndef->getIds(readParam<std::string>(L, 3), filter);
}
lua_newtable(L);

@ -59,7 +59,7 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
lua_pop(L, 1);
}
} else if (lua_isstring(L, 2)) {
req.post_data = lua_tostring(L, 2);
req.post_data = readParam<std::string>(L, 2);
}
lua_pop(L, 1);
@ -154,7 +154,7 @@ int ModApiHttp::l_request_http_api(lua_State *L)
return 0;
}
const char *mod_name = lua_tostring(L, -1);
std::string mod_name = readParam<std::string>(L, -1);
std::string http_mods = g_settings->get("secure.http_mods");
http_mods.erase(std::remove(http_mods.begin(), http_mods.end(), ' '), http_mods.end());
std::vector<std::string> mod_list_http = str_split(http_mods, ',');

@ -336,7 +336,7 @@ int InvRef::l_contains_item(lua_State *L)
InventoryList *list = getlist(L, ref, listname);
bool match_meta = false;
if (lua_isboolean(L, 4))
match_meta = lua_toboolean(L, 4);
match_meta = readParam<bool>(L, 4);
if (list) {
lua_pushboolean(L, list->containsItem(item, match_meta));
} else {
@ -525,7 +525,7 @@ int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char *name = luaL_checkstring(L, 1);
const char *player = lua_isstring(L, 2) ? lua_tostring(L, 2) : "";
std::string player = readParam<std::string>(L, 2, "");
if (getServer(L)->createDetachedInventory(name, player) != NULL) {
InventoryLocation loc;
loc.setDetached(name);

@ -508,7 +508,7 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
std::string name;
lua_getfield(L, table, "name");
if(lua_isstring(L, -1)){
name = lua_tostring(L, -1);
name = readParam<std::string>(L, -1);
verbosestream<<"register_item_raw: "<<name<<std::endl;
} else {
throw LuaError("register_item_raw: name is not defined or not a string");

@ -83,7 +83,7 @@ int ModApiMainMenu::getBoolData(lua_State *L, std::string name,bool& valid)
}
valid = true;
return lua_toboolean(L, -1);
return readParam<bool>(L, -1);
}
/******************************************************************************/
@ -158,7 +158,7 @@ int ModApiMainMenu::l_set_background(lua_State *L)
unsigned int minsize = 16;
if (!lua_isnone(L, 3)) {
tile_image = lua_toboolean(L, 3);
tile_image = readParam<bool>(L, 3);
}
if (!lua_isnone(L, 4)) {
@ -195,7 +195,7 @@ int ModApiMainMenu::l_set_clouds(lua_State *L)
GUIEngine* engine = getGuiEngine(L);
sanity_check(engine != NULL);
bool value = lua_toboolean(L,1);
bool value = readParam<bool>(L,1);
engine->m_clouds_enabled = value;
@ -627,7 +627,8 @@ int ModApiMainMenu::l_set_topleft_text(lua_State *L)
int ModApiMainMenu::l_get_mapgen_names(lua_State *L)
{
std::vector<const char *> names;
Mapgen::getMapgenNames(&names, lua_toboolean(L, 1));
bool include_hidden = lua_isboolean(L, 1) && readParam<bool>(L, 1);
Mapgen::getMapgenNames(&names, include_hidden);
lua_newtable(L);
for (size_t i = 0; i != names.size(); i++) {
@ -722,7 +723,7 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
if ((!lua_isnone(L,3)) &&
(!lua_isnil(L,3))) {
keep_source = lua_toboolean(L,3);
keep_source = readParam<bool>(L,3);
}
std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
@ -871,7 +872,7 @@ int ModApiMainMenu::l_show_path_select_dialog(lua_State *L)
const char *formname= luaL_checkstring(L, 1);
const char *title = luaL_checkstring(L, 2);
bool is_file_select = lua_toboolean(L, 3);
bool is_file_select = readParam<bool>(L, 3);
GUIFileSelectMenu* fileOpenMenu =
new GUIFileSelectMenu(RenderingEngine::get_gui_env(),

@ -855,26 +855,26 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
lua_getfield(L, 1, "mgname");
if (lua_isstring(L, -1))
settingsmgr->setMapSetting("mg_name", lua_tostring(L, -1), true);
settingsmgr->setMapSetting("mg_name", readParam<std::string>(L, -1), true);
lua_getfield(L, 1, "seed");
if (lua_isnumber(L, -1))
settingsmgr->setMapSetting("seed", lua_tostring(L, -1), true);
settingsmgr->setMapSetting("seed", readParam<std::string>(L, -1), true);
lua_getfield(L, 1, "water_level");
if (lua_isnumber(L, -1))
settingsmgr->setMapSetting("water_level", lua_tostring(L, -1), true);
settingsmgr->setMapSetting("water_level", readParam<std::string>(L, -1), true);
lua_getfield(L, 1, "chunksize");
if (lua_isnumber(L, -1))
settingsmgr->setMapSetting("chunksize", lua_tostring(L, -1), true);
settingsmgr->setMapSetting("chunksize", readParam<std::string>(L, -1), true);
warn_if_field_exists(L, 1, "flagmask",
"Deprecated: flags field now includes unset flags.");
lua_getfield(L, 1, "flags");
if (lua_isstring(L, -1))
settingsmgr->setMapSetting("mg_flags", lua_tostring(L, -1), true);
settingsmgr->setMapSetting("mg_flags", readParam<std::string>(L, -1), true);
return 0;
}
@ -924,7 +924,7 @@ int ModApiMapgen::l_set_mapgen_setting(lua_State *L)
const char *name = luaL_checkstring(L, 1);
const char *value = luaL_checkstring(L, 2);
bool override_meta = lua_isboolean(L, 3) && lua_toboolean(L, 3);
bool override_meta = readParam<bool>(L, 3, false);
if (!settingsmgr->setMapSetting(name, value, override_meta)) {
errorstream << "set_mapgen_setting: cannot set '"
@ -953,7 +953,7 @@ int ModApiMapgen::l_set_mapgen_setting_noiseparams(lua_State *L)
return 0;
}
bool override_meta = lua_isboolean(L, 3) && lua_toboolean(L, 3);
bool override_meta = readParam<bool>(L, 3, false);
if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) {
errorstream << "set_mapgen_setting_noiseparams: cannot set '"
@ -979,7 +979,7 @@ int ModApiMapgen::l_set_noiseparams(lua_State *L)
return 0;
}
bool set_default = !lua_isboolean(L, 3) || lua_toboolean(L, 3);
bool set_default = !lua_isboolean(L, 3) || readParam<bool>(L, 3);
g_settings->setNoiseParams(name, np, set_default);
@ -1614,14 +1614,14 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
//// Read rotation
int rot = ROTATE_0;
const char *enumstr = lua_tostring(L, 3);
if (enumstr)
string_to_enum(es_Rotation, rot, std::string(enumstr));
std::string enumstr = readParam<std::string>(L, 3, "");
if (!enumstr.empty())
string_to_enum(es_Rotation, rot, enumstr);
//// Read force placement
bool force_placement = true;
if (lua_isboolean(L, 5))
force_placement = lua_toboolean(L, 5);
force_placement = readParam<bool>(L, 5);
//// Read node replacements
StringMap replace_names;
@ -1662,14 +1662,14 @@ int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L)
//// Read rotation
int rot = ROTATE_0;
const char *enumstr = lua_tostring(L, 4);
if (enumstr)
std::string enumstr = readParam<std::string>(L, 4, "");
if (!enumstr.empty())
string_to_enum(es_Rotation, rot, std::string(enumstr));
//// Read force placement
bool force_placement = true;
if (lua_isboolean(L, 6))
force_placement = lua_toboolean(L, 6);
force_placement = readParam<bool>(L, 6);
//// Read node replacements
StringMap replace_names;
@ -1720,9 +1720,9 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L)
//// Read format of definition to save as
int schem_format = SCHEM_FMT_MTS;
const char *enumstr = lua_tostring(L, 2);
if (enumstr)
string_to_enum(es_SchematicFormatType, schem_format, std::string(enumstr));
std::string enumstr = readParam<std::string>(L, 2, "");
if (!enumstr.empty())
string_to_enum(es_SchematicFormatType, schem_format, enumstr);
//// Serialize to binary string
std::ostringstream os(std::ios_base::binary);

@ -275,7 +275,7 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta)
lua_pushnil(L);
while (lua_next(L, fieldstable) != 0) {
// key at index -2 and value at index -1
std::string name = lua_tostring(L, -2);
std::string name = readParam<std::string>(L, -2);
size_t cl;
const char *cs = lua_tolstring(L, -1, &cl);
meta->setString(name, std::string(cs, cl));

@ -109,12 +109,12 @@ int NodeMetaRef::l_mark_as_private(lua_State *L)
while (lua_next(L, 2) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
meta->markPrivate(lua_tostring(L, -1), true);
meta->markPrivate(readParam<std::string>(L, -1), true);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
} else if (lua_isstring(L, 2)) {
meta->markPrivate(lua_tostring(L, 2), true);
meta->markPrivate(readParam<std::string>(L, 2), true);
}
ref->reportMetadataChange();

@ -156,7 +156,7 @@ int ObjectRef::l_move_to(lua_State *L)
// pos
v3f pos = checkFloatPos(L, 2);
// continuous
bool continuous = lua_toboolean(L, 3);
bool continuous = readParam<bool>(L, 3);
// Do it
co->moveTo(pos, continuous);
return 0;
@ -243,7 +243,8 @@ int ObjectRef::l_set_hp(lua_State *L)
lua_pushvalue(L, 3);
lua_getfield(L, -1, "type");
if (lua_isstring(L, -1) && !reason.setTypeFromString(lua_tostring(L, -1))) {
if (lua_isstring(L, -1) &&
!reason.setTypeFromString(readParam<std::string>(L, -1))) {
errorstream << "Bad type given!" << std::endl;
}
lua_pop(L, 1);
@ -466,7 +467,7 @@ int ObjectRef::l_set_animation(lua_State *L)
frame_blend = lua_tonumber(L, 4);
bool frame_loop = true;
if (lua_isboolean(L, 5))
frame_loop = lua_toboolean(L, 5);
frame_loop = readParam<bool>(L, 5);
co->setAnimation(frames, frame_speed, frame_blend, frame_loop);
return 0;
}
@ -609,7 +610,7 @@ int ObjectRef::l_set_bone_position(lua_State *L)
// Do it
std::string bone;
if (!lua_isnil(L, 2))
bone = lua_tostring(L, 2);
bone = readParam<std::string>(L, 2);
v3f position = v3f(0, 0, 0);
if (!lua_isnil(L, 3))
position = check_v3f(L, 3);
@ -631,7 +632,7 @@ int ObjectRef::l_get_bone_position(lua_State *L)
// Do it
std::string bone;
if (!lua_isnil(L, 2))
bone = lua_tostring(L, 2);
bone = readParam<std::string>(L, 2);
v3f position = v3f(0, 0, 0);
v3f rotation = v3f(0, 0, 0);
@ -668,7 +669,7 @@ int ObjectRef::l_set_attach(lua_State *L)
bone = "";
if (!lua_isnil(L, 3))
bone = lua_tostring(L, 3);
bone = readParam<std::string>(L, 3);
position = v3f(0, 0, 0);
if (!lua_isnil(L, 4))
position = read_v3f(L, 4);
@ -963,7 +964,7 @@ int ObjectRef::l_set_sprite(lua_State *L)
framelength = lua_tonumber(L, 4);
bool select_horiz_by_yawpitch = false;
if (!lua_isnil(L, 5))
select_horiz_by_yawpitch = lua_toboolean(L, 5);
select_horiz_by_yawpitch = readParam<bool>(L, 5);
co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
return 0;
}
@ -1536,7 +1537,7 @@ int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
if (player == NULL)
return 0;
std::string name = lua_tostring(L, 2);
std::string name = readParam<std::string>(L, 2);
getServer(L)->hudSetHotbarImage(player, name);
return 1;
@ -1565,7 +1566,7 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
if (player == NULL)
return 0;
std::string name = lua_tostring(L, 2);
std::string name = readParam<std::string>(L, 2);
getServer(L)->hudSetHotbarSelectedImage(player, name);
return 1;
@ -1605,7 +1606,7 @@ int ObjectRef::l_set_sky(lua_State *L)
while (lua_next(L, 4) != 0) {
// key at index -2 and value at index -1
if (lua_isstring(L, -1))
params.emplace_back(lua_tostring(L, -1));
params.emplace_back(readParam<std::string>(L, -1));
else
params.emplace_back("");
// removes value, keeps key for next iteration
@ -1618,7 +1619,7 @@ int ObjectRef::l_set_sky(lua_State *L)
bool clouds = true;
if (lua_isboolean(L, 5))
clouds = lua_toboolean(L, 5);
clouds = readParam<bool>(L, 5);
getServer(L)->setSky(player, bgcolor, type, params, clouds);
lua_pushboolean(L, true);

@ -66,7 +66,7 @@ int ModApiParticles::l_add_particle(lua_State *L)
acc = check_v3f(L, 3);
expirationtime = luaL_checknumber(L, 4);
size = luaL_checknumber(L, 5);
collisiondetection = lua_toboolean(L, 6);
collisiondetection = readParam<bool>(L, 6);
texture = luaL_checkstring(L, 7);
if (lua_gettop(L) == 8) // only spawn for a single player
playername = luaL_checkstring(L, 8);
@ -177,7 +177,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L)
maxexptime = luaL_checknumber(L, 10);
minsize = luaL_checknumber(L, 11);
maxsize = luaL_checknumber(L, 12);
collisiondetection = lua_toboolean(L, 13);
collisiondetection = readParam<bool>(L, 13);
texture = luaL_checkstring(L, 14);
if (lua_gettop(L) == 15) // only spawn for a single player
playername = luaL_checkstring(L, 15);

@ -33,7 +33,7 @@ int ModApiServer::l_request_shutdown(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char *msg = lua_tolstring(L, 1, NULL);
bool reconnect = lua_toboolean(L, 2);
bool reconnect = readParam<bool>(L, 2);
float seconds_before_shutdown = lua_tonumber(L, 3);
getServer(L)->requestShutdown(msg ? msg : "", reconnect, seconds_before_shutdown);
return 0;
@ -310,15 +310,11 @@ int ModApiServer::l_kick_player(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char *name = luaL_checkstring(L, 1);
std::string message;
std::string message("Kicked");
if (lua_isstring(L, 2))
{
message = std::string("Kicked: ") + lua_tostring(L, 2);
}
message.append(": ").append(readParam<std::string>(L, 2));
else
{
message = "Kicked.";
}
message.append(".");
RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
if (player == NULL) {
@ -475,7 +471,7 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
NO_MAP_LOCK_REQUIRED;
std::string name;
if(lua_isstring(L, 1))
name = lua_tostring(L, 1);
name = readParam<std::string>(L, 1);
getServer(L)->reportPrivsModified(name);
return 0;
}
@ -485,8 +481,8 @@ int ModApiServer::l_get_last_run_mod(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
const char *current_mod = lua_tostring(L, -1);
if (current_mod == NULL || current_mod[0] == '\0') {
std::string current_mod = readParam<std::string>(L, -1, "");
if (current_mod.empty()) {
lua_pop(L, 1);
lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str());
}

@ -102,7 +102,7 @@ int LuaSettings::l_get_bool(lua_State* L)
} else {
// Push default value
if (lua_isboolean(L, 3))
lua_pushboolean(L, lua_toboolean(L, 3));
lua_pushboolean(L, readParam<bool>(L, 3));
else
lua_pushnil(L);
}
@ -152,7 +152,7 @@ int LuaSettings::l_set_bool(lua_State* L)
LuaSettings* o = checkobject(L, 1);
std::string key = std::string(luaL_checkstring(L, 2));
bool value = lua_toboolean(L, 3);
bool value = readParam<bool>(L, 3);
SET_SECURITY_CHECK(L, key);

@ -28,7 +28,7 @@ int ModApiSound::l_sound_play(lua_State *L)
{
SimpleSoundSpec spec;
read_soundspec(L, 1, spec);
bool looped = lua_toboolean(L, 2);
bool looped = readParam<bool>(L, 2);
s32 handle = getGuiEngine(L)->playSound(spec, looped);

@ -30,7 +30,7 @@ int ModApiStorage::l_get_mod_storage(lua_State *L)
return 0;
}
std::string mod_name = lua_tostring(L, -1);
std::string mod_name = readParam<std::string>(L, -1);
ModMetadata *store = new ModMetadata(mod_name);
if (IGameDef *gamedef = getGameDef(L)) {

@ -135,7 +135,7 @@ int ModApiUtil::l_write_json(lua_State *L)
bool styled = false;
if (!lua_isnone(L, 2)) {
styled = lua_toboolean(L, 2);
styled = readParam<bool>(L, 2);
lua_pop(L, 1);
}
@ -231,7 +231,7 @@ int ModApiUtil::l_is_yes(lua_State *L)
lua_getglobal(L, "tostring"); // function to be called
lua_pushvalue(L, 1); // 1st argument
lua_call(L, 1, 1); // execute function
std::string str(lua_tostring(L, -1)); // get result
std::string str = readParam<std::string>(L, -1); // get result
lua_pop(L, 1);
bool yes = is_yes(str);
@ -342,7 +342,7 @@ int ModApiUtil::l_get_dir_list(lua_State *L)
NO_MAP_LOCK_REQUIRED;
const char *path = luaL_checkstring(L, 1);
bool list_all = !lua_isboolean(L, 2); // if its not a boolean list all
bool list_dirs = lua_toboolean(L, 2); // true: list dirs, false: list files
bool list_dirs = readParam<bool>(L, 2); // true: list dirs, false: list files
CHECK_SECURE_PATH(L, path, false);
@ -410,7 +410,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
}
// Check secure.trusted_mods
const char *mod_name = lua_tostring(L, -1);
std::string mod_name = readParam<std::string>(L, -1);
std::string trusted_mods = g_settings->get("secure.trusted_mods");
trusted_mods.erase(std::remove_if(trusted_mods.begin(),
trusted_mods.end(), static_cast<int(*)(int)>(&std::isspace)),
@ -451,7 +451,7 @@ int ModApiUtil::l_sha1(lua_State *L)
NO_MAP_LOCK_REQUIRED;
size_t size;
const char *data = luaL_checklstring(L, 1, &size);
bool hex = !lua_isboolean(L, 2) || !lua_toboolean(L, 2);
bool hex = !lua_isboolean(L, 2) || !readParam<bool>(L, 2);
// Compute actual checksum of data
std::string data_sha1;

@ -111,7 +111,7 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
MAP_LOCK_REQUIRED;
LuaVoxelManip *o = checkobject(L, 1);
bool update_light = !lua_isboolean(L, 2) || lua_toboolean(L, 2);
bool update_light = !lua_isboolean(L, 2) || readParam<bool>(L, 2);
GET_ENV_PTR;
ServerMap *map = &(env->getServerMap());
if (o->is_mapgen_vm || !update_light) {
@ -197,7 +197,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
v3s16 fpmax = vm->m_area.MaxEdge;
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock;
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock;
bool propagate_shadow = !lua_isboolean(L, 4) || lua_toboolean(L, 4);
bool propagate_shadow = !lua_isboolean(L, 4) || readParam<bool>(L, 4);
sortBoxVerticies(pmin, pmax);
if (!vm->m_area.contains(VoxelArea(pmin, pmax)))