mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu
This commit is contained in:
parent
6228d634fb
commit
4e1f50035e
153 changed files with 3725 additions and 3625 deletions
|
@ -2,8 +2,18 @@ add_subdirectory(common)
|
|||
add_subdirectory(cpp_api)
|
||||
add_subdirectory(lua_api)
|
||||
|
||||
set(SCRIPT_SRCS
|
||||
${SCRIPT_COMMON_SRCS}
|
||||
${SCRIPT_CPP_API_SRCS}
|
||||
${SCRIPT_LUA_API_SRCS}
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
|
||||
${common_SCRIPT_COMMON_SRCS}
|
||||
${common_SCRIPT_CPP_API_SRCS}
|
||||
${common_SCRIPT_LUA_API_SRCS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
|
||||
${minetest_SCRIPT_COMMON_SRCS}
|
||||
${minetest_SCRIPT_CPP_API_SRCS}
|
||||
${minetest_SCRIPT_LUA_API_SRCS}
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
set(SCRIPT_COMMON_SRCS
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_COMMON_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_COMMON_SRCS
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "tool.h"
|
||||
#include "server.h"
|
||||
#include "serverobject.h"
|
||||
#include "mapgen.h"
|
||||
|
||||
struct EnumString es_TileAnimationType[] =
|
||||
|
@ -694,8 +694,7 @@ void push_tool_capabilities(lua_State *L,
|
|||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void push_inventory_list(Inventory *inv, const char *name,
|
||||
lua_State *L)
|
||||
void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
|
||||
{
|
||||
InventoryList *invlist = inv->getList(name);
|
||||
if(invlist == NULL){
|
||||
|
@ -709,8 +708,8 @@ void push_inventory_list(Inventory *inv, const char *name,
|
|||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void read_inventory_list(Inventory *inv, const char *name,
|
||||
lua_State *L, int tableindex, Server* srv,int forcesize)
|
||||
void read_inventory_list(lua_State *L, int tableindex,
|
||||
Inventory *inv, const char *name, Server* srv, int forcesize)
|
||||
{
|
||||
if(tableindex < 0)
|
||||
tableindex = lua_gettop(L) + 1 + tableindex;
|
||||
|
|
|
@ -87,14 +87,13 @@ void read_object_properties (lua_State *L,
|
|||
int index,
|
||||
ObjectProperties *prop);
|
||||
|
||||
//TODO fix parameter oreder!
|
||||
void push_inventory_list (Inventory *inv,
|
||||
const char *name,
|
||||
lua_State *L);
|
||||
void read_inventory_list (Inventory *inv,
|
||||
const char *name,
|
||||
lua_State *L,
|
||||
void push_inventory_list (lua_State *L,
|
||||
Inventory *inv,
|
||||
const char *name);
|
||||
void read_inventory_list (lua_State *L,
|
||||
int tableindex,
|
||||
Inventory *inv,
|
||||
const char *name,
|
||||
Server* srv,
|
||||
int forcesize=-1);
|
||||
|
||||
|
|
|
@ -18,17 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "common/c_internal.h"
|
||||
#include "server.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
|
||||
ScriptApi* get_scriptapi(lua_State *L)
|
||||
{
|
||||
// Get server from registry
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
|
||||
ScriptApi* sapi_ptr = (ScriptApi*) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return sapi_ptr;
|
||||
}
|
||||
#include "debug.h"
|
||||
|
||||
std::string script_get_backtrace(lua_State *L)
|
||||
{
|
||||
|
@ -51,15 +41,108 @@ std::string script_get_backtrace(lua_State *L)
|
|||
return s;
|
||||
}
|
||||
|
||||
void script_error(lua_State* L,const char *fmt, ...)
|
||||
void script_error(lua_State *L, const char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
char buf[10000];
|
||||
vsnprintf(buf, 10000, fmt, argp);
|
||||
va_end(argp);
|
||||
//errorstream<<"SCRIPT ERROR: "<<buf;
|
||||
throw LuaError(L, buf);
|
||||
}
|
||||
|
||||
// Push the list of callbacks (a lua table).
|
||||
// Then push nargs arguments.
|
||||
// Then call this function, which
|
||||
// - runs the callbacks
|
||||
// - removes the table and arguments from the lua stack
|
||||
// - pushes the return value, computed depending on mode
|
||||
void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
|
||||
{
|
||||
// Insert the return value into the lua stack, below the table
|
||||
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>
|
||||
|
||||
int rv = lua_gettop(L) - nargs - 1;
|
||||
int table = rv + 1;
|
||||
int arg = table + 1;
|
||||
|
||||
luaL_checktype(L, table, LUA_TTABLE);
|
||||
|
||||
// Foreach
|
||||
lua_pushnil(L);
|
||||
bool first_loop = true;
|
||||
while(lua_next(L, table) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
// Call function
|
||||
for(int i = 0; i < nargs; i++)
|
||||
lua_pushvalue(L, arg+i);
|
||||
if(lua_pcall(L, nargs, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
|
||||
// Move return value to designated space in stack
|
||||
// Or pop it
|
||||
if(first_loop){
|
||||
// Result of first callback is always moved
|
||||
lua_replace(L, rv);
|
||||
first_loop = false;
|
||||
} else {
|
||||
// Otherwise, what happens depends on the mode
|
||||
if(mode == RUN_CALLBACKS_MODE_FIRST)
|
||||
lua_pop(L, 1);
|
||||
else if(mode == RUN_CALLBACKS_MODE_LAST)
|
||||
lua_replace(L, rv);
|
||||
else if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
if((bool)lua_toboolean(L, rv) == true &&
|
||||
(bool)lua_toboolean(L, -1) == false)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
if((bool)lua_toboolean(L, rv) == false &&
|
||||
(bool)lua_toboolean(L, -1) == true)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// Handle short circuit modes
|
||||
if(mode == RUN_CALLBACKS_MODE_AND_SC &&
|
||||
(bool)lua_toboolean(L, rv) == false)
|
||||
break;
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
|
||||
(bool)lua_toboolean(L, rv) == true)
|
||||
break;
|
||||
|
||||
// value removed, keep key for next iteration
|
||||
}
|
||||
|
||||
// Remove stuff from stack, leaving only the return value
|
||||
lua_settop(L, rv);
|
||||
|
||||
// Fix return value in case no callbacks were called
|
||||
if(first_loop){
|
||||
if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,34 +27,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef C_INTERNAL_H_
|
||||
#define C_INTERNAL_H_
|
||||
|
||||
class Server;
|
||||
class ScriptApi;
|
||||
#include <iostream>
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#define luamethod(class, name) {#name, class::l_##name}
|
||||
#define STACK_TO_SERVER(L) get_scriptapi(L)->getServer()
|
||||
#define API_FCT(name) registerFunction(L,#name,l_##name,top)
|
||||
#include "common/c_types.h"
|
||||
|
||||
#define REGISTER_LUA_REF(cln) \
|
||||
class ModApi_##cln : public ModApiBase { \
|
||||
public: \
|
||||
ModApi_##cln() : ModApiBase() {}; \
|
||||
bool Initialize(lua_State* L, int top) { \
|
||||
cln::Register(L); \
|
||||
return true; \
|
||||
}; \
|
||||
}; \
|
||||
ModApi_##cln macro_generated_prototype__##cln;
|
||||
// What script_run_callbacks does with the return values of callbacks.
|
||||
// Regardless of the mode, if only one callback is defined,
|
||||
// its return value is the total return value.
|
||||
// Modes only affect the case where 0 or >= 2 callbacks are defined.
|
||||
enum RunCallbacksMode
|
||||
{
|
||||
// Returns the return value of the first callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_FIRST,
|
||||
// Returns the return value of the last callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_LAST,
|
||||
// If any callback returns a false value, the first such is returned
|
||||
// Otherwise, the first callback's return value (trueish) is returned
|
||||
// Returns true if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_AND,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first false value
|
||||
RUN_CALLBACKS_MODE_AND_SC,
|
||||
// If any callback returns a true value, the first such is returned
|
||||
// Otherwise, the first callback's return value (falseish) is returned
|
||||
// Returns false if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_OR,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// 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.
|
||||
};
|
||||
|
||||
|
||||
ScriptApi* get_scriptapi (lua_State *L);
|
||||
std::string script_get_backtrace (lua_State *L);
|
||||
void script_error (lua_State *L, const char *fmt, ...);
|
||||
void script_run_callbacks (lua_State *L, int nargs,
|
||||
RunCallbacksMode mode);
|
||||
|
||||
#endif /* C_INTERNAL_H_ */
|
||||
|
|
|
@ -50,26 +50,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ModNameStorer
|
||||
{
|
||||
private:
|
||||
lua_State *L;
|
||||
public:
|
||||
ModNameStorer(lua_State *L_, const std::string modname):
|
||||
L(L_)
|
||||
{
|
||||
// Store current modname in registry
|
||||
lua_pushstring(L, modname.c_str());
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
~ModNameStorer()
|
||||
{
|
||||
// Clear current modname in registry
|
||||
lua_pushnil(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
};
|
||||
|
||||
class LuaError : public std::exception
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
set(SCRIPT_CPP_API_SRCS
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp
|
||||
|
@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scriptapi.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -17,31 +17,142 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "serverobject.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include "mods.h"
|
||||
#include "util/string.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdarg>
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "serverobject.h"
|
||||
|
||||
ScriptApiBase::ScriptApiBase() :
|
||||
m_luastackmutex(),
|
||||
#ifdef LOCK_DEBUG
|
||||
m_locked(false),
|
||||
#endif
|
||||
m_luastack(0),
|
||||
m_server(0),
|
||||
m_environment(0)
|
||||
class ModNameStorer
|
||||
{
|
||||
private:
|
||||
lua_State *L;
|
||||
public:
|
||||
ModNameStorer(lua_State *L_, const std::string modname):
|
||||
L(L_)
|
||||
{
|
||||
// Store current modname in registry
|
||||
lua_pushstring(L, modname.c_str());
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
~ModNameStorer()
|
||||
{
|
||||
// Clear current modname in registry
|
||||
lua_pushnil(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
};
|
||||
|
||||
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::ScriptApiBase()
|
||||
{
|
||||
m_luastackmutex.Init();
|
||||
|
||||
#ifdef SCRIPTAPI_LOCK_DEBUG
|
||||
m_locked = false;
|
||||
#endif
|
||||
|
||||
m_luastack = luaL_newstate();
|
||||
assert(m_luastack);
|
||||
|
||||
// Make the ScriptApiBase* accessible to ModApiBase
|
||||
lua_pushlightuserdata(m_luastack, this);
|
||||
lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi");
|
||||
|
||||
m_server = 0;
|
||||
m_environment = 0;
|
||||
m_guiengine = 0;
|
||||
}
|
||||
|
||||
ScriptApiBase::~ScriptApiBase()
|
||||
{
|
||||
lua_close(m_luastack);
|
||||
}
|
||||
|
||||
bool ScriptApiBase::loadMod(const std::string &scriptpath,
|
||||
const std::string &modname)
|
||||
{
|
||||
ModNameStorer modnamestorer(getStack(), modname);
|
||||
|
||||
if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
|
||||
errorstream<<"Error loading mod \""<<modname
|
||||
<<"\": modname does not follow naming conventions: "
|
||||
<<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
try{
|
||||
success = loadScript(scriptpath);
|
||||
}
|
||||
catch(LuaError &e){
|
||||
errorstream<<"Error loading mod \""<<modname
|
||||
<<"\": "<<e.what()<<std::endl;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ScriptApiBase::loadScript(const std::string &scriptpath)
|
||||
{
|
||||
verbosestream<<"Loading and running script from "<<scriptpath<<std::endl;
|
||||
|
||||
lua_State *L = getStack();
|
||||
|
||||
lua_pushcfunction(L, loadScript_ErrorHandler);
|
||||
int errorhandler = lua_gettop(L);
|
||||
|
||||
int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
|
||||
if(ret){
|
||||
errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
|
||||
errorstream<<"Failed to load and run script from "<<std::endl;
|
||||
errorstream<<scriptpath<<":"<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<lua_tostring(L, -1)<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
|
||||
lua_pop(L, 1); // Pop error message from stack
|
||||
lua_pop(L, 1); // Pop the error handler from stack
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 1); // Pop the error handler from stack
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptApiBase::realityCheck()
|
||||
{
|
||||
int top = lua_gettop(m_luastack);
|
||||
|
@ -52,7 +163,7 @@ void ScriptApiBase::realityCheck()
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptApiBase::scriptError(const char *fmt, ...)
|
||||
void ScriptApiBase::scriptError(const char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
|
@ -65,130 +176,34 @@ void ScriptApiBase::scriptError(const char *fmt, ...)
|
|||
|
||||
void ScriptApiBase::stackDump(std::ostream &o)
|
||||
{
|
||||
int i;
|
||||
int top = lua_gettop(m_luastack);
|
||||
for (i = 1; i <= top; i++) { /* repeat for each level */
|
||||
int t = lua_type(m_luastack, i);
|
||||
switch (t) {
|
||||
int i;
|
||||
int top = lua_gettop(m_luastack);
|
||||
for (i = 1; i <= top; i++) { /* repeat for each level */
|
||||
int t = lua_type(m_luastack, i);
|
||||
switch (t) {
|
||||
|
||||
case LUA_TSTRING: /* strings */
|
||||
o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
|
||||
break;
|
||||
case LUA_TSTRING: /* strings */
|
||||
o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
|
||||
break;
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER: /* numbers */ {
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
|
||||
o<<buf;
|
||||
break; }
|
||||
case LUA_TNUMBER: /* numbers */ {
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
|
||||
o<<buf;
|
||||
break; }
|
||||
|
||||
default: /* other values */
|
||||
o<<lua_typename(m_luastack, t);
|
||||
break;
|
||||
default: /* other values */
|
||||
o<<lua_typename(m_luastack, t);
|
||||
break;
|
||||
|
||||
}
|
||||
o<<" ";
|
||||
}
|
||||
o<<std::endl;
|
||||
}
|
||||
|
||||
// Push the list of callbacks (a lua table).
|
||||
// Then push nargs arguments.
|
||||
// Then call this function, which
|
||||
// - runs the callbacks
|
||||
// - removes the table and arguments from the lua stack
|
||||
// - pushes the return value, computed depending on mode
|
||||
void ScriptApiBase::runCallbacks(int nargs,RunCallbacksMode mode)
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
// Insert the return value into the lua stack, below the table
|
||||
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>
|
||||
|
||||
int rv = lua_gettop(L) - nargs - 1;
|
||||
int table = rv + 1;
|
||||
int arg = table + 1;
|
||||
|
||||
luaL_checktype(L, table, LUA_TTABLE);
|
||||
|
||||
// Foreach
|
||||
lua_pushnil(L);
|
||||
bool first_loop = true;
|
||||
while(lua_next(L, table) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
// Call function
|
||||
for(int i = 0; i < nargs; i++)
|
||||
lua_pushvalue(L, arg+i);
|
||||
if(lua_pcall(L, nargs, 1, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
|
||||
// Move return value to designated space in stack
|
||||
// Or pop it
|
||||
if(first_loop){
|
||||
// Result of first callback is always moved
|
||||
lua_replace(L, rv);
|
||||
first_loop = false;
|
||||
} else {
|
||||
// Otherwise, what happens depends on the mode
|
||||
if(mode == RUN_CALLBACKS_MODE_FIRST)
|
||||
lua_pop(L, 1);
|
||||
else if(mode == RUN_CALLBACKS_MODE_LAST)
|
||||
lua_replace(L, rv);
|
||||
else if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
if((bool)lua_toboolean(L, rv) == true &&
|
||||
(bool)lua_toboolean(L, -1) == false)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
if((bool)lua_toboolean(L, rv) == false &&
|
||||
(bool)lua_toboolean(L, -1) == true)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// Handle short circuit modes
|
||||
if(mode == RUN_CALLBACKS_MODE_AND_SC &&
|
||||
(bool)lua_toboolean(L, rv) == false)
|
||||
break;
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
|
||||
(bool)lua_toboolean(L, rv) == true)
|
||||
break;
|
||||
|
||||
// value removed, keep key for next iteration
|
||||
}
|
||||
|
||||
// Remove stuff from stack, leaving only the return value
|
||||
lua_settop(L, rv);
|
||||
|
||||
// Fix return value in case no callbacks were called
|
||||
if(first_loop){
|
||||
if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
o<<" ";
|
||||
}
|
||||
o<<std::endl;
|
||||
}
|
||||
|
||||
void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
|
||||
|
|
|
@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define S_BASE_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "jmutex.h"
|
||||
#include "jmutexautolock.h"
|
||||
#include "common/c_types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define LOCK_DEBUG
|
||||
#define SCRIPTAPI_LOCK_DEBUG
|
||||
|
||||
class Server;
|
||||
class Environment;
|
||||
class GUIEngine;
|
||||
class ServerActiveObject;
|
||||
class LuaABM;
|
||||
class InvRef;
|
||||
class ModApiBase;
|
||||
class ModApiEnvMod;
|
||||
class ObjectRef;
|
||||
class NodeMetaRef;
|
||||
|
||||
|
||||
/* definitions */
|
||||
// What scriptapi_run_callbacks does with the return values of callbacks.
|
||||
// Regardless of the mode, if only one callback is defined,
|
||||
// its return value is the total return value.
|
||||
// Modes only affect the case where 0 or >= 2 callbacks are defined.
|
||||
enum RunCallbacksMode
|
||||
{
|
||||
// Returns the return value of the first callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_FIRST,
|
||||
// Returns the return value of the last callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_LAST,
|
||||
// If any callback returns a false value, the first such is returned
|
||||
// Otherwise, the first callback's return value (trueish) is returned
|
||||
// Returns true if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_AND,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first false value
|
||||
RUN_CALLBACKS_MODE_AND_SC,
|
||||
// If any callback returns a true value, the first such is returned
|
||||
// Otherwise, the first callback's return value (falseish) is returned
|
||||
// Returns false if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_OR,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// 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.
|
||||
};
|
||||
|
||||
|
||||
class ScriptApiBase {
|
||||
public:
|
||||
|
||||
ScriptApiBase();
|
||||
virtual ~ScriptApiBase();
|
||||
|
||||
bool loadMod(const std::string &scriptpath, const std::string &modname);
|
||||
bool loadScript(const std::string &scriptpath);
|
||||
|
||||
/* object */
|
||||
void addObjectReference(ServerActiveObject *cobj);
|
||||
void removeObjectReference(ServerActiveObject *cobj);
|
||||
|
||||
ScriptApiBase();
|
||||
|
||||
protected:
|
||||
friend class LuaABM;
|
||||
friend class InvRef;
|
||||
|
@ -91,78 +61,35 @@ protected:
|
|||
friend class ModApiEnvMod;
|
||||
friend class LuaVoxelManip;
|
||||
|
||||
|
||||
inline lua_State* getStack()
|
||||
lua_State* getStack()
|
||||
{ return m_luastack; }
|
||||
|
||||
bool setStack(lua_State* stack) {
|
||||
if (m_luastack == 0) {
|
||||
m_luastack = stack;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void realityCheck();
|
||||
void scriptError(const char *fmt, ...);
|
||||
void stackDump(std::ostream &o);
|
||||
void runCallbacks(int nargs,RunCallbacksMode mode);
|
||||
|
||||
inline Server* getServer() { return m_server; }
|
||||
Server* getServer() { return m_server; }
|
||||
void setServer(Server* server) { m_server = server; }
|
||||
|
||||
Environment* getEnv() { return m_environment; }
|
||||
void setEnv(Environment* env) { m_environment = env; }
|
||||
|
||||
GUIEngine* getGuiEngine() { return m_guiengine; }
|
||||
void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
|
||||
|
||||
void objectrefGetOrCreate(ServerActiveObject *cobj);
|
||||
void objectrefGet(u16 id);
|
||||
|
||||
JMutex m_luastackmutex;
|
||||
#ifdef LOCK_DEBUG
|
||||
JMutex m_luastackmutex;
|
||||
#ifdef SCRIPTAPI_LOCK_DEBUG
|
||||
bool m_locked;
|
||||
#endif
|
||||
private:
|
||||
lua_State* m_luastack;
|
||||
|
||||
Server* m_server;
|
||||
Environment* m_environment;
|
||||
|
||||
|
||||
Server* m_server;
|
||||
Environment* m_environment;
|
||||
GUIEngine* m_guiengine;
|
||||
};
|
||||
|
||||
#ifdef LOCK_DEBUG
|
||||
class LockChecker {
|
||||
public:
|
||||
LockChecker(bool* variable) {
|
||||
assert(*variable == false);
|
||||
|
||||
m_variable = variable;
|
||||
*m_variable = true;
|
||||
}
|
||||
~LockChecker() {
|
||||
*m_variable = false;
|
||||
}
|
||||
private:
|
||||
bool* m_variable;
|
||||
};
|
||||
|
||||
#define LOCK_CHECK LockChecker(&(this->m_locked))
|
||||
#else
|
||||
#define LOCK_CHECK while(0)
|
||||
#endif
|
||||
|
||||
#define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex)
|
||||
|
||||
#define SCRIPTAPI_PRECHECKHEADER \
|
||||
LUA_STACK_AUTOLOCK; \
|
||||
LOCK_CHECK; \
|
||||
realityCheck(); \
|
||||
lua_State *L = getStack(); \
|
||||
assert(lua_checkstack(L, 20)); \
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface()
|
||||
#define ENV_TO_SA(env) env->getScriptIface()
|
||||
#define SERVER_TO_SA(srv) srv->getScriptIface()
|
||||
|
||||
#endif /* S_BASE_H_ */
|
||||
|
|
|
@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_entity.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "log.h"
|
||||
#include "object_properties.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
|
|
@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_env.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "log.h"
|
||||
#include "environment.h"
|
||||
#include "mapgen.h"
|
||||
#include "lua_api/l_env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
|
||||
u32 blockseed)
|
||||
{
|
||||
|
@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
|
|||
push_v3s16(L, minp);
|
||||
push_v3s16(L, maxp);
|
||||
lua_pushnumber(L, blockseed);
|
||||
runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_Step(float dtime)
|
||||
|
@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime)
|
|||
lua_getfield(L, -1, "registered_globalsteps");
|
||||
// Call callbacks
|
||||
lua_pushnumber(L, dtime);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
|
||||
|
@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
|
|||
lua_pushstring(L, flagstr.c_str());
|
||||
lua_setfield(L, -2, "flags");
|
||||
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
|
||||
|
|
63
src/script/cpp_api/s_internal.h
Normal file
63
src/script/cpp_api/s_internal.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
/* WARNING!!!! do NOT add this header in any include file or any code file */
|
||||
/* not being a modapi file!!!!!!!! */
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef S_INTERNAL_H_
|
||||
#define S_INTERNAL_H_
|
||||
|
||||
#include "common/c_internal.h"
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
#ifdef SCRIPTAPI_LOCK_DEBUG
|
||||
#include "debug.h" // assert()
|
||||
class LockChecker {
|
||||
public:
|
||||
LockChecker(bool* variable) {
|
||||
assert(*variable == false);
|
||||
|
||||
m_variable = variable;
|
||||
*m_variable = true;
|
||||
}
|
||||
~LockChecker() {
|
||||
*m_variable = false;
|
||||
}
|
||||
private:
|
||||
bool* m_variable;
|
||||
};
|
||||
|
||||
#define SCRIPTAPI_LOCK_CHECK LockChecker(&(this->m_locked))
|
||||
#else
|
||||
#define SCRIPTAPI_LOCK_CHECK while(0)
|
||||
#endif
|
||||
|
||||
#define SCRIPTAPI_PRECHECKHEADER \
|
||||
JMutexAutoLock(this->m_luastackmutex); \
|
||||
SCRIPTAPI_LOCK_CHECK; \
|
||||
realityCheck(); \
|
||||
lua_State *L = getStack(); \
|
||||
assert(lua_checkstack(L, 20)); \
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
#endif /* S_INTERNAL_H_ */
|
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_inventory.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "inventorymanager.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "lua_api/l_item.h"
|
||||
|
|
|
@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_item.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "util/pointedthing.h"
|
||||
|
||||
bool ScriptApiItem::item_OnDrop(ItemStack &item,
|
||||
ServerActiveObject *dropper, v3f pos)
|
||||
|
|
80
src/script/cpp_api/s_mainmenu.cpp
Normal file
80
src/script/cpp_api/s_mainmenu.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "cpp_api/s_mainmenu.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
|
||||
void ScriptApiMainMenu::setMainMenuErrorMessage(std::string errormessage)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
lua_getglobal(L, "gamedata");
|
||||
int gamedata_idx = lua_gettop(L);
|
||||
lua_pushstring(L, "errormessage");
|
||||
lua_pushstring(L, errormessage.c_str());
|
||||
lua_settable(L, gamedata_idx);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get handler function
|
||||
lua_getglobal(L, "engine");
|
||||
lua_getfield(L, -1, "event_handler");
|
||||
if(lua_isnil(L, -1))
|
||||
return;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
|
||||
// Call it
|
||||
lua_pushstring(L, text.c_str());
|
||||
if(lua_pcall(L, 1, 0, 0))
|
||||
scriptError("error running function engine.event_handler: %s\n",
|
||||
lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get handler function
|
||||
lua_getglobal(L, "engine");
|
||||
lua_getfield(L, -1, "button_handler");
|
||||
if(lua_isnil(L, -1))
|
||||
return;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
|
||||
// Convert fields to lua table
|
||||
lua_newtable(L);
|
||||
for(std::map<std::string, std::string>::const_iterator
|
||||
i = fields.begin(); i != fields.end(); i++){
|
||||
const std::string &name = i->first;
|
||||
const std::string &value = i->second;
|
||||
lua_pushstring(L, name.c_str());
|
||||
lua_pushlstring(L, value.c_str(), value.size());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
// Call it
|
||||
if(lua_pcall(L, 1, 0, 0))
|
||||
scriptError("error running function engine.button_handler: %s\n",
|
||||
lua_tostring(L, -1));
|
||||
}
|
49
src/script/cpp_api/s_mainmenu.h
Normal file
49
src/script/cpp_api/s_mainmenu.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef S_MAINMENU_H_
|
||||
#define S_MAINMENU_H_
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include <map>
|
||||
|
||||
class ScriptApiMainMenu
|
||||
: virtual public ScriptApiBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* set gamedata.errormessage to inform lua of an error
|
||||
* @param errormessage the error message
|
||||
*/
|
||||
void setMainMenuErrorMessage(std::string errormessage);
|
||||
|
||||
/**
|
||||
* process events received from formspec
|
||||
* @param text events in textual form
|
||||
*/
|
||||
void handleMainMenuEvent(std::string text);
|
||||
|
||||
/**
|
||||
* process field data recieved from formspec
|
||||
* @param fields data in field format
|
||||
*/
|
||||
void handleMainMenuButtons(std::map<std::string, std::string> fields);
|
||||
};
|
||||
|
||||
#endif /* S_MAINMENU_H_ */
|
|
@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_node.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "nodedef.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
|
||||
|
||||
struct EnumString ScriptApiNode::es_DrawType[] =
|
||||
|
|
|
@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_nodemeta.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "nodedef.h"
|
||||
#include "mapnode.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
#include "lua_api/l_item.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
// Return number of accepted items to be moved
|
||||
int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
|
||||
const std::string &from_list, int from_index,
|
||||
|
|
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "cpp_api/s_player.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
|
||||
void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
|
||||
{
|
||||
|
@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
|
|||
lua_getfield(L, -1, "registered_on_newplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
|
||||
|
@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
|
|||
lua_getfield(L, -1, "registered_on_dieplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
|
||||
|
@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
|
|||
lua_getfield(L, -1, "registered_on_respawnplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_OR);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
|
||||
bool positioning_handled_by_some = lua_toboolean(L, -1);
|
||||
return positioning_handled_by_some;
|
||||
}
|
||||
|
@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
|
|||
lua_getfield(L, -1, "registered_on_joinplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
|
||||
|
@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
|
|||
lua_getfield(L, -1, "registered_on_leaveplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
|
||||
|
@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
|
|||
lua_newtable(L);
|
||||
lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
|
||||
lua_setfield(L, -2, "type");
|
||||
runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
|
||||
|
@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
|
|||
lua_pushlstring(L, value.c_str(), value.size());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
|
||||
script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
|
||||
}
|
||||
ScriptApiPlayer::~ScriptApiPlayer() {
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef S_PLAYER_H_
|
||||
#define S_PLAYER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
|
||||
|
|
151
src/script/cpp_api/s_server.cpp
Normal file
151
src/script/cpp_api/s_server.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "cpp_api/s_server.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
|
||||
bool ScriptApiServer::getAuth(const std::string &playername,
|
||||
std::string *dst_password,
|
||||
std::set<std::string> *dst_privs)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "get_auth");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing get_auth");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
if(lua_pcall(L, 1, 1, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
|
||||
// nil = login not allowed
|
||||
if(lua_isnil(L, -1))
|
||||
return false;
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
||||
std::string password;
|
||||
bool found = getstringfield(L, -1, "password", password);
|
||||
if(!found)
|
||||
throw LuaError(L, "Authentication handler didn't return password");
|
||||
if(dst_password)
|
||||
*dst_password = password;
|
||||
|
||||
lua_getfield(L, -1, "privileges");
|
||||
if(!lua_istable(L, -1))
|
||||
throw LuaError(L,
|
||||
"Authentication handler didn't return privilege table");
|
||||
if(dst_privs)
|
||||
readPrivileges(-1, *dst_privs);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptApiServer::getAuthHandler()
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_auth_handler");
|
||||
if(lua_isnil(L, -1)){
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "builtin_auth_handler");
|
||||
}
|
||||
if(lua_type(L, -1) != LUA_TTABLE)
|
||||
throw LuaError(L, "Authentication handler table not valid");
|
||||
}
|
||||
|
||||
void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
result.clear();
|
||||
lua_pushnil(L);
|
||||
if(index < 0)
|
||||
index -= 1;
|
||||
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);
|
||||
if(value)
|
||||
result.insert(key);
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptApiServer::createAuth(const std::string &playername,
|
||||
const std::string &password)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "create_auth");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing create_auth");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
lua_pushstring(L, password.c_str());
|
||||
if(lua_pcall(L, 2, 0, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
bool ScriptApiServer::setPassword(const std::string &playername,
|
||||
const std::string &password)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "set_password");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing set_password");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
lua_pushstring(L, password.c_str());
|
||||
if(lua_pcall(L, 2, 1, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
|
||||
bool ScriptApiServer::on_chat_message(const std::string &name,
|
||||
const std::string &message)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get minetest.registered_on_chat_messages
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_on_chat_messages");
|
||||
// Call callbacks
|
||||
lua_pushstring(L, name.c_str());
|
||||
lua_pushstring(L, message.c_str());
|
||||
script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
|
||||
bool ate = lua_toboolean(L, -1);
|
||||
return ate;
|
||||
}
|
||||
|
||||
void ScriptApiServer::on_shutdown()
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get registered shutdown hooks
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_on_shutdown");
|
||||
// Call callbacks
|
||||
script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
52
src/script/cpp_api/s_server.h
Normal file
52
src/script/cpp_api/s_server.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef S_SERVER_H_
|
||||
#define S_SERVER_H_
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include <set>
|
||||
|
||||
class ScriptApiServer
|
||||
: virtual public ScriptApiBase
|
||||
{
|
||||
public:
|
||||
// Calls on_chat_message handlers
|
||||
// Returns true if script handled message
|
||||
bool on_chat_message(const std::string &name, const std::string &message);
|
||||
|
||||
// Calls on_shutdown handlers
|
||||
void on_shutdown();
|
||||
|
||||
/* auth */
|
||||
bool getAuth(const std::string &playername,
|
||||
std::string *dst_password,
|
||||
std::set<std::string> *dst_privs);
|
||||
void createAuth(const std::string &playername,
|
||||
const std::string &password);
|
||||
bool setPassword(const std::string &playername,
|
||||
const std::string &password);
|
||||
private:
|
||||
void getAuthHandler();
|
||||
void readPrivileges(int index, std::set<std::string> &result);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* S_SERVER_H_ */
|
|
@ -1,291 +0,0 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
|
||||
#include "scriptapi.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "log.h"
|
||||
#include "mods.h"
|
||||
|
||||
int script_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;
|
||||
}
|
||||
|
||||
|
||||
bool ScriptApi::getAuth(const std::string &playername,
|
||||
std::string *dst_password, std::set<std::string> *dst_privs)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "get_auth");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing get_auth");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
if(lua_pcall(L, 1, 1, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
|
||||
// nil = login not allowed
|
||||
if(lua_isnil(L, -1))
|
||||
return false;
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
||||
std::string password;
|
||||
bool found = getstringfield(L, -1, "password", password);
|
||||
if(!found)
|
||||
throw LuaError(L, "Authentication handler didn't return password");
|
||||
if(dst_password)
|
||||
*dst_password = password;
|
||||
|
||||
lua_getfield(L, -1, "privileges");
|
||||
if(!lua_istable(L, -1))
|
||||
throw LuaError(L,
|
||||
"Authentication handler didn't return privilege table");
|
||||
if(dst_privs)
|
||||
readPrivileges(-1, *dst_privs);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptApi::getAuthHandler()
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_auth_handler");
|
||||
if(lua_isnil(L, -1)){
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "builtin_auth_handler");
|
||||
}
|
||||
if(lua_type(L, -1) != LUA_TTABLE)
|
||||
throw LuaError(L, "Authentication handler table not valid");
|
||||
}
|
||||
|
||||
void ScriptApi::readPrivileges(int index,std::set<std::string> &result)
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
result.clear();
|
||||
lua_pushnil(L);
|
||||
if(index < 0)
|
||||
index -= 1;
|
||||
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);
|
||||
if(value)
|
||||
result.insert(key);
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptApi::createAuth(const std::string &playername,
|
||||
const std::string &password)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "create_auth");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing create_auth");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
lua_pushstring(L, password.c_str());
|
||||
if(lua_pcall(L, 2, 0, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
bool ScriptApi::setPassword(const std::string &playername,
|
||||
const std::string &password)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
getAuthHandler();
|
||||
lua_getfield(L, -1, "set_password");
|
||||
if(lua_type(L, -1) != LUA_TFUNCTION)
|
||||
throw LuaError(L, "Authentication handler missing set_password");
|
||||
lua_pushstring(L, playername.c_str());
|
||||
lua_pushstring(L, password.c_str());
|
||||
if(lua_pcall(L, 2, 1, 0))
|
||||
scriptError("error: %s", lua_tostring(L, -1));
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
|
||||
bool ScriptApi::on_chat_message(const std::string &name,
|
||||
const std::string &message)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get minetest.registered_on_chat_messages
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_on_chat_messages");
|
||||
// Call callbacks
|
||||
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;
|
||||
}
|
||||
|
||||
void ScriptApi::on_shutdown()
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get registered shutdown hooks
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "registered_on_shutdown");
|
||||
// Call callbacks
|
||||
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
bool ScriptApi::loadMod(const std::string &scriptpath,const std::string &modname)
|
||||
{
|
||||
ModNameStorer modnamestorer(getStack(), modname);
|
||||
|
||||
if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
|
||||
errorstream<<"Error loading mod \""<<modname
|
||||
<<"\": modname does not follow naming conventions: "
|
||||
<<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
try{
|
||||
success = scriptLoad(scriptpath.c_str());
|
||||
}
|
||||
catch(LuaError &e){
|
||||
errorstream<<"Error loading mod \""<<modname
|
||||
<<"\": "<<e.what()<<std::endl;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
ScriptApi::ScriptApi() {
|
||||
assert("Invalid call to default constructor of scriptapi!" == 0);
|
||||
}
|
||||
|
||||
ScriptApi::ScriptApi(Server* server)
|
||||
{
|
||||
|
||||
setServer(server);
|
||||
setStack(luaL_newstate());
|
||||
assert(getStack());
|
||||
|
||||
//TODO add security
|
||||
|
||||
luaL_openlibs(getStack());
|
||||
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "scriptapi");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setglobal(L, "minetest");
|
||||
|
||||
|
||||
for (std::vector<ModApiBase*>::iterator i = m_mod_api_modules->begin();
|
||||
i != m_mod_api_modules->end(); i++) {
|
||||
//initializers are called within minetest global table!
|
||||
lua_getglobal(L, "minetest");
|
||||
int top = lua_gettop(L);
|
||||
bool ModInitializedSuccessfull = (*i)->Initialize(L,top);
|
||||
assert(ModInitializedSuccessfull);
|
||||
}
|
||||
|
||||
infostream << "SCRIPTAPI: initialized " << m_mod_api_modules->size()
|
||||
<< " modules" << std::endl;
|
||||
|
||||
// Get the main minetest table
|
||||
lua_getglobal(L, "minetest");
|
||||
|
||||
// Add tables to minetest
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "object_refs");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "luaentities");
|
||||
}
|
||||
|
||||
ScriptApi::~ScriptApi() {
|
||||
lua_close(getStack());
|
||||
}
|
||||
|
||||
bool ScriptApi::scriptLoad(const char *path)
|
||||
{
|
||||
lua_State* L = getStack();
|
||||
setStack(0);
|
||||
|
||||
verbosestream<<"Loading and running script from "<<path<<std::endl;
|
||||
|
||||
lua_pushcfunction(L, script_ErrorHandler);
|
||||
int errorhandler = lua_gettop(L);
|
||||
|
||||
int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, errorhandler);
|
||||
if(ret){
|
||||
errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
|
||||
errorstream<<"Failed to load and run script from "<<std::endl;
|
||||
errorstream<<path<<":"<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<lua_tostring(L, -1)<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
|
||||
lua_pop(L, 1); // Pop error message from stack
|
||||
lua_pop(L, 1); // Pop the error handler from stack
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 1); // Pop the error handler from stack
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptApi::registerModApiModule(ModApiBase* ptr) {
|
||||
if (ScriptApi::m_mod_api_modules == 0)
|
||||
ScriptApi::m_mod_api_modules = new std::vector<ModApiBase*>();
|
||||
|
||||
assert(ScriptApi::m_mod_api_modules != 0);
|
||||
|
||||
ScriptApi::m_mod_api_modules->push_back(ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<ModApiBase*>* ScriptApi::m_mod_api_modules = 0;
|
|
@ -1,14 +1,23 @@
|
|||
set(SCRIPT_LUA_API_SRCS
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_LUA_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/luaapi.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_util.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_LUA_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -17,32 +17,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "log.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
ScriptApiBase* ModApiBase::getScriptApiBase(lua_State *L) {
|
||||
// Get server from registry
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
|
||||
ScriptApiBase *sapi_ptr = (ScriptApiBase*) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return sapi_ptr;
|
||||
}
|
||||
|
||||
ModApiBase::ModApiBase() {
|
||||
ScriptApi::registerModApiModule(this);
|
||||
Server* ModApiBase::getServer(lua_State *L) {
|
||||
return getScriptApiBase(L)->getServer();
|
||||
}
|
||||
|
||||
Server* ModApiBase::getServer(lua_State* L) {
|
||||
return get_scriptapi(L)->getServer();
|
||||
Environment* ModApiBase::getEnv(lua_State *L) {
|
||||
return getScriptApiBase(L)->getEnv();
|
||||
}
|
||||
|
||||
Environment* ModApiBase::getEnv(lua_State* L) {
|
||||
return get_scriptapi(L)->getEnv();
|
||||
GUIEngine* ModApiBase::getGuiEngine(lua_State *L) {
|
||||
return getScriptApiBase(L)->getGuiEngine();
|
||||
}
|
||||
|
||||
bool ModApiBase::registerFunction( lua_State* L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
) {
|
||||
bool ModApiBase::registerFunction(lua_State *L,
|
||||
const char *name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
) {
|
||||
//TODO check presence first!
|
||||
|
||||
lua_pushstring(L,name);
|
||||
|
@ -51,13 +54,3 @@ bool ModApiBase::registerFunction( lua_State* L,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct EnumString es_BiomeTerrainType[] =
|
||||
{
|
||||
{BIOME_TERRAIN_NORMAL, "normal"},
|
||||
{BIOME_TERRAIN_LIQUID, "liquid"},
|
||||
{BIOME_TERRAIN_NETHER, "nether"},
|
||||
{BIOME_TERRAIN_AETHER, "aether"},
|
||||
{BIOME_TERRAIN_FLAT, "flat"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
|
|
@ -20,44 +20,43 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_BASE_H_
|
||||
#define L_BASE_H_
|
||||
|
||||
#include "biome.h"
|
||||
#include "common/c_types.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
extern struct EnumString es_BiomeTerrainType[];
|
||||
|
||||
class ScriptApi;
|
||||
class ScriptApiBase;
|
||||
class Server;
|
||||
class Environment;
|
||||
class GUIEngine;
|
||||
|
||||
typedef class ModApiBase {
|
||||
|
||||
public:
|
||||
ModApiBase();
|
||||
|
||||
virtual bool Initialize(lua_State* L, int top) = 0;
|
||||
virtual ~ModApiBase() {};
|
||||
class ModApiBase {
|
||||
|
||||
protected:
|
||||
static Server* getServer( lua_State* L);
|
||||
static Environment* getEnv( lua_State* L);
|
||||
static bool registerFunction( lua_State* L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
);
|
||||
} ModApiBase;
|
||||
static ScriptApiBase* getScriptApiBase(lua_State *L);
|
||||
static Server* getServer(lua_State *L);
|
||||
static Environment* getEnv(lua_State *L);
|
||||
static GUIEngine* getGuiEngine(lua_State *L);
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32_WCE))
|
||||
#define NO_MAP_LOCK_REQUIRED
|
||||
#else
|
||||
#include "main.h"
|
||||
#include "profiler.h"
|
||||
#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
|
||||
//#define NO_ENVLOCK_REQUIRED assert(getServer(L).m_env_mutex.IsLocked() == false)
|
||||
#endif
|
||||
// Get an arbitrary subclass of ScriptApiBase
|
||||
// by using dynamic_cast<> on getScriptApiBase()
|
||||
template<typename T>
|
||||
static T* getScriptApi(lua_State *L) {
|
||||
ScriptApiBase *scriptIface = getScriptApiBase(L);
|
||||
T *scriptIfaceDowncast = dynamic_cast<T*>(scriptIface);
|
||||
if (!scriptIfaceDowncast) {
|
||||
throw LuaError(L, "Requested unavailable ScriptApi - core engine bug!");
|
||||
}
|
||||
return scriptIfaceDowncast;
|
||||
}
|
||||
|
||||
static bool registerFunction(lua_State *L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
);
|
||||
};
|
||||
|
||||
#endif /* L_BASE_H_ */
|
||||
|
|
|
@ -19,20 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
|
||||
#include "lua_api/l_craft.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "server.h"
|
||||
#include "lua_api/l_item.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
ModApiCraft::ModApiCraft()
|
||||
: ModApiBase() {
|
||||
|
||||
}
|
||||
#include "craftdef.h"
|
||||
|
||||
struct EnumString ModApiCraft::es_CraftMethod[] =
|
||||
{
|
||||
|
@ -463,15 +455,10 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool ModApiCraft::Initialize(lua_State* L, int top) {
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(get_all_craft_recipes);
|
||||
retval &= API_FCT(get_craft_recipe);
|
||||
retval &= API_FCT(get_craft_result);
|
||||
retval &= API_FCT(register_craft);
|
||||
|
||||
return retval;
|
||||
void ModApiCraft::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(get_all_craft_recipes);
|
||||
API_FCT(get_craft_recipe);
|
||||
API_FCT(get_craft_result);
|
||||
API_FCT(register_craft);
|
||||
}
|
||||
|
||||
ModApiCraft modapicraft_prototype;
|
||||
|
|
|
@ -20,19 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_CRAFT_H_
|
||||
#define L_CRAFT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "craftdef.h"
|
||||
|
||||
struct CraftReplacements;
|
||||
|
||||
class ModApiCraft : public ModApiBase {
|
||||
public:
|
||||
ModApiCraft();
|
||||
bool Initialize(lua_State* L, int top);
|
||||
private:
|
||||
static int l_register_craft(lua_State *L);
|
||||
static int l_get_craft_recipe(lua_State *L);
|
||||
|
@ -47,6 +42,9 @@ private:
|
|||
int &width, std::vector<std::string> &recipe);
|
||||
|
||||
static struct EnumString es_CraftMethod[];
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
#endif /* L_CRAFT_H_ */
|
||||
|
|
|
@ -17,53 +17,39 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "lua_api/l_env.h"
|
||||
#include "lua_api/l_vmanip.h"
|
||||
#include "environment.h"
|
||||
#include "server.h"
|
||||
#include "daynightratio.h"
|
||||
#include "util/pointedthing.h"
|
||||
#include "content_sao.h"
|
||||
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_nodemeta.h"
|
||||
#include "lua_api/l_nodetimer.h"
|
||||
#include "lua_api/l_noise.h"
|
||||
#include "lua_api/l_vmanip.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "scripting_game.h"
|
||||
#include "environment.h"
|
||||
#include "server.h"
|
||||
#include "nodedef.h"
|
||||
#include "daynightratio.h"
|
||||
#include "util/pointedthing.h"
|
||||
#include "content_sao.h"
|
||||
#include "treegen.h"
|
||||
#include "pathfinder.h"
|
||||
#include "emerge.h"
|
||||
#include "mapgen_v7.h"
|
||||
|
||||
|
||||
#define GET_ENV_PTR ServerEnvironment* env = \
|
||||
dynamic_cast<ServerEnvironment*>(getEnv(L)); \
|
||||
if( env == NULL) return 0
|
||||
|
||||
struct EnumString ModApiEnvMod::es_MapgenObject[] =
|
||||
{
|
||||
{MGOBJ_VMANIP, "voxelmanip"},
|
||||
{MGOBJ_HEIGHTMAP, "heightmap"},
|
||||
{MGOBJ_BIOMEMAP, "biomemap"},
|
||||
{MGOBJ_HEATMAP, "heatmap"},
|
||||
{MGOBJ_HUMIDMAP, "humiditymap"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
|
||||
u32 active_object_count, u32 active_object_count_wider)
|
||||
{
|
||||
ScriptApi* scriptIface = SERVER_TO_SA(env);
|
||||
GameScripting *scriptIface = env->getScriptIface();
|
||||
scriptIface->realityCheck();
|
||||
|
||||
lua_State* L = scriptIface->getStack();
|
||||
lua_State *L = scriptIface->getStack();
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
|
@ -196,8 +182,13 @@ int ModApiEnvMod::l_place_node(lua_State *L)
|
|||
{
|
||||
GET_ENV_PTR;
|
||||
|
||||
ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L);
|
||||
Server *server = getServer(L);
|
||||
INodeDefManager *ndef = server->ndef();
|
||||
IItemDefManager *idef = server->idef();
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
MapNode n = readnode(L, 2, env->getGameDef()->ndef());
|
||||
MapNode n = readnode(L, 2, ndef);
|
||||
|
||||
// Don't attempt to load non-loaded area as of now
|
||||
MapNode n_old = env->getMap().getNodeNoEx(pos);
|
||||
|
@ -206,8 +197,6 @@ int ModApiEnvMod::l_place_node(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
// Create item to place
|
||||
INodeDefManager *ndef = getServer(L)->ndef();
|
||||
IItemDefManager *idef = getServer(L)->idef();
|
||||
ItemStack item(ndef->get(n).name, 1, 0, "", idef);
|
||||
// Make pointed position
|
||||
PointedThing pointed;
|
||||
|
@ -216,7 +205,7 @@ int ModApiEnvMod::l_place_node(lua_State *L)
|
|||
pointed.node_undersurface = pos + v3s16(0,-1,0);
|
||||
// Place it with a NULL placer (appears in Lua as a non-functional
|
||||
// ObjectRef)
|
||||
bool success = get_scriptapi(L)->item_OnPlace(item, NULL, pointed);
|
||||
bool success = scriptIfaceItem->item_OnPlace(item, NULL, pointed);
|
||||
lua_pushboolean(L, success);
|
||||
return 1;
|
||||
}
|
||||
|
@ -227,6 +216,8 @@ int ModApiEnvMod::l_dig_node(lua_State *L)
|
|||
{
|
||||
GET_ENV_PTR;
|
||||
|
||||
ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
|
||||
// Don't attempt to load non-loaded area as of now
|
||||
|
@ -237,7 +228,7 @@ int ModApiEnvMod::l_dig_node(lua_State *L)
|
|||
}
|
||||
// Dig it out with a NULL digger (appears in Lua as a
|
||||
// non-functional ObjectRef)
|
||||
bool success = get_scriptapi(L)->node_on_dig(pos, n, NULL);
|
||||
bool success = scriptIfaceNode->node_on_dig(pos, n, NULL);
|
||||
lua_pushboolean(L, success);
|
||||
return 1;
|
||||
}
|
||||
|
@ -248,6 +239,8 @@ int ModApiEnvMod::l_punch_node(lua_State *L)
|
|||
{
|
||||
GET_ENV_PTR;
|
||||
|
||||
ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
|
||||
// Don't attempt to load non-loaded area as of now
|
||||
|
@ -258,7 +251,7 @@ int ModApiEnvMod::l_punch_node(lua_State *L)
|
|||
}
|
||||
// Punch it with a NULL puncher (appears in Lua as a non-functional
|
||||
// ObjectRef)
|
||||
bool success = get_scriptapi(L)->node_on_punch(pos, n, NULL);
|
||||
bool success = scriptIfaceNode->node_on_punch(pos, n, NULL);
|
||||
lua_pushboolean(L, success);
|
||||
return 1;
|
||||
}
|
||||
|
@ -361,7 +354,7 @@ int ModApiEnvMod::l_add_entity(lua_State *L)
|
|||
if(objectid == 0)
|
||||
return 0;
|
||||
// Return ObjectRef
|
||||
get_scriptapi(L)->objectrefGetOrCreate(obj);
|
||||
getScriptApiBase(L)->objectrefGetOrCreate(obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -420,7 +413,7 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
// Put player on stack
|
||||
get_scriptapi(L)->objectrefGetOrCreate(sao);
|
||||
getScriptApiBase(L)->objectrefGetOrCreate(sao);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -446,7 +439,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
|
|||
// Insert object reference into table
|
||||
lua_pushvalue(L, table_insert);
|
||||
lua_pushvalue(L, table);
|
||||
get_scriptapi(L)->objectrefGetOrCreate(obj);
|
||||
getScriptApiBase(L)->objectrefGetOrCreate(obj);
|
||||
if(lua_pcall(L, 2, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
@ -624,142 +617,6 @@ int ModApiEnvMod::l_get_voxel_manip(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// minetest.get_mapgen_object(objectname)
|
||||
// returns the requested object used during map generation
|
||||
int ModApiEnvMod::l_get_mapgen_object(lua_State *L)
|
||||
{
|
||||
const char *mgobjstr = lua_tostring(L, 1);
|
||||
|
||||
int mgobjint;
|
||||
if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
|
||||
return 0;
|
||||
|
||||
enum MapgenObject mgobj = (MapgenObject)mgobjint;
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
Mapgen *mg = emerge->getCurrentMapgen();
|
||||
if (!mg)
|
||||
return 0;
|
||||
|
||||
size_t maplen = mg->csize.X * mg->csize.Z;
|
||||
|
||||
int nargs = 1;
|
||||
|
||||
switch (mgobj) {
|
||||
case MGOBJ_VMANIP: {
|
||||
ManualMapVoxelManipulator *vm = mg->vm;
|
||||
|
||||
// VoxelManip object
|
||||
LuaVoxelManip *o = new LuaVoxelManip(vm, true);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, "VoxelManip");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// emerged min pos
|
||||
push_v3s16(L, vm->m_area.MinEdge);
|
||||
|
||||
// emerged max pos
|
||||
push_v3s16(L, vm->m_area.MaxEdge);
|
||||
|
||||
nargs = 3;
|
||||
|
||||
break; }
|
||||
case MGOBJ_HEIGHTMAP: {
|
||||
if (!mg->heightmap)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushinteger(L, mg->heightmap[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
case MGOBJ_BIOMEMAP: {
|
||||
if (!mg->biomemap)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushinteger(L, mg->biomemap[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
|
||||
case MGOBJ_HUMIDMAP:
|
||||
if (strcmp(emerge->params->mg_name.c_str(), "v7"))
|
||||
return 0;
|
||||
|
||||
MapgenV7 *mgv7 = (MapgenV7 *)mg;
|
||||
|
||||
float *arr = (mgobj == MGOBJ_HEATMAP) ?
|
||||
mgv7->noise_heat->result : mgv7->noise_humidity->result;
|
||||
if (!arr)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushnumber(L, arr[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
}
|
||||
|
||||
return nargs;
|
||||
}
|
||||
|
||||
// minetest.set_mapgen_params(params)
|
||||
// set mapgen parameters
|
||||
int ModApiEnvMod::l_set_mapgen_params(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1))
|
||||
return 0;
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
if (emerge->mapgen.size())
|
||||
return 0;
|
||||
|
||||
MapgenParams *oparams = new MapgenParams;
|
||||
u32 paramsmodified = 0;
|
||||
u32 flagmask = 0;
|
||||
|
||||
lua_getfield(L, 1, "mgname");
|
||||
if (lua_isstring(L, -1)) {
|
||||
oparams->mg_name = std::string(lua_tostring(L, -1));
|
||||
paramsmodified |= MGPARAMS_SET_MGNAME;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "seed");
|
||||
if (lua_isnumber(L, -1)) {
|
||||
oparams->seed = lua_tointeger(L, -1);
|
||||
paramsmodified |= MGPARAMS_SET_SEED;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "water_level");
|
||||
if (lua_isnumber(L, -1)) {
|
||||
oparams->water_level = lua_tointeger(L, -1);
|
||||
paramsmodified |= MGPARAMS_SET_WATER_LEVEL;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "flags");
|
||||
if (lua_isstring(L, -1)) {
|
||||
std::string flagstr = std::string(lua_tostring(L, -1));
|
||||
oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
|
||||
paramsmodified |= MGPARAMS_SET_FLAGS;
|
||||
|
||||
lua_getfield(L, 1, "flagmask");
|
||||
if (lua_isstring(L, -1)) {
|
||||
flagstr = std::string(lua_tostring(L, -1));
|
||||
flagmask = readFlagString(flagstr, flagdesc_mapgen);
|
||||
}
|
||||
}
|
||||
|
||||
emerge->luaoverride_params = oparams;
|
||||
emerge->luaoverride_params_modified = paramsmodified;
|
||||
emerge->luaoverride_flagmask = flagmask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// minetest.clear_objects()
|
||||
// clear all objects in the environment
|
||||
int ModApiEnvMod::l_clear_objects(lua_State *L)
|
||||
|
@ -913,48 +770,39 @@ int ModApiEnvMod::l_get_humidity(lua_State *L)
|
|||
}
|
||||
|
||||
|
||||
bool ModApiEnvMod::Initialize(lua_State *L,int top)
|
||||
void ModApiEnvMod::Initialize(lua_State *L, int top)
|
||||
{
|
||||
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(set_node);
|
||||
retval &= API_FCT(add_node);
|
||||
retval &= API_FCT(add_item);
|
||||
retval &= API_FCT(remove_node);
|
||||
retval &= API_FCT(get_node);
|
||||
retval &= API_FCT(get_node_or_nil);
|
||||
retval &= API_FCT(get_node_light);
|
||||
retval &= API_FCT(place_node);
|
||||
retval &= API_FCT(dig_node);
|
||||
retval &= API_FCT(punch_node);
|
||||
retval &= API_FCT(get_node_max_level);
|
||||
retval &= API_FCT(get_node_level);
|
||||
retval &= API_FCT(set_node_level);
|
||||
retval &= API_FCT(add_node_level);
|
||||
retval &= API_FCT(add_entity);
|
||||
retval &= API_FCT(get_meta);
|
||||
retval &= API_FCT(get_node_timer);
|
||||
retval &= API_FCT(get_player_by_name);
|
||||
retval &= API_FCT(get_objects_inside_radius);
|
||||
retval &= API_FCT(set_timeofday);
|
||||
retval &= API_FCT(get_timeofday);
|
||||
retval &= API_FCT(find_node_near);
|
||||
retval &= API_FCT(find_nodes_in_area);
|
||||
retval &= API_FCT(get_perlin);
|
||||
retval &= API_FCT(get_perlin_map);
|
||||
retval &= API_FCT(get_voxel_manip);
|
||||
retval &= API_FCT(get_mapgen_object);
|
||||
retval &= API_FCT(set_mapgen_params);
|
||||
retval &= API_FCT(clear_objects);
|
||||
retval &= API_FCT(spawn_tree);
|
||||
retval &= API_FCT(find_path);
|
||||
retval &= API_FCT(line_of_sight);
|
||||
retval &= API_FCT(transforming_liquid_add);
|
||||
retval &= API_FCT(get_heat);
|
||||
retval &= API_FCT(get_humidity);
|
||||
|
||||
return retval;
|
||||
API_FCT(set_node);
|
||||
API_FCT(add_node);
|
||||
API_FCT(add_item);
|
||||
API_FCT(remove_node);
|
||||
API_FCT(get_node);
|
||||
API_FCT(get_node_or_nil);
|
||||
API_FCT(get_node_light);
|
||||
API_FCT(place_node);
|
||||
API_FCT(dig_node);
|
||||
API_FCT(punch_node);
|
||||
API_FCT(get_node_max_level);
|
||||
API_FCT(get_node_level);
|
||||
API_FCT(set_node_level);
|
||||
API_FCT(add_node_level);
|
||||
API_FCT(add_entity);
|
||||
API_FCT(get_meta);
|
||||
API_FCT(get_node_timer);
|
||||
API_FCT(get_player_by_name);
|
||||
API_FCT(get_objects_inside_radius);
|
||||
API_FCT(set_timeofday);
|
||||
API_FCT(get_timeofday);
|
||||
API_FCT(find_node_near);
|
||||
API_FCT(find_nodes_in_area);
|
||||
API_FCT(get_perlin);
|
||||
API_FCT(get_perlin_map);
|
||||
API_FCT(get_voxel_manip);
|
||||
API_FCT(clear_objects);
|
||||
API_FCT(spawn_tree);
|
||||
API_FCT(find_path);
|
||||
API_FCT(line_of_sight);
|
||||
API_FCT(transforming_liquid_add);
|
||||
API_FCT(get_heat);
|
||||
API_FCT(get_humidity);
|
||||
}
|
||||
|
||||
ModApiEnvMod modapienv_prototype;
|
||||
|
|
|
@ -20,17 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_ENV_H_
|
||||
#define L_ENV_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "environment.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "environment.h"
|
||||
|
||||
class ModApiEnvMod
|
||||
:public ModApiBase
|
||||
{
|
||||
class ModApiEnvMod : public ModApiBase {
|
||||
private:
|
||||
// minetest.set_node(pos, node)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
|
@ -131,14 +124,6 @@ private:
|
|||
// returns world-specific voxel manipulator
|
||||
static int l_get_voxel_manip(lua_State *L);
|
||||
|
||||
// minetest.get_mapgen_object(objectname)
|
||||
// returns the requested object used during map generation
|
||||
static int l_get_mapgen_object(lua_State *L);
|
||||
|
||||
// minetest.set_mapgen_params(params)
|
||||
// set mapgen parameters
|
||||
static int l_set_mapgen_params(lua_State *L);
|
||||
|
||||
// minetest.clear_objects()
|
||||
// clear all objects in the environment
|
||||
static int l_clear_objects(lua_State *L);
|
||||
|
@ -159,10 +144,8 @@ private:
|
|||
static int l_get_heat(lua_State *L);
|
||||
static int l_get_humidity(lua_State *L);
|
||||
|
||||
static struct EnumString es_MapgenObject[];
|
||||
|
||||
public:
|
||||
bool Initialize(lua_State *L, int top);
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
class LuaABM : public ActiveBlockModifier
|
||||
|
|
43
src/script/lua_api/l_internal.h
Normal file
43
src/script/lua_api/l_internal.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
/* WARNING!!!! do NOT add this header in any include file or any code file */
|
||||
/* not being a modapi file!!!!!!!! */
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef L_INTERNAL_H_
|
||||
#define L_INTERNAL_H_
|
||||
|
||||
#include "common/c_internal.h"
|
||||
|
||||
#define luamethod(class, name) {#name, class::l_##name}
|
||||
#define API_FCT(name) registerFunction(L,#name,l_##name,top)
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32_WCE))
|
||||
#define NO_MAP_LOCK_REQUIRED
|
||||
#else
|
||||
#include "main.h"
|
||||
#include "profiler.h"
|
||||
#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
|
||||
#endif
|
||||
|
||||
#endif /* L_INTERNAL_H_ */
|
|
@ -17,15 +17,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "inventorymanager.h"
|
||||
#include "player.h"
|
||||
|
||||
/*
|
||||
InvRef
|
||||
|
@ -40,7 +38,7 @@ InvRef* InvRef::checkobject(lua_State *L, int narg)
|
|||
|
||||
Inventory* InvRef::getinv(lua_State *L, InvRef *ref)
|
||||
{
|
||||
return STACK_TO_SERVER(L)->getInventory(ref->m_loc);
|
||||
return getServer(L)->getInventory(ref->m_loc);
|
||||
}
|
||||
|
||||
InventoryList* InvRef::getlist(lua_State *L, InvRef *ref,
|
||||
|
@ -56,7 +54,7 @@ InventoryList* InvRef::getlist(lua_State *L, InvRef *ref,
|
|||
void InvRef::reportInventoryChange(lua_State *L, InvRef *ref)
|
||||
{
|
||||
// Inform other things that the inventory has changed
|
||||
STACK_TO_SERVER(L)->setInventoryModified(ref->m_loc);
|
||||
getServer(L)->setInventoryModified(ref->m_loc);
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
|
@ -182,7 +180,7 @@ int InvRef::l_set_stack(lua_State *L)
|
|||
InvRef *ref = checkobject(L, 1);
|
||||
const char *listname = luaL_checkstring(L, 2);
|
||||
int i = luaL_checknumber(L, 3) - 1;
|
||||
ItemStack newitem = read_item(L, 4,STACK_TO_SERVER(L));
|
||||
ItemStack newitem = read_item(L, 4, getServer(L));
|
||||
InventoryList *list = getlist(L, ref, listname);
|
||||
if(list != NULL && i >= 0 && i < (int) list->getSize()){
|
||||
list->changeItem(i, newitem);
|
||||
|
@ -202,7 +200,7 @@ int InvRef::l_get_list(lua_State *L)
|
|||
const char *listname = luaL_checkstring(L, 2);
|
||||
Inventory *inv = getinv(L, ref);
|
||||
if(inv){
|
||||
push_inventory_list(inv, listname, L);
|
||||
push_inventory_list(L, inv, listname);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
@ -221,10 +219,10 @@ int InvRef::l_set_list(lua_State *L)
|
|||
}
|
||||
InventoryList *list = inv->getList(listname);
|
||||
if(list)
|
||||
read_inventory_list(inv, listname, L, 3,
|
||||
STACK_TO_SERVER(L),list->getSize());
|
||||
read_inventory_list(L, 3, inv, listname,
|
||||
getServer(L), list->getSize());
|
||||
else
|
||||
read_inventory_list(inv, listname, L, 3,STACK_TO_SERVER(L));
|
||||
read_inventory_list(L, 3, inv, listname, getServer(L));
|
||||
reportInventoryChange(L, ref);
|
||||
return 0;
|
||||
}
|
||||
|
@ -236,7 +234,7 @@ int InvRef::l_add_item(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
InvRef *ref = checkobject(L, 1);
|
||||
const char *listname = luaL_checkstring(L, 2);
|
||||
ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 3, getServer(L));
|
||||
InventoryList *list = getlist(L, ref, listname);
|
||||
if(list){
|
||||
ItemStack leftover = list->addItem(item);
|
||||
|
@ -256,7 +254,7 @@ int InvRef::l_room_for_item(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
InvRef *ref = checkobject(L, 1);
|
||||
const char *listname = luaL_checkstring(L, 2);
|
||||
ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 3, getServer(L));
|
||||
InventoryList *list = getlist(L, ref, listname);
|
||||
if(list){
|
||||
lua_pushboolean(L, list->roomForItem(item));
|
||||
|
@ -273,7 +271,7 @@ int InvRef::l_contains_item(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
InvRef *ref = checkobject(L, 1);
|
||||
const char *listname = luaL_checkstring(L, 2);
|
||||
ItemStack item = read_item(L, 3, STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 3, getServer(L));
|
||||
InventoryList *list = getlist(L, ref, listname);
|
||||
if(list){
|
||||
lua_pushboolean(L, list->containsItem(item));
|
||||
|
@ -290,7 +288,7 @@ int InvRef::l_remove_item(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
InvRef *ref = checkobject(L, 1);
|
||||
const char *listname = luaL_checkstring(L, 2);
|
||||
ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 3, getServer(L));
|
||||
InventoryList *list = getlist(L, ref, listname);
|
||||
if(list){
|
||||
ItemStack removed = list->removeItem(item);
|
||||
|
@ -473,20 +471,8 @@ int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool ModApiInventory::Initialize(lua_State *L, int top) {
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(create_detached_inventory_raw);
|
||||
retval &= API_FCT(get_inventory);
|
||||
|
||||
InvRef::Register(L);
|
||||
|
||||
return retval;
|
||||
void ModApiInventory::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(create_detached_inventory_raw);
|
||||
API_FCT(get_inventory);
|
||||
}
|
||||
|
||||
ModApiInventory::ModApiInventory()
|
||||
: ModApiBase() {
|
||||
|
||||
}
|
||||
|
||||
ModApiInventory modapiinventory_prototype;
|
||||
|
|
|
@ -20,23 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_INVENTORY_H_
|
||||
#define L_INVENTORY_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "inventorymanager.h"
|
||||
#include "player.h"
|
||||
#include "serverobject.h"
|
||||
#include "inventory.h"
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
#include "inventory.h"
|
||||
#include "inventorymanager.h"
|
||||
|
||||
class Player;
|
||||
|
||||
/*
|
||||
InvRef
|
||||
*/
|
||||
|
||||
class InvRef
|
||||
{
|
||||
class InvRef : public ModApiBase {
|
||||
private:
|
||||
InventoryLocation m_loc;
|
||||
|
||||
|
@ -116,22 +111,19 @@ public:
|
|||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
class ModApiInventory
|
||||
: public ModApiBase
|
||||
{
|
||||
public:
|
||||
ModApiInventory();
|
||||
|
||||
bool Initialize(lua_State *L, int top);
|
||||
|
||||
static int l_create_detached_inventory_raw(lua_State *L);
|
||||
static int l_get_inventory(lua_State *L);
|
||||
class ModApiInventory : public ModApiBase {
|
||||
private:
|
||||
static int l_create_detached_inventory_raw(lua_State *L);
|
||||
|
||||
static int l_get_inventory(lua_State *L);
|
||||
|
||||
static void inventory_set_list_from_lua(Inventory *inv, const char *name,
|
||||
lua_State *L, int tableindex, int forcesize);
|
||||
static void inventory_get_list_to_lua(Inventory *inv, const char *name,
|
||||
lua_State *L);
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
#endif /* L_INVENTORY_H_ */
|
||||
|
|
|
@ -18,11 +18,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "lua_api/l_item.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "itemdef.h"
|
||||
#include "nodedef.h"
|
||||
#include "server.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "content_sao.h"
|
||||
#include "inventory.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
// garbage collector
|
||||
int LuaItemStack::gc_object(lua_State *L)
|
||||
|
@ -97,7 +102,7 @@ int LuaItemStack::l_replace(lua_State *L)
|
|||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
o->m_stack = read_item(L,2,STACK_TO_SERVER(L));
|
||||
o->m_stack = read_item(L,2,getServer(L));
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
@ -143,7 +148,7 @@ int LuaItemStack::l_get_stack_max(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
lua_pushinteger(L, item.getStackMax(STACK_TO_SERVER(L)->idef()));
|
||||
lua_pushinteger(L, item.getStackMax(getServer(L)->idef()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -153,7 +158,7 @@ int LuaItemStack::l_get_free_space(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
lua_pushinteger(L, item.freeSpace(STACK_TO_SERVER(L)->idef()));
|
||||
lua_pushinteger(L, item.freeSpace(getServer(L)->idef()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -164,7 +169,7 @@ int LuaItemStack::l_is_known(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
bool is_known = item.isKnown(STACK_TO_SERVER(L)->idef());
|
||||
bool is_known = item.isKnown(getServer(L)->idef());
|
||||
lua_pushboolean(L, is_known);
|
||||
return 1;
|
||||
}
|
||||
|
@ -200,7 +205,7 @@ int LuaItemStack::l_get_tool_capabilities(lua_State *L)
|
|||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
const ToolCapabilities &prop =
|
||||
item.getToolCapabilities(STACK_TO_SERVER(L)->idef());
|
||||
item.getToolCapabilities(getServer(L)->idef());
|
||||
push_tool_capabilities(L, prop);
|
||||
return 1;
|
||||
}
|
||||
|
@ -215,7 +220,7 @@ int LuaItemStack::l_add_wear(lua_State *L)
|
|||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
int amount = lua_tointeger(L, 2);
|
||||
bool result = item.addWear(amount, STACK_TO_SERVER(L)->idef());
|
||||
bool result = item.addWear(amount, getServer(L)->idef());
|
||||
lua_pushboolean(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
@ -227,8 +232,8 @@ int LuaItemStack::l_add_item(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
ItemStack newitem = read_item(L,-1, STACK_TO_SERVER(L));
|
||||
ItemStack leftover = item.addItem(newitem, STACK_TO_SERVER(L)->idef());
|
||||
ItemStack newitem = read_item(L,-1, getServer(L));
|
||||
ItemStack leftover = item.addItem(newitem, getServer(L)->idef());
|
||||
create(L, leftover);
|
||||
return 1;
|
||||
}
|
||||
|
@ -241,9 +246,9 @@ int LuaItemStack::l_item_fits(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
LuaItemStack *o = checkobject(L, 1);
|
||||
ItemStack &item = o->m_stack;
|
||||
ItemStack newitem = read_item(L, 2 ,STACK_TO_SERVER(L));
|
||||
ItemStack newitem = read_item(L, 2, getServer(L));
|
||||
ItemStack restitem;
|
||||
bool fits = item.itemFits(newitem, &restitem, STACK_TO_SERVER(L)->idef());
|
||||
bool fits = item.itemFits(newitem, &restitem, getServer(L)->idef());
|
||||
lua_pushboolean(L, fits); // first return value
|
||||
create(L, restitem); // second return value
|
||||
return 2;
|
||||
|
@ -300,7 +305,7 @@ ItemStack& LuaItemStack::getItem()
|
|||
int LuaItemStack::create_object(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
ItemStack item = read_item(L,1,STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 1, getServer(L));
|
||||
LuaItemStack *o = new LuaItemStack(item);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, className);
|
||||
|
@ -378,9 +383,6 @@ const luaL_reg LuaItemStack::methods[] = {
|
|||
{0,0}
|
||||
};
|
||||
|
||||
ModApiItemMod::ModApiItemMod() {
|
||||
}
|
||||
|
||||
/*
|
||||
ItemDefinition
|
||||
*/
|
||||
|
@ -392,13 +394,11 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
|
|||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
int table = 1;
|
||||
|
||||
ScriptApi* scriptIface = get_scriptapi(L);
|
||||
|
||||
// Get the writable item and node definition managers from the server
|
||||
IWritableItemDefManager *idef =
|
||||
scriptIface->getServer()->getWritableItemDefManager();
|
||||
getServer(L)->getWritableItemDefManager();
|
||||
IWritableNodeDefManager *ndef =
|
||||
scriptIface->getServer()->getWritableNodeDefManager();
|
||||
getServer(L)->getWritableNodeDefManager();
|
||||
|
||||
// Check if name is defined
|
||||
std::string name;
|
||||
|
@ -455,7 +455,7 @@ int ModApiItemMod::l_register_alias_raw(lua_State *L)
|
|||
|
||||
// Get the writable item definition manager from the server
|
||||
IWritableItemDefManager *idef =
|
||||
STACK_TO_SERVER(L)->getWritableItemDefManager();
|
||||
getServer(L)->getWritableItemDefManager();
|
||||
|
||||
idef->registerAlias(name, convert_to);
|
||||
|
||||
|
@ -468,7 +468,7 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string name = luaL_checkstring(L, 1);
|
||||
|
||||
INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
content_t c = ndef->getId(name);
|
||||
|
||||
lua_pushinteger(L, c);
|
||||
|
@ -481,25 +481,17 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
|
|||
NO_MAP_LOCK_REQUIRED;
|
||||
content_t c = luaL_checkint(L, 1);
|
||||
|
||||
INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
const char *name = ndef->get(c).name.c_str();
|
||||
|
||||
lua_pushstring(L, name);
|
||||
return 1; /* number of results */
|
||||
}
|
||||
|
||||
bool ModApiItemMod::Initialize(lua_State *L,int top) {
|
||||
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(register_item_raw);
|
||||
retval &= API_FCT(register_alias_raw);
|
||||
retval &= API_FCT(get_content_id);
|
||||
retval &= API_FCT(get_name_from_content_id);
|
||||
|
||||
LuaItemStack::Register(L);
|
||||
|
||||
return retval;
|
||||
void ModApiItemMod::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(register_item_raw);
|
||||
API_FCT(register_alias_raw);
|
||||
API_FCT(get_content_id);
|
||||
API_FCT(get_name_from_content_id);
|
||||
}
|
||||
|
||||
ModApiItemMod modapi_item_prototyp;
|
||||
|
|
|
@ -20,24 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_ITEM_H_
|
||||
#define L_ITEM_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "itemdef.h"
|
||||
#include "content_sao.h"
|
||||
#include "util/pointedthing.h"
|
||||
#include "inventory.h"
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "inventory.h" // ItemStack
|
||||
|
||||
class ModApiInventory;
|
||||
|
||||
class LuaItemStack
|
||||
{
|
||||
class LuaItemStack : public ModApiBase {
|
||||
private:
|
||||
ItemStack m_stack;
|
||||
|
||||
|
@ -134,18 +120,14 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class ModApiItemMod
|
||||
:virtual public ModApiBase
|
||||
{
|
||||
public:
|
||||
ModApiItemMod();
|
||||
|
||||
bool Initialize(lua_State *L, int top);
|
||||
|
||||
class ModApiItemMod : public ModApiBase {
|
||||
private:
|
||||
static int l_register_item_raw(lua_State *L);
|
||||
static int l_register_alias_raw(lua_State *L);
|
||||
static int l_get_content_id(lua_State *L);
|
||||
static int l_get_name_from_content_id(lua_State *L);
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
|
||||
|
|
1016
src/script/lua_api/l_mainmenu.cpp
Normal file
1016
src/script/lua_api/l_mainmenu.cpp
Normal file
File diff suppressed because it is too large
Load diff
137
src/script/lua_api/l_mainmenu.h
Normal file
137
src/script/lua_api/l_mainmenu.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 sapier
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef L_MAINMENU_H_
|
||||
#define L_MAINMENU_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
/** Implementation of lua api support for mainmenu */
|
||||
class ModApiMainMenu : public ModApiBase {
|
||||
|
||||
private:
|
||||
/**
|
||||
* read a text variable from gamedata table within lua stack
|
||||
* @param L stack to read variable from
|
||||
* @param name name of variable to read
|
||||
* @return string value of requested variable
|
||||
*/
|
||||
static std::string getTextData(lua_State *L, std::string name);
|
||||
|
||||
/**
|
||||
* read a integer variable from gamedata table within lua stack
|
||||
* @param L stack to read variable from
|
||||
* @param name name of variable to read
|
||||
* @return integer value of requested variable
|
||||
*/
|
||||
static int getIntegerData(lua_State *L, std::string name,bool& valid);
|
||||
|
||||
/**
|
||||
* read a bool variable from gamedata table within lua stack
|
||||
* @param L stack to read variable from
|
||||
* @param name name of variable to read
|
||||
* @return bool value of requested variable
|
||||
*/
|
||||
static int getBoolData(lua_State *L, std::string name,bool& valid);
|
||||
|
||||
/**
|
||||
* check if a path is within some of minetests folders
|
||||
* @param path path to check
|
||||
* @return true/false
|
||||
*/
|
||||
static bool isMinetestPath(std::string path);
|
||||
|
||||
//api calls
|
||||
|
||||
static int l_start(lua_State *L);
|
||||
|
||||
static int l_close(lua_State *L);
|
||||
|
||||
static int l_create_world(lua_State *L);
|
||||
|
||||
static int l_delete_world(lua_State *L);
|
||||
|
||||
static int l_get_worlds(lua_State *L);
|
||||
|
||||
static int l_get_games(lua_State *L);
|
||||
|
||||
static int l_get_favorites(lua_State *L);
|
||||
|
||||
static int l_delete_favorite(lua_State *L);
|
||||
|
||||
static int l_get_version(lua_State *L);
|
||||
|
||||
static int l_sound_play(lua_State *L);
|
||||
|
||||
static int l_sound_stop(lua_State *L);
|
||||
|
||||
//gui
|
||||
|
||||
static int l_show_keys_menu(lua_State *L);
|
||||
|
||||
static int l_show_file_open_dialog(lua_State *L);
|
||||
|
||||
static int l_set_topleft_text(lua_State *L);
|
||||
|
||||
static int l_set_clouds(lua_State *L);
|
||||
|
||||
static int l_get_textlist_index(lua_State *L);
|
||||
|
||||
static int l_set_background(lua_State *L);
|
||||
|
||||
static int l_update_formspec(lua_State *L);
|
||||
|
||||
//filesystem
|
||||
|
||||
static int l_get_scriptdir(lua_State *L);
|
||||
|
||||
static int l_get_modpath(lua_State *L);
|
||||
|
||||
static int l_get_gamepath(lua_State *L);
|
||||
|
||||
static int l_get_texturepath(lua_State *L);
|
||||
|
||||
static int l_get_dirlist(lua_State *L);
|
||||
|
||||
static int l_create_dir(lua_State *L);
|
||||
|
||||
static int l_delete_dir(lua_State *L);
|
||||
|
||||
static int l_copy_dir(lua_State *L);
|
||||
|
||||
static int l_extract_zip(lua_State *L);
|
||||
|
||||
static int l_get_modstore_details(lua_State *L);
|
||||
|
||||
static int l_get_modstore_list(lua_State *L);
|
||||
|
||||
static int l_download_file(lua_State *L);
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* initialize this API module
|
||||
* @param L lua stack to initialize
|
||||
* @param top index (in lua stack) of global API table
|
||||
*/
|
||||
static void Initialize(lua_State *L, int top);
|
||||
|
||||
};
|
||||
|
||||
#endif /* L_MAINMENU_H_ */
|
574
src/script/lua_api/l_mapgen.cpp
Normal file
574
src/script/lua_api/l_mapgen.cpp
Normal file
|
@ -0,0 +1,574 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "lua_api/l_mapgen.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_vmanip.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
#include "biome.h"
|
||||
#include "emerge.h"
|
||||
#include "mapgen_v7.h"
|
||||
|
||||
|
||||
struct EnumString ModApiMapgen::es_BiomeTerrainType[] =
|
||||
{
|
||||
{BIOME_TERRAIN_NORMAL, "normal"},
|
||||
{BIOME_TERRAIN_LIQUID, "liquid"},
|
||||
{BIOME_TERRAIN_NETHER, "nether"},
|
||||
{BIOME_TERRAIN_AETHER, "aether"},
|
||||
{BIOME_TERRAIN_FLAT, "flat"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiMapgen::es_DecorationType[] =
|
||||
{
|
||||
{DECO_SIMPLE, "simple"},
|
||||
{DECO_SCHEMATIC, "schematic"},
|
||||
{DECO_LSYSTEM, "lsystem"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiMapgen::es_MapgenObject[] =
|
||||
{
|
||||
{MGOBJ_VMANIP, "voxelmanip"},
|
||||
{MGOBJ_HEIGHTMAP, "heightmap"},
|
||||
{MGOBJ_BIOMEMAP, "biomemap"},
|
||||
{MGOBJ_HEATMAP, "heatmap"},
|
||||
{MGOBJ_HUMIDMAP, "humiditymap"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiMapgen::es_OreType[] =
|
||||
{
|
||||
{ORE_SCATTER, "scatter"},
|
||||
{ORE_SHEET, "sheet"},
|
||||
{ORE_CLAYLIKE, "claylike"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiMapgen::es_Rotation[] =
|
||||
{
|
||||
{ROTATE_0, "0"},
|
||||
{ROTATE_90, "90"},
|
||||
{ROTATE_180, "180"},
|
||||
{ROTATE_270, "270"},
|
||||
{ROTATE_RAND, "random"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
// minetest.get_mapgen_object(objectname)
|
||||
// returns the requested object used during map generation
|
||||
int ModApiMapgen::l_get_mapgen_object(lua_State *L)
|
||||
{
|
||||
const char *mgobjstr = lua_tostring(L, 1);
|
||||
|
||||
int mgobjint;
|
||||
if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
|
||||
return 0;
|
||||
|
||||
enum MapgenObject mgobj = (MapgenObject)mgobjint;
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
Mapgen *mg = emerge->getCurrentMapgen();
|
||||
if (!mg)
|
||||
return 0;
|
||||
|
||||
size_t maplen = mg->csize.X * mg->csize.Z;
|
||||
|
||||
int nargs = 1;
|
||||
|
||||
switch (mgobj) {
|
||||
case MGOBJ_VMANIP: {
|
||||
ManualMapVoxelManipulator *vm = mg->vm;
|
||||
|
||||
// VoxelManip object
|
||||
LuaVoxelManip *o = new LuaVoxelManip(vm, true);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, "VoxelManip");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// emerged min pos
|
||||
push_v3s16(L, vm->m_area.MinEdge);
|
||||
|
||||
// emerged max pos
|
||||
push_v3s16(L, vm->m_area.MaxEdge);
|
||||
|
||||
nargs = 3;
|
||||
|
||||
break; }
|
||||
case MGOBJ_HEIGHTMAP: {
|
||||
if (!mg->heightmap)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushinteger(L, mg->heightmap[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
case MGOBJ_BIOMEMAP: {
|
||||
if (!mg->biomemap)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushinteger(L, mg->biomemap[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
|
||||
case MGOBJ_HUMIDMAP:
|
||||
if (strcmp(emerge->params->mg_name.c_str(), "v7"))
|
||||
return 0;
|
||||
|
||||
MapgenV7 *mgv7 = (MapgenV7 *)mg;
|
||||
|
||||
float *arr = (mgobj == MGOBJ_HEATMAP) ?
|
||||
mgv7->noise_heat->result : mgv7->noise_humidity->result;
|
||||
if (!arr)
|
||||
return 0;
|
||||
|
||||
lua_newtable(L);
|
||||
for (size_t i = 0; i != maplen; i++) {
|
||||
lua_pushnumber(L, arr[i]);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
break; }
|
||||
}
|
||||
|
||||
return nargs;
|
||||
}
|
||||
|
||||
// minetest.set_mapgen_params(params)
|
||||
// set mapgen parameters
|
||||
int ModApiMapgen::l_set_mapgen_params(lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, 1))
|
||||
return 0;
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
if (emerge->mapgen.size())
|
||||
return 0;
|
||||
|
||||
MapgenParams *oparams = new MapgenParams;
|
||||
u32 paramsmodified = 0;
|
||||
u32 flagmask = 0;
|
||||
|
||||
lua_getfield(L, 1, "mgname");
|
||||
if (lua_isstring(L, -1)) {
|
||||
oparams->mg_name = std::string(lua_tostring(L, -1));
|
||||
paramsmodified |= MGPARAMS_SET_MGNAME;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "seed");
|
||||
if (lua_isnumber(L, -1)) {
|
||||
oparams->seed = lua_tointeger(L, -1);
|
||||
paramsmodified |= MGPARAMS_SET_SEED;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "water_level");
|
||||
if (lua_isnumber(L, -1)) {
|
||||
oparams->water_level = lua_tointeger(L, -1);
|
||||
paramsmodified |= MGPARAMS_SET_WATER_LEVEL;
|
||||
}
|
||||
|
||||
lua_getfield(L, 1, "flags");
|
||||
if (lua_isstring(L, -1)) {
|
||||
std::string flagstr = std::string(lua_tostring(L, -1));
|
||||
oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
|
||||
paramsmodified |= MGPARAMS_SET_FLAGS;
|
||||
|
||||
lua_getfield(L, 1, "flagmask");
|
||||
if (lua_isstring(L, -1)) {
|
||||
flagstr = std::string(lua_tostring(L, -1));
|
||||
flagmask = readFlagString(flagstr, flagdesc_mapgen);
|
||||
}
|
||||
}
|
||||
|
||||
emerge->luaoverride_params = oparams;
|
||||
emerge->luaoverride_params_modified = paramsmodified;
|
||||
emerge->luaoverride_flagmask = flagmask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register_biome({lots of stuff})
|
||||
int ModApiMapgen::l_register_biome(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
|
||||
if (!bmgr) {
|
||||
verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
|
||||
"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
|
||||
Biome *b = bmgr->createBiome(terrain);
|
||||
|
||||
b->name = getstringfield_default(L, index, "name",
|
||||
"<no name>");
|
||||
b->nname_top = getstringfield_default(L, index, "node_top",
|
||||
"mapgen_dirt_with_grass");
|
||||
b->nname_filler = getstringfield_default(L, index, "node_filler",
|
||||
"mapgen_dirt");
|
||||
b->nname_water = getstringfield_default(L, index, "node_water",
|
||||
"mapgen_water_source");
|
||||
b->nname_dust = getstringfield_default(L, index, "node_dust",
|
||||
"air");
|
||||
b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
|
||||
"mapgen_water_source");
|
||||
|
||||
b->depth_top = getintfield_default(L, index, "depth_top", 1);
|
||||
b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
|
||||
b->height_min = getintfield_default(L, index, "height_min", 0);
|
||||
b->height_max = getintfield_default(L, index, "height_max", 0);
|
||||
b->heat_point = getfloatfield_default(L, index, "heat_point", 0.);
|
||||
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
|
||||
|
||||
b->flags = 0; //reserved
|
||||
b->c_top = CONTENT_IGNORE;
|
||||
b->c_filler = CONTENT_IGNORE;
|
||||
b->c_water = CONTENT_IGNORE;
|
||||
b->c_dust = CONTENT_IGNORE;
|
||||
b->c_dust_water = CONTENT_IGNORE;
|
||||
|
||||
verbosestream << "register_biome: " << b->name << std::endl;
|
||||
bmgr->addBiome(b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register_decoration({lots of stuff})
|
||||
int ModApiMapgen::l_register_decoration(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
BiomeDefManager *bdef = emerge->biomedef;
|
||||
|
||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||
"deco_type", es_DecorationType, -1);
|
||||
if (decotype == -1) {
|
||||
errorstream << "register_decoration: unrecognized "
|
||||
"decoration placement type";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Decoration *deco = createDecoration(decotype);
|
||||
if (!deco) {
|
||||
errorstream << "register_decoration: decoration placement type "
|
||||
<< decotype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
deco->c_place_on = CONTENT_IGNORE;
|
||||
deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
|
||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
if (deco->sidelen <= 0) {
|
||||
errorstream << "register_decoration: sidelen must be "
|
||||
"greater than 0" << std::endl;
|
||||
delete deco;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_getfield(L, index, "noise_params");
|
||||
deco->np = read_noiseparams(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "biomes");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
u8 biomeid = bdef->getBiomeIdByName(s);
|
||||
if (biomeid)
|
||||
deco->biomes.insert(biomeid);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
switch (decotype) {
|
||||
case DECO_SIMPLE: {
|
||||
DecoSimple *dsimple = (DecoSimple *)deco;
|
||||
dsimple->c_deco = CONTENT_IGNORE;
|
||||
dsimple->c_spawnby = CONTENT_IGNORE;
|
||||
dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air");
|
||||
dsimple->deco_height = getintfield_default(L, index, "height", 1);
|
||||
dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
||||
dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||
|
||||
lua_getfield(L, index, "decoration");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
std::string str(s);
|
||||
dsimple->decolist_names.push_back(str);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
dsimple->deco_name = std::string(lua_tostring(L, -1));
|
||||
} else {
|
||||
dsimple->deco_name = std::string("air");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (dsimple->deco_height <= 0) {
|
||||
errorstream << "register_decoration: simple decoration height"
|
||||
" must be greater than 0" << std::endl;
|
||||
delete dsimple;
|
||||
return 0;
|
||||
}
|
||||
|
||||
break; }
|
||||
case DECO_SCHEMATIC: {
|
||||
DecoSchematic *dschem = (DecoSchematic *)deco;
|
||||
dschem->flags = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
|
||||
dschem->rotation = (Rotation)getenumfield(L, index,
|
||||
"rotation", es_Rotation, ROTATE_0);
|
||||
|
||||
lua_getfield(L, index, "replacements");
|
||||
if (lua_istable(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, i) != 0) {
|
||||
// key at index -2 and value at index -1
|
||||
lua_rawgeti(L, -1, 1);
|
||||
std::string replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
std::string replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
dschem->replacements[replace_from] = replace_to;
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "schematic");
|
||||
if (!read_schematic(L, -1, dschem, getServer(L))) {
|
||||
delete dschem;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L, -1);
|
||||
|
||||
if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
|
||||
errorstream << "register_decoration: failed to load schematic file '"
|
||||
<< dschem->filename << "'" << std::endl;
|
||||
delete dschem;
|
||||
return 0;
|
||||
}
|
||||
break; }
|
||||
case DECO_LSYSTEM: {
|
||||
//DecoLSystem *decolsystem = (DecoLSystem *)deco;
|
||||
|
||||
break; }
|
||||
}
|
||||
|
||||
emerge->decorations.push_back(deco);
|
||||
|
||||
verbosestream << "register_decoration: decoration '" << deco->getName()
|
||||
<< "' registered" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register_ore({lots of stuff})
|
||||
int ModApiMapgen::l_register_ore(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
|
||||
enum OreType oretype = (OreType)getenumfield(L, index,
|
||||
"ore_type", es_OreType, ORE_SCATTER);
|
||||
Ore *ore = createOre(oretype);
|
||||
if (!ore) {
|
||||
errorstream << "register_ore: ore_type "
|
||||
<< oretype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
ore->ore_name = getstringfield_default(L, index, "ore", "");
|
||||
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
|
||||
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
|
||||
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
|
||||
ore->clust_size = getintfield_default(L, index, "clust_size", 0);
|
||||
ore->height_min = getintfield_default(L, index, "height_min", 0);
|
||||
ore->height_max = getintfield_default(L, index, "height_max", 0);
|
||||
ore->flags = getflagsfield(L, index, "flags", flagdesc_ore);
|
||||
ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.);
|
||||
|
||||
lua_getfield(L, index, "wherein");
|
||||
if (lua_istable(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, i) != 0) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
} else {
|
||||
ore->wherein_names.push_back("");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "noise_params");
|
||||
ore->np = read_noiseparams(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
ore->noise = NULL;
|
||||
|
||||
if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
|
||||
errorstream << "register_ore: clust_scarcity and clust_num_ores"
|
||||
"must be greater than 0" << std::endl;
|
||||
delete ore;
|
||||
return 0;
|
||||
}
|
||||
|
||||
emerge->ores.push_back(ore);
|
||||
|
||||
verbosestream << "register_ore: ore '" << ore->ore_name
|
||||
<< "' registered" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create_schematic(p1, p2, probability_list, filename)
|
||||
int ModApiMapgen::l_create_schematic(lua_State *L)
|
||||
{
|
||||
DecoSchematic dschem;
|
||||
|
||||
Map *map = &(getEnv(L)->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
|
||||
v3s16 p1 = read_v3s16(L, 1);
|
||||
v3s16 p2 = read_v3s16(L, 2);
|
||||
sortBoxVerticies(p1, p2);
|
||||
|
||||
std::vector<std::pair<v3s16, u8> > probability_list;
|
||||
if (lua_istable(L, 3)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 3)) {
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_getfield(L, -1, "pos");
|
||||
v3s16 pos = read_v3s16(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
u8 prob = getintfield_default(L, -1, "prob", 0xFF);
|
||||
probability_list.push_back(std::make_pair(pos, prob));
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dschem.filename = std::string(lua_tostring(L, 4));
|
||||
|
||||
if (!dschem.getSchematicFromMap(map, p1, p2)) {
|
||||
errorstream << "create_schematic: failed to get schematic "
|
||||
"from map" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dschem.applyProbabilities(&probability_list, p1);
|
||||
|
||||
dschem.saveSchematicFile(ndef);
|
||||
actionstream << "create_schematic: saved schematic file '"
|
||||
<< dschem.filename << "'." << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// place_schematic(p, schematic, rotation, replacement)
|
||||
int ModApiMapgen::l_place_schematic(lua_State *L)
|
||||
{
|
||||
DecoSchematic dschem;
|
||||
|
||||
Map *map = &(getEnv(L)->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
|
||||
v3s16 p = read_v3s16(L, 1);
|
||||
if (!read_schematic(L, 2, &dschem, getServer(L)))
|
||||
return 0;
|
||||
|
||||
Rotation rot = ROTATE_0;
|
||||
if (lua_isstring(L, 3))
|
||||
string_to_enum(es_Rotation, (int &)rot, std::string(lua_tostring(L, 3)));
|
||||
|
||||
dschem.rotation = rot;
|
||||
|
||||
if (lua_istable(L, 4)) {
|
||||
int index = 4;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
// key at index -2 and value at index -1
|
||||
lua_rawgeti(L, -1, 1);
|
||||
std::string replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
std::string replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
dschem.replacements[replace_from] = replace_to;
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dschem.filename.empty()) {
|
||||
if (!dschem.loadSchematicFile()) {
|
||||
errorstream << "place_schematic: failed to load schematic file '"
|
||||
<< dschem.filename << "'" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
dschem.resolveNodeNames(ndef);
|
||||
}
|
||||
|
||||
dschem.placeStructure(map, p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ModApiMapgen::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(get_mapgen_object);
|
||||
|
||||
API_FCT(set_mapgen_params);
|
||||
|
||||
API_FCT(register_biome);
|
||||
API_FCT(register_decoration);
|
||||
API_FCT(register_ore);
|
||||
|
||||
API_FCT(create_schematic);
|
||||
API_FCT(place_schematic);
|
||||
}
|
62
src/script/lua_api/l_mapgen.h
Normal file
62
src/script/lua_api/l_mapgen.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef L_MAPGEN_H_
|
||||
#define L_MAPGEN_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiMapgen : public ModApiBase {
|
||||
private:
|
||||
// minetest.get_mapgen_object(objectname)
|
||||
// returns the requested object used during map generation
|
||||
static int l_get_mapgen_object(lua_State *L);
|
||||
|
||||
// minetest.set_mapgen_params(params)
|
||||
// set mapgen parameters
|
||||
static int l_set_mapgen_params(lua_State *L);
|
||||
|
||||
// register_biome({lots of stuff})
|
||||
static int l_register_biome(lua_State *L);
|
||||
|
||||
// register_decoration({lots of stuff})
|
||||
static int l_register_decoration(lua_State *L);
|
||||
|
||||
// register_ore({lots of stuff})
|
||||
static int l_register_ore(lua_State *L);
|
||||
|
||||
// create_schematic(p1, p2, probability_list, filename)
|
||||
static int l_create_schematic(lua_State *L);
|
||||
|
||||
// place_schematic(p, schematic, rotation, replacement)
|
||||
static int l_place_schematic(lua_State *L);
|
||||
|
||||
static struct EnumString es_BiomeTerrainType[];
|
||||
static struct EnumString es_DecorationType[];
|
||||
static struct EnumString es_MapgenObject[];
|
||||
static struct EnumString es_OreType[];
|
||||
static struct EnumString es_Rotation[];
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* L_MAPGEN_H_ */
|
|
@ -17,13 +17,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_nodemeta.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
#include "lua_api/l_nodemeta.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "nodemetadata.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -211,7 +213,7 @@ int NodeMetaRef::l_to_table(lua_State *L)
|
|||
std::vector<const InventoryList*> lists = inv->getLists();
|
||||
for(std::vector<const InventoryList*>::const_iterator
|
||||
i = lists.begin(); i != lists.end(); i++){
|
||||
push_inventory_list(inv, (*i)->getName().c_str(), L);
|
||||
push_inventory_list(L, inv, (*i)->getName().c_str());
|
||||
lua_setfield(L, -2, (*i)->getName().c_str());
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +259,7 @@ int NodeMetaRef::l_from_table(lua_State *L)
|
|||
while(lua_next(L, inventorytable) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
std::string name = lua_tostring(L, -2);
|
||||
read_inventory_list(inv, name.c_str(), L, -1,STACK_TO_SERVER(L));
|
||||
read_inventory_list(L, -1, inv, name.c_str(), getServer(L));
|
||||
lua_pop(L, 1); // removes value, keeps key for next iteration
|
||||
}
|
||||
reportMetadataChange(ref);
|
||||
|
@ -328,5 +330,3 @@ const luaL_reg NodeMetaRef::methods[] = {
|
|||
luamethod(NodeMetaRef, from_table),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
REGISTER_LUA_REF(NodeMetaRef);
|
||||
|
|
|
@ -19,20 +19,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_NODEMETA_H_
|
||||
#define L_NODEMETA_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irrlichttypes_bloated.h"
|
||||
|
||||
#include "environment.h"
|
||||
#include "nodemetadata.h"
|
||||
class ServerEnvironment;
|
||||
class NodeMetadata;
|
||||
|
||||
/*
|
||||
NodeMetaRef
|
||||
*/
|
||||
|
||||
class NodeMetaRef
|
||||
{
|
||||
class NodeMetaRef : public ModApiBase {
|
||||
private:
|
||||
v3s16 m_p;
|
||||
ServerEnvironment *m_env;
|
||||
|
@ -90,4 +87,4 @@ public:
|
|||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
#endif //L_NODEMETA_H_
|
||||
#endif /* L_NODEMETA_H_ */
|
||||
|
|
|
@ -17,9 +17,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_nodetimer.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
|
||||
|
||||
|
@ -165,5 +165,3 @@ const luaL_reg NodeTimerRef::methods[] = {
|
|||
luamethod(NodeTimerRef, get_elapsed),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
REGISTER_LUA_REF(NodeTimerRef);
|
||||
|
|
|
@ -20,15 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_NODETIMER_H_
|
||||
#define L_NODETIMER_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irr_v3d.h"
|
||||
|
||||
#include "environment.h"
|
||||
class ServerEnvironment;
|
||||
|
||||
class NodeTimerRef
|
||||
{
|
||||
class NodeTimerRef : public ModApiBase {
|
||||
private:
|
||||
v3s16 m_p;
|
||||
ServerEnvironment *m_env;
|
||||
|
|
|
@ -18,8 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "lua_api/l_noise.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "log.h"
|
||||
|
||||
// garbage collector
|
||||
|
@ -412,7 +413,3 @@ const luaL_reg LuaPseudoRandom::methods[] = {
|
|||
luamethod(LuaPseudoRandom, next),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
REGISTER_LUA_REF(LuaPseudoRandom);
|
||||
REGISTER_LUA_REF(LuaPerlinNoiseMap);
|
||||
REGISTER_LUA_REF(LuaPerlinNoise);
|
||||
|
|
|
@ -20,16 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_NOISE_H_
|
||||
#define L_NOISE_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "noise.h"
|
||||
|
||||
class LuaPerlinNoise
|
||||
{
|
||||
/*
|
||||
LuaPerlinNoise
|
||||
*/
|
||||
class LuaPerlinNoise : public ModApiBase {
|
||||
private:
|
||||
int seed;
|
||||
int octaves;
|
||||
|
@ -62,10 +60,9 @@ public:
|
|||
};
|
||||
|
||||
/*
|
||||
PerlinNoiseMap
|
||||
*/
|
||||
class LuaPerlinNoiseMap
|
||||
{
|
||||
LuaPerlinNoiseMap
|
||||
*/
|
||||
class LuaPerlinNoiseMap : public ModApiBase {
|
||||
private:
|
||||
Noise *noise;
|
||||
static const char className[];
|
||||
|
@ -95,10 +92,7 @@ public:
|
|||
/*
|
||||
LuaPseudoRandom
|
||||
*/
|
||||
|
||||
|
||||
class LuaPseudoRandom
|
||||
{
|
||||
class LuaPseudoRandom : public ModApiBase {
|
||||
private:
|
||||
PseudoRandom m_pseudo;
|
||||
|
||||
|
@ -130,6 +124,4 @@ public:
|
|||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
NoiseParams *read_noiseparams(lua_State *L, int index);
|
||||
|
||||
#endif /* L_NOISE_H_ */
|
||||
|
|
|
@ -17,13 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "log.h"
|
||||
#include "tool.h"
|
||||
#include "serverobject.h"
|
||||
|
@ -275,7 +274,7 @@ int ObjectRef::l_get_inventory(lua_State *L)
|
|||
if(co == NULL) return 0;
|
||||
// Do it
|
||||
InventoryLocation loc = co->getInventoryLocation();
|
||||
if(STACK_TO_SERVER(L)->getInventory(loc) != NULL)
|
||||
if(getServer(L)->getInventory(loc) != NULL)
|
||||
InvRef::create(L, loc);
|
||||
else
|
||||
lua_pushnil(L); // An object may have no inventory (nil)
|
||||
|
@ -330,7 +329,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L)
|
|||
ServerActiveObject *co = getobject(ref);
|
||||
if(co == NULL) return 0;
|
||||
// Do it
|
||||
ItemStack item = read_item(L, 2,STACK_TO_SERVER(L));
|
||||
ItemStack item = read_item(L, 2, getServer(L));
|
||||
bool success = co->setWieldedItem(item);
|
||||
lua_pushboolean(L, success);
|
||||
return 1;
|
||||
|
@ -739,7 +738,7 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L)
|
|||
std::string formspec = luaL_checkstring(L, 2);
|
||||
|
||||
player->inventory_formspec = formspec;
|
||||
STACK_TO_SERVER(L)->reportInventoryFormspecModified(player->getName());
|
||||
getServer(L)->reportInventoryFormspecModified(player->getName());
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
@ -841,7 +840,7 @@ int ObjectRef::l_hud_add(lua_State *L)
|
|||
elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
|
||||
lua_pop(L, 1);
|
||||
|
||||
u32 id = STACK_TO_SERVER(L)->hudAdd(player, elem);
|
||||
u32 id = getServer(L)->hudAdd(player, elem);
|
||||
if (id == (u32)-1) {
|
||||
delete elem;
|
||||
return 0;
|
||||
|
@ -863,7 +862,7 @@ int ObjectRef::l_hud_remove(lua_State *L)
|
|||
if (!lua_isnil(L, 2))
|
||||
id = lua_tonumber(L, 2);
|
||||
|
||||
if (!STACK_TO_SERVER(L)->hudRemove(player, id))
|
||||
if (!getServer(L)->hudRemove(player, id))
|
||||
return 0;
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
|
@ -929,7 +928,7 @@ int ObjectRef::l_hud_change(lua_State *L)
|
|||
value = &e->offset;
|
||||
}
|
||||
|
||||
STACK_TO_SERVER(L)->hudChange(player, id, stat, value);
|
||||
getServer(L)->hudChange(player, id, stat, value);
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
|
@ -999,7 +998,7 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
|
|||
mask |= esp[i].num;
|
||||
}
|
||||
}
|
||||
if (!STACK_TO_SERVER(L)->hudSetFlags(player, flags, mask))
|
||||
if (!getServer(L)->hudSetFlags(player, flags, mask))
|
||||
return 0;
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
|
@ -1016,7 +1015,7 @@ int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
|
|||
|
||||
s32 hotbar_itemcount = lua_tonumber(L, 2);
|
||||
|
||||
if (!STACK_TO_SERVER(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
|
||||
if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
|
||||
return 0;
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
|
@ -1139,5 +1138,3 @@ const luaL_reg ObjectRef::methods[] = {
|
|||
luamethod(ObjectRef, hud_set_hotbar_itemcount),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
REGISTER_LUA_REF(ObjectRef)
|
||||
|
|
|
@ -20,10 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_OBJECT_H_
|
||||
#define L_OBJECT_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irrlichttypes.h"
|
||||
|
||||
class ServerActiveObject;
|
||||
class LuaEntitySAO;
|
||||
|
@ -34,8 +32,7 @@ class Player;
|
|||
ObjectRef
|
||||
*/
|
||||
|
||||
class ObjectRef
|
||||
{
|
||||
class ObjectRef : public ModApiBase {
|
||||
private:
|
||||
ServerActiveObject *m_object;
|
||||
|
||||
|
|
|
@ -17,22 +17,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "lua_api/l_particles.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "server.h"
|
||||
#include "common/c_internal.h"
|
||||
|
||||
bool ModApiParticles::Initialize(lua_State *L, int top) {
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(add_particle);
|
||||
retval &= API_FCT(add_particlespawner);
|
||||
retval &= API_FCT(delete_particlespawner);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// add_particle(pos, velocity, acceleration, expirationtime,
|
||||
// size, collisiondetection, texture, player)
|
||||
|
@ -146,4 +134,10 @@ int ModApiParticles::l_delete_particlespawner(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
ModApiParticles modapiparticles_prototyp;
|
||||
void ModApiParticles::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(add_particle);
|
||||
API_FCT(add_particlespawner);
|
||||
API_FCT(delete_particlespawner);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,20 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_PARTICLES_H_
|
||||
#define L_PARTICLES_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiParticles : public ModApiBase {
|
||||
public:
|
||||
bool Initialize(lua_State *L, int top);
|
||||
private:
|
||||
static int l_add_particle(lua_State *L);
|
||||
static int l_add_particlespawner(lua_State *L);
|
||||
static int l_delete_particlespawner(lua_State *L);
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // L_PARTICLES_H_
|
||||
#endif /* L_PARTICLES_H_ */
|
||||
|
|
80
src/script/lua_api/l_rollback.cpp
Normal file
80
src/script/lua_api/l_rollback.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "lua_api/l_rollback.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "server.h"
|
||||
#include "rollback.h"
|
||||
|
||||
|
||||
// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
|
||||
int ModApiRollback::l_rollback_get_last_node_actor(lua_State *L)
|
||||
{
|
||||
v3s16 p = read_v3s16(L, 1);
|
||||
int range = luaL_checknumber(L, 2);
|
||||
int seconds = luaL_checknumber(L, 3);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
v3s16 act_p;
|
||||
int act_seconds = 0;
|
||||
std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
|
||||
lua_pushstring(L, actor.c_str());
|
||||
push_v3s16(L, act_p);
|
||||
lua_pushnumber(L, act_seconds);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// rollback_revert_actions_by(actor, seconds) -> bool, log messages
|
||||
int ModApiRollback::l_rollback_revert_actions_by(lua_State *L)
|
||||
{
|
||||
std::string actor = luaL_checkstring(L, 1);
|
||||
int seconds = luaL_checknumber(L, 2);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
|
||||
std::list<std::string> log;
|
||||
bool success = server->rollbackRevertActions(actions, &log);
|
||||
// Push boolean result
|
||||
lua_pushboolean(L, success);
|
||||
// Get the table insert function and push the log table
|
||||
lua_getglobal(L, "table");
|
||||
lua_getfield(L, -1, "insert");
|
||||
int table_insert = lua_gettop(L);
|
||||
lua_newtable(L);
|
||||
int table = lua_gettop(L);
|
||||
for(std::list<std::string>::const_iterator i = log.begin();
|
||||
i != log.end(); i++)
|
||||
{
|
||||
lua_pushvalue(L, table_insert);
|
||||
lua_pushvalue(L, table);
|
||||
lua_pushstring(L, i->c_str());
|
||||
if(lua_pcall(L, 2, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
lua_remove(L, -2); // Remove table
|
||||
lua_remove(L, -2); // Remove insert
|
||||
return 2;
|
||||
}
|
||||
|
||||
void ModApiRollback::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(rollback_get_last_node_actor);
|
||||
API_FCT(rollback_revert_actions_by);
|
||||
}
|
37
src/script/lua_api/l_rollback.h
Normal file
37
src/script/lua_api/l_rollback.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef L_ROLLBACK_H_
|
||||
#define L_ROLLBACK_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiRollback : public ModApiBase {
|
||||
private:
|
||||
// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
|
||||
static int l_rollback_get_last_node_actor(lua_State *L);
|
||||
|
||||
// rollback_revert_actions_by(actor, seconds) -> bool, log messages
|
||||
static int l_rollback_revert_actions_by(lua_State *L);
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
#endif /* L_ROLLBACK_H_ */
|
347
src/script/lua_api/l_server.cpp
Normal file
347
src/script/lua_api/l_server.cpp
Normal file
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "lua_api/l_server.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
#include "player.h"
|
||||
|
||||
// request_shutdown()
|
||||
int ModApiServer::l_request_shutdown(lua_State *L)
|
||||
{
|
||||
getServer(L)->requestShutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_server_status()
|
||||
int ModApiServer::l_get_server_status(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// chat_send_all(text)
|
||||
int ModApiServer::l_chat_send_all(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *text = luaL_checkstring(L, 1);
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Send
|
||||
server->notifyPlayers(narrow_to_wide(text));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// chat_send_player(name, text, prepend)
|
||||
int ModApiServer::l_chat_send_player(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const char *text = luaL_checkstring(L, 2);
|
||||
bool prepend = true;
|
||||
|
||||
if (lua_isboolean(L, 3))
|
||||
prepend = lua_toboolean(L, 3);
|
||||
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Send
|
||||
server->notifyPlayer(name, narrow_to_wide(text), prepend);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_player_privs(name, text)
|
||||
int ModApiServer::l_get_player_privs(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Do it
|
||||
lua_newtable(L);
|
||||
int table = lua_gettop(L);
|
||||
std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
|
||||
for(std::set<std::string>::const_iterator
|
||||
i = privs_s.begin(); i != privs_s.end(); i++){
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, table, i->c_str());
|
||||
}
|
||||
lua_pushvalue(L, table);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_player_ip()
|
||||
int ModApiServer::l_get_player_ip(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * name = luaL_checkstring(L, 1);
|
||||
Player *player = getEnv(L)->getPlayer(name);
|
||||
if(player == NULL)
|
||||
{
|
||||
lua_pushnil(L); // no such player
|
||||
return 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
|
||||
std::string ip_str = addr.serializeString();
|
||||
lua_pushstring(L, ip_str.c_str());
|
||||
return 1;
|
||||
}
|
||||
catch(con::PeerNotFoundException) // unlikely
|
||||
{
|
||||
dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
|
||||
lua_pushnil(L); // error
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// get_ban_list()
|
||||
int ModApiServer::l_get_ban_list(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_ban_description()
|
||||
int ModApiServer::l_get_ban_description(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * ip_or_name = luaL_checkstring(L, 1);
|
||||
lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ban_player()
|
||||
int ModApiServer::l_ban_player(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * name = luaL_checkstring(L, 1);
|
||||
Player *player = getEnv(L)->getPlayer(name);
|
||||
if(player == NULL)
|
||||
{
|
||||
lua_pushboolean(L, false); // no such player
|
||||
return 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
|
||||
std::string ip_str = addr.serializeString();
|
||||
getServer(L)->setIpBanned(ip_str, name);
|
||||
}
|
||||
catch(con::PeerNotFoundException) // unlikely
|
||||
{
|
||||
dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
|
||||
lua_pushboolean(L, false); // error
|
||||
return 1;
|
||||
}
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// unban_player_or_ip()
|
||||
int ModApiServer::l_unban_player_or_ip(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * ip_or_name = luaL_checkstring(L, 1);
|
||||
getServer(L)->unsetIpBanned(ip_or_name);
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// show_formspec(playername,formname,formspec)
|
||||
int ModApiServer::l_show_formspec(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *playername = luaL_checkstring(L, 1);
|
||||
const char *formname = luaL_checkstring(L, 2);
|
||||
const char *formspec = luaL_checkstring(L, 3);
|
||||
|
||||
if(getServer(L)->showFormspec(playername,formspec,formname))
|
||||
{
|
||||
lua_pushboolean(L, true);
|
||||
}else{
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_current_modname()
|
||||
int ModApiServer::l_get_current_modname(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_modpath(modname)
|
||||
int ModApiServer::l_get_modpath(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string modname = luaL_checkstring(L, 1);
|
||||
// Do it
|
||||
if(modname == "__builtin"){
|
||||
std::string path = getServer(L)->getBuiltinLuaPath();
|
||||
lua_pushstring(L, path.c_str());
|
||||
return 1;
|
||||
}
|
||||
const ModSpec *mod = getServer(L)->getModSpec(modname);
|
||||
if(!mod){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
lua_pushstring(L, mod->path.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_modnames()
|
||||
// the returned list is sorted alphabetically for you
|
||||
int ModApiServer::l_get_modnames(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
// Get a list of mods
|
||||
std::list<std::string> mods_unsorted, mods_sorted;
|
||||
getServer(L)->getModNames(mods_unsorted);
|
||||
|
||||
// Take unsorted items from mods_unsorted and sort them into
|
||||
// mods_sorted; not great performance but the number of mods on a
|
||||
// server will likely be small.
|
||||
for(std::list<std::string>::iterator i = mods_unsorted.begin();
|
||||
i != mods_unsorted.end(); ++i)
|
||||
{
|
||||
bool added = false;
|
||||
for(std::list<std::string>::iterator x = mods_sorted.begin();
|
||||
x != mods_sorted.end(); ++x)
|
||||
{
|
||||
// I doubt anybody using Minetest will be using
|
||||
// anything not ASCII based :)
|
||||
if((*i).compare(*x) <= 0)
|
||||
{
|
||||
mods_sorted.insert(x, *i);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!added)
|
||||
mods_sorted.push_back(*i);
|
||||
}
|
||||
|
||||
// Get the table insertion function from Lua.
|
||||
lua_getglobal(L, "table");
|
||||
lua_getfield(L, -1, "insert");
|
||||
int insertion_func = lua_gettop(L);
|
||||
|
||||
// Package them up for Lua
|
||||
lua_newtable(L);
|
||||
int new_table = lua_gettop(L);
|
||||
std::list<std::string>::iterator i = mods_sorted.begin();
|
||||
while(i != mods_sorted.end())
|
||||
{
|
||||
lua_pushvalue(L, insertion_func);
|
||||
lua_pushvalue(L, new_table);
|
||||
lua_pushstring(L, (*i).c_str());
|
||||
if(lua_pcall(L, 2, 0, 0) != 0)
|
||||
{
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_worldpath()
|
||||
int ModApiServer::l_get_worldpath(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string worldpath = getServer(L)->getWorldPath();
|
||||
lua_pushstring(L, worldpath.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sound_play(spec, parameters)
|
||||
int ModApiServer::l_sound_play(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
SimpleSoundSpec spec;
|
||||
read_soundspec(L, 1, spec);
|
||||
ServerSoundParams params;
|
||||
read_server_sound_params(L, 2, params);
|
||||
s32 handle = getServer(L)->playSound(spec, params);
|
||||
lua_pushinteger(L, handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sound_stop(handle)
|
||||
int ModApiServer::l_sound_stop(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
int handle = luaL_checkinteger(L, 1);
|
||||
getServer(L)->stopSound(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// is_singleplayer()
|
||||
int ModApiServer::l_is_singleplayer(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushboolean(L, getServer(L)->isSingleplayer());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// notify_authentication_modified(name)
|
||||
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);
|
||||
getServer(L)->reportPrivsModified(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ModApiServer::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(request_shutdown);
|
||||
API_FCT(get_server_status);
|
||||
API_FCT(get_worldpath);
|
||||
API_FCT(is_singleplayer);
|
||||
|
||||
API_FCT(get_current_modname);
|
||||
API_FCT(get_modpath);
|
||||
API_FCT(get_modnames);
|
||||
|
||||
API_FCT(chat_send_all);
|
||||
API_FCT(chat_send_player);
|
||||
API_FCT(show_formspec);
|
||||
API_FCT(sound_play);
|
||||
API_FCT(sound_stop);
|
||||
|
||||
API_FCT(get_player_privs);
|
||||
API_FCT(get_player_ip);
|
||||
API_FCT(get_ban_list);
|
||||
API_FCT(get_ban_description);
|
||||
API_FCT(ban_player);
|
||||
API_FCT(unban_player_or_ip);
|
||||
API_FCT(notify_authentication_modified);
|
||||
}
|
|
@ -17,48 +17,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef LUAAPI_H_
|
||||
#define LUAAPI_H_
|
||||
#ifndef L_SERVER_H_
|
||||
#define L_SERVER_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiBasic : public ModApiBase {
|
||||
|
||||
public:
|
||||
ModApiBasic();
|
||||
|
||||
bool Initialize(lua_State* L,int top);
|
||||
|
||||
class ModApiServer : public ModApiBase {
|
||||
private:
|
||||
// debug(text)
|
||||
// Writes a line to dstream
|
||||
static int l_debug(lua_State *L);
|
||||
|
||||
// log([level,] text)
|
||||
// Writes a line to the logger.
|
||||
// The one-argument version logs to infostream.
|
||||
// The two-argument version accept a log level: error, action, info, or verbose.
|
||||
static int l_log(lua_State *L);
|
||||
|
||||
// request_shutdown()
|
||||
static int l_request_shutdown(lua_State *L);
|
||||
|
||||
// get_server_status()
|
||||
static int l_get_server_status(lua_State *L);
|
||||
|
||||
// register_biome({lots of stuff})
|
||||
static int l_register_biome(lua_State *L);
|
||||
// get_worldpath()
|
||||
static int l_get_worldpath(lua_State *L);
|
||||
|
||||
// setting_set(name, value)
|
||||
static int l_setting_set(lua_State *L);
|
||||
// is_singleplayer()
|
||||
static int l_is_singleplayer(lua_State *L);
|
||||
|
||||
// setting_get(name)
|
||||
static int l_setting_get(lua_State *L);
|
||||
// get_current_modname()
|
||||
static int l_get_current_modname(lua_State *L);
|
||||
|
||||
// setting_getbool(name)
|
||||
static int l_setting_getbool(lua_State *L);
|
||||
// get_modpath(modname)
|
||||
static int l_get_modpath(lua_State *L);
|
||||
|
||||
// setting_save()
|
||||
static int l_setting_save(lua_State *L);
|
||||
// get_modnames()
|
||||
// the returned list is sorted alphabetically for you
|
||||
static int l_get_modnames(lua_State *L);
|
||||
|
||||
// chat_send_all(text)
|
||||
static int l_chat_send_all(lua_State *L);
|
||||
|
@ -66,6 +52,15 @@ private:
|
|||
// chat_send_player(name, text)
|
||||
static int l_chat_send_player(lua_State *L);
|
||||
|
||||
// show_formspec(playername,formname,formspec)
|
||||
static int l_show_formspec(lua_State *L);
|
||||
|
||||
// sound_play(spec, parameters)
|
||||
static int l_sound_play(lua_State *L);
|
||||
|
||||
// sound_stop(handle)
|
||||
static int l_sound_stop(lua_State *L);
|
||||
|
||||
// get_player_privs(name, text)
|
||||
static int l_get_player_privs(lua_State *L);
|
||||
|
||||
|
@ -84,67 +79,12 @@ private:
|
|||
// unban_player_or_ip()
|
||||
static int l_unban_player_or_ip(lua_State *L);
|
||||
|
||||
// show_formspec(playername,formname,formspec)
|
||||
static int l_show_formspec(lua_State *L);
|
||||
|
||||
// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
static int l_get_dig_params(lua_State *L);
|
||||
|
||||
// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
static int l_get_hit_params(lua_State *L);
|
||||
|
||||
// get_current_modname()
|
||||
static int l_get_current_modname(lua_State *L);
|
||||
|
||||
// get_modpath(modname)
|
||||
static int l_get_modpath(lua_State *L);
|
||||
|
||||
// get_modnames()
|
||||
// the returned list is sorted alphabetically for you
|
||||
static int l_get_modnames(lua_State *L);
|
||||
|
||||
// get_worldpath()
|
||||
static int l_get_worldpath(lua_State *L);
|
||||
|
||||
// sound_play(spec, parameters)
|
||||
static int l_sound_play(lua_State *L);
|
||||
|
||||
// sound_stop(handle)
|
||||
static int l_sound_stop(lua_State *L);
|
||||
|
||||
// is_singleplayer()
|
||||
static int l_is_singleplayer(lua_State *L);
|
||||
|
||||
// get_password_hash(name, raw_password)
|
||||
static int l_get_password_hash(lua_State *L);
|
||||
|
||||
// notify_authentication_modified(name)
|
||||
static int l_notify_authentication_modified(lua_State *L);
|
||||
|
||||
// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
|
||||
static int l_rollback_get_last_node_actor(lua_State *L);
|
||||
|
||||
// rollback_revert_actions_by(actor, seconds) -> bool, log messages
|
||||
static int l_rollback_revert_actions_by(lua_State *L);
|
||||
|
||||
// register_ore(oredesc)
|
||||
static int l_register_ore(lua_State *L);
|
||||
|
||||
// register_decoration(deco)
|
||||
static int l_register_decoration(lua_State *L);
|
||||
|
||||
// create_schematic(p1, p2, filename)
|
||||
static int l_create_schematic(lua_State *L);
|
||||
|
||||
// place_schematic(p, filename, rotation)
|
||||
static int l_place_schematic(lua_State *L);
|
||||
|
||||
static struct EnumString es_OreType[];
|
||||
static struct EnumString es_DecorationType[];
|
||||
static struct EnumString es_Rotation[];
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* LUAAPI_H_ */
|
||||
#endif /* L_SERVER_H_ */
|
199
src/script/lua_api/l_util.cpp
Normal file
199
src/script/lua_api/l_util.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "lua_api/l_util.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include "tool.h"
|
||||
#include "settings.h"
|
||||
#include "main.h" //required for g_settings, g_settings_path
|
||||
|
||||
// debug(...)
|
||||
// Writes a line to dstream
|
||||
int ModApiUtil::l_debug(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
// Handle multiple parameters to behave like standard lua print()
|
||||
int n = lua_gettop(L);
|
||||
lua_getglobal(L, "tostring");
|
||||
for (int i = 1; i <= n; i++) {
|
||||
/*
|
||||
Call tostring(i-th argument).
|
||||
This is what print() does, and it behaves a bit
|
||||
differently from directly calling lua_tostring.
|
||||
*/
|
||||
lua_pushvalue(L, -1); /* function to be called */
|
||||
lua_pushvalue(L, i); /* value to print */
|
||||
lua_call(L, 1, 1);
|
||||
const char *s = lua_tostring(L, -1);
|
||||
if (i>1)
|
||||
dstream << "\t";
|
||||
if (s)
|
||||
dstream << s;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
dstream << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// log([level,] text)
|
||||
// Writes a line to the logger.
|
||||
// The one-argument version logs to infostream.
|
||||
// The two-argument version accept a log level: error, action, info, or verbose.
|
||||
int ModApiUtil::l_log(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string text;
|
||||
LogMessageLevel level = LMT_INFO;
|
||||
if (lua_isnone(L, 2)) {
|
||||
text = lua_tostring(L, 1);
|
||||
}
|
||||
else {
|
||||
std::string levelname = luaL_checkstring(L, 1);
|
||||
text = luaL_checkstring(L, 2);
|
||||
if(levelname == "error")
|
||||
level = LMT_ERROR;
|
||||
else if(levelname == "action")
|
||||
level = LMT_ACTION;
|
||||
else if(levelname == "verbose")
|
||||
level = LMT_VERBOSE;
|
||||
}
|
||||
log_printline(level, text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// setting_set(name, value)
|
||||
int ModApiUtil::l_setting_set(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const char *value = luaL_checkstring(L, 2);
|
||||
g_settings->set(name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// setting_get(name)
|
||||
int ModApiUtil::l_setting_get(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
try{
|
||||
std::string value = g_settings->get(name);
|
||||
lua_pushstring(L, value.c_str());
|
||||
} catch(SettingNotFoundException &e){
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// setting_setbool(name)
|
||||
int ModApiUtil::l_setting_setbool(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
bool value = lua_toboolean(L, 2);
|
||||
g_settings->setBool(name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// setting_getbool(name)
|
||||
int ModApiUtil::l_setting_getbool(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
try{
|
||||
bool value = g_settings->getBool(name);
|
||||
lua_pushboolean(L, value);
|
||||
} catch(SettingNotFoundException &e){
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// setting_save()
|
||||
int ModApiUtil::l_setting_save(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
if(g_settings_path != "")
|
||||
g_settings->updateConfigFile(g_settings_path.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
int ModApiUtil::l_get_dig_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
push_dig_params(L, getDigParams(groups, &tp));
|
||||
else
|
||||
push_dig_params(L, getDigParams(groups, &tp,
|
||||
luaL_checknumber(L, 3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
int ModApiUtil::l_get_hit_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
push_hit_params(L, getHitParams(groups, &tp));
|
||||
else
|
||||
push_hit_params(L, getHitParams(groups, &tp,
|
||||
luaL_checknumber(L, 3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_password_hash(name, raw_password)
|
||||
int ModApiUtil::l_get_password_hash(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string name = luaL_checkstring(L, 1);
|
||||
std::string raw_password = luaL_checkstring(L, 2);
|
||||
std::string hash = translatePassword(name,
|
||||
narrow_to_wide(raw_password));
|
||||
lua_pushstring(L, hash.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ModApiUtil::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(debug);
|
||||
API_FCT(log);
|
||||
|
||||
API_FCT(setting_set);
|
||||
API_FCT(setting_get);
|
||||
API_FCT(setting_setbool);
|
||||
API_FCT(setting_getbool);
|
||||
API_FCT(setting_save);
|
||||
|
||||
API_FCT(get_dig_params);
|
||||
API_FCT(get_hit_params);
|
||||
|
||||
API_FCT(get_password_hash);
|
||||
}
|
||||
|
76
src/script/lua_api/l_util.h
Normal file
76
src/script/lua_api/l_util.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef L_UTIL_H_
|
||||
#define L_UTIL_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiUtil : public ModApiBase {
|
||||
private:
|
||||
/*
|
||||
NOTE:
|
||||
The functions in this module are available through
|
||||
minetest.<function> in the in-game API as well as
|
||||
engine.<function> in the mainmenu API
|
||||
|
||||
All functions that don't require either a Server or
|
||||
GUIEngine instance should be in here.
|
||||
*/
|
||||
|
||||
// debug(text)
|
||||
// Writes a line to dstream
|
||||
static int l_debug(lua_State *L);
|
||||
|
||||
// log([level,] text)
|
||||
// Writes a line to the logger.
|
||||
// The one-argument version logs to infostream.
|
||||
// The two-argument version accept a log level: error, action, info, or verbose.
|
||||
static int l_log(lua_State *L);
|
||||
|
||||
// setting_set(name, value)
|
||||
static int l_setting_set(lua_State *L);
|
||||
|
||||
// setting_get(name)
|
||||
static int l_setting_get(lua_State *L);
|
||||
|
||||
// setting_setbool(name, value)
|
||||
static int l_setting_setbool(lua_State *L);
|
||||
|
||||
// setting_getbool(name)
|
||||
static int l_setting_getbool(lua_State *L);
|
||||
|
||||
// setting_save()
|
||||
static int l_setting_save(lua_State *L);
|
||||
|
||||
// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
static int l_get_dig_params(lua_State *L);
|
||||
|
||||
// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
static int l_get_hit_params(lua_State *L);
|
||||
|
||||
// get_password_hash(name, raw_password)
|
||||
static int l_get_password_hash(lua_State *L);
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
|
||||
};
|
||||
|
||||
#endif /* L_UTIL_H_ */
|
|
@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "lua_api/l_vmanip.h"
|
||||
|
||||
///////
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "server.h"
|
||||
#include "emerge.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
#include "server.h"
|
||||
#include "mapgen.h"
|
||||
|
||||
// garbage collector
|
||||
int LuaVoxelManip::gc_object(lua_State *L)
|
||||
|
@ -111,9 +109,13 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
|
|||
int LuaVoxelManip::l_update_liquids(lua_State *L)
|
||||
{
|
||||
LuaVoxelManip *o = checkobject(L, 1);
|
||||
|
||||
INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
|
||||
Map *map = &(get_scriptapi(L)->getEnv()->getMap());
|
||||
|
||||
Environment *env = getEnv(L);
|
||||
if (!env)
|
||||
return 0;
|
||||
|
||||
Map *map = &(env->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
ManualMapVoxelManipulator *vm = o->vm;
|
||||
|
||||
Mapgen mg;
|
||||
|
@ -134,8 +136,8 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
|
|||
if (!o->is_mapgen_vm)
|
||||
return 0;
|
||||
|
||||
INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
|
||||
EmergeManager *emerge = STACK_TO_SERVER(L)->getEmergeManager();
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
ManualMapVoxelManipulator *vm = o->vm;
|
||||
|
||||
Mapgen mg;
|
||||
|
@ -182,13 +184,18 @@ int LuaVoxelManip::l_update_map(lua_State *L)
|
|||
if (o->is_mapgen_vm)
|
||||
return 0;
|
||||
|
||||
Environment *env = getEnv(L);
|
||||
if (!env)
|
||||
return 0;
|
||||
|
||||
Map *map = &(env->getMap());
|
||||
|
||||
// TODO: Optimize this by using Mapgen::calcLighting() instead
|
||||
std::map<v3s16, MapBlock *> lighting_mblocks;
|
||||
std::map<v3s16, MapBlock *> *mblocks = &o->modified_blocks;
|
||||
|
||||
lighting_mblocks.insert(mblocks->begin(), mblocks->end());
|
||||
|
||||
Map *map = &(get_scriptapi(L)->getEnv()->getMap());
|
||||
map->updateLighting(lighting_mblocks, *mblocks);
|
||||
|
||||
MapEditEvent event;
|
||||
|
@ -228,7 +235,7 @@ int LuaVoxelManip::create_object(lua_State *L)
|
|||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
Environment *env = get_scriptapi(L)->getEnv();
|
||||
Environment *env = getEnv(L);
|
||||
if (!env)
|
||||
return 0;
|
||||
|
||||
|
@ -278,7 +285,7 @@ void LuaVoxelManip::Register(lua_State *L)
|
|||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
||||
lua_pop(L, 1); // drop methodtable
|
||||
|
||||
// Can be created from Lua (VoxelManip()
|
||||
// Can be created from Lua (VoxelManip())
|
||||
lua_register(L, className, create_object);
|
||||
}
|
||||
|
||||
|
@ -294,5 +301,3 @@ const luaL_reg LuaVoxelManip::methods[] = {
|
|||
luamethod(LuaVoxelManip, set_lighting),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
REGISTER_LUA_REF(LuaVoxelManip);
|
||||
|
|
|
@ -20,19 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#ifndef L_VMANIP_H_
|
||||
#define L_VMANIP_H_
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "map.h"
|
||||
#include <map>
|
||||
|
||||
class Map;
|
||||
class MapBlock;
|
||||
class ManualMapVoxelManipulator;
|
||||
|
||||
/*
|
||||
VoxelManip
|
||||
*/
|
||||
class LuaVoxelManip
|
||||
{
|
||||
class LuaVoxelManip : public ModApiBase {
|
||||
private:
|
||||
ManualMapVoxelManipulator *vm;
|
||||
std::map<v3s16, MapBlock *> modified_blocks;
|
||||
|
@ -67,4 +66,4 @@ public:
|
|||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
#endif // L_VMANIP_H_
|
||||
#endif /* L_VMANIP_H_ */
|
||||
|
|
|
@ -1,955 +0,0 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "server.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "lua_api/luaapi.h"
|
||||
#include "settings.h"
|
||||
#include "tool.h"
|
||||
#include "rollback.h"
|
||||
#include "log.h"
|
||||
#include "emerge.h"
|
||||
#include "main.h" //required for g_settings
|
||||
|
||||
struct EnumString ModApiBasic::es_OreType[] =
|
||||
{
|
||||
{ORE_SCATTER, "scatter"},
|
||||
{ORE_SHEET, "sheet"},
|
||||
{ORE_CLAYLIKE, "claylike"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiBasic::es_DecorationType[] =
|
||||
{
|
||||
{DECO_SIMPLE, "simple"},
|
||||
{DECO_SCHEMATIC, "schematic"},
|
||||
{DECO_LSYSTEM, "lsystem"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
struct EnumString ModApiBasic::es_Rotation[] =
|
||||
{
|
||||
{ROTATE_0, "0"},
|
||||
{ROTATE_90, "90"},
|
||||
{ROTATE_180, "180"},
|
||||
{ROTATE_270, "270"},
|
||||
{ROTATE_RAND, "random"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
ModApiBasic::ModApiBasic() : ModApiBase() {
|
||||
}
|
||||
|
||||
bool ModApiBasic::Initialize(lua_State* L,int top) {
|
||||
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(debug);
|
||||
retval &= API_FCT(log);
|
||||
retval &= API_FCT(request_shutdown);
|
||||
retval &= API_FCT(get_server_status);
|
||||
|
||||
retval &= API_FCT(register_biome);
|
||||
|
||||
retval &= API_FCT(setting_set);
|
||||
retval &= API_FCT(setting_get);
|
||||
retval &= API_FCT(setting_getbool);
|
||||
retval &= API_FCT(setting_save);
|
||||
|
||||
retval &= API_FCT(chat_send_all);
|
||||
retval &= API_FCT(chat_send_player);
|
||||
retval &= API_FCT(show_formspec);
|
||||
|
||||
retval &= API_FCT(get_player_privs);
|
||||
retval &= API_FCT(get_player_ip);
|
||||
retval &= API_FCT(get_ban_list);
|
||||
retval &= API_FCT(get_ban_description);
|
||||
retval &= API_FCT(ban_player);
|
||||
retval &= API_FCT(unban_player_or_ip);
|
||||
retval &= API_FCT(get_password_hash);
|
||||
retval &= API_FCT(notify_authentication_modified);
|
||||
|
||||
retval &= API_FCT(get_dig_params);
|
||||
retval &= API_FCT(get_hit_params);
|
||||
|
||||
retval &= API_FCT(get_current_modname);
|
||||
retval &= API_FCT(get_modpath);
|
||||
retval &= API_FCT(get_modnames);
|
||||
|
||||
retval &= API_FCT(get_worldpath);
|
||||
retval &= API_FCT(is_singleplayer);
|
||||
retval &= API_FCT(sound_play);
|
||||
retval &= API_FCT(sound_stop);
|
||||
|
||||
retval &= API_FCT(rollback_get_last_node_actor);
|
||||
retval &= API_FCT(rollback_revert_actions_by);
|
||||
|
||||
retval &= API_FCT(register_ore);
|
||||
retval &= API_FCT(register_decoration);
|
||||
retval &= API_FCT(create_schematic);
|
||||
retval &= API_FCT(place_schematic);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// debug(...)
|
||||
// Writes a line to dstream
|
||||
int ModApiBasic::l_debug(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
// Handle multiple parameters to behave like standard lua print()
|
||||
int n = lua_gettop(L);
|
||||
lua_getglobal(L, "tostring");
|
||||
for(int i = 1; i <= n; i++){
|
||||
/*
|
||||
Call tostring(i-th argument).
|
||||
This is what print() does, and it behaves a bit
|
||||
differently from directly calling lua_tostring.
|
||||
*/
|
||||
lua_pushvalue(L, -1); /* function to be called */
|
||||
lua_pushvalue(L, i); /* value to print */
|
||||
lua_call(L, 1, 1);
|
||||
const char *s = lua_tostring(L, -1);
|
||||
if(i>1)
|
||||
dstream << "\t";
|
||||
if(s)
|
||||
dstream << s;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
dstream << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// log([level,] text)
|
||||
// Writes a line to the logger.
|
||||
// The one-argument version logs to infostream.
|
||||
// The two-argument version accept a log level: error, action, info, or verbose.
|
||||
int ModApiBasic::l_log(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string text;
|
||||
LogMessageLevel level = LMT_INFO;
|
||||
if(lua_isnone(L, 2))
|
||||
{
|
||||
text = lua_tostring(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string levelname = luaL_checkstring(L, 1);
|
||||
text = luaL_checkstring(L, 2);
|
||||
if(levelname == "error")
|
||||
level = LMT_ERROR;
|
||||
else if(levelname == "action")
|
||||
level = LMT_ACTION;
|
||||
else if(levelname == "verbose")
|
||||
level = LMT_VERBOSE;
|
||||
}
|
||||
log_printline(level, text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// request_shutdown()
|
||||
int ModApiBasic::l_request_shutdown(lua_State *L)
|
||||
{
|
||||
getServer(L)->requestShutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_server_status()
|
||||
int ModApiBasic::l_get_server_status(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// register_biome({lots of stuff})
|
||||
int ModApiBasic::l_register_biome(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
|
||||
if (!bmgr) {
|
||||
verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
|
||||
"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
|
||||
Biome *b = bmgr->createBiome(terrain);
|
||||
|
||||
b->name = getstringfield_default(L, index, "name",
|
||||
"<no name>");
|
||||
b->nname_top = getstringfield_default(L, index, "node_top",
|
||||
"mapgen_dirt_with_grass");
|
||||
b->nname_filler = getstringfield_default(L, index, "node_filler",
|
||||
"mapgen_dirt");
|
||||
b->nname_water = getstringfield_default(L, index, "node_water",
|
||||
"mapgen_water_source");
|
||||
b->nname_dust = getstringfield_default(L, index, "node_dust",
|
||||
"air");
|
||||
b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
|
||||
"mapgen_water_source");
|
||||
|
||||
b->depth_top = getintfield_default(L, index, "depth_top", 1);
|
||||
b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
|
||||
b->height_min = getintfield_default(L, index, "height_min", 0);
|
||||
b->height_max = getintfield_default(L, index, "height_max", 0);
|
||||
b->heat_point = getfloatfield_default(L, index, "heat_point", 0.);
|
||||
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
|
||||
|
||||
b->flags = 0; //reserved
|
||||
b->c_top = CONTENT_IGNORE;
|
||||
b->c_filler = CONTENT_IGNORE;
|
||||
b->c_water = CONTENT_IGNORE;
|
||||
b->c_dust = CONTENT_IGNORE;
|
||||
b->c_dust_water = CONTENT_IGNORE;
|
||||
|
||||
verbosestream << "register_biome: " << b->name << std::endl;
|
||||
bmgr->addBiome(b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// setting_set(name, value)
|
||||
int ModApiBasic::l_setting_set(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const char *value = luaL_checkstring(L, 2);
|
||||
g_settings->set(name, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// setting_get(name)
|
||||
int ModApiBasic::l_setting_get(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
try{
|
||||
std::string value = g_settings->get(name);
|
||||
lua_pushstring(L, value.c_str());
|
||||
} catch(SettingNotFoundException &e){
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// setting_getbool(name)
|
||||
int ModApiBasic::l_setting_getbool(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
try{
|
||||
bool value = g_settings->getBool(name);
|
||||
lua_pushboolean(L, value);
|
||||
} catch(SettingNotFoundException &e){
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// setting_save()
|
||||
int ModApiBasic::l_setting_save(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
getServer(L)->saveConfig();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// chat_send_all(text)
|
||||
int ModApiBasic::l_chat_send_all(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *text = luaL_checkstring(L, 1);
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Send
|
||||
server->notifyPlayers(narrow_to_wide(text));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// chat_send_player(name, text, prepend)
|
||||
int ModApiBasic::l_chat_send_player(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const char *text = luaL_checkstring(L, 2);
|
||||
bool prepend = true;
|
||||
|
||||
if (lua_isboolean(L, 3))
|
||||
prepend = lua_toboolean(L, 3);
|
||||
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Send
|
||||
server->notifyPlayer(name, narrow_to_wide(text), prepend);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_player_privs(name, text)
|
||||
int ModApiBasic::l_get_player_privs(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
// Get server from registry
|
||||
Server *server = getServer(L);
|
||||
// Do it
|
||||
lua_newtable(L);
|
||||
int table = lua_gettop(L);
|
||||
std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
|
||||
for(std::set<std::string>::const_iterator
|
||||
i = privs_s.begin(); i != privs_s.end(); i++){
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, table, i->c_str());
|
||||
}
|
||||
lua_pushvalue(L, table);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_player_ip()
|
||||
int ModApiBasic::l_get_player_ip(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * name = luaL_checkstring(L, 1);
|
||||
Player *player = getEnv(L)->getPlayer(name);
|
||||
if(player == NULL)
|
||||
{
|
||||
lua_pushnil(L); // no such player
|
||||
return 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
|
||||
std::string ip_str = addr.serializeString();
|
||||
lua_pushstring(L, ip_str.c_str());
|
||||
return 1;
|
||||
}
|
||||
catch(con::PeerNotFoundException) // unlikely
|
||||
{
|
||||
dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
|
||||
lua_pushnil(L); // error
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// get_ban_list()
|
||||
int ModApiBasic::l_get_ban_list(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_ban_description()
|
||||
int ModApiBasic::l_get_ban_description(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * ip_or_name = luaL_checkstring(L, 1);
|
||||
lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ban_player()
|
||||
int ModApiBasic::l_ban_player(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * name = luaL_checkstring(L, 1);
|
||||
Player *player = getEnv(L)->getPlayer(name);
|
||||
if(player == NULL)
|
||||
{
|
||||
lua_pushboolean(L, false); // no such player
|
||||
return 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
|
||||
std::string ip_str = addr.serializeString();
|
||||
getServer(L)->setIpBanned(ip_str, name);
|
||||
}
|
||||
catch(con::PeerNotFoundException) // unlikely
|
||||
{
|
||||
dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
|
||||
lua_pushboolean(L, false); // error
|
||||
return 1;
|
||||
}
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// unban_player_or_ip()
|
||||
int ModApiBasic::l_unban_player_or_ip(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char * ip_or_name = luaL_checkstring(L, 1);
|
||||
getServer(L)->unsetIpBanned(ip_or_name);
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// show_formspec(playername,formname,formspec)
|
||||
int ModApiBasic::l_show_formspec(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
const char *playername = luaL_checkstring(L, 1);
|
||||
const char *formname = luaL_checkstring(L, 2);
|
||||
const char *formspec = luaL_checkstring(L, 3);
|
||||
|
||||
if(getServer(L)->showFormspec(playername,formspec,formname))
|
||||
{
|
||||
lua_pushboolean(L, true);
|
||||
}else{
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
int ModApiBasic::l_get_dig_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
push_dig_params(L, getDigParams(groups, &tp));
|
||||
else
|
||||
push_dig_params(L, getDigParams(groups, &tp,
|
||||
luaL_checknumber(L, 3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
|
||||
int ModApiBasic::l_get_hit_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
push_hit_params(L, getHitParams(groups, &tp));
|
||||
else
|
||||
push_hit_params(L, getHitParams(groups, &tp,
|
||||
luaL_checknumber(L, 3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_current_modname()
|
||||
int ModApiBasic::l_get_current_modname(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_modpath(modname)
|
||||
int ModApiBasic::l_get_modpath(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string modname = luaL_checkstring(L, 1);
|
||||
// Do it
|
||||
if(modname == "__builtin"){
|
||||
std::string path = getServer(L)->getBuiltinLuaPath();
|
||||
lua_pushstring(L, path.c_str());
|
||||
return 1;
|
||||
}
|
||||
const ModSpec *mod = getServer(L)->getModSpec(modname);
|
||||
if(!mod){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
lua_pushstring(L, mod->path.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_modnames()
|
||||
// the returned list is sorted alphabetically for you
|
||||
int ModApiBasic::l_get_modnames(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
// Get a list of mods
|
||||
std::list<std::string> mods_unsorted, mods_sorted;
|
||||
getServer(L)->getModNames(mods_unsorted);
|
||||
|
||||
// Take unsorted items from mods_unsorted and sort them into
|
||||
// mods_sorted; not great performance but the number of mods on a
|
||||
// server will likely be small.
|
||||
for(std::list<std::string>::iterator i = mods_unsorted.begin();
|
||||
i != mods_unsorted.end(); ++i)
|
||||
{
|
||||
bool added = false;
|
||||
for(std::list<std::string>::iterator x = mods_sorted.begin();
|
||||
x != mods_sorted.end(); ++x)
|
||||
{
|
||||
// I doubt anybody using Minetest will be using
|
||||
// anything not ASCII based :)
|
||||
if((*i).compare(*x) <= 0)
|
||||
{
|
||||
mods_sorted.insert(x, *i);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!added)
|
||||
mods_sorted.push_back(*i);
|
||||
}
|
||||
|
||||
// Get the table insertion function from Lua.
|
||||
lua_getglobal(L, "table");
|
||||
lua_getfield(L, -1, "insert");
|
||||
int insertion_func = lua_gettop(L);
|
||||
|
||||
// Package them up for Lua
|
||||
lua_newtable(L);
|
||||
int new_table = lua_gettop(L);
|
||||
std::list<std::string>::iterator i = mods_sorted.begin();
|
||||
while(i != mods_sorted.end())
|
||||
{
|
||||
lua_pushvalue(L, insertion_func);
|
||||
lua_pushvalue(L, new_table);
|
||||
lua_pushstring(L, (*i).c_str());
|
||||
if(lua_pcall(L, 2, 0, 0) != 0)
|
||||
{
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_worldpath()
|
||||
int ModApiBasic::l_get_worldpath(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string worldpath = getServer(L)->getWorldPath();
|
||||
lua_pushstring(L, worldpath.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sound_play(spec, parameters)
|
||||
int ModApiBasic::l_sound_play(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
SimpleSoundSpec spec;
|
||||
read_soundspec(L, 1, spec);
|
||||
ServerSoundParams params;
|
||||
read_server_sound_params(L, 2, params);
|
||||
s32 handle = getServer(L)->playSound(spec, params);
|
||||
lua_pushinteger(L, handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sound_stop(handle)
|
||||
int ModApiBasic::l_sound_stop(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
int handle = luaL_checkinteger(L, 1);
|
||||
getServer(L)->stopSound(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// is_singleplayer()
|
||||
int ModApiBasic::l_is_singleplayer(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
lua_pushboolean(L, getServer(L)->isSingleplayer());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_password_hash(name, raw_password)
|
||||
int ModApiBasic::l_get_password_hash(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string name = luaL_checkstring(L, 1);
|
||||
std::string raw_password = luaL_checkstring(L, 2);
|
||||
std::string hash = translatePassword(name,
|
||||
narrow_to_wide(raw_password));
|
||||
lua_pushstring(L, hash.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// notify_authentication_modified(name)
|
||||
int ModApiBasic::l_notify_authentication_modified(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::string name = "";
|
||||
if(lua_isstring(L, 1))
|
||||
name = lua_tostring(L, 1);
|
||||
getServer(L)->reportPrivsModified(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
|
||||
int ModApiBasic::l_rollback_get_last_node_actor(lua_State *L)
|
||||
{
|
||||
v3s16 p = read_v3s16(L, 1);
|
||||
int range = luaL_checknumber(L, 2);
|
||||
int seconds = luaL_checknumber(L, 3);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
v3s16 act_p;
|
||||
int act_seconds = 0;
|
||||
std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
|
||||
lua_pushstring(L, actor.c_str());
|
||||
push_v3s16(L, act_p);
|
||||
lua_pushnumber(L, act_seconds);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// rollback_revert_actions_by(actor, seconds) -> bool, log messages
|
||||
int ModApiBasic::l_rollback_revert_actions_by(lua_State *L)
|
||||
{
|
||||
std::string actor = luaL_checkstring(L, 1);
|
||||
int seconds = luaL_checknumber(L, 2);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
|
||||
std::list<std::string> log;
|
||||
bool success = server->rollbackRevertActions(actions, &log);
|
||||
// Push boolean result
|
||||
lua_pushboolean(L, success);
|
||||
// Get the table insert function and push the log table
|
||||
lua_getglobal(L, "table");
|
||||
lua_getfield(L, -1, "insert");
|
||||
int table_insert = lua_gettop(L);
|
||||
lua_newtable(L);
|
||||
int table = lua_gettop(L);
|
||||
for(std::list<std::string>::const_iterator i = log.begin();
|
||||
i != log.end(); i++)
|
||||
{
|
||||
lua_pushvalue(L, table_insert);
|
||||
lua_pushvalue(L, table);
|
||||
lua_pushstring(L, i->c_str());
|
||||
if(lua_pcall(L, 2, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
lua_remove(L, -2); // Remove table
|
||||
lua_remove(L, -2); // Remove insert
|
||||
return 2;
|
||||
}
|
||||
|
||||
int ModApiBasic::l_register_ore(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
|
||||
enum OreType oretype = (OreType)getenumfield(L, index,
|
||||
"ore_type", es_OreType, ORE_SCATTER);
|
||||
Ore *ore = createOre(oretype);
|
||||
if (!ore) {
|
||||
errorstream << "register_ore: ore_type "
|
||||
<< oretype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
ore->ore_name = getstringfield_default(L, index, "ore", "");
|
||||
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
|
||||
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
|
||||
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
|
||||
ore->clust_size = getintfield_default(L, index, "clust_size", 0);
|
||||
ore->height_min = getintfield_default(L, index, "height_min", 0);
|
||||
ore->height_max = getintfield_default(L, index, "height_max", 0);
|
||||
ore->flags = getflagsfield(L, index, "flags", flagdesc_ore);
|
||||
ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.);
|
||||
|
||||
lua_getfield(L, index, "wherein");
|
||||
if (lua_istable(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, i) != 0) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
} else {
|
||||
ore->wherein_names.push_back("");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "noise_params");
|
||||
ore->np = read_noiseparams(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
ore->noise = NULL;
|
||||
|
||||
if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
|
||||
errorstream << "register_ore: clust_scarcity and clust_num_ores"
|
||||
"must be greater than 0" << std::endl;
|
||||
delete ore;
|
||||
return 0;
|
||||
}
|
||||
|
||||
emerge->ores.push_back(ore);
|
||||
|
||||
verbosestream << "register_ore: ore '" << ore->ore_name
|
||||
<< "' registered" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register_decoration({lots of stuff})
|
||||
int ModApiBasic::l_register_decoration(lua_State *L)
|
||||
{
|
||||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
BiomeDefManager *bdef = emerge->biomedef;
|
||||
|
||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||
"deco_type", es_DecorationType, -1);
|
||||
if (decotype == -1) {
|
||||
errorstream << "register_decoration: unrecognized "
|
||||
"decoration placement type";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Decoration *deco = createDecoration(decotype);
|
||||
if (!deco) {
|
||||
errorstream << "register_decoration: decoration placement type "
|
||||
<< decotype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
deco->c_place_on = CONTENT_IGNORE;
|
||||
deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
|
||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
if (deco->sidelen <= 0) {
|
||||
errorstream << "register_decoration: sidelen must be "
|
||||
"greater than 0" << std::endl;
|
||||
delete deco;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_getfield(L, index, "noise_params");
|
||||
deco->np = read_noiseparams(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "biomes");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
u8 biomeid = bdef->getBiomeIdByName(s);
|
||||
if (biomeid)
|
||||
deco->biomes.insert(biomeid);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
switch (decotype) {
|
||||
case DECO_SIMPLE: {
|
||||
DecoSimple *dsimple = (DecoSimple *)deco;
|
||||
dsimple->c_deco = CONTENT_IGNORE;
|
||||
dsimple->c_spawnby = CONTENT_IGNORE;
|
||||
dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air");
|
||||
dsimple->deco_height = getintfield_default(L, index, "height", 1);
|
||||
dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
||||
dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||
|
||||
lua_getfield(L, index, "decoration");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
std::string str(s);
|
||||
dsimple->decolist_names.push_back(str);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
dsimple->deco_name = std::string(lua_tostring(L, -1));
|
||||
} else {
|
||||
dsimple->deco_name = std::string("air");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (dsimple->deco_height <= 0) {
|
||||
errorstream << "register_decoration: simple decoration height"
|
||||
" must be greater than 0" << std::endl;
|
||||
delete dsimple;
|
||||
return 0;
|
||||
}
|
||||
|
||||
break; }
|
||||
case DECO_SCHEMATIC: {
|
||||
DecoSchematic *dschem = (DecoSchematic *)deco;
|
||||
dschem->flags = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
|
||||
dschem->rotation = (Rotation)getenumfield(L, index,
|
||||
"rotation", es_Rotation, ROTATE_0);
|
||||
|
||||
lua_getfield(L, index, "replacements");
|
||||
if (lua_istable(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, i) != 0) {
|
||||
// key at index -2 and value at index -1
|
||||
lua_rawgeti(L, -1, 1);
|
||||
std::string replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
std::string replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
dschem->replacements[replace_from] = replace_to;
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "schematic");
|
||||
if (!read_schematic(L, -1, dschem, getServer(L))) {
|
||||
delete dschem;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L, -1);
|
||||
|
||||
if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
|
||||
errorstream << "register_decoration: failed to load schematic file '"
|
||||
<< dschem->filename << "'" << std::endl;
|
||||
delete dschem;
|
||||
return 0;
|
||||
}
|
||||
break; }
|
||||
case DECO_LSYSTEM: {
|
||||
//DecoLSystem *decolsystem = (DecoLSystem *)deco;
|
||||
|
||||
break; }
|
||||
}
|
||||
|
||||
emerge->decorations.push_back(deco);
|
||||
|
||||
verbosestream << "register_decoration: decoration '" << deco->getName()
|
||||
<< "' registered" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create_schematic(p1, p2, probability_list, filename)
|
||||
int ModApiBasic::l_create_schematic(lua_State *L)
|
||||
{
|
||||
DecoSchematic dschem;
|
||||
|
||||
Map *map = &(getEnv(L)->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
|
||||
v3s16 p1 = read_v3s16(L, 1);
|
||||
v3s16 p2 = read_v3s16(L, 2);
|
||||
sortBoxVerticies(p1, p2);
|
||||
|
||||
std::vector<std::pair<v3s16, u8> > probability_list;
|
||||
if (lua_istable(L, 3)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 3)) {
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_getfield(L, -1, "pos");
|
||||
v3s16 pos = read_v3s16(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
u8 prob = getintfield_default(L, -1, "prob", 0xFF);
|
||||
probability_list.push_back(std::make_pair(pos, prob));
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dschem.filename = std::string(lua_tostring(L, 4));
|
||||
|
||||
if (!dschem.getSchematicFromMap(map, p1, p2)) {
|
||||
errorstream << "create_schematic: failed to get schematic "
|
||||
"from map" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dschem.applyProbabilities(&probability_list, p1);
|
||||
|
||||
dschem.saveSchematicFile(ndef);
|
||||
actionstream << "create_schematic: saved schematic file '"
|
||||
<< dschem.filename << "'." << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// place_schematic(p, schematic, rotation, replacement)
|
||||
int ModApiBasic::l_place_schematic(lua_State *L)
|
||||
{
|
||||
DecoSchematic dschem;
|
||||
|
||||
Map *map = &(getEnv(L)->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
|
||||
v3s16 p = read_v3s16(L, 1);
|
||||
if (!read_schematic(L, 2, &dschem, getServer(L)))
|
||||
return 0;
|
||||
|
||||
Rotation rot = ROTATE_0;
|
||||
if (lua_isstring(L, 3))
|
||||
string_to_enum(es_Rotation, (int &)rot, std::string(lua_tostring(L, 3)));
|
||||
|
||||
dschem.rotation = rot;
|
||||
|
||||
if (lua_istable(L, 4)) {
|
||||
int index = 4;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
// key at index -2 and value at index -1
|
||||
lua_rawgeti(L, -1, 1);
|
||||
std::string replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
std::string replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
dschem.replacements[replace_from] = replace_to;
|
||||
// removes value, keeps key for next iteration
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dschem.filename.empty()) {
|
||||
if (!dschem.loadSchematicFile()) {
|
||||
errorstream << "place_schematic: failed to load schematic file '"
|
||||
<< dschem.filename << "'" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
dschem.resolveNodeNames(ndef);
|
||||
}
|
||||
|
||||
dschem.placeStructure(map, p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ModApiBasic modapibasic_prototype;
|
99
src/script/scripting_game.cpp
Normal file
99
src/script/scripting_game.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "scripting_game.h"
|
||||
#include "log.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "lua_api/l_craft.h"
|
||||
#include "lua_api/l_env.h"
|
||||
#include "lua_api/l_inventory.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "lua_api/l_mapgen.h"
|
||||
#include "lua_api/l_nodemeta.h"
|
||||
#include "lua_api/l_nodetimer.h"
|
||||
#include "lua_api/l_noise.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "lua_api/l_particles.h"
|
||||
#include "lua_api/l_rollback.h"
|
||||
#include "lua_api/l_server.h"
|
||||
#include "lua_api/l_util.h"
|
||||
#include "lua_api/l_vmanip.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
GameScripting::GameScripting(Server* server)
|
||||
{
|
||||
setServer(server);
|
||||
|
||||
// setEnv(env) is called by ScriptApiEnv::initializeEnvironment()
|
||||
// once the environment has been created
|
||||
|
||||
//TODO add security
|
||||
|
||||
luaL_openlibs(getStack());
|
||||
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Create the main minetest table
|
||||
lua_newtable(L);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "object_refs");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "luaentities");
|
||||
|
||||
lua_setglobal(L, "minetest");
|
||||
|
||||
// Initialize our lua_api modules
|
||||
lua_getglobal(L, "minetest");
|
||||
int top = lua_gettop(L);
|
||||
InitializeModApi(L, top);
|
||||
lua_pop(L, 1);
|
||||
|
||||
infostream << "SCRIPTAPI: initialized game modules" << std::endl;
|
||||
}
|
||||
|
||||
void GameScripting::InitializeModApi(lua_State *L, int top)
|
||||
{
|
||||
// Initialize mod api modules
|
||||
ModApiCraft::Initialize(L, top);
|
||||
ModApiEnvMod::Initialize(L, top);
|
||||
ModApiInventory::Initialize(L, top);
|
||||
ModApiItemMod::Initialize(L, top);
|
||||
ModApiMapgen::Initialize(L, top);
|
||||
ModApiParticles::Initialize(L, top);
|
||||
ModApiRollback::Initialize(L, top);
|
||||
ModApiServer::Initialize(L, top);
|
||||
ModApiUtil::Initialize(L, top);
|
||||
|
||||
// Register reference classes (userdata)
|
||||
InvRef::Register(L);
|
||||
LuaItemStack::Register(L);
|
||||
LuaPerlinNoise::Register(L);
|
||||
LuaPerlinNoiseMap::Register(L);
|
||||
LuaPseudoRandom::Register(L);
|
||||
LuaVoxelManip::Register(L);
|
||||
NodeMetaRef::Register(L);
|
||||
NodeTimerRef::Register(L);
|
||||
ObjectRef::Register(L);
|
||||
}
|
|
@ -17,66 +17,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTAPI_H_
|
||||
#define SCRIPTAPI_H_
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#ifndef SCRIPTING_GAME_H_
|
||||
#define SCRIPTING_GAME_H_
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "cpp_api/s_player.h"
|
||||
#include "cpp_api/s_env.h"
|
||||
#include "cpp_api/s_node.h"
|
||||
#include "cpp_api/s_inventory.h"
|
||||
#include "cpp_api/s_entity.h"
|
||||
|
||||
class ModApiBase;
|
||||
#include "cpp_api/s_env.h"
|
||||
#include "cpp_api/s_inventory.h"
|
||||
#include "cpp_api/s_node.h"
|
||||
#include "cpp_api/s_player.h"
|
||||
#include "cpp_api/s_server.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Scriptapi <-> Core Interface */
|
||||
/* Scripting <-> Game Interface */
|
||||
/*****************************************************************************/
|
||||
|
||||
class ScriptApi
|
||||
class GameScripting
|
||||
: virtual public ScriptApiBase,
|
||||
public ScriptApiPlayer,
|
||||
public ScriptApiDetached,
|
||||
public ScriptApiEntity,
|
||||
public ScriptApiEnv,
|
||||
public ScriptApiNode,
|
||||
public ScriptApiDetached,
|
||||
public ScriptApiEntity
|
||||
public ScriptApiPlayer,
|
||||
public ScriptApiServer
|
||||
{
|
||||
public:
|
||||
ScriptApi();
|
||||
ScriptApi(Server* server);
|
||||
~ScriptApi();
|
||||
GameScripting(Server* server);
|
||||
|
||||
// Returns true if script handled message
|
||||
bool on_chat_message(const std::string &name, const std::string &message);
|
||||
|
||||
/* server */
|
||||
void on_shutdown();
|
||||
|
||||
/* auth */
|
||||
bool getAuth(const std::string &playername,
|
||||
std::string *dst_password, std::set<std::string> *dst_privs);
|
||||
void createAuth(const std::string &playername,
|
||||
const std::string &password);
|
||||
bool setPassword(const std::string &playername,
|
||||
const std::string &password);
|
||||
|
||||
/** register a lua api module to scriptapi */
|
||||
static bool registerModApiModule(ModApiBase* prototype);
|
||||
/** load a mod **/
|
||||
bool loadMod(const std::string &scriptpath,const std::string &modname);
|
||||
// use ScriptApiBase::loadMod() to load mods
|
||||
|
||||
private:
|
||||
void getAuthHandler();
|
||||
void readPrivileges(int index,std::set<std::string> &result);
|
||||
|
||||
bool scriptLoad(const char *path);
|
||||
|
||||
static std::vector<ModApiBase*>* m_mod_api_modules;
|
||||
|
||||
void InitializeModApi(lua_State *L, int top);
|
||||
};
|
||||
|
||||
#endif /* SCRIPTAPI_H_ */
|
||||
#endif /* SCRIPTING_GAME_H_ */
|
65
src/script/scripting_mainmenu.cpp
Normal file
65
src/script/scripting_mainmenu.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "scripting_mainmenu.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "lua_api/l_mainmenu.h"
|
||||
#include "lua_api/l_util.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
MainMenuScripting::MainMenuScripting(GUIEngine* guiengine)
|
||||
{
|
||||
setGuiEngine(guiengine);
|
||||
|
||||
//TODO add security
|
||||
|
||||
luaL_openlibs(getStack());
|
||||
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
lua_pushstring(L, DIR_DELIM);
|
||||
lua_setglobal(L, "DIR_DELIM");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setglobal(L, "gamedata");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setglobal(L, "engine");
|
||||
|
||||
// Initialize our lua_api modules
|
||||
lua_getglobal(L, "engine");
|
||||
int top = lua_gettop(L);
|
||||
InitializeModApi(L, top);
|
||||
lua_pop(L, 1);
|
||||
|
||||
infostream << "SCRIPTAPI: initialized mainmenu modules" << std::endl;
|
||||
}
|
||||
|
||||
void MainMenuScripting::InitializeModApi(lua_State *L, int top)
|
||||
{
|
||||
// Initialize mod api modules
|
||||
ModApiMainMenu::Initialize(L, top);
|
||||
ModApiUtil::Initialize(L, top);
|
||||
}
|
45
src/script/scripting_mainmenu.h
Normal file
45
src/script/scripting_mainmenu.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTING_MAINMENU_H_
|
||||
#define SCRIPTING_MAINMENU_H_
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "cpp_api/s_mainmenu.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Scripting <-> Main Menu Interface */
|
||||
/*****************************************************************************/
|
||||
|
||||
class MainMenuScripting
|
||||
: virtual public ScriptApiBase,
|
||||
public ScriptApiMainMenu
|
||||
{
|
||||
public:
|
||||
MainMenuScripting(GUIEngine* guiengine);
|
||||
|
||||
// use ScriptApiBase::loadMod() or ScriptApiBase::loadScript()
|
||||
// to load scripts
|
||||
|
||||
private:
|
||||
void InitializeModApi(lua_State *L, int top);
|
||||
};
|
||||
|
||||
|
||||
#endif /* SCRIPTING_MAINMENU_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue