aboutsummaryrefslogtreecommitdiff
path: root/src/script/cpp_api
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r--src/script/cpp_api/CMakeLists.txt10
-rw-r--r--src/script/cpp_api/s_base.cpp279
-rw-r--r--src/script/cpp_api/s_base.h119
-rw-r--r--src/script/cpp_api/s_entity.cpp5
-rw-r--r--src/script/cpp_api/s_env.cpp11
-rw-r--r--src/script/cpp_api/s_internal.h63
-rw-r--r--src/script/cpp_api/s_inventory.cpp1
-rw-r--r--src/script/cpp_api/s_item.cpp3
-rw-r--r--src/script/cpp_api/s_mainmenu.cpp80
-rw-r--r--src/script/cpp_api/s_mainmenu.h49
-rw-r--r--src/script/cpp_api/s_node.cpp2
-rw-r--r--src/script/cpp_api/s_nodemeta.cpp6
-rw-r--r--src/script/cpp_api/s_player.cpp15
-rw-r--r--src/script/cpp_api/s_player.h2
-rw-r--r--src/script/cpp_api/s_server.cpp151
-rw-r--r--src/script/cpp_api/s_server.h (renamed from src/script/cpp_api/scriptapi.h)54
-rw-r--r--src/script/cpp_api/scriptapi.cpp291
17 files changed, 556 insertions, 585 deletions
diff --git a/src/script/cpp_api/CMakeLists.txt b/src/script/cpp_api/CMakeLists.txt
index 6f5b51a49..b753eda17 100644
--- a/src/script/cpp_api/CMakeLists.txt
+++ b/src/script/cpp_api/CMakeLists.txt
@@ -1,4 +1,5 @@
-set(SCRIPT_CPP_API_SRCS
+# Used by server and client
+set(common_SCRIPT_CPP_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp
@@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/scriptapi.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp
+ PARENT_SCOPE)
+
+# Used by client only
+set(minetest_SCRIPT_CPP_API_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
PARENT_SCOPE)
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index e2e586357..e26d54ba7 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -17,30 +17,141 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "cpp_api/s_base.h"
+#include "cpp_api/s_internal.h"
+#include "lua_api/l_object.h"
+#include "serverobject.h"
+#include "debug.h"
+#include "log.h"
+#include "mods.h"
+#include "util/string.h"
+
+
+extern "C" {
+#include "lualib.h"
+}
+
#include <stdio.h>
#include <cstdarg>
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
+
+class ModNameStorer
+{
+private:
+ lua_State *L;
+public:
+ ModNameStorer(lua_State *L_, const std::string modname):
+ L(L_)
+ {
+ // Store current modname in registry
+ lua_pushstring(L, modname.c_str());
+ lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
+ }
+ ~ModNameStorer()
+ {
+ // Clear current modname in registry
+ lua_pushnil(L);
+ lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
+ }
+};
+
+static int loadScript_ErrorHandler(lua_State *L) {
+ lua_getfield(L, LUA_GLOBALSINDEX, "debug");
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ return 1;
+ }
+ lua_getfield(L, -1, "traceback");
+ if (!lua_isfunction(L, -1)) {
+ lua_pop(L, 2);
+ return 1;
+ }
+ lua_pushvalue(L, 1);
+ lua_pushinteger(L, 2);
+ lua_call(L, 2, 1);
+ return 1;
}
-#include "cpp_api/s_base.h"
-#include "lua_api/l_object.h"
-#include "serverobject.h"
-ScriptApiBase::ScriptApiBase() :
- m_luastackmutex(),
-#ifdef LOCK_DEBUG
- m_locked(false),
-#endif
- m_luastack(0),
- m_server(0),
- m_environment(0)
+/*
+ ScriptApiBase
+*/
+
+ScriptApiBase::ScriptApiBase()
{
+ m_luastackmutex.Init();
+
+ #ifdef SCRIPTAPI_LOCK_DEBUG
+ m_locked = false;
+ #endif
+ m_luastack = luaL_newstate();
+ assert(m_luastack);
+
+ // Make the ScriptApiBase* accessible to ModApiBase
+ lua_pushlightuserdata(m_luastack, this);
+ lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi");
+
+ m_server = 0;
+ m_environment = 0;
+ m_guiengine = 0;
}
+ScriptApiBase::~ScriptApiBase()
+{
+ lua_close(m_luastack);
+}
+
+bool ScriptApiBase::loadMod(const std::string &scriptpath,
+ const std::string &modname)
+{
+ ModNameStorer modnamestorer(getStack(), modname);
+
+ if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
+ errorstream<<"Error loading mod \""<<modname
+ <<"\": modname does not follow naming conventions: "
+ <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
+ return false;
+ }
+
+ bool success = false;
+
+ try{
+ success = loadScript(scriptpath);
+ }
+ catch(LuaError &e){
+ errorstream<<"Error loading mod \""<<modname
+ <<"\": "<<e.what()<<std::endl;
+ }
+
+ return success;
+}
+
+bool ScriptApiBase::loadScript(const std::string &scriptpath)
+{
+ verbosestream<<"Loading and running script from "<<scriptpath<<std::endl;
+
+ lua_State *L = getStack();
+
+ lua_pushcfunction(L, loadScript_ErrorHandler);
+ int errorhandler = lua_gettop(L);
+
+ int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
+ if(ret){
+ errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
+ errorstream<<"Failed to load and run script from "<<std::endl;
+ errorstream<<scriptpath<<":"<<std::endl;
+ errorstream<<std::endl;
+ errorstream<<lua_tostring(L, -1)<<std::endl;
+ errorstream<<std::endl;
+ errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
+ lua_pop(L, 1); // Pop error message from stack
+ lua_pop(L, 1); // Pop the error handler from stack
+ return false;
+ }
+ lua_pop(L, 1); // Pop the error handler from stack
+ return true;
+}
void ScriptApiBase::realityCheck()
{
@@ -52,7 +163,7 @@ void ScriptApiBase::realityCheck()
}
}
-void ScriptApiBase::scriptError(const char *fmt, ...)
+void ScriptApiBase::scriptError(const char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
@@ -65,130 +176,34 @@ void ScriptApiBase::scriptError(const char *fmt, ...)
void ScriptApiBase::stackDump(std::ostream &o)
{
- int i;
- int top = lua_gettop(m_luastack);
- for (i = 1; i <= top; i++) { /* repeat for each level */
- int t = lua_type(m_luastack, i);
- switch (t) {
-
- case LUA_TSTRING: /* strings */
- o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
- break;
-
- case LUA_TBOOLEAN: /* booleans */
- o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
- break;
-
- case LUA_TNUMBER: /* numbers */ {
- char buf[10];
- snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
- o<<buf;
- break; }
-
- default: /* other values */
- o<<lua_typename(m_luastack, t);
- break;
-
- }
- o<<" ";
- }
- o<<std::endl;
-}
-
-// Push the list of callbacks (a lua table).
-// Then push nargs arguments.
-// Then call this function, which
-// - runs the callbacks
-// - removes the table and arguments from the lua stack
-// - pushes the return value, computed depending on mode
-void ScriptApiBase::runCallbacks(int nargs,RunCallbacksMode mode)
-{
- lua_State *L = getStack();
-
- // Insert the return value into the lua stack, below the table
- assert(lua_gettop(L) >= nargs + 1);
- lua_pushnil(L);
- lua_insert(L, -(nargs + 1) - 1);
- // Stack now looks like this:
- // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
+ int i;
+ int top = lua_gettop(m_luastack);
+ for (i = 1; i <= top; i++) { /* repeat for each level */
+ int t = lua_type(m_luastack, i);
+ switch (t) {
- int rv = lua_gettop(L) - nargs - 1;
- int table = rv + 1;
- int arg = table + 1;
+ case LUA_TSTRING: /* strings */
+ o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
+ break;
- luaL_checktype(L, table, LUA_TTABLE);
+ case LUA_TBOOLEAN: /* booleans */
+ o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
+ break;
- // Foreach
- lua_pushnil(L);
- bool first_loop = true;
- while(lua_next(L, table) != 0){
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TFUNCTION);
- // Call function
- for(int i = 0; i < nargs; i++)
- lua_pushvalue(L, arg+i);
- if(lua_pcall(L, nargs, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
-
- // Move return value to designated space in stack
- // Or pop it
- if(first_loop){
- // Result of first callback is always moved
- lua_replace(L, rv);
- first_loop = false;
- } else {
- // Otherwise, what happens depends on the mode
- if(mode == RUN_CALLBACKS_MODE_FIRST)
- lua_pop(L, 1);
- else if(mode == RUN_CALLBACKS_MODE_LAST)
- lua_replace(L, rv);
- else if(mode == RUN_CALLBACKS_MODE_AND ||
- mode == RUN_CALLBACKS_MODE_AND_SC){
- if((bool)lua_toboolean(L, rv) == true &&
- (bool)lua_toboolean(L, -1) == false)
- lua_replace(L, rv);
- else
- lua_pop(L, 1);
- }
- else if(mode == RUN_CALLBACKS_MODE_OR ||
- mode == RUN_CALLBACKS_MODE_OR_SC){
- if((bool)lua_toboolean(L, rv) == false &&
- (bool)lua_toboolean(L, -1) == true)
- lua_replace(L, rv);
- else
- lua_pop(L, 1);
- }
- else
- assert(0);
- }
+ case LUA_TNUMBER: /* numbers */ {
+ char buf[10];
+ snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
+ o<<buf;
+ break; }
- // Handle short circuit modes
- if(mode == RUN_CALLBACKS_MODE_AND_SC &&
- (bool)lua_toboolean(L, rv) == false)
- break;
- else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
- (bool)lua_toboolean(L, rv) == true)
- break;
+ default: /* other values */
+ o<<lua_typename(m_luastack, t);
+ break;
- // value removed, keep key for next iteration
- }
-
- // Remove stuff from stack, leaving only the return value
- lua_settop(L, rv);
-
- // Fix return value in case no callbacks were called
- if(first_loop){
- if(mode == RUN_CALLBACKS_MODE_AND ||
- mode == RUN_CALLBACKS_MODE_AND_SC){
- lua_pop(L, 1);
- lua_pushboolean(L, true);
- }
- else if(mode == RUN_CALLBACKS_MODE_OR ||
- mode == RUN_CALLBACKS_MODE_OR_SC){
- lua_pop(L, 1);
- lua_pushboolean(L, false);
}
+ o<<" ";
}
+ o<<std::endl;
}
void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index 8799d3c00..3cb59634b 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define S_BASE_H_
#include <iostream>
+#include <string>
+
+extern "C" {
+#include <lua.h>
+}
#include "irrlichttypes.h"
#include "jmutex.h"
#include "jmutexautolock.h"
#include "common/c_types.h"
-#include "debug.h"
-#define LOCK_DEBUG
+#define SCRIPTAPI_LOCK_DEBUG
class Server;
class Environment;
+class GUIEngine;
class ServerActiveObject;
-class LuaABM;
-class InvRef;
-class ModApiBase;
-class ModApiEnvMod;
-class ObjectRef;
-class NodeMetaRef;
-
-
-/* definitions */
-// What scriptapi_run_callbacks does with the return values of callbacks.
-// Regardless of the mode, if only one callback is defined,
-// its return value is the total return value.
-// Modes only affect the case where 0 or >= 2 callbacks are defined.
-enum RunCallbacksMode
-{
- // Returns the return value of the first callback
- // Returns nil if list of callbacks is empty
- RUN_CALLBACKS_MODE_FIRST,
- // Returns the return value of the last callback
- // Returns nil if list of callbacks is empty
- RUN_CALLBACKS_MODE_LAST,
- // If any callback returns a false value, the first such is returned
- // Otherwise, the first callback's return value (trueish) is returned
- // Returns true if list of callbacks is empty
- RUN_CALLBACKS_MODE_AND,
- // Like above, but stops calling callbacks (short circuit)
- // after seeing the first false value
- RUN_CALLBACKS_MODE_AND_SC,
- // If any callback returns a true value, the first such is returned
- // Otherwise, the first callback's return value (falseish) is returned
- // Returns false if list of callbacks is empty
- RUN_CALLBACKS_MODE_OR,
- // Like above, but stops calling callbacks (short circuit)
- // after seeing the first true value
- RUN_CALLBACKS_MODE_OR_SC,
- // Note: "a true value" and "a false value" refer to values that
- // are converted by lua_toboolean to true or false, respectively.
-};
-
class ScriptApiBase {
public:
+ ScriptApiBase();
+ virtual ~ScriptApiBase();
+
+ bool loadMod(const std::string &scriptpath, const std::string &modname);
+ bool loadScript(const std::string &scriptpath);
+
/* object */
void addObjectReference(ServerActiveObject *cobj);
void removeObjectReference(ServerActiveObject *cobj);
- ScriptApiBase();
-
protected:
friend class LuaABM;
friend class InvRef;
@@ -91,78 +61,35 @@ protected:
friend class ModApiEnvMod;
friend class LuaVoxelManip;
-
- inline lua_State* getStack()
+ lua_State* getStack()
{ return m_luastack; }
- bool setStack(lua_State* stack) {
- if (m_luastack == 0) {
- m_luastack = stack;
- return true;
- }
- return false;
- }
-
void realityCheck();
void scriptError(const char *fmt, ...);
void stackDump(std::ostream &o);
- void runCallbacks(int nargs,RunCallbacksMode mode);
- inline Server* getServer() { return m_server; }
+ Server* getServer() { return m_server; }
void setServer(Server* server) { m_server = server; }
Environment* getEnv() { return m_environment; }
void setEnv(Environment* env) { m_environment = env; }
+ GUIEngine* getGuiEngine() { return m_guiengine; }
+ void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
+
void objectrefGetOrCreate(ServerActiveObject *cobj);
void objectrefGet(u16 id);
- JMutex m_luastackmutex;
-#ifdef LOCK_DEBUG
+ JMutex m_luastackmutex;
+#ifdef SCRIPTAPI_LOCK_DEBUG
bool m_locked;
#endif
private:
lua_State* m_luastack;
- Server* m_server;
- Environment* m_environment;
-
-
-};
-
-#ifdef LOCK_DEBUG
-class LockChecker {
-public:
- LockChecker(bool* variable) {
- assert(*variable == false);
-
- m_variable = variable;
- *m_variable = true;
- }
- ~LockChecker() {
- *m_variable = false;
- }
-private:
-bool* m_variable;
+ Server* m_server;
+ Environment* m_environment;
+ GUIEngine* m_guiengine;
};
-#define LOCK_CHECK LockChecker(&(this->m_locked))
-#else
-#define LOCK_CHECK while(0)
-#endif
-
-#define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex)
-
-#define SCRIPTAPI_PRECHECKHEADER \
- LUA_STACK_AUTOLOCK; \
- LOCK_CHECK; \
- realityCheck(); \
- lua_State *L = getStack(); \
- assert(lua_checkstack(L, 20)); \
- StackUnroller stack_unroller(L);
-
-#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface()
-#define ENV_TO_SA(env) env->getScriptIface()
-#define SERVER_TO_SA(srv) srv->getScriptIface()
-
#endif /* S_BASE_H_ */
diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp
index c494e8232..cefa27cb1 100644
--- a/src/script/cpp_api/s_entity.cpp
+++ b/src/script/cpp_api/s_entity.cpp
@@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_entity.h"
+#include "cpp_api/s_internal.h"
#include "log.h"
#include "object_properties.h"
#include "common/c_converter.h"
#include "common/c_content.h"
-extern "C" {
-#include "lauxlib.h"
-}
-
bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
{
SCRIPTAPI_PRECHECKHEADER
diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp
index 632b28f45..ef3a1dddf 100644
--- a/src/script/cpp_api/s_env.cpp
+++ b/src/script/cpp_api/s_env.cpp
@@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_env.h"
+#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
#include "log.h"
#include "environment.h"
#include "mapgen.h"
#include "lua_api/l_env.h"
-extern "C" {
-#include "lauxlib.h"
-}
-
void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
u32 blockseed)
{
@@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
push_v3s16(L, minp);
push_v3s16(L, maxp);
lua_pushnumber(L, blockseed);
- runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiEnv::environment_Step(float dtime)
@@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime)
lua_getfield(L, -1, "registered_globalsteps");
// Call callbacks
lua_pushnumber(L, dtime);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
@@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
lua_pushstring(L, flagstr.c_str());
lua_setfield(L, -2, "flags");
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h
new file mode 100644
index 000000000..10ee1a7de
--- /dev/null
+++ b/src/script/cpp_api/s_internal.h
@@ -0,0 +1,63 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+/******************************************************************************/
+/******************************************************************************/
+/* WARNING!!!! do NOT add this header in any include file or any code file */
+/* not being a modapi file!!!!!!!! */
+/******************************************************************************/
+/******************************************************************************/
+
+#ifndef S_INTERNAL_H_
+#define S_INTERNAL_H_
+
+#include "common/c_internal.h"
+#include "cpp_api/s_base.h"
+
+#ifdef SCRIPTAPI_LOCK_DEBUG
+#include "debug.h" // assert()
+class LockChecker {
+public:
+ LockChecker(bool* variable) {
+ assert(*variable == false);
+
+ m_variable = variable;
+ *m_variable = true;
+ }
+ ~LockChecker() {
+ *m_variable = false;
+ }
+private:
+bool* m_variable;
+};
+
+#define SCRIPTAPI_LOCK_CHECK LockChecker(&(this->m_locked))
+#else
+#define SCRIPTAPI_LOCK_CHECK while(0)
+#endif
+
+#define SCRIPTAPI_PRECHECKHEADER \
+ JMutexAutoLock(this->m_luastackmutex); \
+ SCRIPTAPI_LOCK_CHECK; \
+ realityCheck(); \
+ lua_State *L = getStack(); \
+ assert(lua_checkstack(L, 20)); \
+ StackUnroller stack_unroller(L);
+
+#endif /* S_INTERNAL_H_ */
diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp
index 2402d198c..09f26d80c 100644
--- a/src/script/cpp_api/s_inventory.cpp
+++ b/src/script/cpp_api/s_inventory.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_inventory.h"
+#include "cpp_api/s_internal.h"
#include "inventorymanager.h"
#include "lua_api/l_inventory.h"
#include "lua_api/l_item.h"
diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp
index 6937ebbeb..b4536ac63 100644
--- a/src/script/cpp_api/s_item.cpp
+++ b/src/script/cpp_api/s_item.cpp
@@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_item.h"
+#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "lua_api/l_item.h"
#include "server.h"
+#include "log.h"
+#include "util/pointedthing.h"
bool ScriptApiItem::item_OnDrop(ItemStack &item,
ServerActiveObject *dropper, v3f pos)
diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp
new file mode 100644
index 000000000..af92c59a9
--- /dev/null
+++ b/src/script/cpp_api/s_mainmenu.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 "cpp_api/s_mainmenu.h"
+#include "cpp_api/s_internal.h"
+#include "common/c_converter.h"
+
+void ScriptApiMainMenu::setMainMenuErrorMessage(std::string errormessage)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ lua_getglobal(L, "gamedata");
+ int gamedata_idx = lua_gettop(L);
+ lua_pushstring(L, "errormessage");
+ lua_pushstring(L, errormessage.c_str());
+ lua_settable(L, gamedata_idx);
+ lua_pop(L, 1);
+}
+
+void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get handler function
+ lua_getglobal(L, "engine");
+ lua_getfield(L, -1, "event_handler");
+ if(lua_isnil(L, -1))
+ return;
+ luaL_checktype(L, -1, LUA_TFUNCTION);
+
+ // Call it
+ lua_pushstring(L, text.c_str());
+ if(lua_pcall(L, 1, 0, 0))
+ scriptError("error running function engine.event_handler: %s\n",
+ lua_tostring(L, -1));
+}
+
+void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get handler function
+ lua_getglobal(L, "engine");
+ lua_getfield(L, -1, "button_handler");
+ if(lua_isnil(L, -1))
+ return;
+ luaL_checktype(L, -1, LUA_TFUNCTION);
+
+ // Convert fields to lua table
+ lua_newtable(L);
+ for(std::map<std::string, std::string>::const_iterator
+ i = fields.begin(); i != fields.end(); i++){
+ const std::string &name = i->first;
+ const std::string &value = i->second;
+ lua_pushstring(L, name.c_str());
+ lua_pushlstring(L, value.c_str(), value.size());
+ lua_settable(L, -3);
+ }
+
+ // Call it
+ if(lua_pcall(L, 1, 0, 0))
+ scriptError("error running function engine.button_handler: %s\n",
+ lua_tostring(L, -1));
+}
diff --git a/src/script/cpp_api/s_mainmenu.h b/src/script/cpp_api/s_mainmenu.h
new file mode 100644
index 000000000..53dcd37e9
--- /dev/null
+++ b/src/script/cpp_api/s_mainmenu.h
@@ -0,0 +1,49 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef S_MAINMENU_H_
+#define S_MAINMENU_H_
+
+#include "cpp_api/s_base.h"
+#include <map>
+
+class ScriptApiMainMenu
+ : virtual public ScriptApiBase
+{
+public:
+ /**
+ * set gamedata.errormessage to inform lua of an error
+ * @param errormessage the error message
+ */
+ void setMainMenuErrorMessage(std::string errormessage);
+
+ /**
+ * process events received from formspec
+ * @param text events in textual form
+ */
+ void handleMainMenuEvent(std::string text);
+
+ /**
+ * process field data recieved from formspec
+ * @param fields data in field format
+ */
+ void handleMainMenuButtons(std::map<std::string, std::string> fields);
+};
+
+#endif /* S_MAINMENU_H_ */
diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp
index d0b0583c0..92fd00a74 100644
--- a/src/script/cpp_api/s_node.cpp
+++ b/src/script/cpp_api/s_node.cpp
@@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_node.h"
+#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "nodedef.h"
#include "server.h"
+#include "environment.h"
struct EnumString ScriptApiNode::es_DrawType[] =
diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp
index 56cea8e5f..e87464c61 100644
--- a/src/script/cpp_api/s_nodemeta.cpp
+++ b/src/script/cpp_api/s_nodemeta.cpp
@@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_nodemeta.h"
+#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
#include "nodedef.h"
#include "mapnode.h"
#include "server.h"
+#include "environment.h"
#include "lua_api/l_item.h"
-extern "C" {
-#include "lauxlib.h"
-}
-
// Return number of accepted items to be moved
int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
const std::string &from_list, int from_index,
diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp
index 0dbd52527..215a34d53 100644
--- a/src/script/cpp_api/s_player.cpp
+++ b/src/script/cpp_api/s_player.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "cpp_api/s_player.h"
+#include "cpp_api/s_internal.h"
void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
{
@@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_newplayers");
// Call callbacks
objectrefGetOrCreate(player);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
@@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_dieplayers");
// Call callbacks
objectrefGetOrCreate(player);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
@@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_respawnplayers");
// Call callbacks
objectrefGetOrCreate(player);
- runCallbacks(1, RUN_CALLBACKS_MODE_OR);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
bool positioning_handled_by_some = lua_toboolean(L, -1);
return positioning_handled_by_some;
}
@@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_joinplayers");
// Call callbacks
objectrefGetOrCreate(player);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
@@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_leaveplayers");
// Call callbacks
objectrefGetOrCreate(player);
- runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
@@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
lua_newtable(L);
lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
lua_setfield(L, -2, "type");
- runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+ script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
@@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3);
}
- runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
+ script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
}
ScriptApiPlayer::~ScriptApiPlayer() {
}
diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h
index c0409a481..88221f486 100644
--- a/src/script/cpp_api/s_player.h
+++ b/src/script/cpp_api/s_player.h
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef S_PLAYER_H_
#define S_PLAYER_H_
+#include <map>
+
#include "cpp_api/s_base.h"
diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp
new file mode 100644
index 000000000..d41805b7b
--- /dev/null
+++ b/src/script/cpp_api/s_server.cpp
@@ -0,0 +1,151 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "cpp_api/s_server.h"
+#include "cpp_api/s_internal.h"
+#include "common/c_converter.h"
+
+bool ScriptApiServer::getAuth(const std::string &playername,
+ std::string *dst_password,
+ std::set<std::string> *dst_privs)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ getAuthHandler();
+ lua_getfield(L, -1, "get_auth");
+ if(lua_type(L, -1) != LUA_TFUNCTION)
+ throw LuaError(L, "Authentication handler missing get_auth");
+ lua_pushstring(L, playername.c_str());
+ if(lua_pcall(L, 1, 1, 0))
+ scriptError("error: %s", lua_tostring(L, -1));
+
+ // nil = login not allowed
+ if(lua_isnil(L, -1))
+ return false;
+ luaL_checktype(L, -1, LUA_TTABLE);
+
+ std::string password;
+ bool found = getstringfield(L, -1, "password", password);
+ if(!found)
+ throw LuaError(L, "Authentication handler didn't return password");
+ if(dst_password)
+ *dst_password = password;
+
+ lua_getfield(L, -1, "privileges");
+ if(!lua_istable(L, -1))
+ throw LuaError(L,
+ "Authentication handler didn't return privilege table");
+ if(dst_privs)
+ readPrivileges(-1, *dst_privs);
+ lua_pop(L, 1);
+
+ return true;
+}
+
+void ScriptApiServer::getAuthHandler()
+{
+ lua_State *L = getStack();
+
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "registered_auth_handler");
+ if(lua_isnil(L, -1)){
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "builtin_auth_handler");
+ }
+ if(lua_type(L, -1) != LUA_TTABLE)
+ throw LuaError(L, "Authentication handler table not valid");
+}
+
+void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
+{
+ lua_State *L = getStack();
+
+ result.clear();
+ lua_pushnil(L);
+ if(index < 0)
+ index -= 1;
+ while(lua_next(L, index) != 0){
+ // key at index -2 and value at index -1
+ std::string key = luaL_checkstring(L, -2);
+ bool value = lua_toboolean(L, -1);
+ if(value)
+ result.insert(key);
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+}
+
+void ScriptApiServer::createAuth(const std::string &playername,
+ const std::string &password)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ getAuthHandler();
+ lua_getfield(L, -1, "create_auth");
+ if(lua_type(L, -1) != LUA_TFUNCTION)
+ throw LuaError(L, "Authentication handler missing create_auth");
+ lua_pushstring(L, playername.c_str());
+ lua_pushstring(L, password.c_str());
+ if(lua_pcall(L, 2, 0, 0))
+ scriptError("error: %s", lua_tostring(L, -1));
+}
+
+bool ScriptApiServer::setPassword(const std::string &playername,
+ const std::string &password)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ getAuthHandler();
+ lua_getfield(L, -1, "set_password");
+ if(lua_type(L, -1) != LUA_TFUNCTION)
+ throw LuaError(L, "Authentication handler missing set_password");
+ lua_pushstring(L, playername.c_str());
+ lua_pushstring(L, password.c_str());
+ if(lua_pcall(L, 2, 1, 0))
+ scriptError("error: %s", lua_tostring(L, -1));
+ return lua_toboolean(L, -1);
+}
+
+bool ScriptApiServer::on_chat_message(const std::string &name,
+ const std::string &message)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get minetest.registered_on_chat_messages
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "registered_on_chat_messages");
+ // Call callbacks
+ lua_pushstring(L, name.c_str());
+ lua_pushstring(L, message.c_str());
+ script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
+ bool ate = lua_toboolean(L, -1);
+ return ate;
+}
+
+void ScriptApiServer::on_shutdown()
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get registered shutdown hooks
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "registered_on_shutdown");
+ // Call callbacks
+ script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
+}
+
diff --git a/src/script/cpp_api/scriptapi.h b/src/script/cpp_api/s_server.h
index bbd0bdda7..a63e36320 100644
--- a/src/script/cpp_api/scriptapi.h
+++ b/src/script/cpp_api/s_server.h
@@ -17,66 +17,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef SCRIPTAPI_H_
-#define SCRIPTAPI_H_
-
-#include <map>
-#include <set>
-#include <vector>
+#ifndef S_SERVER_H_
+#define S_SERVER_H_
#include "cpp_api/s_base.h"
-#include "cpp_api/s_player.h"
-#include "cpp_api/s_env.h"
-#include "cpp_api/s_node.h"
-#include "cpp_api/s_inventory.h"
-#include "cpp_api/s_entity.h"
-
-class ModApiBase;
-
-/*****************************************************************************/
-/* Scriptapi <-> Core Interface */
-/*****************************************************************************/
+#include <set>
-class ScriptApi
- : virtual public ScriptApiBase,
- public ScriptApiPlayer,
- public ScriptApiEnv,
- public ScriptApiNode,
- public ScriptApiDetached,
- public ScriptApiEntity
+class ScriptApiServer
+ : virtual public ScriptApiBase
{
public:
- ScriptApi();
- ScriptApi(Server* server);
- ~ScriptApi();
-
+ // Calls on_chat_message handlers
// Returns true if script handled message
bool on_chat_message(const std::string &name, const std::string &message);
- /* server */
+ // Calls on_shutdown handlers
void on_shutdown();
/* auth */
bool getAuth(const std::string &playername,
- std::string *dst_password, std::set<std::string> *dst_privs);
+ std::string *dst_password,
+ std::set<std::string> *dst_privs);
void createAuth(const std::string &playername,
const std::string &password);
bool setPassword(const std::string &playername,
const std::string &password);
-
- /** register a lua api module to scriptapi */
- static bool registerModApiModule(ModApiBase* prototype);
- /** load a mod **/
- bool loadMod(const std::string &scriptpath,const std::string &modname);
-
private:
void getAuthHandler();
- void readPrivileges(int index,std::set<std::string> &result);
-
- bool scriptLoad(const char *path);
+ void readPrivileges(int index, std::set<std::string> &result);
+};
- static std::vector<ModApiBase*>* m_mod_api_modules;
-};
-#endif /* SCRIPTAPI_H_ */
+#endif /* S_SERVER_H_ */
diff --git a/src/script/cpp_api/scriptapi.cpp b/src/script/cpp_api/scriptapi.cpp
deleted file mode 100644
index b6d376b1f..000000000
--- a/src/script/cpp_api/scriptapi.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-}
-
-
-#include "scriptapi.h"
-#include "common/c_converter.h"
-#include "lua_api/l_base.h"
-#include "log.h"
-#include "mods.h"
-
-int script_ErrorHandler(lua_State *L) {
- lua_getfield(L, LUA_GLOBALSINDEX, "debug");
- if (!lua_istable(L, -1)) {
- lua_pop(L, 1);
- return 1;
- }
- lua_getfield(L, -1, "traceback");
- if (!lua_isfunction(L, -1)) {
- lua_pop(L, 2);
- return 1;
- }
- lua_pushvalue(L, 1);
- lua_pushinteger(L, 2);
- lua_call(L, 2, 1);
- return 1;
-}
-
-
-bool ScriptApi::getAuth(const std::string &playername,
- std::string *dst_password, std::set<std::string> *dst_privs)
-{
- SCRIPTAPI_PRECHECKHEADER
-
- getAuthHandler();
- lua_getfield(L, -1, "get_auth");
- if(lua_type(L, -1) != LUA_TFUNCTION)
- throw LuaError(L, "Authentication handler missing get_auth");
- lua_pushstring(L, playername.c_str());
- if(lua_pcall(L, 1, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
-
- // nil = login not allowed
- if(lua_isnil(L, -1))
- return false;
- luaL_checktype(L, -1, LUA_TTABLE);
-
- std::string password;
- bool found = getstringfield(L, -1, "password", password);
- if(!found)
- throw LuaError(L, "Authentication handler didn't return password");
- if(dst_password)
- *dst_password = password;
-
- lua_getfield(L, -1, "privileges");
- if(!lua_istable(L, -1))
- throw LuaError(L,
- "Authentication handler didn't return privilege table");
- if(dst_privs)
- readPrivileges(-1, *dst_privs);
- lua_pop(L, 1);
-
- return true;
-}
-
-void ScriptApi::getAuthHandler()
-{
- lua_State *L = getStack();
-
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_auth_handler");
- if(lua_isnil(L, -1)){
- lua_pop(L, 1);
- lua_getfield(L, -1, "builtin_auth_handler");
- }
- if(lua_type(L, -1) != LUA_TTABLE)
- throw LuaError(L, "Authentication handler table not valid");
-}
-
-void ScriptApi::readPrivileges(int index,std::set<std::string> &result)
-{
- lua_State *L = getStack();
-
- result.clear();
- lua_pushnil(L);
- if(index < 0)
- index -= 1;
- while(lua_next(L, index) != 0){
- // key at index -2 and value at index -1
- std::string key = luaL_checkstring(L, -2);
- bool value = lua_toboolean(L, -1);
- if(value)
- result.insert(key);
- // removes value, keeps key for next iteration
- lua_pop(L, 1);
- }
-}
-
-void ScriptApi::createAuth(const std::string &playername,
- const std::string &password)
-{
- SCRIPTAPI_PRECHECKHEADER
-
- getAuthHandler();
- lua_getfield(L, -1, "create_auth");
- if(lua_type(L, -1) != LUA_TFUNCTION)
- throw LuaError(L, "Authentication handler missing create_auth");
- lua_pushstring(L, playername.c_str());
- lua_pushstring(L, password.c_str());
- if(lua_pcall(L, 2, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
-}
-
-bool ScriptApi::setPassword(const std::string &playername,
- const std::string &password)
-{
- SCRIPTAPI_PRECHECKHEADER
-
- getAuthHandler();
- lua_getfield(L, -1, "set_password");
- if(lua_type(L, -1) != LUA_TFUNCTION)
- throw LuaError(L, "Authentication handler missing set_password");
- lua_pushstring(L, playername.c_str());
- lua_pushstring(L, password.c_str());
- if(lua_pcall(L, 2, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
- return lua_toboolean(L, -1);
-}
-
-bool ScriptApi::on_chat_message(const std::string &name,
- const std::string &message)
-{
- SCRIPTAPI_PRECHECKHEADER
-
- // Get minetest.registered_on_chat_messages
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_on_chat_messages");
- // Call callbacks
- lua_pushstring(L, name.c_str());
- lua_pushstring(L, message.c_str());
- runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
- bool ate = lua_toboolean(L, -1);
- return ate;
-}
-
-void ScriptApi::on_shutdown()
-{
- SCRIPTAPI_PRECHECKHEADER
-
- // Get registered shutdown hooks
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_on_shutdown");
- // Call callbacks
- runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
-}
-
-bool ScriptApi::loadMod(const std::string &scriptpath,const std::string &modname)
-{
- ModNameStorer modnamestorer(getStack(), modname);
-
- if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
- errorstream<<"Error loading mod \""<<modname
- <<"\": modname does not follow naming conventions: "
- <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
- return false;
- }
-
- bool success = false;
-
- try{
- success = scriptLoad(scriptpath.c_str());
- }
- catch(LuaError &e){
- errorstream<<"Error loading mod \""<<modname
- <<"\": "<<e.what()<<std::endl;
- }
-
- return success;
-}
-
-ScriptApi::ScriptApi() {
- assert("Invalid call to default constructor of scriptapi!" == 0);
-}
-
-ScriptApi::ScriptApi(Server* server)
-{
-
- setServer(server);
- setStack(luaL_newstate());
- assert(getStack());
-
- //TODO add security
-
- luaL_openlibs(getStack());
-
- SCRIPTAPI_PRECHECKHEADER
-
- lua_pushlightuserdata(L, this);
- lua_setfield(L, LUA_REGISTRYINDEX, "scriptapi");
-
- lua_newtable(L);
- lua_setglobal(L, "minetest");
-
-
- for (std::vector<ModApiBase*>::iterator i = m_mod_api_modules->begin();
- i != m_mod_api_modules->end(); i++) {
- //initializers are called within minetest global table!
- lua_getglobal(L, "minetest");
- int top = lua_gettop(L);
- bool ModInitializedSuccessfull = (*i)->Initialize(L,top);
- assert(ModInitializedSuccessfull);
- }
-
- infostream << "SCRIPTAPI: initialized " << m_mod_api_modules->size()
- << " modules" << std::endl;
-
- // Get the main minetest table
- lua_getglobal(L, "minetest");
-
- // Add tables to minetest
- lua_newtable(L);
- lua_setfield(L, -2, "object_refs");
-
- lua_newtable(L);
- lua_setfield(L, -2, "luaentities");
-}
-
-ScriptApi::~ScriptApi() {
- lua_close(getStack());
-}
-
-bool ScriptApi::scriptLoad(const char *path)
-{
- lua_State* L = getStack();
- setStack(0);
-
- verbosestream<<"Loading and running script from "<<path<<std::endl;
-
- lua_pushcfunction(L, script_ErrorHandler);
- int errorhandler = lua_gettop(L);
-
- int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, errorhandler);
- if(ret){
- errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
- errorstream<<"Failed to load and run script from "<<std::endl;
- errorstream<<path<<":"<<std::endl;
- errorstream<<std::endl;
- errorstream<<lua_tostring(L, -1)<<std::endl;
- errorstream<<std::endl;
- errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
- lua_pop(L, 1); // Pop error message from stack
- lua_pop(L, 1); // Pop the error handler from stack
- return false;
- }
- lua_pop(L, 1); // Pop the error handler from stack
- return true;
-}
-
-bool ScriptApi::registerModApiModule(ModApiBase* ptr) {
- if (ScriptApi::m_mod_api_modules == 0)
- ScriptApi::m_mod_api_modules = new std::vector<ModApiBase*>();
-
- assert(ScriptApi::m_mod_api_modules != 0);
-
- ScriptApi::m_mod_api_modules->push_back(ptr);
-
- return true;
-}
-
-std::vector<ModApiBase*>* ScriptApi::m_mod_api_modules = 0;