You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

388 lines
11 KiB

  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "cpp_api/s_base.h"
  17. #include "cpp_api/s_internal.h"
  18. #include "cpp_api/s_security.h"
  19. #include "lua_api/l_object.h"
  20. #include "common/c_converter.h"
  21. #include "serverobject.h"
  22. #include "filesys.h"
  23. #include "mods.h"
  24. #include "porting.h"
  25. #include "util/string.h"
  26. #include "server.h"
  27. #ifndef SERVER
  28. #include "client.h"
  29. #endif
  30. extern "C" {
  31. #include "lualib.h"
  32. #if USE_LUAJIT
  33. #include "luajit.h"
  34. #endif
  35. }
  36. #include <stdio.h>
  37. #include <cstdarg>
  38. #include "script/common/c_content.h"
  39. #include "content_sao.h"
  40. #include <sstream>
  41. class ModNameStorer
  42. {
  43. private:
  44. lua_State *L;
  45. public:
  46. ModNameStorer(lua_State *L_, const std::string &mod_name):
  47. L(L_)
  48. {
  49. // Store current mod name in registry
  50. lua_pushstring(L, mod_name.c_str());
  51. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  52. }
  53. ~ModNameStorer()
  54. {
  55. // Clear current mod name from registry
  56. lua_pushnil(L);
  57. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  58. }
  59. };
  60. /*
  61. ScriptApiBase
  62. */
  63. ScriptApiBase::ScriptApiBase()
  64. {
  65. #ifdef SCRIPTAPI_LOCK_DEBUG
  66. m_lock_recursion_count = 0;
  67. #endif
  68. m_luastack = luaL_newstate();
  69. FATAL_ERROR_IF(!m_luastack, "luaL_newstate() failed");
  70. lua_atpanic(m_luastack, &luaPanic);
  71. luaL_openlibs(m_luastack);
  72. // Make the ScriptApiBase* accessible to ModApiBase
  73. lua_pushlightuserdata(m_luastack, this);
  74. lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
  75. // Add and save an error handler
  76. lua_getglobal(m_luastack, "debug");
  77. lua_getfield(m_luastack, -1, "traceback");
  78. lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE);
  79. lua_pop(m_luastack, 1); // pop debug
  80. // If we are using LuaJIT add a C++ wrapper function to catch
  81. // exceptions thrown in Lua -> C++ calls
  82. #if USE_LUAJIT
  83. lua_pushlightuserdata(m_luastack, (void*) script_exception_wrapper);
  84. luaJIT_setmode(m_luastack, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
  85. lua_pop(m_luastack, 1);
  86. #endif
  87. // Add basic globals
  88. lua_newtable(m_luastack);
  89. lua_setglobal(m_luastack, "core");
  90. lua_pushstring(m_luastack, DIR_DELIM);
  91. lua_setglobal(m_luastack, "DIR_DELIM");
  92. lua_pushstring(m_luastack, porting::getPlatformName());
  93. lua_setglobal(m_luastack, "PLATFORM");
  94. }
  95. ScriptApiBase::~ScriptApiBase()
  96. {
  97. lua_close(m_luastack);
  98. }
  99. int ScriptApiBase::luaPanic(lua_State *L)
  100. {
  101. std::ostringstream oss;
  102. oss << "LUA PANIC: unprotected error in call to Lua API ("
  103. << readParam<std::string>(L, -1) << ")";
  104. FATAL_ERROR(oss.str().c_str());
  105. // NOTREACHED
  106. return 0;
  107. }
  108. void ScriptApiBase::loadMod(const std::string &script_path,
  109. const std::string &mod_name)
  110. {
  111. ModNameStorer mod_name_storer(getStack(), mod_name);
  112. loadScript(script_path);
  113. }
  114. void ScriptApiBase::loadScript(const std::string &script_path)
  115. {
  116. verbosestream << "Loading and running script from " << script_path << std::endl;
  117. lua_State *L = getStack();
  118. int error_handler = PUSH_ERROR_HANDLER(L);
  119. bool ok;
  120. if (m_secure) {
  121. ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str());
  122. } else {
  123. ok = !luaL_loadfile(L, script_path.c_str());
  124. }
  125. ok = ok && !lua_pcall(L, 0, 0, error_handler);
  126. if (!ok) {
  127. std::string error_msg = readParam<std::string>(L, -1);
  128. lua_pop(L, 2); // Pop error message and error handler
  129. throw ModError("Failed to load and run script from " +
  130. script_path + ":\n" + error_msg);
  131. }
  132. lua_pop(L, 1); // Pop error handler
  133. }
  134. #ifndef SERVER
  135. void ScriptApiBase::loadModFromMemory(const std::string &mod_name)
  136. {
  137. ModNameStorer mod_name_storer(getStack(), mod_name);
  138. const std::string *init_filename = getClient()->getModFile(mod_name + ":init.lua");
  139. const std::string display_filename = mod_name + ":init.lua";
  140. if(init_filename == NULL)
  141. throw ModError("Mod:\"" + mod_name + "\" lacks init.lua");
  142. verbosestream << "Loading and running script " << display_filename << std::endl;
  143. lua_State *L = getStack();
  144. int error_handler = PUSH_ERROR_HANDLER(L);
  145. bool ok = ScriptApiSecurity::safeLoadFile(L, init_filename->c_str(), display_filename.c_str());
  146. if (ok)
  147. ok = !lua_pcall(L, 0, 0, error_handler);
  148. if (!ok) {
  149. std::string error_msg = luaL_checkstring(L, -1);
  150. lua_pop(L, 2); // Pop error message and error handler
  151. throw ModError("Failed to load and run mod \"" +
  152. mod_name + "\":\n" + error_msg);
  153. }
  154. lua_pop(L, 1); // Pop error handler
  155. }
  156. #endif
  157. // Push the list of callbacks (a lua table).
  158. // Then push nargs arguments.
  159. // Then call this function, which
  160. // - runs the callbacks
  161. // - replaces the table and arguments with the return value,
  162. // computed depending on mode
  163. // This function must only be called with scriptlock held (i.e. inside of a
  164. // code block with SCRIPTAPI_PRECHECKHEADER declared)
  165. void ScriptApiBase::runCallbacksRaw(int nargs,
  166. RunCallbacksMode mode, const char *fxn)
  167. {
  168. #ifdef SCRIPTAPI_LOCK_DEBUG
  169. assert(m_lock_recursion_count > 0);
  170. #endif
  171. lua_State *L = getStack();
  172. FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
  173. // Insert error handler
  174. PUSH_ERROR_HANDLER(L);
  175. int error_handler = lua_gettop(L) - nargs - 1;
  176. lua_insert(L, error_handler);
  177. // Insert run_callbacks between error handler and table
  178. lua_getglobal(L, "core");
  179. lua_getfield(L, -1, "run_callbacks");
  180. lua_remove(L, -2);
  181. lua_insert(L, error_handler + 1);
  182. // Insert mode after table
  183. lua_pushnumber(L, (int)mode);
  184. lua_insert(L, error_handler + 3);
  185. // Stack now looks like this:
  186. // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
  187. int result = lua_pcall(L, nargs + 2, 1, error_handler);
  188. if (result != 0)
  189. scriptError(result, fxn);
  190. lua_remove(L, error_handler);
  191. }
  192. void ScriptApiBase::realityCheck()
  193. {
  194. int top = lua_gettop(m_luastack);
  195. if (top >= 30) {
  196. dstream << "Stack is over 30:" << std::endl;
  197. stackDump(dstream);
  198. std::string traceback = script_get_backtrace(m_luastack);
  199. throw LuaError("Stack is over 30 (reality check)\n" + traceback);
  200. }
  201. }
  202. void ScriptApiBase::scriptError(int result, const char *fxn)
  203. {
  204. script_error(getStack(), result, m_last_run_mod.c_str(), fxn);
  205. }
  206. void ScriptApiBase::stackDump(std::ostream &o)
  207. {
  208. int top = lua_gettop(m_luastack);
  209. for (int i = 1; i <= top; i++) { /* repeat for each level */
  210. int t = lua_type(m_luastack, i);
  211. switch (t) {
  212. case LUA_TSTRING: /* strings */
  213. o << "\"" << readParam<std::string>(m_luastack, i) << "\"";
  214. break;
  215. case LUA_TBOOLEAN: /* booleans */
  216. o << (readParam<bool>(m_luastack, i) ? "true" : "false");
  217. break;
  218. case LUA_TNUMBER: /* numbers */ {
  219. char buf[10];
  220. snprintf(buf, 10, "%lf", lua_tonumber(m_luastack, i));
  221. o << buf;
  222. break;
  223. }
  224. default: /* other values */
  225. o << lua_typename(m_luastack, t);
  226. break;
  227. }
  228. o << " ";
  229. }
  230. o << std::endl;
  231. }
  232. void ScriptApiBase::setOriginDirect(const char *origin)
  233. {
  234. m_last_run_mod = origin ? origin : "??";
  235. }
  236. void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
  237. {
  238. #ifdef SCRIPTAPI_DEBUG
  239. lua_State *L = getStack();
  240. m_last_run_mod = lua_istable(L, index) ?
  241. getstringfield_default(L, index, "mod_origin", "") : "";
  242. //printf(">>>> running %s for mod: %s\n", fxn, m_last_run_mod.c_str());
  243. #endif
  244. }
  245. void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
  246. {
  247. SCRIPTAPI_PRECHECKHEADER
  248. //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
  249. // Create object on stack
  250. ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
  251. int object = lua_gettop(L);
  252. // Get core.object_refs table
  253. lua_getglobal(L, "core");
  254. lua_getfield(L, -1, "object_refs");
  255. luaL_checktype(L, -1, LUA_TTABLE);
  256. int objectstable = lua_gettop(L);
  257. // object_refs[id] = object
  258. lua_pushnumber(L, cobj->getId()); // Push id
  259. lua_pushvalue(L, object); // Copy object to top of stack
  260. lua_settable(L, objectstable);
  261. }
  262. void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
  263. {
  264. SCRIPTAPI_PRECHECKHEADER
  265. //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
  266. // Get core.object_refs table
  267. lua_getglobal(L, "core");
  268. lua_getfield(L, -1, "object_refs");
  269. luaL_checktype(L, -1, LUA_TTABLE);
  270. int objectstable = lua_gettop(L);
  271. // Get object_refs[id]
  272. lua_pushnumber(L, cobj->getId()); // Push id
  273. lua_gettable(L, objectstable);
  274. // Set object reference to NULL
  275. ObjectRef::set_null(L);
  276. lua_pop(L, 1); // pop object
  277. // Set object_refs[id] = nil
  278. lua_pushnumber(L, cobj->getId()); // Push id
  279. lua_pushnil(L);
  280. lua_settable(L, objectstable);
  281. }
  282. // Creates a new anonymous reference if cobj=NULL or id=0
  283. void ScriptApiBase::objectrefGetOrCreate(lua_State *L,
  284. ServerActiveObject *cobj)
  285. {
  286. if (cobj == NULL || cobj->getId() == 0) {
  287. ObjectRef::create(L, cobj);
  288. } else {
  289. push_objectRef(L, cobj->getId());
  290. if (cobj->isGone())
  291. warningstream << "ScriptApiBase::objectrefGetOrCreate(): "
  292. << "Pushing ObjectRef to removed/deactivated object"
  293. << ", this is probably a bug." << std::endl;
  294. }
  295. }
  296. void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason)
  297. {
  298. if (reason.hasLuaReference())
  299. lua_rawgeti(L, LUA_REGISTRYINDEX, reason.lua_reference);
  300. else
  301. lua_newtable(L);
  302. lua_getfield(L, -1, "type");
  303. bool has_type = (bool)lua_isstring(L, -1);
  304. lua_pop(L, 1);
  305. if (!has_type) {
  306. lua_pushstring(L, reason.getTypeAsString().c_str());
  307. lua_setfield(L, -2, "type");
  308. }
  309. lua_pushstring(L, reason.from_mod ? "mod" : "engine");
  310. lua_setfield(L, -2, "from");
  311. if (reason.object) {
  312. objectrefGetOrCreate(L, reason.object);
  313. lua_setfield(L, -2, "object");
  314. }
  315. }
  316. Server* ScriptApiBase::getServer()
  317. {
  318. return dynamic_cast<Server *>(m_gamedef);
  319. }
  320. #ifndef SERVER
  321. Client* ScriptApiBase::getClient()
  322. {
  323. return dynamic_cast<Client *>(m_gamedef);
  324. }
  325. #endif