s_base.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. #pragma once
  17. #include <iostream>
  18. #include <string>
  19. #include <thread>
  20. #include <mutex>
  21. #include <unordered_map>
  22. #include "common/helper.h"
  23. #include "util/basic_macros.h"
  24. extern "C" {
  25. #include <lua.h>
  26. #include <lualib.h>
  27. }
  28. #include "irrlichttypes.h"
  29. #include "common/c_types.h"
  30. #include "common/c_internal.h"
  31. #include "debug.h"
  32. #include "config.h"
  33. #define SCRIPTAPI_LOCK_DEBUG
  34. // MUST be an invalid mod name so that mods can't
  35. // use that name to bypass security!
  36. #define BUILTIN_MOD_NAME "*builtin*"
  37. #define PCALL_RES(RES) { \
  38. int result_ = (RES); \
  39. if (result_ != 0) { \
  40. scriptError(result_, __FUNCTION__); \
  41. } \
  42. }
  43. #define runCallbacks(nargs, mode) \
  44. runCallbacksRaw((nargs), (mode), __FUNCTION__)
  45. #define setOriginFromTable(index) \
  46. setOriginFromTableRaw(index, __FUNCTION__)
  47. enum class ScriptingType: u8 {
  48. Async, // either mainmenu (client) or ingame (server)
  49. Client,
  50. MainMenu,
  51. Server
  52. };
  53. class Server;
  54. #ifndef SERVER
  55. class Client;
  56. #endif
  57. class IGameDef;
  58. class Environment;
  59. class GUIEngine;
  60. class ServerActiveObject;
  61. struct PlayerHPChangeReason;
  62. class ScriptApiBase : protected LuaHelper {
  63. public:
  64. ScriptApiBase(ScriptingType type);
  65. // fake constructor to allow script API classes (e.g ScriptApiEnv) to virtually inherit from this one.
  66. ScriptApiBase()
  67. {
  68. FATAL_ERROR("ScriptApiBase created without ScriptingType!");
  69. }
  70. virtual ~ScriptApiBase();
  71. DISABLE_CLASS_COPY(ScriptApiBase);
  72. // These throw a ModError on failure
  73. void loadMod(const std::string &script_path, const std::string &mod_name);
  74. void loadScript(const std::string &script_path);
  75. #ifndef SERVER
  76. void loadModFromMemory(const std::string &mod_name);
  77. #endif
  78. void runCallbacksRaw(int nargs,
  79. RunCallbacksMode mode, const char *fxn);
  80. /* object */
  81. void addObjectReference(ServerActiveObject *cobj);
  82. void removeObjectReference(ServerActiveObject *cobj);
  83. ScriptingType getType() { return m_type; }
  84. IGameDef *getGameDef() { return m_gamedef; }
  85. Server* getServer();
  86. #ifndef SERVER
  87. Client* getClient();
  88. #endif
  89. // IMPORTANT: these cannot be used for any security-related uses, they exist
  90. // only to enrich error messages
  91. const std::string &getOrigin() { return m_last_run_mod; }
  92. void setOriginDirect(const char *origin);
  93. void setOriginFromTableRaw(int index, const char *fxn);
  94. void clientOpenLibs(lua_State *L);
  95. // Check things that should be set by the builtin mod.
  96. void checkSetByBuiltin();
  97. protected:
  98. friend class LuaABM;
  99. friend class LuaLBM;
  100. friend class InvRef;
  101. friend class ObjectRef;
  102. friend class NodeMetaRef;
  103. friend class ModApiBase;
  104. friend class ModApiEnvMod;
  105. friend class LuaVoxelManip;
  106. /*
  107. Subtle edge case with coroutines: If for whatever reason you have a
  108. method in a subclass that's called from existing lua_CFunction
  109. (any of the l_*.cpp files) then make it static and take the lua_State*
  110. as an argument. This is REQUIRED because getStack() will not return the
  111. correct state if called inside coroutines.
  112. Also note that src/script/common/ is the better place for such helpers.
  113. */
  114. lua_State* getStack()
  115. { return m_luastack; }
  116. // Checks that stack size is sane
  117. void realityCheck();
  118. // Takes an error from lua_pcall and throws it as a LuaError
  119. void scriptError(int result, const char *fxn);
  120. // Dumps stack contents for debugging
  121. void stackDump(std::ostream &o);
  122. void setGameDef(IGameDef* gamedef) { m_gamedef = gamedef; }
  123. Environment* getEnv() { return m_environment; }
  124. void setEnv(Environment* env) { m_environment = env; }
  125. #ifndef SERVER
  126. GUIEngine* getGuiEngine() { return m_guiengine; }
  127. void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
  128. #endif
  129. void objectrefGetOrCreate(lua_State *L, ServerActiveObject *cobj);
  130. void pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason& reason);
  131. std::recursive_mutex m_luastackmutex;
  132. std::string m_last_run_mod;
  133. bool m_secure = false;
  134. #ifdef SCRIPTAPI_LOCK_DEBUG
  135. int m_lock_recursion_count{};
  136. std::thread::id m_owning_thread;
  137. #endif
  138. private:
  139. static int luaPanic(lua_State *L);
  140. lua_State *m_luastack = nullptr;
  141. IGameDef *m_gamedef = nullptr;
  142. Environment *m_environment = nullptr;
  143. #ifndef SERVER
  144. GUIEngine *m_guiengine = nullptr;
  145. #endif
  146. ScriptingType m_type;
  147. };