aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api
diff options
context:
space:
mode:
authorKahrl <kahrl@gmx.net>2013-08-11 04:09:45 +0200
committerKahrl <kahrl@gmx.net>2013-08-14 21:03:33 +0200
commit4e1f50035e860a00636ca5d804c267119df99601 (patch)
treec6cab522305ef2a5b9cfdb3685340d57590f1ff1 /src/script/lua_api
parent6228d634fb31d1ce925d1fdc2dac022629a007ef (diff)
downloadminetest-4e1f50035e860a00636ca5d804c267119df99601.tar.gz
minetest-4e1f50035e860a00636ca5d804c267119df99601.tar.bz2
minetest-4e1f50035e860a00636ca5d804c267119df99601.zip
Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu
Diffstat (limited to 'src/script/lua_api')
-rw-r--r--src/script/lua_api/CMakeLists.txt13
-rw-r--r--src/script/lua_api/l_base.cpp47
-rw-r--r--src/script/lua_api/l_base.h57
-rw-r--r--src/script/lua_api/l_craft.cpp31
-rw-r--r--src/script/lua_api/l_craft.h14
-rw-r--r--src/script/lua_api/l_env.cpp276
-rw-r--r--src/script/lua_api/l_env.h23
-rw-r--r--src/script/lua_api/l_internal.h43
-rw-r--r--src/script/lua_api/l_inventory.cpp52
-rw-r--r--src/script/lua_api/l_inventory.h30
-rw-r--r--src/script/lua_api/l_item.cpp66
-rw-r--r--src/script/lua_api/l_item.h30
-rw-r--r--src/script/lua_api/l_mainmenu.cpp1016
-rw-r--r--src/script/lua_api/l_mainmenu.h137
-rw-r--r--src/script/lua_api/l_mapgen.cpp574
-rw-r--r--src/script/lua_api/l_mapgen.h62
-rw-r--r--src/script/lua_api/l_nodemeta.cpp16
-rw-r--r--src/script/lua_api/l_nodemeta.h15
-rw-r--r--src/script/lua_api/l_nodetimer.cpp6
-rw-r--r--src/script/lua_api/l_nodetimer.h11
-rw-r--r--src/script/lua_api/l_noise.cpp7
-rw-r--r--src/script/lua_api/l_noise.h26
-rw-r--r--src/script/lua_api/l_object.cpp25
-rw-r--r--src/script/lua_api/l_object.h9
-rw-r--r--src/script/lua_api/l_particles.cpp24
-rw-r--r--src/script/lua_api/l_particles.h12
-rw-r--r--src/script/lua_api/l_rollback.cpp80
-rw-r--r--src/script/lua_api/l_rollback.h37
-rw-r--r--src/script/lua_api/l_server.cpp347
-rw-r--r--src/script/lua_api/l_server.h (renamed from src/script/lua_api/luaapi.h)114
-rw-r--r--src/script/lua_api/l_util.cpp199
-rw-r--r--src/script/lua_api/l_util.h76
-rw-r--r--src/script/lua_api/l_vmanip.cpp39
-rw-r--r--src/script/lua_api/l_vmanip.h17
-rw-r--r--src/script/lua_api/luaapi.cpp955
35 files changed, 2891 insertions, 1595 deletions
diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt
index f67cf6886..d75c04335 100644
--- a/src/script/lua_api/CMakeLists.txt
+++ b/src/script/lua_api/CMakeLists.txt
@@ -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)
diff --git a/src/script/lua_api/l_base.cpp b/src/script/lua_api/l_base.cpp
index b1766e6df..b8d673ee4 100644
--- a/src/script/lua_api/l_base.cpp
+++ b/src/script/lua_api/l_base.cpp
@@ -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"
-
-extern "C" {
-#include "lua.h"
+#include "lua_api/l_internal.h"
+#include "cpp_api/s_base.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},
-};
diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h
index f2e0d59a9..71ebd215c 100644
--- a/src/script/lua_api/l_base.h
+++ b/src/script/lua_api/l_base.h
@@ -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;
-
-#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
+ static ScriptApiBase* getScriptApiBase(lua_State *L);
+ static Server* getServer(lua_State *L);
+ static Environment* getEnv(lua_State *L);
+ static GUIEngine* getGuiEngine(lua_State *L);
+
+ // 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_ */
diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp
index a32fb9dff..b0a47bfc1 100644
--- a/src/script/lua_api/l_craft.cpp
+++ b/src/script/lua_api/l_craft.cpp
@@ -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;
diff --git a/src/script/lua_api/l_craft.h b/src/script/lua_api/l_craft.h
index d8319199d..548608776 100644
--- a/src/script/lua_api/l_craft.h
+++ b/src/script/lua_api/l_craft.h
@@ -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_ */
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 47bc9baf7..dbaf6fb36 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -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_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 "common/c_converter.h"
-#include "common/c_content.h"
-#include "common/c_internal.h"
-#include "lua_api/l_nodemeta.h"
-#include "lua_api/l_nodetimer.h"
-#include "lua_api/l_noise.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)
-{
-
- 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;
-}
-
-ModApiEnvMod modapienv_prototype;
+void ModApiEnvMod::Initialize(lua_State *L, int top)
+{
+ 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);
+}
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 4122fd037..adb80a8a8 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -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
diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h
new file mode 100644
index 000000000..14215ee5d
--- /dev/null
+++ b/src/script/lua_api/l_internal.h
@@ -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_ */
diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp
index f57a4e8cd..67b78bcaf 100644
--- a/src/script/lua_api/l_inventory.cpp
+++ b/src/script/lua_api/l_inventory.cpp
@@ -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 "common/c_converter.h"
-#include "common/c_content.h"
#include "lua_api/l_inventory.h"
+#include "lua_api/l_internal.h"
#include "lua_api/l_item.h"
-#include "common/c_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.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;
-}
-
-ModApiInventory::ModApiInventory()
- : ModApiBase() {
-
+void ModApiInventory::Initialize(lua_State *L, int top)
+{
+ API_FCT(create_detached_inventory_raw);
+ API_FCT(get_inventory);
}
-
-ModApiInventory modapiinventory_prototype;
diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h
index 83e8039b8..ed3249e5f 100644
--- a/src/script/lua_api/l_inventory.h
+++ b/src/script/lua_api/l_inventory.h
@@ -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 "lua_api/l_base.h"
-#include "inventorymanager.h"
-#include "player.h"
-#include "serverobject.h"
#include "inventory.h"
+#include "inventorymanager.h"
+
+class Player;
-#include "lua_api/l_base.h"
/*
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);
-
+class ModApiInventory : public ModApiBase {
+private:
static int l_create_detached_inventory_raw(lua_State *L);
+
static int l_get_inventory(lua_State *L);
-private:
+
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_ */
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index 6182c037b..a43b2858f 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -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;
diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h
index bad517e08..7c2e1b098 100644
--- a/src/script/lua_api/l_item.h
+++ b/src/script/lua_api/l_item.h
@@ -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);
};
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
new file mode 100644
index 000000000..b3ae1f3f1
--- /dev/null
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -0,0 +1,1016 @@
+/*
+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.
+*/
+
+#include "lua_api/l_mainmenu.h"
+#include "lua_api/l_internal.h"
+#include "common/c_content.h"
+#include "guiEngine.h"
+#include "guiMainMenu.h"
+#include "guiKeyChangeMenu.h"
+#include "guiFileSelectMenu.h"
+#include "subgame.h"
+#include "porting.h"
+#include "filesys.h"
+#include "convert_json.h"
+#include "serverlist.h"
+#include "sound.h"
+#include "settings.h"
+#include "main.h" // for g_settings
+
+#include <IFileArchive.h>
+#include <IFileSystem.h>
+
+/******************************************************************************/
+std::string ModApiMainMenu::getTextData(lua_State *L, std::string name)
+{
+ lua_getglobal(L, "gamedata");
+
+ lua_getfield(L, -1, name.c_str());
+
+ if(lua_isnil(L, -1))
+ return "";
+
+ return luaL_checkstring(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::getIntegerData(lua_State *L, std::string name,bool& valid)
+{
+ lua_getglobal(L, "gamedata");
+
+ lua_getfield(L, -1, name.c_str());
+
+ if(lua_isnil(L, -1)) {
+ valid = false;
+ return -1;
+ }
+
+ valid = true;
+ return luaL_checkinteger(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::getBoolData(lua_State *L, std::string name,bool& valid)
+{
+ lua_getglobal(L, "gamedata");
+
+ lua_getfield(L, -1, name.c_str());
+
+ if(lua_isnil(L, -1)) {
+ valid = false;
+ return false;
+ }
+
+ valid = true;
+ return lua_toboolean(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_update_formspec(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ if (engine->m_startgame)
+ return 0;
+
+ //read formspec
+ std::string formspec(luaL_checkstring(L, 1));
+
+ if (engine->m_formspecgui != 0) {
+ engine->m_formspecgui->setForm(formspec);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_start(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ //update c++ gamedata from lua table
+
+ bool valid = false;
+
+
+ engine->m_data->selected_world = getIntegerData(L, "selected_world",valid) -1;
+ engine->m_data->simple_singleplayer_mode = getBoolData(L,"singleplayer",valid);
+ engine->m_data->name = getTextData(L,"playername");
+ engine->m_data->password = getTextData(L,"password");
+ engine->m_data->address = getTextData(L,"address");
+ engine->m_data->port = getTextData(L,"port");
+ engine->m_data->serverdescription = getTextData(L,"serverdescription");
+ engine->m_data->servername = getTextData(L,"servername");
+
+ //close menu next time
+ engine->m_startgame = true;
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_close(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ engine->m_data->kill = true;
+
+ //close menu next time
+ engine->m_startgame = true;
+ engine->m_menu->quitMenu();
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_background(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::string backgroundlevel(luaL_checkstring(L, 1));
+ std::string texturename(luaL_checkstring(L, 2));
+
+ bool retval = false;
+
+ if (backgroundlevel == "background") {
+ retval |= engine->setTexture(TEX_LAYER_BACKGROUND,texturename);
+ }
+
+ if (backgroundlevel == "overlay") {
+ retval |= engine->setTexture(TEX_LAYER_OVERLAY,texturename);
+ }
+
+ if (backgroundlevel == "header") {
+ retval |= engine->setTexture(TEX_LAYER_HEADER,texturename);
+ }
+
+ if (backgroundlevel == "footer") {
+ retval |= engine->setTexture(TEX_LAYER_FOOTER,texturename);
+ }
+
+ lua_pushboolean(L,retval);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_clouds(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ bool value = lua_toboolean(L,1);
+
+ engine->m_clouds_enabled = value;
+
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_textlist_index(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::string listboxname(luaL_checkstring(L, 1));
+
+ int selection = engine->m_menu->getListboxIndex(listboxname);
+
+ if (selection >= 0)
+ selection++;
+
+ lua_pushinteger(L, selection);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_worlds(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::vector<WorldSpec> worlds = getAvailableWorlds();
+
+ lua_newtable(L);
+ int top = lua_gettop(L);
+ unsigned int index = 1;
+
+ for (unsigned int i = 0; i < worlds.size(); i++)
+ {
+ lua_pushnumber(L,index);
+
+ lua_newtable(L);
+ int top_lvl2 = lua_gettop(L);
+
+ lua_pushstring(L,"path");
+ lua_pushstring(L,worlds[i].path.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"name");
+ lua_pushstring(L,worlds[i].name.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"gameid");
+ lua_pushstring(L,worlds[i].gameid.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_settable(L, top);
+ index++;
+ }
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_games(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::vector<SubgameSpec> games = getAvailableGames();
+
+ lua_newtable(L);
+ int top = lua_gettop(L);
+ unsigned int index = 1;
+
+ for (unsigned int i = 0; i < games.size(); i++)
+ {
+ lua_pushnumber(L,index);
+ lua_newtable(L);
+ int top_lvl2 = lua_gettop(L);
+
+ lua_pushstring(L,"id");
+ lua_pushstring(L,games[i].id.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"path");
+ lua_pushstring(L,games[i].path.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"gamemods_path");
+ lua_pushstring(L,games[i].gamemods_path.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"name");
+ lua_pushstring(L,games[i].name.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"menuicon_path");
+ lua_pushstring(L,games[i].menuicon_path.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"addon_mods_paths");
+ lua_newtable(L);
+ int table2 = lua_gettop(L);
+ int internal_index=1;
+ for (std::set<std::string>::iterator iter = games[i].addon_mods_paths.begin();
+ iter != games[i].addon_mods_paths.end(); iter++) {
+ lua_pushnumber(L,internal_index);
+ lua_pushstring(L,(*iter).c_str());
+ lua_settable(L, table2);
+ internal_index++;
+ }
+ lua_settable(L, top_lvl2);
+ lua_settable(L, top);
+ index++;
+ }
+ return 1;
+}
+/******************************************************************************/
+int ModApiMainMenu::l_get_modstore_details(lua_State *L)
+{
+ const char *modid = luaL_checkstring(L, 1);
+
+ if (modid != 0) {
+ Json::Value details;
+ std::string url = "";
+ try{
+ url = g_settings->get("modstore_details_url");
+ }
+ catch(SettingNotFoundException &e) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ size_t idpos = url.find("*");
+ url.erase(idpos,1);
+ url.insert(idpos,modid);
+
+ details = getModstoreUrl(url);
+
+ ModStoreModDetails current_mod = readModStoreModDetails(details);
+
+ if ( current_mod.valid) {
+ lua_newtable(L);
+ int top = lua_gettop(L);
+
+ lua_pushstring(L,"id");
+ lua_pushnumber(L,current_mod.id);
+ lua_settable(L, top);
+
+ lua_pushstring(L,"title");
+ lua_pushstring(L,current_mod.title.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"basename");
+ lua_pushstring(L,current_mod.basename.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"description");
+ lua_pushstring(L,current_mod.description.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"author");
+ lua_pushstring(L,current_mod.author.username.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"download_url");
+ lua_pushstring(L,current_mod.versions[0].file.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"screenshot_url");
+ lua_pushstring(L,current_mod.titlepic.file.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"license");
+ lua_pushstring(L,current_mod.license.shortinfo.c_str());
+ lua_settable(L, top);
+
+ lua_pushstring(L,"rating");
+ lua_pushnumber(L,current_mod.rating);
+ lua_settable(L, top);
+
+ //TODO depends
+
+ //TODO softdepends
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_modstore_list(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::string listtype = "local";
+
+ if (!lua_isnone(L,1)) {
+ listtype = luaL_checkstring(L,1);
+ }
+ Json::Value mods;
+ std::string url = "";
+ try{
+ url = g_settings->get("modstore_listmods_url");
+ }
+ catch(SettingNotFoundException &e) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ mods = getModstoreUrl(url);
+
+ std::vector<ModStoreMod> moddata = readModStoreList(mods);
+
+ lua_newtable(L);
+ int top = lua_gettop(L);
+ unsigned int index = 1;
+
+ for (unsigned int i = 0; i < moddata.size(); i++)
+ {
+ if (moddata[i].valid) {
+ lua_pushnumber(L,index);
+ lua_newtable(L);
+
+ int top_lvl2 = lua_gettop(L);
+
+ lua_pushstring(L,"id");
+ lua_pushnumber(L,moddata[i].id);
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"title");
+ lua_pushstring(L,moddata[i].title.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_pushstring(L,"basename");
+ lua_pushstring(L,moddata[i].basename.c_str());
+ lua_settable(L, top_lvl2);
+
+ lua_settable(L, top);
+ index++;
+ }
+ }
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_favorites(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::string listtype = "local";
+
+ if (!lua_isnone(L,1)) {
+ listtype = luaL_checkstring(L,1);
+ }
+
+ std::vector<ServerListSpec> servers;
+#if USE_CURL
+ if(listtype == "online") {
+ servers = ServerList::getOnline();
+ } else {
+ servers = ServerList::getLocal();
+ }
+#else
+ servers = ServerList::getLocal();
+#endif
+
+ lua_newtable(L);
+ int top = lua_gettop(L);
+ unsigned int index = 1;
+
+ for (unsigned int i = 0; i < servers.size(); i++)
+ {
+ lua_pushnumber(L,index);
+
+ lua_newtable(L);
+ int top_lvl2 = lua_gettop(L);
+
+ if (servers[i]["clients"].asString().size()) {
+
+ const char* clients_raw = servers[i]["clients"].asString().c_str();
+ char* endptr = 0;
+ int numbervalue = strtol(clients_raw,&endptr,10);
+
+ if ((*clients_raw != 0) && (*endptr == 0)) {
+ lua_pushstring(L,"clients");
+ lua_pushnumber(L,numbervalue);
+ lua_settable(L, top_lvl2);
+ }
+ }
+
+ if (servers[i]["clients_max"].asString().size()) {
+
+ const char* clients_max_raw = servers[i]["clients_max"].asString().c_str();
+ char* endptr = 0;
+ int numbervalue = strtol(clients_max_raw,&endptr,10);
+
+ if ((*clients_max_raw != 0) && (*endptr == 0)) {
+ lua_pushstring(L,"clients_max");
+ lua_pushnumber(L,numbervalue);
+ lua_settable(L, top_lvl2);
+ }
+ }
+
+ if (servers[i]["version"].asString().size()) {
+ lua_pushstring(L,"version");
+ lua_pushstring(L,servers[i]["version"].asString().c_str());
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["password"].asString().size()) {
+ lua_pushstring(L,"password");
+ lua_pushboolean(L,true);
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["creative"].asString().size()) {
+ lua_pushstring(L,"creative");
+ lua_pushboolean(L,true);
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["damage"].asString().size()) {
+ lua_pushstring(L,"damage");
+ lua_pushboolean(L,true);
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["pvp"].asString().size()) {
+ lua_pushstring(L,"pvp");
+ lua_pushboolean(L,true);
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["description"].asString().size()) {
+ lua_pushstring(L,"description");
+ lua_pushstring(L,servers[i]["description"].asString().c_str());
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["name"].asString().size()) {
+ lua_pushstring(L,"name");
+ lua_pushstring(L,servers[i]["name"].asString().c_str());
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["address"].asString().size()) {
+ lua_pushstring(L,"address");
+ lua_pushstring(L,servers[i]["address"].asString().c_str());
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["port"].asString().size()) {
+ lua_pushstring(L,"port");
+ lua_pushstring(L,servers[i]["port"].asString().c_str());
+ lua_settable(L, top_lvl2);
+ }
+
+ lua_settable(L, top);
+ index++;
+ }
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_favorite(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::vector<ServerListSpec> servers;
+
+ std::string listtype = "local";
+
+ if (!lua_isnone(L,2)) {
+ listtype = luaL_checkstring(L,2);
+ }
+
+ if ((listtype != "local") &&
+ (listtype != "online"))
+ return 0;
+
+#if USE_CURL
+ if(listtype == "online") {
+ servers = ServerList::getOnline();
+ } else {
+ servers = ServerList::getLocal();
+ }
+#else
+ servers = ServerList::getLocal();
+#endif
+
+ int fav_idx = luaL_checkinteger(L,1) -1;
+
+ if ((fav_idx >= 0) &&
+ (fav_idx < (int) servers.size())) {
+
+ ServerList::deleteEntry(servers[fav_idx]);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_show_keys_menu(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ GUIKeyChangeMenu *kmenu
+ = new GUIKeyChangeMenu( engine->m_device->getGUIEnvironment(),
+ engine->m_parent,
+ -1,
+ engine->m_menumanager);
+ kmenu->drop();
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_create_world(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ const char *name = luaL_checkstring(L, 1);
+ int gameidx = luaL_checkinteger(L,2) -1;
+
+ std::string path = porting::path_user + DIR_DELIM
+ "worlds" + DIR_DELIM
+ + name;
+
+ std::vector<SubgameSpec> games = getAvailableGames();
+
+ if ((gameidx >= 0) &&
+ (gameidx < (int) games.size())) {
+
+ // Create world if it doesn't exist
+ if(!initializeWorld(path, games[gameidx].id)){
+ lua_pushstring(L, "Failed to initialize world");
+
+ }
+ else {
+ lua_pushnil(L);
+ }
+ }
+ else {
+ lua_pushstring(L, "Invalid game index");
+ }
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_world(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ int worldidx = luaL_checkinteger(L,1) -1;
+
+ std::vector<WorldSpec> worlds = getAvailableWorlds();
+
+ if ((worldidx >= 0) &&
+ (worldidx < (int) worlds.size())) {
+
+ WorldSpec spec = worlds[worldidx];
+
+ std::vector<std::string> paths;
+ paths.push_back(spec.path);
+ fs::GetRecursiveSubPaths(spec.path, paths);
+
+ // Delete files
+ if (!fs::DeletePaths(paths)) {
+ lua_pushstring(L, "Failed to delete world");
+ }
+ else {
+ lua_pushnil(L);
+ }
+ }
+ else {
+ lua_pushstring(L, "Invalid world index");
+ }
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_topleft_text(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ std::string text = "";
+
+ if (!lua_isnone(L,1) && !lua_isnil(L,1))
+ text = luaL_checkstring(L, 1);
+
+ engine->setTopleftText(text);
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_modpath(lua_State *L)
+{
+ std::string modpath
+ = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);
+ lua_pushstring(L, modpath.c_str());
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_gamepath(lua_State *L)
+{
+ std::string gamepath
+ = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "games" + DIR_DELIM);
+ lua_pushstring(L, gamepath.c_str());
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_texturepath(lua_State *L)
+{
+ std::string gamepath
+ = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "textures");
+ lua_pushstring(L, gamepath.c_str());
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_dirlist(lua_State *L)
+{
+ const char *path = luaL_checkstring(L, 1);
+ bool dironly = lua_toboolean(L, 2);
+
+ std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path);
+
+ unsigned int index = 1;
+ lua_newtable(L);
+ int table = lua_gettop(L);
+
+ for (unsigned int i=0;i< dirlist.size(); i++) {
+ if ((dirlist[i].dir) || (dironly == false)) {
+ lua_pushnumber(L,index);
+ lua_pushstring(L,dirlist[i].name.c_str());
+ lua_settable(L, table);
+ index++;
+ }
+ }
+
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_create_dir(lua_State *L) {
+ const char *path = luaL_checkstring(L, 1);
+
+ if (ModApiMainMenu::isMinetestPath(path)) {
+ lua_pushboolean(L,fs::CreateAllDirs(path));
+ return 1;
+ }
+ lua_pushboolean(L,false);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_dir(lua_State *L)
+{
+ const char *path = luaL_checkstring(L, 1);
+
+ std::string absolute_path = fs::RemoveRelativePathComponents(path);
+
+ if (ModApiMainMenu::isMinetestPath(absolute_path)) {
+ lua_pushboolean(L,fs::RecursiveDelete(absolute_path));
+ return 1;
+ }
+ lua_pushboolean(L,false);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_copy_dir(lua_State *L)
+{
+ const char *source = luaL_checkstring(L, 1);
+ const char *destination = luaL_checkstring(L, 2);
+
+ bool keep_source = true;
+
+ if ((!lua_isnone(L,3)) &&
+ (!lua_isnil(L,3))) {
+ keep_source = lua_toboolean(L,3);
+ }
+
+ std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
+ std::string absolute_source = fs::RemoveRelativePathComponents(source);
+
+ if ((ModApiMainMenu::isMinetestPath(absolute_source)) &&
+ (ModApiMainMenu::isMinetestPath(absolute_destination))) {
+ bool retval = fs::CopyDir(absolute_source,absolute_destination);
+
+ if (retval && (!keep_source)) {
+
+ retval &= fs::RecursiveDelete(absolute_source);
+ }
+ lua_pushboolean(L,retval);
+ return 1;
+ }
+ lua_pushboolean(L,false);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_extract_zip(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ const char *zipfile = luaL_checkstring(L, 1);
+ const char *destination = luaL_checkstring(L, 2);
+
+ std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
+
+ if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
+ fs::CreateAllDirs(absolute_destination);
+
+ io::IFileSystem* fs = engine->m_device->getFileSystem();
+
+ fs->addFileArchive(zipfile,true,false,io::EFAT_ZIP);
+
+ assert(fs->getFileArchiveCount() > 0);
+
+ /**********************************************************************/
+ /* WARNING this is not threadsafe!! */
+ /**********************************************************************/
+ io::IFileArchive* opened_zip =
+ fs->getFileArchive(fs->getFileArchiveCount()-1);
+
+ const io::IFileList* files_in_zip = opened_zip->getFileList();
+
+ unsigned int number_of_files = files_in_zip->getFileCount();
+
+ for (unsigned int i=0; i < number_of_files; i++) {
+ std::string fullpath = destination;
+ fullpath += DIR_DELIM;
+ fullpath += files_in_zip->getFullFileName(i).c_str();
+
+ if (files_in_zip->isDirectory(i)) {
+ if (! fs::CreateAllDirs(fullpath) ) {
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ lua_pushboolean(L,false);
+ return 1;
+ }
+ }
+ else {
+ io::IReadFile* toread = opened_zip->createAndOpenFile(i);
+
+ FILE *targetfile = fopen(fullpath.c_str(),"wb");
+
+ if (targetfile == NULL) {
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ lua_pushboolean(L,false);
+ return 1;
+ }
+
+ char read_buffer[1024];
+ unsigned int total_read = 0;
+
+ while (total_read < toread->getSize()) {
+
+ unsigned int bytes_read =
+ toread->read(read_buffer,sizeof(read_buffer));
+ unsigned int bytes_written;
+ if ((bytes_read < 0 ) ||
+ (bytes_written = fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
+ {
+ fclose(targetfile);
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ lua_pushboolean(L,false);
+ return 1;
+ }
+ total_read += bytes_read;
+ }
+
+ fclose(targetfile);
+ }
+
+ }
+
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ lua_pushboolean(L,true);
+ return 1;
+ }
+
+ lua_pushboolean(L,false);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_scriptdir(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ lua_pushstring(L,engine->getScriptDir().c_str());
+ return 1;
+}
+
+/******************************************************************************/
+bool ModApiMainMenu::isMinetestPath(std::string path)
+{
+ if (fs::PathStartsWith(path,fs::TempPath()))
+ return true;
+
+ /* games */
+ if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "games")))
+ return true;
+
+ /* mods */
+ if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods")))
+ return true;
+
+ /* worlds */
+ if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "worlds")))
+ return true;
+
+
+ return false;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ const char *formname= luaL_checkstring(L, 1);
+ const char *title = luaL_checkstring(L, 2);
+
+ GUIFileSelectMenu* fileOpenMenu =
+ new GUIFileSelectMenu(engine->m_device->getGUIEnvironment(),
+ engine->m_parent,
+ -1,
+ engine->m_menumanager,
+ title,
+ formname);
+ fileOpenMenu->setTextDest(engine->m_buttonhandler);
+ fileOpenMenu->drop();
+ return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_version(lua_State *L)
+{
+ lua_pushstring(L,VERSION_STRING);
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_sound_play(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+
+ SimpleSoundSpec spec;
+ read_soundspec(L, 1, spec);
+ bool looped = lua_toboolean(L, 2);
+
+ u32 handle = engine->playSound(spec, looped);
+
+ lua_pushinteger(L, handle);
+
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_sound_stop(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+
+ u32 handle = luaL_checkinteger(L, 1);
+ engine->stopSound(handle);
+
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_download_file(lua_State *L)
+{
+ GUIEngine* engine = getGuiEngine(L);
+ assert(engine != 0);
+
+ const char *url = luaL_checkstring(L, 1);
+ const char *target = luaL_checkstring(L, 2);
+
+ //check path
+ std::string absolute_destination = fs::RemoveRelativePathComponents(target);
+
+ if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
+ if (engine->downloadFile(url,absolute_destination)) {
+ lua_pushboolean(L,true);
+ return 1;
+ }
+ }
+ lua_pushboolean(L,false);
+ return 1;
+}
+
+/******************************************************************************/
+void ModApiMainMenu::Initialize(lua_State *L, int top)
+{
+ API_FCT(update_formspec);
+ API_FCT(set_clouds);
+ API_FCT(get_textlist_index);
+ API_FCT(get_worlds);
+ API_FCT(get_games);
+ API_FCT(start);
+ API_FCT(close);
+ API_FCT(get_favorites);
+ API_FCT(show_keys_menu);
+ API_FCT(create_world);
+ API_FCT(delete_world);
+ API_FCT(delete_favorite);
+ API_FCT(set_background);
+ API_FCT(set_topleft_text);
+ API_FCT(get_modpath);
+ API_FCT(get_gamepath);
+ API_FCT(get_texturepath);
+ API_FCT(get_dirlist);
+ API_FCT(create_dir);
+ API_FCT(delete_dir);
+ API_FCT(copy_dir);
+ API_FCT(extract_zip);
+ API_FCT(get_scriptdir);
+ API_FCT(show_file_open_dialog);
+ API_FCT(get_version);
+ API_FCT(download_file);
+ API_FCT(get_modstore_details);
+ API_FCT(get_modstore_list);
+ API_FCT(sound_play);
+ API_FCT(sound_stop);
+}
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
new file mode 100644
index 000000000..21dd82c68
--- /dev/null
+++ b/src/script/lua_api/l_mainmenu.h
@@ -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_ */
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
new file mode 100644
index 000000000..14693b43f
--- /dev/null
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -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);
+}
diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h
new file mode 100644
index 000000000..d0da5bb13
--- /dev/null
+++ b/src/script/lua_api/l_mapgen.h
@@ -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_ */
diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp
index 511fb38ce..f9c8794d5 100644
--- a/src/script/lua_api/l_nodemeta.cpp
+++ b/src/script/lua_api/l_nodemeta.cpp
@@ -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);
diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h
index 23404a084..ed06ff0fa 100644
--- a/src/script/lua_api/l_nodemeta.h
+++ b/src/script/lua_api/l_nodemeta.h
@@ -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_ */
diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp
index 60e4ec061..c81a7ebc9 100644
--- a/src/script/lua_api/l_nodetimer.cpp
+++ b/src/script/lua_api/l_nodetimer.cpp
@@ -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);
diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h
index f652b4900..9f8dd21c8 100644
--- a/src/script/lua_api/l_nodetimer.h
+++ b/src/script/lua_api/l_nodetimer.h
@@ -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;
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index 43149e93c..ecbda9fad 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -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);
diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h
index 6275ca472..65a927882 100644
--- a/src/script/lua_api/l_noise.h
+++ b/src/script/lua_api/l_noise.h
@@ -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_ */
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index ee24789c5..c0da79c29 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -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)
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index a82638442..b6f5cd06f 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -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;
diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp
index c291cc21e..6b009149e 100644
--- a/src/script/lua_api/l_particles.cpp
+++ b/src/script/lua_api/l_particles.cpp
@@ -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);
+}
+
diff --git a/src/script/lua_api/l_particles.h b/src/script/lua_api/l_particles.h
index 3729f8761..c593f47e4 100644
--- a/src/script/lua_api/l_particles.h
+++ b/src/script/lua_api/l_particles.h
@@ -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_ */
diff --git a/src/script/lua_api/l_rollback.cpp b/src/script/lua_api/l_rollback.cpp
new file mode 100644
index 000000000..6076399ae
--- /dev/null
+++ b/src/script/lua_api/l_rollback.cpp
@@ -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);
+}
diff --git a/src/script/lua_api/l_rollback.h b/src/script/lua_api/l_rollback.h
new file mode 100644
index 000000000..86992a47e
--- /dev/null
+++ b/src/script/lua_api/l_rollback.h
@@ -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_ */
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
new file mode 100644
index 000000000..8e809c36a
--- /dev/null
+++ b/src/script/lua_api/l_server.cpp
@@ -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);
+}
diff --git a/src/script/lua_api/luaapi.h b/src/script/lua_api/l_server.h
index af73625ba..21f300400 100644
--- a/src/script/lua_api/luaapi.h
+++ b/src/script/lua_api/l_server.h
@@ -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_ */
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
new file mode 100644
index 000000000..0e4de9eee
--- /dev/null
+++ b/src/script/lua_api/l_util.cpp
@@ -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);
+}
+
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
new file mode 100644
index 000000000..b102e315b
--- /dev/null
+++ b/src/script/lua_api/l_util.h
@@ -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_ */
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index 195682579..1e9cc350f 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -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);
diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h
index a7791e56b..d2f035a3e 100644
--- a/src/script/lua_api/l_vmanip.h
+++ b/src/script/lua_api/l_vmanip.h
@@ -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_ */
diff --git a/src/script/lua_api/luaapi.cpp b/src/script/lua_api/luaapi.cpp
deleted file mode 100644
index 26fb0c318..000000000
--- a/src/script/lua_api/luaapi.cpp
+++ /dev/null
@@ -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;