Pass a errfunc to lua_pcall to get a traceback
This commit is contained in:
parent
3f519eb729
commit
371b39a09a
@ -871,6 +871,8 @@ void read_groups(lua_State *L, int index,
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
void push_items(lua_State *L, const std::vector<ItemStack> &items)
|
void push_items(lua_State *L, const std::vector<ItemStack> &items)
|
||||||
{
|
{
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
// Get the table insert function
|
// Get the table insert function
|
||||||
lua_getglobal(L, "table");
|
lua_getglobal(L, "table");
|
||||||
lua_getfield(L, -1, "insert");
|
lua_getfield(L, -1, "insert");
|
||||||
@ -883,11 +885,12 @@ void push_items(lua_State *L, const std::vector<ItemStack> &items)
|
|||||||
lua_pushvalue(L, table_insert);
|
lua_pushvalue(L, table_insert);
|
||||||
lua_pushvalue(L, table);
|
lua_pushvalue(L, table);
|
||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, errorhandler))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
lua_remove(L, -2); // Remove table
|
|
||||||
lua_remove(L, -2); // Remove insert
|
lua_remove(L, -2); // Remove insert
|
||||||
|
lua_remove(L, -2); // Remove table
|
||||||
|
lua_remove(L, -2); // Remove error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -23,32 +23,41 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
std::string script_get_backtrace(lua_State *L)
|
std::string script_get_backtrace(lua_State *L)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
lua_getglobal(L, "debug");
|
||||||
if(lua_istable(L, -1)){
|
if(lua_istable(L, -1)){
|
||||||
lua_getfield(L, -1, "traceback");
|
lua_getfield(L, -1, "traceback");
|
||||||
if(lua_isfunction(L, -1)){
|
if(lua_isfunction(L, -1)) {
|
||||||
lua_call(L, 0, 1);
|
lua_call(L, 0, 1);
|
||||||
if(lua_isstring(L, -1)){
|
if(lua_isstring(L, -1)){
|
||||||
s += lua_tostring(L, -1);
|
s = lua_tostring(L, -1);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void script_error(lua_State *L, const char *fmt, ...)
|
int script_error_handler(lua_State *L) {
|
||||||
|
lua_getglobal(L, "debug");
|
||||||
|
if (!lua_istable(L, -1)) {
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua_getfield(L, -1, "traceback");
|
||||||
|
if (!lua_isfunction(L, -1)) {
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_pushinteger(L, 2);
|
||||||
|
lua_call(L, 2, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void script_error(lua_State *L)
|
||||||
{
|
{
|
||||||
va_list argp;
|
throw LuaError(NULL, lua_tostring(L, -1));
|
||||||
va_start(argp, fmt);
|
|
||||||
char buf[10000];
|
|
||||||
vsnprintf(buf, 10000, fmt, argp);
|
|
||||||
va_end(argp);
|
|
||||||
throw LuaError(L, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the list of callbacks (a lua table).
|
// Push the list of callbacks (a lua table).
|
||||||
@ -61,13 +70,20 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
|
|||||||
{
|
{
|
||||||
// Insert the return value into the lua stack, below the table
|
// Insert the return value into the lua stack, below the table
|
||||||
assert(lua_gettop(L) >= nargs + 1);
|
assert(lua_gettop(L) >= nargs + 1);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_insert(L, -(nargs + 1) - 1);
|
|
||||||
// Stack now looks like this:
|
|
||||||
// ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
|
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
int rv = lua_gettop(L) - nargs - 1;
|
int rv = lua_gettop(L) - nargs - 1;
|
||||||
int table = rv + 1;
|
lua_insert(L, rv);
|
||||||
|
|
||||||
|
// Insert error handler after return value
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = rv + 1;
|
||||||
|
lua_insert(L, errorhandler);
|
||||||
|
|
||||||
|
// Stack now looks like this:
|
||||||
|
// ... <return value = nil> <error handler> <table> <arg#1> <arg#2> ... <arg#n>
|
||||||
|
|
||||||
|
int table = errorhandler + 1;
|
||||||
int arg = table + 1;
|
int arg = table + 1;
|
||||||
|
|
||||||
luaL_checktype(L, table, LUA_TTABLE);
|
luaL_checktype(L, table, LUA_TTABLE);
|
||||||
@ -81,8 +97,8 @@ void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
|
|||||||
// Call function
|
// Call function
|
||||||
for(int i = 0; i < nargs; i++)
|
for(int i = 0; i < nargs; i++)
|
||||||
lua_pushvalue(L, arg+i);
|
lua_pushvalue(L, arg+i);
|
||||||
if(lua_pcall(L, nargs, 1, 0))
|
if(lua_pcall(L, nargs, 1, errorhandler))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
|
|
||||||
// Move return value to designated space in stack
|
// Move return value to designated space in stack
|
||||||
// Or pop it
|
// Or pop it
|
||||||
|
@ -64,9 +64,10 @@ enum RunCallbacksMode
|
|||||||
// are converted by lua_toboolean to true or false, respectively.
|
// are converted by lua_toboolean to true or false, respectively.
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string script_get_backtrace (lua_State *L);
|
std::string script_get_backtrace(lua_State *L);
|
||||||
void script_error (lua_State *L, const char *fmt, ...);
|
int script_error_handler(lua_State *L);
|
||||||
void script_run_callbacks (lua_State *L, int nargs,
|
void script_error(lua_State *L);
|
||||||
RunCallbacksMode mode);
|
void script_run_callbacks(lua_State *L, int nargs,
|
||||||
|
RunCallbacksMode mode);
|
||||||
|
|
||||||
#endif /* C_INTERNAL_H_ */
|
#endif /* C_INTERNAL_H_ */
|
||||||
|
@ -25,9 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
LuaError::LuaError(lua_State *L, const std::string &s)
|
LuaError::LuaError(lua_State *L, const std::string &s)
|
||||||
{
|
{
|
||||||
m_s = "LuaError: ";
|
m_s = "LuaError: " + s;
|
||||||
m_s += s + "\n";
|
if (L) m_s += '\n' + script_get_backtrace(L);
|
||||||
m_s += script_get_backtrace(L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EnumString es_ItemType[] =
|
struct EnumString es_ItemType[] =
|
||||||
|
@ -55,23 +55,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int loadScript_ErrorHandler(lua_State *L) {
|
|
||||||
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
|
||||||
if (!lua_istable(L, -1)) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lua_getfield(L, -1, "traceback");
|
|
||||||
if (!lua_isfunction(L, -1)) {
|
|
||||||
lua_pop(L, 2);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_pushinteger(L, 2);
|
|
||||||
lua_call(L, 2, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ScriptApiBase
|
ScriptApiBase
|
||||||
@ -133,7 +116,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath)
|
|||||||
|
|
||||||
lua_State *L = getStack();
|
lua_State *L = getStack();
|
||||||
|
|
||||||
lua_pushcfunction(L, loadScript_ErrorHandler);
|
lua_pushcfunction(L, script_error_handler);
|
||||||
int errorhandler = lua_gettop(L);
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
|
int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
|
||||||
@ -144,7 +127,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath)
|
|||||||
errorstream<<std::endl;
|
errorstream<<std::endl;
|
||||||
errorstream<<lua_tostring(L, -1)<<std::endl;
|
errorstream<<lua_tostring(L, -1)<<std::endl;
|
||||||
errorstream<<std::endl;
|
errorstream<<std::endl;
|
||||||
errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
|
errorstream<<"======= END OF ERROR FROM LUA ========"<<std::endl;
|
||||||
lua_pop(L, 1); // Pop error message from stack
|
lua_pop(L, 1); // Pop error message from stack
|
||||||
lua_pop(L, 1); // Pop the error handler from stack
|
lua_pop(L, 1); // Pop the error handler from stack
|
||||||
return false;
|
return false;
|
||||||
@ -159,19 +142,13 @@ void ScriptApiBase::realityCheck()
|
|||||||
if(top >= 30){
|
if(top >= 30){
|
||||||
dstream<<"Stack is over 30:"<<std::endl;
|
dstream<<"Stack is over 30:"<<std::endl;
|
||||||
stackDump(dstream);
|
stackDump(dstream);
|
||||||
scriptError("Stack is over 30 (reality check)");
|
throw LuaError(m_luastack, "Stack is over 30 (reality check)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiBase::scriptError(const char *fmt, ...)
|
void ScriptApiBase::scriptError()
|
||||||
{
|
{
|
||||||
va_list argp;
|
throw LuaError(NULL, lua_tostring(m_luastack, -1));
|
||||||
va_start(argp, fmt);
|
|
||||||
char buf[10000];
|
|
||||||
vsnprintf(buf, 10000, fmt, argp);
|
|
||||||
va_end(argp);
|
|
||||||
//errorstream<<"SCRIPT ERROR: "<<buf;
|
|
||||||
throw LuaError(m_luastack, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiBase::stackDump(std::ostream &o)
|
void ScriptApiBase::stackDump(std::ostream &o)
|
||||||
|
@ -31,6 +31,7 @@ extern "C" {
|
|||||||
#include "jthread/jmutex.h"
|
#include "jthread/jmutex.h"
|
||||||
#include "jthread/jmutexautolock.h"
|
#include "jthread/jmutexautolock.h"
|
||||||
#include "common/c_types.h"
|
#include "common/c_types.h"
|
||||||
|
#include "common/c_internal.h"
|
||||||
|
|
||||||
#define SCRIPTAPI_LOCK_DEBUG
|
#define SCRIPTAPI_LOCK_DEBUG
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ protected:
|
|||||||
{ return m_luastack; }
|
{ return m_luastack; }
|
||||||
|
|
||||||
void realityCheck();
|
void realityCheck();
|
||||||
void scriptError(const char *fmt, ...);
|
void scriptError();
|
||||||
void stackDump(std::ostream &o);
|
void stackDump(std::ostream &o);
|
||||||
|
|
||||||
Server* getServer() { return m_server; }
|
Server* getServer() { return m_server; }
|
||||||
|
@ -78,25 +78,29 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
|
verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
|
||||||
|
|
||||||
// Get minetest.luaentities[id]
|
// Get minetest.luaentities[id]
|
||||||
luaentity_get(L,id);
|
luaentity_get(L, id);
|
||||||
int object = lua_gettop(L);
|
int object = lua_gettop(L);
|
||||||
|
|
||||||
// Get on_activate function
|
// Get on_activate function
|
||||||
lua_pushvalue(L, object);
|
|
||||||
lua_getfield(L, -1, "on_activate");
|
lua_getfield(L, -1, "on_activate");
|
||||||
if(!lua_isnil(L, -1)){
|
if(!lua_isnil(L, -1)) {
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
|
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
|
||||||
lua_pushinteger(L, dtime_s);
|
lua_pushinteger(L, dtime_s);
|
||||||
// Call with 3 arguments, 0 results
|
// Call with 3 arguments, 0 results
|
||||||
if(lua_pcall(L, 3, 0, 0))
|
if(lua_pcall(L, 3, 0, errorhandler))
|
||||||
scriptError("error running function on_activate: %s\n",
|
scriptError();
|
||||||
lua_tostring(L, -1));
|
} else {
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 2); // Pop object and error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiEntity::luaentity_Remove(u16 id)
|
void ScriptApiEntity::luaentity_Remove(u16 id)
|
||||||
@ -123,14 +127,16 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
|
//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
|
||||||
|
|
||||||
// Get minetest.luaentities[id]
|
// Get minetest.luaentities[id]
|
||||||
luaentity_get(L,id);
|
luaentity_get(L, id);
|
||||||
int object = lua_gettop(L);
|
int object = lua_gettop(L);
|
||||||
|
|
||||||
// Get get_staticdata function
|
// Get get_staticdata function
|
||||||
lua_pushvalue(L, object);
|
|
||||||
lua_getfield(L, -1, "get_staticdata");
|
lua_getfield(L, -1, "get_staticdata");
|
||||||
if(lua_isnil(L, -1))
|
if(lua_isnil(L, -1))
|
||||||
return "";
|
return "";
|
||||||
@ -138,11 +144,12 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
|
|||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
// Call with 1 arguments, 1 results
|
// Call with 1 arguments, 1 results
|
||||||
if(lua_pcall(L, 1, 1, 0))
|
if(lua_pcall(L, 1, 1, errorhandler))
|
||||||
scriptError("error running function get_staticdata: %s\n",
|
scriptError();
|
||||||
lua_tostring(L, -1));
|
lua_remove(L, object); // Remove object
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
|
|
||||||
size_t len=0;
|
size_t len = 0;
|
||||||
const char *s = lua_tolstring(L, -1, &len);
|
const char *s = lua_tolstring(L, -1, &len);
|
||||||
return std::string(s, len);
|
return std::string(s, len);
|
||||||
}
|
}
|
||||||
@ -192,10 +199,13 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
||||||
|
|
||||||
// Get minetest.luaentities[id]
|
// Get minetest.luaentities[id]
|
||||||
luaentity_get(L,id);
|
luaentity_get(L, id);
|
||||||
int object = lua_gettop(L);
|
int object = lua_gettop(L);
|
||||||
// State: object is at top of stack
|
// State: object is at top of stack
|
||||||
// Get step function
|
// Get step function
|
||||||
@ -206,8 +216,10 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
|
|||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
lua_pushnumber(L, dtime); // dtime
|
lua_pushnumber(L, dtime); // dtime
|
||||||
// Call with 2 arguments, 0 results
|
// Call with 2 arguments, 0 results
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, errorhandler))
|
||||||
scriptError("error running function 'on_step': %s\n", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_remove(L, object); // Remove object
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
|
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
|
||||||
@ -218,6 +230,9 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
||||||
|
|
||||||
// Get minetest.luaentities[id]
|
// Get minetest.luaentities[id]
|
||||||
@ -235,8 +250,10 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
|
|||||||
push_tool_capabilities(L, *toolcap);
|
push_tool_capabilities(L, *toolcap);
|
||||||
push_v3f(L, dir);
|
push_v3f(L, dir);
|
||||||
// Call with 5 arguments, 0 results
|
// Call with 5 arguments, 0 results
|
||||||
if(lua_pcall(L, 5, 0, 0))
|
if(lua_pcall(L, 5, 0, errorhandler))
|
||||||
scriptError("error running function 'on_punch': %s\n", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_remove(L, object); // Remove object
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls entity:on_rightclick(ObjectRef clicker)
|
// Calls entity:on_rightclick(ObjectRef clicker)
|
||||||
@ -245,6 +262,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
|
||||||
|
|
||||||
// Get minetest.luaentities[id]
|
// Get minetest.luaentities[id]
|
||||||
@ -259,7 +279,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
|
|||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
objectrefGetOrCreate(clicker); // Clicker reference
|
objectrefGetOrCreate(clicker); // Clicker reference
|
||||||
// Call with 2 arguments, 0 results
|
// Call with 2 arguments, 0 results
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, errorhandler))
|
||||||
scriptError("error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_remove(L, object); // Remove object
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ int ScriptApiDetached::detached_inventory_AllowMove(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "allow_move"))
|
if(!getDetachedInventoryCallback(name, "allow_move"))
|
||||||
return count;
|
return count;
|
||||||
@ -42,23 +45,19 @@ int ScriptApiDetached::detached_inventory_AllowMove(
|
|||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc);
|
||||||
// from_list
|
lua_pushstring(L, from_list.c_str()); // from_list
|
||||||
lua_pushstring(L, from_list.c_str());
|
lua_pushinteger(L, from_index + 1); // from_index
|
||||||
// from_index
|
lua_pushstring(L, to_list.c_str()); // to_list
|
||||||
lua_pushinteger(L, from_index + 1);
|
lua_pushinteger(L, to_index + 1); // to_index
|
||||||
// to_list
|
lua_pushinteger(L, count); // count
|
||||||
lua_pushstring(L, to_list.c_str());
|
objectrefGetOrCreate(player); // player
|
||||||
// to_index
|
if(lua_pcall(L, 7, 1, errorhandler))
|
||||||
lua_pushinteger(L, to_index + 1);
|
scriptError();
|
||||||
// count
|
|
||||||
lua_pushinteger(L, count);
|
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 7, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_move should return a number");
|
throw LuaError(L, "allow_move should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int ret = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 2); // Pop integer and error handler
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return number of accepted items to be put
|
// Return number of accepted items to be put
|
||||||
@ -69,28 +68,28 @@ int ScriptApiDetached::detached_inventory_AllowPut(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "allow_put"))
|
if(!getDetachedInventoryCallback(name, "allow_put"))
|
||||||
return stack.count; // All will be accepted
|
return stack.count; // All will be accepted
|
||||||
|
|
||||||
// Call function(inv, listname, index, stack, player)
|
// Call function(inv, listname, index, stack, player)
|
||||||
// inv
|
|
||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc); // inv
|
||||||
// listname
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
lua_pushstring(L, listname.c_str());
|
lua_pushinteger(L, index + 1); // index
|
||||||
// index
|
LuaItemStack::create(L, stack); // stack
|
||||||
lua_pushinteger(L, index + 1);
|
objectrefGetOrCreate(player); // player
|
||||||
// stack
|
if(lua_pcall(L, 5, 1, errorhandler))
|
||||||
LuaItemStack::create(L, stack);
|
scriptError();
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_put should return a number");
|
throw LuaError(L, "allow_put should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int ret = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 2); // Pop integer and error handler
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return number of accepted items to be taken
|
// Return number of accepted items to be taken
|
||||||
@ -101,28 +100,28 @@ int ScriptApiDetached::detached_inventory_AllowTake(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "allow_take"))
|
if(!getDetachedInventoryCallback(name, "allow_take"))
|
||||||
return stack.count; // All will be accepted
|
return stack.count; // All will be accepted
|
||||||
|
|
||||||
// Call function(inv, listname, index, stack, player)
|
// Call function(inv, listname, index, stack, player)
|
||||||
// inv
|
|
||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc); // inv
|
||||||
// listname
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
lua_pushstring(L, listname.c_str());
|
lua_pushinteger(L, index + 1); // index
|
||||||
// index
|
LuaItemStack::create(L, stack); // stack
|
||||||
lua_pushinteger(L, index + 1);
|
objectrefGetOrCreate(player); // player
|
||||||
// stack
|
if(lua_pcall(L, 5, 1, errorhandler))
|
||||||
LuaItemStack::create(L, stack);
|
scriptError();
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_take should return a number");
|
throw LuaError(L, "allow_take should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int ret = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 2); // Pop integer and error handler
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report moved items
|
// Report moved items
|
||||||
@ -134,6 +133,9 @@ void ScriptApiDetached::detached_inventory_OnMove(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "on_move"))
|
if(!getDetachedInventoryCallback(name, "on_move"))
|
||||||
return;
|
return;
|
||||||
@ -143,20 +145,15 @@ void ScriptApiDetached::detached_inventory_OnMove(
|
|||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc);
|
||||||
// from_list
|
lua_pushstring(L, from_list.c_str()); // from_list
|
||||||
lua_pushstring(L, from_list.c_str());
|
lua_pushinteger(L, from_index + 1); // from_index
|
||||||
// from_index
|
lua_pushstring(L, to_list.c_str()); // to_list
|
||||||
lua_pushinteger(L, from_index + 1);
|
lua_pushinteger(L, to_index + 1); // to_index
|
||||||
// to_list
|
lua_pushinteger(L, count); // count
|
||||||
lua_pushstring(L, to_list.c_str());
|
objectrefGetOrCreate(player); // player
|
||||||
// to_index
|
if(lua_pcall(L, 7, 0, errorhandler))
|
||||||
lua_pushinteger(L, to_index + 1);
|
scriptError();
|
||||||
// count
|
lua_pop(L, 1); // Pop error handler
|
||||||
lua_pushinteger(L, count);
|
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 7, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report put items
|
// Report put items
|
||||||
@ -167,6 +164,9 @@ void ScriptApiDetached::detached_inventory_OnPut(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "on_put"))
|
if(!getDetachedInventoryCallback(name, "on_put"))
|
||||||
return;
|
return;
|
||||||
@ -176,16 +176,13 @@ void ScriptApiDetached::detached_inventory_OnPut(
|
|||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc);
|
||||||
// listname
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
lua_pushstring(L, listname.c_str());
|
lua_pushinteger(L, index + 1); // index
|
||||||
// index
|
LuaItemStack::create(L, stack); // stack
|
||||||
lua_pushinteger(L, index + 1);
|
objectrefGetOrCreate(player); // player
|
||||||
// stack
|
if(lua_pcall(L, 5, 0, errorhandler))
|
||||||
LuaItemStack::create(L, stack);
|
scriptError();
|
||||||
// player
|
lua_pop(L, 1); // Pop error handler
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report taken items
|
// Report taken items
|
||||||
@ -196,6 +193,9 @@ void ScriptApiDetached::detached_inventory_OnTake(
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getDetachedInventoryCallback(name, "on_take"))
|
if(!getDetachedInventoryCallback(name, "on_take"))
|
||||||
return;
|
return;
|
||||||
@ -205,16 +205,13 @@ void ScriptApiDetached::detached_inventory_OnTake(
|
|||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.setDetached(name);
|
loc.setDetached(name);
|
||||||
InvRef::create(L, loc);
|
InvRef::create(L, loc);
|
||||||
// listname
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
lua_pushstring(L, listname.c_str());
|
lua_pushinteger(L, index + 1); // index
|
||||||
// index
|
LuaItemStack::create(L, stack); // stack
|
||||||
lua_pushinteger(L, index + 1);
|
objectrefGetOrCreate(player); // player
|
||||||
// stack
|
if(lua_pcall(L, 5, 0, errorhandler))
|
||||||
LuaItemStack::create(L, stack);
|
scriptError();
|
||||||
// player
|
lua_pop(L, 1); // Pop error handler
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves minetest.detached_inventories[name][callbackname]
|
// Retrieves minetest.detached_inventories[name][callbackname]
|
||||||
|
@ -34,6 +34,9 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getItemCallback(item.name.c_str(), "on_drop"))
|
if(!getItemCallback(item.name.c_str(), "on_drop"))
|
||||||
return false;
|
return false;
|
||||||
@ -42,10 +45,11 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
|
|||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
objectrefGetOrCreate(dropper);
|
objectrefGetOrCreate(dropper);
|
||||||
pushFloatPos(L, pos);
|
pushFloatPos(L, pos);
|
||||||
if(lua_pcall(L, 3, 1, 0))
|
if(lua_pcall(L, 3, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if(!lua_isnil(L, -1))
|
if(!lua_isnil(L, -1))
|
||||||
item = read_item(L,-1, getServer());
|
item = read_item(L,-1, getServer());
|
||||||
|
lua_pop(L, 2); // Pop item and error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +58,9 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getItemCallback(item.name.c_str(), "on_place"))
|
if(!getItemCallback(item.name.c_str(), "on_place"))
|
||||||
return false;
|
return false;
|
||||||
@ -62,10 +69,11 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
|
|||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
objectrefGetOrCreate(placer);
|
objectrefGetOrCreate(placer);
|
||||||
pushPointedThing(pointed);
|
pushPointedThing(pointed);
|
||||||
if(lua_pcall(L, 3, 1, 0))
|
if(lua_pcall(L, 3, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if(!lua_isnil(L, -1))
|
if(!lua_isnil(L, -1))
|
||||||
item = read_item(L,-1, getServer());
|
item = read_item(L,-1, getServer());
|
||||||
|
lua_pop(L, 2); // Pop item and error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +82,9 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
if(!getItemCallback(item.name.c_str(), "on_use"))
|
if(!getItemCallback(item.name.c_str(), "on_use"))
|
||||||
return false;
|
return false;
|
||||||
@ -82,10 +93,11 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
|
|||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
objectrefGetOrCreate(user);
|
objectrefGetOrCreate(user);
|
||||||
pushPointedThing(pointed);
|
pushPointedThing(pointed);
|
||||||
if(lua_pcall(L, 3, 1, 0))
|
if(lua_pcall(L, 3, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if(!lua_isnil(L, -1))
|
if(!lua_isnil(L, -1))
|
||||||
item = read_item(L,-1, getServer());
|
item = read_item(L,-1, getServer());
|
||||||
|
lua_pop(L, 2); // Pop item and error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +106,9 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "on_craft");
|
lua_getfield(L, -1, "on_craft");
|
||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
@ -106,10 +121,11 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
|
|||||||
push_items(L, items);
|
push_items(L, items);
|
||||||
|
|
||||||
InvRef::create(L, craft_inv);
|
InvRef::create(L, craft_inv);
|
||||||
if(lua_pcall(L, 4, 1, 0))
|
if(lua_pcall(L, 4, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if(!lua_isnil(L, -1))
|
if(!lua_isnil(L, -1))
|
||||||
item = read_item(L,-1, getServer());
|
item = read_item(L,-1, getServer());
|
||||||
|
lua_pop(L, 2); // Pop item and error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +134,9 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "craft_predict");
|
lua_getfield(L, -1, "craft_predict");
|
||||||
LuaItemStack::create(L, item);
|
LuaItemStack::create(L, item);
|
||||||
@ -130,10 +149,11 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
|
|||||||
push_items(L, items);
|
push_items(L, items);
|
||||||
|
|
||||||
InvRef::create(L, craft_inv);
|
InvRef::create(L, craft_inv);
|
||||||
if(lua_pcall(L, 4, 1, 0))
|
if(lua_pcall(L, 4, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if(!lua_isnil(L, -1))
|
if(!lua_isnil(L, -1))
|
||||||
item = read_item(L,-1, getServer());
|
item = read_item(L,-1, getServer());
|
||||||
|
lua_pop(L, 2); // Pop item and error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,15 +169,15 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
|
|||||||
|
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "registered_items");
|
lua_getfield(L, -1, "registered_items");
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2); // Remove minetest
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
lua_getfield(L, -1, name);
|
lua_getfield(L, -1, name);
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2); // Remove registered_items
|
||||||
// Should be a table
|
// Should be a table
|
||||||
if(lua_type(L, -1) != LUA_TTABLE)
|
if(lua_type(L, -1) != LUA_TTABLE)
|
||||||
{
|
{
|
||||||
// Report error and clean up
|
// Report error and clean up
|
||||||
errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
|
errorstream << "Item \"" << name << "\" not defined" << std::endl;
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// Try minetest.nodedef_default instead
|
// Try minetest.nodedef_default instead
|
||||||
@ -167,24 +187,16 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
|
|||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
}
|
}
|
||||||
lua_getfield(L, -1, callbackname);
|
lua_getfield(L, -1, callbackname);
|
||||||
lua_remove(L, -2);
|
lua_remove(L, -2); // Remove item def
|
||||||
// Should be a function or nil
|
// Should be a function or nil
|
||||||
if(lua_type(L, -1) == LUA_TFUNCTION)
|
if (lua_type(L, -1) == LUA_TFUNCTION) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
|
} else if (!lua_isnil(L, -1)) {
|
||||||
|
errorstream << "Item \"" << name << "\" callback \""
|
||||||
|
<< callbackname << "\" is not a function" << std::endl;
|
||||||
}
|
}
|
||||||
else if(lua_isnil(L, -1))
|
lua_pop(L, 1);
|
||||||
{
|
return false;
|
||||||
lua_pop(L, 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errorstream<<"Item \""<<name<<"\" callback \""
|
|
||||||
<<callbackname<<" is not a function"<<std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
|
void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
|
||||||
|
@ -37,29 +37,41 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Get handler function
|
// Get handler function
|
||||||
lua_getglobal(L, "engine");
|
lua_getglobal(L, "engine");
|
||||||
lua_getfield(L, -1, "event_handler");
|
lua_getfield(L, -1, "event_handler");
|
||||||
if(lua_isnil(L, -1))
|
lua_remove(L, -2); // Remove engine
|
||||||
|
if(lua_isnil(L, -1)) {
|
||||||
|
lua_pop(L, 1); // Pop event_handler
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
|
||||||
// Call it
|
// Call it
|
||||||
lua_pushstring(L, text.c_str());
|
lua_pushstring(L, text.c_str());
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error running function engine.event_handler: %s\n",
|
scriptError();
|
||||||
lua_tostring(L, -1));
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
|
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Get handler function
|
// Get handler function
|
||||||
lua_getglobal(L, "engine");
|
lua_getglobal(L, "engine");
|
||||||
lua_getfield(L, -1, "button_handler");
|
lua_getfield(L, -1, "button_handler");
|
||||||
if(lua_isnil(L, -1))
|
lua_remove(L, -2); // Remove engine
|
||||||
|
if(lua_isnil(L, -1)) {
|
||||||
|
lua_pop(L, 1); // Pop button handler
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
|
||||||
// Convert fields to lua table
|
// Convert fields to lua table
|
||||||
@ -74,7 +86,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call it
|
// Call it
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error running function engine.button_handler: %s\n",
|
scriptError();
|
||||||
lua_tostring(L, -1));
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -101,8 +104,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
|
|||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
pushnode(L, node, ndef);
|
pushnode(L, node, ndef);
|
||||||
objectrefGetOrCreate(puncher);
|
objectrefGetOrCreate(puncher);
|
||||||
if(lua_pcall(L, 3, 0, 0))
|
if(lua_pcall(L, 3, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +115,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -121,8 +128,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
|
|||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
pushnode(L, node, ndef);
|
pushnode(L, node, ndef);
|
||||||
objectrefGetOrCreate(digger);
|
objectrefGetOrCreate(digger);
|
||||||
if(lua_pcall(L, 3, 0, 0))
|
if(lua_pcall(L, 3, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +138,9 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -138,14 +149,18 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
|
|||||||
|
|
||||||
// Call function
|
// Call function
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
|
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -154,14 +169,18 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
|
|||||||
|
|
||||||
// Call function
|
// Call function
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
|
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -171,14 +190,18 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
|
|||||||
// Call function
|
// Call function
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
pushnode(L, node, ndef);
|
pushnode(L, node, ndef);
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
|
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// Push callback function on stack
|
// Push callback function on stack
|
||||||
@ -188,12 +211,10 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
|
|||||||
// Call function
|
// Call function
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
lua_pushnumber(L,dtime);
|
lua_pushnumber(L,dtime);
|
||||||
if(lua_pcall(L, 2, 1, 0))
|
if(lua_pcall(L, 2, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true)
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
return true;
|
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiNode::node_on_receive_fields(v3s16 p,
|
void ScriptApiNode::node_on_receive_fields(v3s16 p,
|
||||||
@ -203,6 +224,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -215,12 +239,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Call function
|
// Call function
|
||||||
// param 1
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, formname.c_str()); // formname
|
||||||
// param 2
|
lua_newtable(L); // fields
|
||||||
lua_pushstring(L, formname.c_str());
|
|
||||||
// param 3
|
|
||||||
lua_newtable(L);
|
|
||||||
for(std::map<std::string, std::string>::const_iterator
|
for(std::map<std::string, std::string>::const_iterator
|
||||||
i = fields.begin(); i != fields.end(); i++){
|
i = fields.begin(); i != fields.end(); i++){
|
||||||
const std::string &name = i->first;
|
const std::string &name = i->first;
|
||||||
@ -229,26 +250,37 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
|
|||||||
lua_pushlstring(L, value.c_str(), value.size());
|
lua_pushlstring(L, value.c_str(), value.size());
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
}
|
}
|
||||||
// param 4
|
objectrefGetOrCreate(sender); // player
|
||||||
objectrefGetOrCreate(sender);
|
if(lua_pcall(L, 4, 0, errorhandler))
|
||||||
if(lua_pcall(L, 4, 0, 0))
|
scriptError();
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiNode::node_falling_update(v3s16 p)
|
void ScriptApiNode::node_falling_update(v3s16 p)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
lua_getglobal(L, "nodeupdate");
|
lua_getglobal(L, "nodeupdate");
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptApiNode::node_falling_update_single(v3s16 p)
|
void ScriptApiNode::node_falling_update_single(v3s16 p)
|
||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
lua_getglobal(L, "nodeupdate_single");
|
lua_getglobal(L, "nodeupdate_single");
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
if(lua_pcall(L, 1, 0, 0))
|
if(lua_pcall(L, 1, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -47,25 +50,21 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
|
|||||||
return count;
|
return count;
|
||||||
|
|
||||||
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, from_list.c_str()); // from_list
|
||||||
// from_list
|
lua_pushinteger(L, from_index + 1); // from_index
|
||||||
lua_pushstring(L, from_list.c_str());
|
lua_pushstring(L, to_list.c_str()); // to_list
|
||||||
// from_index
|
lua_pushinteger(L, to_index + 1); // to_index
|
||||||
lua_pushinteger(L, from_index + 1);
|
lua_pushinteger(L, count); // count
|
||||||
// to_list
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushstring(L, to_list.c_str());
|
if(lua_pcall(L, 7, 1, errorhandler))
|
||||||
// to_index
|
scriptError();
|
||||||
lua_pushinteger(L, to_index + 1);
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
// count
|
|
||||||
lua_pushinteger(L, count);
|
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 7, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_metadata_inventory_move should return a number");
|
throw LuaError(L, "allow_metadata_inventory_move should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int num = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 1); // Pop integer
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return number of accepted items to be put
|
// Return number of accepted items to be put
|
||||||
@ -75,6 +74,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -88,21 +90,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
|
|||||||
return stack.count;
|
return stack.count;
|
||||||
|
|
||||||
// Call function(pos, listname, index, stack, player)
|
// Call function(pos, listname, index, stack, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
// listname
|
lua_pushinteger(L, index + 1); // index
|
||||||
lua_pushstring(L, listname.c_str());
|
LuaItemStack::create(L, stack); // stack
|
||||||
// index
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushinteger(L, index + 1);
|
if(lua_pcall(L, 5, 1, errorhandler))
|
||||||
// stack
|
scriptError();
|
||||||
LuaItemStack::create(L, stack);
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_metadata_inventory_put should return a number");
|
throw LuaError(L, "allow_metadata_inventory_put should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int num = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 1); // Pop integer
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return number of accepted items to be taken
|
// Return number of accepted items to be taken
|
||||||
@ -112,6 +112,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -125,21 +128,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
|
|||||||
return stack.count;
|
return stack.count;
|
||||||
|
|
||||||
// Call function(pos, listname, index, count, player)
|
// Call function(pos, listname, index, count, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
// listname
|
lua_pushinteger(L, index + 1); // index
|
||||||
lua_pushstring(L, listname.c_str());
|
LuaItemStack::create(L, stack); // stack
|
||||||
// index
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushinteger(L, index + 1);
|
if(lua_pcall(L, 5, 1, errorhandler))
|
||||||
// stack
|
scriptError();
|
||||||
LuaItemStack::create(L, stack);
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 1, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
if(!lua_isnumber(L, -1))
|
if(!lua_isnumber(L, -1))
|
||||||
throw LuaError(L, "allow_metadata_inventory_take should return a number");
|
throw LuaError(L, "allow_metadata_inventory_take should return a number");
|
||||||
return luaL_checkinteger(L, -1);
|
int num = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 1); // Pop integer
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report moved items
|
// Report moved items
|
||||||
@ -150,6 +151,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -163,22 +167,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, from_list.c_str()); // from_list
|
||||||
// from_list
|
lua_pushinteger(L, from_index + 1); // from_index
|
||||||
lua_pushstring(L, from_list.c_str());
|
lua_pushstring(L, to_list.c_str()); // to_list
|
||||||
// from_index
|
lua_pushinteger(L, to_index + 1); // to_index
|
||||||
lua_pushinteger(L, from_index + 1);
|
lua_pushinteger(L, count); // count
|
||||||
// to_list
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushstring(L, to_list.c_str());
|
if(lua_pcall(L, 7, 0, errorhandler))
|
||||||
// to_index
|
scriptError();
|
||||||
lua_pushinteger(L, to_index + 1);
|
lua_pop(L, 1); // Pop error handler
|
||||||
// count
|
|
||||||
lua_pushinteger(L, count);
|
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 7, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report put items
|
// Report put items
|
||||||
@ -188,6 +186,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -201,18 +202,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Call function(pos, listname, index, stack, player)
|
// Call function(pos, listname, index, stack, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
// listname
|
lua_pushinteger(L, index + 1); // index
|
||||||
lua_pushstring(L, listname.c_str());
|
LuaItemStack::create(L, stack); // stack
|
||||||
// index
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushinteger(L, index + 1);
|
if(lua_pcall(L, 5, 0, errorhandler))
|
||||||
// stack
|
scriptError();
|
||||||
LuaItemStack::create(L, stack);
|
lua_pop(L, 1); // Pop error handler
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report taken items
|
// Report taken items
|
||||||
@ -222,6 +219,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
INodeDefManager *ndef = getServer()->ndef();
|
INodeDefManager *ndef = getServer()->ndef();
|
||||||
|
|
||||||
// If node doesn't exist, we don't know what callback to call
|
// If node doesn't exist, we don't know what callback to call
|
||||||
@ -235,18 +235,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Call function(pos, listname, index, stack, player)
|
// Call function(pos, listname, index, stack, player)
|
||||||
// pos
|
push_v3s16(L, p); // pos
|
||||||
push_v3s16(L, p);
|
lua_pushstring(L, listname.c_str()); // listname
|
||||||
// listname
|
lua_pushinteger(L, index + 1); // index
|
||||||
lua_pushstring(L, listname.c_str());
|
LuaItemStack::create(L, stack); // stack
|
||||||
// index
|
objectrefGetOrCreate(player); // player
|
||||||
lua_pushinteger(L, index + 1);
|
if(lua_pcall(L, 5, 0, errorhandler))
|
||||||
// stack
|
scriptError();
|
||||||
LuaItemStack::create(L, stack);
|
lua_pop(L, 1); // Pop error handler
|
||||||
// player
|
|
||||||
objectrefGetOrCreate(player);
|
|
||||||
if(lua_pcall(L, 5, 0, 0))
|
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptApiNodemeta::ScriptApiNodemeta() {
|
ScriptApiNodemeta::ScriptApiNodemeta() {
|
||||||
|
@ -27,13 +27,18 @@ bool ScriptApiServer::getAuth(const std::string &playername,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
getAuthHandler();
|
getAuthHandler();
|
||||||
lua_getfield(L, -1, "get_auth");
|
lua_getfield(L, -1, "get_auth");
|
||||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||||
throw LuaError(L, "Authentication handler missing get_auth");
|
throw LuaError(L, "Authentication handler missing get_auth");
|
||||||
lua_pushstring(L, playername.c_str());
|
lua_pushstring(L, playername.c_str());
|
||||||
if(lua_pcall(L, 1, 1, 0))
|
if(lua_pcall(L, 1, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_remove(L, -2); // Remove auth handler
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
|
|
||||||
// nil = login not allowed
|
// nil = login not allowed
|
||||||
if(lua_isnil(L, -1))
|
if(lua_isnil(L, -1))
|
||||||
@ -49,8 +54,7 @@ bool ScriptApiServer::getAuth(const std::string &playername,
|
|||||||
|
|
||||||
lua_getfield(L, -1, "privileges");
|
lua_getfield(L, -1, "privileges");
|
||||||
if(!lua_istable(L, -1))
|
if(!lua_istable(L, -1))
|
||||||
throw LuaError(L,
|
throw LuaError(L, "Authentication handler didn't return privilege table");
|
||||||
"Authentication handler didn't return privilege table");
|
|
||||||
if(dst_privs)
|
if(dst_privs)
|
||||||
readPrivileges(-1, *dst_privs);
|
readPrivileges(-1, *dst_privs);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@ -68,6 +72,7 @@ void ScriptApiServer::getAuthHandler()
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_getfield(L, -1, "builtin_auth_handler");
|
lua_getfield(L, -1, "builtin_auth_handler");
|
||||||
}
|
}
|
||||||
|
lua_remove(L, -2); // Remove minetest
|
||||||
if(lua_type(L, -1) != LUA_TTABLE)
|
if(lua_type(L, -1) != LUA_TTABLE)
|
||||||
throw LuaError(L, "Authentication handler table not valid");
|
throw LuaError(L, "Authentication handler table not valid");
|
||||||
}
|
}
|
||||||
@ -96,14 +101,19 @@ void ScriptApiServer::createAuth(const std::string &playername,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
getAuthHandler();
|
getAuthHandler();
|
||||||
lua_getfield(L, -1, "create_auth");
|
lua_getfield(L, -1, "create_auth");
|
||||||
|
lua_remove(L, -2); // Remove auth handler
|
||||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||||
throw LuaError(L, "Authentication handler missing create_auth");
|
throw LuaError(L, "Authentication handler missing create_auth");
|
||||||
lua_pushstring(L, playername.c_str());
|
lua_pushstring(L, playername.c_str());
|
||||||
lua_pushstring(L, password.c_str());
|
lua_pushstring(L, password.c_str());
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptApiServer::setPassword(const std::string &playername,
|
bool ScriptApiServer::setPassword(const std::string &playername,
|
||||||
@ -111,14 +121,19 @@ bool ScriptApiServer::setPassword(const std::string &playername,
|
|||||||
{
|
{
|
||||||
SCRIPTAPI_PRECHECKHEADER
|
SCRIPTAPI_PRECHECKHEADER
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
getAuthHandler();
|
getAuthHandler();
|
||||||
lua_getfield(L, -1, "set_password");
|
lua_getfield(L, -1, "set_password");
|
||||||
|
lua_remove(L, -2); // Remove auth handler
|
||||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||||
throw LuaError(L, "Authentication handler missing set_password");
|
throw LuaError(L, "Authentication handler missing set_password");
|
||||||
lua_pushstring(L, playername.c_str());
|
lua_pushstring(L, playername.c_str());
|
||||||
lua_pushstring(L, password.c_str());
|
lua_pushstring(L, password.c_str());
|
||||||
if(lua_pcall(L, 2, 1, 0))
|
if(lua_pcall(L, 2, 1, errorhandler))
|
||||||
scriptError("error: %s", lua_tostring(L, -1));
|
scriptError();
|
||||||
|
lua_remove(L, -2); // Remove error handler
|
||||||
return lua_toboolean(L, -1);
|
return lua_toboolean(L, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define L_BASE_H_
|
#define L_BASE_H_
|
||||||
|
|
||||||
#include "common/c_types.h"
|
#include "common/c_types.h"
|
||||||
|
#include "common/c_internal.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
@ -449,7 +449,7 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
|
|||||||
lua_pushstring(L, &tmpout.item[0]);
|
lua_pushstring(L, &tmpout.item[0]);
|
||||||
lua_setfield(L, -2, "output");
|
lua_setfield(L, -2, "output");
|
||||||
if (lua_pcall(L, 2, 0, 0))
|
if (lua_pcall(L, 2, 0, 0))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -53,28 +53,34 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
|
|||||||
assert(lua_checkstack(L, 20));
|
assert(lua_checkstack(L, 20));
|
||||||
StackUnroller stack_unroller(L);
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Get minetest.registered_abms
|
// Get minetest.registered_abms
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "registered_abms");
|
lua_getfield(L, -1, "registered_abms");
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
int registered_abms = lua_gettop(L);
|
lua_remove(L, -2); // Remove "minetest"
|
||||||
|
|
||||||
// Get minetest.registered_abms[m_id]
|
// Get minetest.registered_abms[m_id]
|
||||||
lua_pushnumber(L, m_id);
|
lua_pushnumber(L, m_id);
|
||||||
lua_gettable(L, registered_abms);
|
lua_gettable(L, -2);
|
||||||
if(lua_isnil(L, -1))
|
if(lua_isnil(L, -1))
|
||||||
assert(0);
|
assert(0);
|
||||||
|
lua_remove(L, -2); // Remove "registered_abms"
|
||||||
|
|
||||||
// Call action
|
// Call action
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
lua_getfield(L, -1, "action");
|
lua_getfield(L, -1, "action");
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
lua_remove(L, -2); // Remove "registered_abms[m_id]"
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
pushnode(L, n, env->getGameDef()->ndef());
|
pushnode(L, n, env->getGameDef()->ndef());
|
||||||
lua_pushnumber(L, active_object_count);
|
lua_pushnumber(L, active_object_count);
|
||||||
lua_pushnumber(L, active_object_count_wider);
|
lua_pushnumber(L, active_object_count_wider);
|
||||||
if(lua_pcall(L, 4, 0, 0))
|
if(lua_pcall(L, 4, 0, errorhandler))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
|
lua_pop(L, 1); // Pop error handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported functions
|
// Exported functions
|
||||||
@ -370,15 +376,21 @@ int ModApiEnvMod::l_add_item(lua_State *L)
|
|||||||
ItemStack item = read_item(L, 2,getServer(L));
|
ItemStack item = read_item(L, 2,getServer(L));
|
||||||
if(item.empty() || !item.isKnown(getServer(L)->idef()))
|
if(item.empty() || !item.isKnown(getServer(L)->idef()))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
lua_pushcfunction(L, script_error_handler);
|
||||||
|
int errorhandler = lua_gettop(L);
|
||||||
|
|
||||||
// Use minetest.spawn_item to spawn a __builtin:item
|
// Use minetest.spawn_item to spawn a __builtin:item
|
||||||
lua_getglobal(L, "minetest");
|
lua_getglobal(L, "minetest");
|
||||||
lua_getfield(L, -1, "spawn_item");
|
lua_getfield(L, -1, "spawn_item");
|
||||||
|
lua_remove(L, -2); // Remove minetest
|
||||||
if(lua_isnil(L, -1))
|
if(lua_isnil(L, -1))
|
||||||
return 0;
|
return 0;
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushstring(L, item.getItemString().c_str());
|
lua_pushstring(L, item.getItemString().c_str());
|
||||||
if(lua_pcall(L, 2, 1, 0))
|
if(lua_pcall(L, 2, 1, errorhandler))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
|
lua_remove(L, errorhandler); // Remove error handler
|
||||||
return 1;
|
return 1;
|
||||||
/*lua_pushvalue(L, 1);
|
/*lua_pushvalue(L, 1);
|
||||||
lua_pushstring(L, "__builtin:item");
|
lua_pushstring(L, "__builtin:item");
|
||||||
@ -441,7 +453,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
|
|||||||
lua_pushvalue(L, table);
|
lua_pushvalue(L, table);
|
||||||
getScriptApiBase(L)->objectrefGetOrCreate(obj);
|
getScriptApiBase(L)->objectrefGetOrCreate(obj);
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -569,7 +581,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
|||||||
lua_pushvalue(L, table);
|
lua_pushvalue(L, table);
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -333,7 +333,10 @@ int LuaPseudoRandom::l_next(lua_State *L)
|
|||||||
throw LuaError(L, "PseudoRandom.next(): max < min");
|
throw LuaError(L, "PseudoRandom.next(): max < min");
|
||||||
}
|
}
|
||||||
if(max - min != 32767 && max - min > 32767/5)
|
if(max - min != 32767 && max - min > 32767/5)
|
||||||
throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make.");
|
throw LuaError(L, "PseudoRandom.next() max-min is not 32767"
|
||||||
|
" and is > 32768/5. This is disallowed due to"
|
||||||
|
" the bad random distribution the"
|
||||||
|
" implementation would otherwise make.");
|
||||||
PseudoRandom &pseudo = o->m_pseudo;
|
PseudoRandom &pseudo = o->m_pseudo;
|
||||||
int val = pseudo.next();
|
int val = pseudo.next();
|
||||||
val = (val % (max-min+1)) + min;
|
val = (val % (max-min+1)) + min;
|
||||||
|
@ -66,7 +66,7 @@ int ModApiRollback::l_rollback_revert_actions_by(lua_State *L)
|
|||||||
lua_pushvalue(L, table);
|
lua_pushvalue(L, table);
|
||||||
lua_pushstring(L, i->c_str());
|
lua_pushstring(L, i->c_str());
|
||||||
if(lua_pcall(L, 2, 0, 0))
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
lua_remove(L, -2); // Remove table
|
lua_remove(L, -2); // Remove table
|
||||||
lua_remove(L, -2); // Remove insert
|
lua_remove(L, -2); // Remove insert
|
||||||
|
@ -220,6 +220,7 @@ int ModApiServer::l_get_modpath(lua_State *L)
|
|||||||
int ModApiServer::l_get_modnames(lua_State *L)
|
int ModApiServer::l_get_modnames(lua_State *L)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
// Get a list of mods
|
// Get a list of mods
|
||||||
std::list<std::string> mods_unsorted, mods_sorted;
|
std::list<std::string> mods_unsorted, mods_sorted;
|
||||||
getServer(L)->getModNames(mods_unsorted);
|
getServer(L)->getModNames(mods_unsorted);
|
||||||
@ -263,7 +264,7 @@ int ModApiServer::l_get_modnames(lua_State *L)
|
|||||||
lua_pushstring(L, (*i).c_str());
|
lua_pushstring(L, (*i).c_str());
|
||||||
if(lua_pcall(L, 2, 0, 0) != 0)
|
if(lua_pcall(L, 2, 0, 0) != 0)
|
||||||
{
|
{
|
||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user