aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Blot <loic.blot@unix-experience.fr>2017-01-21 15:02:08 +0100
committerLoïc Blot <nerzhul@users.noreply.github.com>2017-03-13 23:56:05 +0100
commit2efae3ffd720095222c800e016286a45c9fe1e5c (patch)
tree3a8b19daa071cf742fee52d70a0e0adf94d56c0c
parentc9492b4d37c11f35cfdc1558f771eef87fc5c972 (diff)
downloadminetest-2efae3ffd720095222c800e016286a45c9fe1e5c.tar.gz
minetest-2efae3ffd720095222c800e016286a45c9fe1e5c.tar.bz2
minetest-2efae3ffd720095222c800e016286a45c9fe1e5c.zip
[CSM] Client side modding
* rename GameScripting to ServerScripting * Make getBuiltinLuaPath static serverside * Add on_shutdown callback * Add on_receiving_chat_message & on_sending_chat_message callbacks * ScriptApiBase: use IGameDef instead of Server This permits to share common attribute between client & server * Enable mod security in client side modding without conditions
-rw-r--r--builtin/client/init.lua22
-rw-r--r--builtin/client/register.lua62
-rw-r--r--builtin/init.lua3
-rw-r--r--src/client.cpp45
-rw-r--r--src/client.h10
-rw-r--r--src/content_abm.cpp2
-rw-r--r--src/content_sao.cpp2
-rw-r--r--src/emerge.cpp2
-rw-r--r--src/environment.cpp2
-rw-r--r--src/game.cpp2
-rw-r--r--src/gamedef.h7
-rw-r--r--src/guiFormSpecMenu.cpp2
-rw-r--r--src/inventorymanager.cpp2
-rw-r--r--src/network/clientpackethandler.cpp6
-rw-r--r--src/network/serverpackethandler.cpp2
-rw-r--r--src/script/CMakeLists.txt7
-rw-r--r--src/script/clientscripting.cpp54
-rw-r--r--src/script/clientscripting.h40
-rw-r--r--src/script/cpp_api/CMakeLists.txt1
-rw-r--r--src/script/cpp_api/s_base.cpp21
-rw-r--r--src/script/cpp_api/s_base.h14
-rw-r--r--src/script/cpp_api/s_client.cpp61
-rw-r--r--src/script/cpp_api/s_client.h36
-rw-r--r--src/script/cpp_api/s_security.cpp12
-rw-r--r--src/script/lua_api/CMakeLists.txt1
-rw-r--r--src/script/lua_api/l_client.cpp33
-rw-r--r--src/script/lua_api/l_client.h36
-rw-r--r--src/script/lua_api/l_env.cpp6
-rw-r--r--src/script/lua_api/l_env.h2
-rw-r--r--src/script/lua_api/l_object.cpp2
-rw-r--r--src/script/serverscripting.cpp (renamed from src/script/scripting_game.cpp)8
-rw-r--r--src/script/serverscripting.h (renamed from src/script/scripting_game.h)10
-rw-r--r--src/server.cpp6
-rw-r--r--src/server.h10
-rw-r--r--src/serverenvironment.cpp4
-rw-r--r--src/serverenvironment.h8
-rw-r--r--src/unittest/test.cpp9
37 files changed, 488 insertions, 64 deletions
diff --git a/builtin/client/init.lua b/builtin/client/init.lua
new file mode 100644
index 000000000..d14301ade
--- /dev/null
+++ b/builtin/client/init.lua
@@ -0,0 +1,22 @@
+-- Minetest: builtin/client/init.lua
+local scriptpath = core.get_builtin_path()..DIR_DELIM
+local clientpath = scriptpath.."client"..DIR_DELIM
+
+dofile(clientpath .. "register.lua")
+
+-- This is an example function to ensure it's working properly, should be removed before merge
+core.register_on_shutdown(function()
+ print("shutdown client")
+end)
+
+-- This is an example function to ensure it's working properly, should be removed before merge
+core.register_on_receiving_chat_messages(function(message)
+ print("Received message " .. message)
+ return false
+end)
+
+-- This is an example function to ensure it's working properly, should be removed before merge
+core.register_on_sending_chat_messages(function(message)
+ print("Sending message " .. message)
+ return false
+end)
diff --git a/builtin/client/register.lua b/builtin/client/register.lua
new file mode 100644
index 000000000..c793195a1
--- /dev/null
+++ b/builtin/client/register.lua
@@ -0,0 +1,62 @@
+
+core.callback_origins = {}
+
+function core.run_callbacks(callbacks, mode, ...)
+ assert(type(callbacks) == "table")
+ local cb_len = #callbacks
+ if cb_len == 0 then
+ if mode == 2 or mode == 3 then
+ return true
+ elseif mode == 4 or mode == 5 then
+ return false
+ end
+ end
+ local ret
+ for i = 1, cb_len do
+ local cb_ret = callbacks[i](...)
+
+ if mode == 0 and i == 1 or mode == 1 and i == cb_len then
+ ret = cb_ret
+ elseif mode == 2 then
+ if not cb_ret or i == 1 then
+ ret = cb_ret
+ end
+ elseif mode == 3 then
+ if cb_ret then
+ return cb_ret
+ end
+ ret = cb_ret
+ elseif mode == 4 then
+ if (cb_ret and not ret) or i == 1 then
+ ret = cb_ret
+ end
+ elseif mode == 5 and cb_ret then
+ return cb_ret
+ end
+ end
+ return ret
+end
+
+--
+-- Callback registration
+--
+
+local function make_registration()
+ local t = {}
+ local registerfunc = function(func)
+ t[#t + 1] = func
+ core.callback_origins[func] = {
+ mod = core.get_current_modname() or "??",
+ name = debug.getinfo(1, "n").name or "??"
+ }
+ --local origin = core.callback_origins[func]
+ --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
+ end
+ return t, registerfunc
+end
+
+core.registered_on_shutdown, core.register_on_shutdown = make_registration()
+core.registered_on_receiving_chat_messages, core.register_on_receiving_chat_messages = make_registration()
+core.registered_on_sending_chat_messages, core.register_on_sending_chat_messages = make_registration()
+
+
diff --git a/builtin/init.lua b/builtin/init.lua
index b34ad14a0..590f7fa8c 100644
--- a/builtin/init.lua
+++ b/builtin/init.lua
@@ -27,6 +27,7 @@ minetest = core
-- Load other files
local scriptdir = core.get_builtin_path() .. DIR_DELIM
local gamepath = scriptdir .. "game" .. DIR_DELIM
+local clientpath = scriptdir .. "client" .. DIR_DELIM
local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM
@@ -45,6 +46,8 @@ elseif INIT == "mainmenu" then
end
elseif INIT == "async" then
dofile(asyncpath .. "init.lua")
+elseif INIT == "client" then
+ dofile(clientpath .. "init.lua")
else
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
end
diff --git a/src/client.cpp b/src/client.cpp
index 30058a2b0..faf454b35 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -32,28 +32,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client.h"
#include "network/clientopcodes.h"
#include "filesys.h"
-#include "porting.h"
#include "mapblock_mesh.h"
#include "mapblock.h"
#include "minimap.h"
-#include "settings.h"
+#include "mods.h"
#include "profiler.h"
#include "gettext.h"
-#include "log.h"
-#include "nodemetadata.h"
-#include "itemdef.h"
-#include "shader.h"
#include "clientmap.h"
#include "clientmedia.h"
-#include "sound.h"
-#include "IMeshCache.h"
-#include "config.h"
#include "version.h"
#include "drawscene.h"
#include "database-sqlite3.h"
#include "serialization.h"
#include "guiscalingfilter.h"
-#include "raycast.h"
+#include "script/clientscripting.h"
extern gui::IGUIEnvironment* guienv;
@@ -269,10 +261,36 @@ Client::Client(
m_cache_use_tangent_vertices = m_cache_enable_shaders && (
g_settings->getBool("enable_bumpmapping") ||
g_settings->getBool("enable_parallax_occlusion"));
+
+ m_script = new ClientScripting(this);
+}
+
+void Client::initMods()
+{
+ std::string script_path = getBuiltinLuaPath() + DIR_DELIM "init.lua";
+
+ m_script->loadMod(script_path, BUILTIN_MOD_NAME);
+}
+
+const std::string Client::getBuiltinLuaPath()
+{
+ return porting::path_share + DIR_DELIM + "builtin";
+}
+
+const std::vector<ModSpec>& Client::getMods() const
+{
+ static std::vector<ModSpec> client_modspec_temp;
+ return client_modspec_temp;
+}
+
+const ModSpec* Client::getModSpec(const std::string &modname) const
+{
+ return NULL;
}
void Client::Stop()
{
+ m_script->on_shutdown();
//request all client managed threads to stop
m_mesh_update_thread.stop();
// Save local server map
@@ -280,6 +298,8 @@ void Client::Stop()
infostream << "Local map saving ended." << std::endl;
m_localdb->endSave();
}
+
+ delete m_script;
}
bool Client::isShutdown()
@@ -1553,6 +1573,11 @@ void Client::typeChatMessage(const std::wstring &message)
if(message == L"")
return;
+ // If message was ate by script API, don't send it to server
+ if (m_script->on_sending_message(wide_to_utf8(message))) {
+ return;
+ }
+
// Send to others
sendChatMessage(message);
diff --git a/src/client.h b/src/client.h
index b33358d94..2fdade61a 100644
--- a/src/client.h
+++ b/src/client.h
@@ -305,6 +305,8 @@ private:
std::map<u16, u16> m_packets;
};
+class ClientScripting;
+
class Client : public con::PeerHandler, public InventoryManager, public IGameDef
{
public:
@@ -328,6 +330,8 @@ public:
~Client();
+ void initMods();
+
/*
request all threads managed by client to be stopped
*/
@@ -428,6 +432,10 @@ public:
ClientEnvironment& getEnv() { return m_env; }
ITextureSource *tsrc() { return getTextureSource(); }
ISoundManager *sound() { return getSoundManager(); }
+ static const std::string getBuiltinLuaPath();
+
+ virtual const std::vector<ModSpec> &getMods() const;
+ virtual const ModSpec* getModSpec(const std::string &modname) const;
// Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
void removeNode(v3s16 p);
@@ -692,6 +700,8 @@ private:
bool m_cache_enable_shaders;
bool m_cache_use_tangent_vertices;
+ ClientScripting *m_script;
+
DISABLE_CLASS_COPY(Client);
};
diff --git a/src/content_abm.cpp b/src/content_abm.cpp
index ee444ae77..2ab3a968c 100644
--- a/src/content_abm.cpp
+++ b/src/content_abm.cpp
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "mapblock.h" // For getNodeBlockPos
#include "map.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "log.h"
void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) {
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index d4a218505..93662b035 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h"
#include "remoteplayer.h"
#include "server.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "genericobject.h"
std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
diff --git a/src/emerge.cpp b/src/emerge.cpp
index 1c9719c48..8719a9eb3 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mg_schematic.h"
#include "nodedef.h"
#include "profiler.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "server.h"
#include "serverobject.h"
#include "settings.h"
diff --git a/src/environment.cpp b/src/environment.cpp
index 8c1aad9d3..737d93ecd 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h"
#include "collision.h"
#include "serverobject.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "server.h"
#include "daynightratio.h"
#include "emerge.h"
diff --git a/src/game.cpp b/src/game.cpp
index 55b2ccec9..9868142f7 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2222,6 +2222,8 @@ bool Game::connectToServer(const std::string &playername,
fps_control.last_time = device->getTimer()->getTime();
+ client->initMods();
+
while (device->run()) {
limitFps(&fps_control, &dtime);
diff --git a/src/gamedef.h b/src/gamedef.h
index cb624bd6a..16b53e24f 100644
--- a/src/gamedef.h
+++ b/src/gamedef.h
@@ -39,6 +39,7 @@ namespace irr { namespace scene {
class ISceneManager;
}}
+struct ModSpec;
/*
An interface for fetching game-global definitions like tool and
mapnode properties
@@ -68,7 +69,11 @@ public:
ICraftDefManager *cdef() { return getCraftDefManager(); }
MtEventManager *event() { return getEventManager(); }
- IRollbackManager *rollback() { return getRollbackManager();}
+ IRollbackManager *rollback() { return getRollbackManager(); }
+
+ virtual const std::vector<ModSpec> &getMods() const = 0;
+ virtual const ModSpec* getModSpec(const std::string &modname) const = 0;
+ virtual std::string getWorldPath() const { return ""; }
};
#endif
diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index ae3fad7c6..19cac6241 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h"
#include "gettime.h"
#include "gettext.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "porting.h"
#include "settings.h"
#include "client.h"
diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp
index 469e7396b..6ebc2994b 100644
--- a/src/inventorymanager.cpp
+++ b/src/inventorymanager.cpp
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventorymanager.h"
#include "log.h"
#include "serverenvironment.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "serverobject.h"
#include "settings.h"
#include "craftdef.h"
diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp
index b11f73e86..f1c44c7d8 100644
--- a/src/network/clientpackethandler.cpp
+++ b/src/network/clientpackethandler.cpp
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server.h"
#include "util/strfnd.h"
#include "network/clientopcodes.h"
+#include "script/clientscripting.h"
#include "util/serialize.h"
#include "util/srp.h"
#include "tileanimation.h"
@@ -411,7 +412,10 @@ void Client::handleCommand_ChatMessage(NetworkPacket* pkt)
message += (wchar_t)read_wchar;
}
- m_chat_queue.push(message);
+ // If chat message not consummed by client lua API
+ if (!m_script->on_receiving_message(wide_to_utf8(message))) {
+ m_chat_queue.push(message);
+ }
}
void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt)
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp
index ac428e8ed..b707c6fad 100644
--- a/src/network/serverpackethandler.cpp
+++ b/src/network/serverpackethandler.cpp
@@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h"
#include "player.h"
#include "rollback_interface.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "settings.h"
#include "tool.h"
#include "version.h"
diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt
index 5ef672ca9..c96ccc816 100644
--- a/src/script/CMakeLists.txt
+++ b/src/script/CMakeLists.txt
@@ -3,16 +3,17 @@ add_subdirectory(cpp_api)
add_subdirectory(lua_api)
# Used by server and client
-set(common_SCRIPT_SRCS
- ${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
+set(common_SCRIPT_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/serverscripting.cpp
${common_SCRIPT_COMMON_SRCS}
${common_SCRIPT_CPP_API_SRCS}
${common_SCRIPT_LUA_API_SRCS}
PARENT_SCOPE)
# Used by client only
-set(client_SCRIPT_SRCS
+set(client_SCRIPT_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/clientscripting.cpp
${client_SCRIPT_COMMON_SRCS}
${client_SCRIPT_CPP_API_SRCS}
${client_SCRIPT_LUA_API_SRCS}
diff --git a/src/script/clientscripting.cpp b/src/script/clientscripting.cpp
new file mode 100644
index 000000000..43bc6f94e
--- /dev/null
+++ b/src/script/clientscripting.cpp
@@ -0,0 +1,54 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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 "clientscripting.h"
+#include "client.h"
+#include "cpp_api/s_internal.h"
+#include "lua_api/l_client.h"
+#include "lua_api/l_util.h"
+
+ClientScripting::ClientScripting(Client *client):
+ ScriptApiBase()
+{
+ setGameDef(client);
+
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Security is mandatory client side
+ initializeSecurity();
+
+ lua_getglobal(L, "core");
+ int top = lua_gettop(L);
+
+ InitializeModApi(L, top);
+ lua_pop(L, 1);
+
+ // Push builtin initialization type
+ lua_pushstring(L, "client");
+ lua_setglobal(L, "INIT");
+
+ infostream << "SCRIPTAPI: Initialized client game modules" << std::endl;
+}
+
+void ClientScripting::InitializeModApi(lua_State *L, int top)
+{
+ ModApiUtil::Initialize(L, top);
+ ModApiClient::Initialize(L, top);
+}
diff --git a/src/script/clientscripting.h b/src/script/clientscripting.h
new file mode 100644
index 000000000..e2a91f695
--- /dev/null
+++ b/src/script/clientscripting.h
@@ -0,0 +1,40 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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 CLIENT_SCRIPTING_H_
+#define CLIENT_SCRIPTING_H_
+
+#include "cpp_api/s_base.h"
+#include "cpp_api/s_client.h"
+#include "cpp_api/s_security.h"
+
+class Client;
+class ClientScripting:
+ virtual public ScriptApiBase,
+ public ScriptApiSecurity,
+ public ScriptApiClient
+{
+public:
+ ClientScripting(Client *client);
+
+private:
+ virtual void InitializeModApi(lua_State *L, int top);
+};
+#endif
diff --git a/src/script/cpp_api/CMakeLists.txt b/src/script/cpp_api/CMakeLists.txt
index be4d0131e..4b13356a8 100644
--- a/src/script/cpp_api/CMakeLists.txt
+++ b/src/script/cpp_api/CMakeLists.txt
@@ -13,6 +13,7 @@ set(common_SCRIPT_CPP_API_SRCS
PARENT_SCOPE)
set(client_SCRIPT_CPP_API_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/s_client.cpp
${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 cbe5735a7..6a843810f 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -23,12 +23,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_object.h"
#include "common/c_converter.h"
#include "serverobject.h"
-#include "debug.h"
#include "filesys.h"
-#include "log.h"
#include "mods.h"
#include "porting.h"
#include "util/string.h"
+#include "server.h"
+#ifndef SERVER
+#include "client.h"
+#endif
extern "C" {
@@ -69,7 +71,8 @@ public:
*/
ScriptApiBase::ScriptApiBase() :
- m_luastackmutex()
+ m_luastackmutex(),
+ m_gamedef(NULL)
{
#ifdef SCRIPTAPI_LOCK_DEBUG
m_lock_recursion_count = 0;
@@ -113,7 +116,6 @@ ScriptApiBase::ScriptApiBase() :
// Default to false otherwise
m_secure = false;
- m_server = NULL;
m_environment = NULL;
m_guiengine = NULL;
}
@@ -333,3 +335,14 @@ void ScriptApiBase::objectrefGet(lua_State *L, u16 id)
lua_remove(L, -2); // object_refs
lua_remove(L, -2); // core
}
+
+Server* ScriptApiBase::getServer()
+{
+ return dynamic_cast<Server *>(m_gamedef);
+}
+#ifndef SERVER
+Client* ScriptApiBase::getClient()
+{
+ return dynamic_cast<Client *>(m_gamedef);
+}
+#endif
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index c27235255..19d71df65 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -55,6 +55,10 @@ extern "C" {
setOriginFromTableRaw(index, __FUNCTION__)
class Server;
+#ifndef SERVER
+class Client;
+#endif
+class IGameDef;
class Environment;
class GUIEngine;
class ServerActiveObject;
@@ -75,7 +79,11 @@ public:
void addObjectReference(ServerActiveObject *cobj);
void removeObjectReference(ServerActiveObject *cobj);
- Server* getServer() { return m_server; }
+ IGameDef *getGameDef() { return m_gamedef; }
+ Server* getServer();
+#ifndef SERVER
+ Client* getClient();
+#endif
std::string getOrigin() { return m_last_run_mod; }
void setOriginDirect(const char *origin);
@@ -98,7 +106,7 @@ protected:
void scriptError(int result, const char *fxn);
void stackDump(std::ostream &o);
- void setServer(Server* server) { m_server = server; }
+ void setGameDef(IGameDef* gamedef) { m_gamedef = gamedef; }
Environment* getEnv() { return m_environment; }
void setEnv(Environment* env) { m_environment = env; }
@@ -122,7 +130,7 @@ private:
lua_State* m_luastack;
- Server* m_server;
+ IGameDef* m_gamedef;
Environment* m_environment;
GUIEngine* m_guiengine;
};
diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp
new file mode 100644
index 000000000..08af8ebdc
--- /dev/null
+++ b/src/script/cpp_api/s_client.cpp
@@ -0,0 +1,61 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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 "s_client.h"
+#include "s_internal.h"
+
+void ScriptApiClient::on_shutdown()
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get registered shutdown hooks
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_shutdown");
+ // Call callbacks
+ runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
+}
+
+bool ScriptApiClient::on_sending_message(const std::string &message)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_chat_messages
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_sending_chat_messages");
+ // Call callbacks
+ lua_pushstring(L, message.c_str());
+ runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
+ bool ate = lua_toboolean(L, -1);
+ return ate;
+}
+
+bool ScriptApiClient::on_receiving_message(const std::string &message)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_chat_messages
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_receiving_chat_messages");
+ // Call callbacks
+ lua_pushstring(L, message.c_str());
+ runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
+ bool ate = lua_toboolean(L, -1);
+ return ate;
+}
diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h
new file mode 100644
index 000000000..08fdd8fc0
--- /dev/null
+++ b/src/script/cpp_api/s_client.h
@@ -0,0 +1,36 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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_CLIENT_H_
+#define S_CLIENT_H_
+
+#include "cpp_api/s_base.h"
+
+class ScriptApiClient: virtual public ScriptApiBase
+{
+public:
+ // Calls on_shutdown handlers
+ void on_shutdown();
+
+ // Chat message handlers
+ bool on_sending_message(const std::string &message);
+ bool on_receiving_message(const std::string &message);
+};
+#endif
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp
index be2b884cc..f85cd0c9c 100644
--- a/src/script/cpp_api/s_security.cpp
+++ b/src/script/cpp_api/s_security.cpp
@@ -382,9 +382,9 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1);
lua_pop(L, 1);
- const Server *server = script->getServer();
-
- if (!server) return false;
+ const IGameDef *gamedef = script->getGameDef();
+ if (!gamedef)
+ return false;
// Get mod name
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
@@ -400,7 +400,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
// Allow paths in mod path
// Don't bother if write access isn't important, since it will be handled later
if (write_required || write_allowed != NULL) {
- const ModSpec *mod = server->getModSpec(mod_name);
+ const ModSpec *mod = gamedef->getModSpec(mod_name);
if (mod) {
str = fs::AbsolutePath(mod->path);
if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
@@ -414,7 +414,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
// Allow read-only access to all mod directories
if (!write_required) {
- const std::vector<ModSpec> mods = server->getMods();
+ const std::vector<ModSpec> mods = gamedef->getMods();
for (size_t i = 0; i < mods.size(); ++i) {
str = fs::AbsolutePath(mods[i].path);
if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
@@ -423,7 +423,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
}
}
- str = fs::AbsolutePath(server->getWorldPath());
+ str = fs::AbsolutePath(gamedef->getWorldPath());
if (!str.empty()) {
// Don't allow access to other paths in the world mod/game path.
// These have to be blocked so you can't override a trusted mod
diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt
index e82560696..ea3d75ffa 100644
--- a/src/script/lua_api/CMakeLists.txt
+++ b/src/script/lua_api/CMakeLists.txt
@@ -23,5 +23,6 @@ set(common_SCRIPT_LUA_API_SRCS
PARENT_SCOPE)
set(client_SCRIPT_LUA_API_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/l_client.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
PARENT_SCOPE)
diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp
new file mode 100644
index 000000000..9c478602a
--- /dev/null
+++ b/src/script/lua_api/l_client.cpp
@@ -0,0 +1,33 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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 "l_client.h"
+#include "l_internal.h"
+
+int ModApiClient::l_get_current_modname(lua_State *L)
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+ return 1;
+}
+
+void ModApiClient::Initialize(lua_State *L, int top)
+{
+ API_FCT(get_current_modname);
+}
diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h
new file mode 100644
index 000000000..332f00132
--- /dev/null
+++ b/src/script/lua_api/l_client.h
@@ -0,0 +1,36 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+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_CLIENT_H_
+#define L_CLIENT_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiClient : public ModApiBase
+{
+private:
+ // get_current_modname()
+ static int l_get_current_modname(lua_State *L);
+
+public:
+ static void Initialize(lua_State *L, int top);
+};
+
+#endif
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 2722e35a4..442c4b99a 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_vmanip.h"
#include "common/c_converter.h"
#include "common/c_content.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "environment.h"
#include "server.h"
#include "nodedef.h"
@@ -49,7 +49,7 @@ struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider)
{
- GameScripting *scriptIface = env->getScriptIface();
+ ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck();
lua_State *L = scriptIface->getStack();
@@ -92,7 +92,7 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
{
- GameScripting *scriptIface = env->getScriptIface();
+ ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck();
lua_State *L = scriptIface->getStack();
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 21b235f84..322959411 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -242,7 +242,7 @@ public:
};
struct ScriptCallbackState {
- GameScripting *script;
+ ServerScripting *script;
int callback_ref;
int args_ref;
unsigned int refcount;
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 9352812ab..be454ad45 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h"
#include "server.h"
#include "hud.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
struct EnumString es_HudElementType[] =
{
diff --git a/src/script/scripting_game.cpp b/src/script/serverscripting.cpp
index 4da752263..215b2cfd7 100644
--- a/src/script/scripting_game.cpp
+++ b/src/script/serverscripting.cpp
@@ -17,7 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "server.h"
#include "log.h"
#include "settings.h"
@@ -47,9 +47,9 @@ extern "C" {
#include "lualib.h"
}
-GameScripting::GameScripting(Server* server)
+ServerScripting::ServerScripting(Server* server)
{
- setServer(server);
+ setGameDef(server);
// setEnv(env) is called by ScriptApiEnv::initializeEnvironment()
// once the environment has been created
@@ -80,7 +80,7 @@ GameScripting::GameScripting(Server* server)
infostream << "SCRIPTAPI: Initialized game modules" << std::endl;
}
-void GameScripting::InitializeModApi(lua_State *L, int top)
+void ServerScripting::InitializeModApi(lua_State *L, int top)
{
// Initialize mod api modules
ModApiCraft::Initialize(L, top);
diff --git a/src/script/scripting_game.h b/src/script/serverscripting.h
index 970b3e80d..fd97ea40b 100644
--- a/src/script/scripting_game.h
+++ b/src/script/serverscripting.h
@@ -17,8 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef SCRIPTING_GAME_H_
-#define SCRIPTING_GAME_H_
+#ifndef SERVER_SCRIPTING_H_
+#define SERVER_SCRIPTING_H_
#include "cpp_api/s_base.h"
#include "cpp_api/s_entity.h"
@@ -30,10 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "cpp_api/s_security.h"
/*****************************************************************************/
-/* Scripting <-> Game Interface */
+/* Scripting <-> Server Game Interface */
/*****************************************************************************/
-class GameScripting :
+class ServerScripting:
virtual public ScriptApiBase,
public ScriptApiDetached,
public ScriptApiEntity,
@@ -44,7 +44,7 @@ class GameScripting :
public ScriptApiSecurity
{
public:
- GameScripting(Server* server);
+ ServerScripting(Server* server);
// use ScriptApiBase::loadMod() to load mods
diff --git a/src/server.cpp b/src/server.cpp
index 8b9f46f85..3adbf40cc 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "profiler.h"
#include "log.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "nodedef.h"
#include "itemdef.h"
#include "craftdef.h"
@@ -269,7 +269,7 @@ Server::Server(
// Initialize scripting
infostream<<"Server: Initializing Lua"<<std::endl;
- m_script = new GameScripting(this);
+ m_script = new ServerScripting(this);
std::string script_path = getBuiltinLuaPath() + DIR_DELIM "init.lua";
@@ -3411,7 +3411,7 @@ void Server::getModNames(std::vector<std::string> &modlist)
modlist.push_back(it->name);
}
-std::string Server::getBuiltinLuaPath()
+const std::string Server::getBuiltinLuaPath()
{
return porting::path_share + DIR_DELIM + "builtin";
}
diff --git a/src/server.h b/src/server.h
index 3eee67b78..417d31bd8 100644
--- a/src/server.h
+++ b/src/server.h
@@ -53,7 +53,7 @@ class PlayerSAO;
class IRollbackManager;
struct RollbackAction;
class EmergeManager;
-class GameScripting;
+class ServerScripting;
class ServerEnvironment;
struct SimpleSoundSpec;
class ServerThread;
@@ -274,7 +274,7 @@ public:
Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
// Envlock and conlock should be locked when using scriptapi
- GameScripting *getScriptIface(){ return m_script; }
+ ServerScripting *getScriptIface(){ return m_script; }
// actions: time-reversed list
// Return value: success/failure
@@ -295,8 +295,8 @@ public:
IWritableNodeDefManager* getWritableNodeDefManager();
IWritableCraftDefManager* getWritableCraftDefManager();
- const std::vector<ModSpec> &getMods() const { return m_mods; }
- const ModSpec* getModSpec(const std::string &modname) const;
+ virtual const std::vector<ModSpec> &getMods() const { return m_mods; }
+ virtual const ModSpec* getModSpec(const std::string &modname) const;
void getModNames(std::vector<std::string> &modlist);
std::string getBuiltinLuaPath();
inline const std::string &getWorldPath() const { return m_path_world; }
@@ -540,7 +540,7 @@ private:
// Scripting
// Envlock and conlock should be locked when using Lua
- GameScripting *m_script;
+ ServerScripting *m_script;
// Item definition manager
IWritableItemDefManager *m_itemdef;
diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp
index f3f489092..ecc7c3150 100644
--- a/src/serverenvironment.cpp
+++ b/src/serverenvironment.cpp
@@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h"
#include "raycast.h"
#include "remoteplayer.h"
-#include "scripting_game.h"
+#include "serverscripting.h"
#include "server.h"
#include "voxelalgorithms.h"
#include "util/serialize.h"
@@ -352,7 +352,7 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions,
*/
ServerEnvironment::ServerEnvironment(ServerMap *map,
- GameScripting *scriptIface, Server *server,
+ ServerScripting *scriptIface, Server *server,
const std::string &path_world) :
m_map(map),
m_script(scriptIface),
diff --git a/src/serverenvironment.h b/src/serverenvironment.h
index b7056c00c..b7796b5f1 100644
--- a/src/serverenvironment.h
+++ b/src/serverenvironment.h
@@ -33,7 +33,7 @@ class ServerEnvironment;
class ActiveBlockModifier;
class ServerActiveObject;
class Server;
-class GameScripting;
+class ServerScripting;
/*
{Active, Loading} block modifier interface.
@@ -194,7 +194,7 @@ typedef UNORDERED_MAP<u16, ServerActiveObject *> ActiveObjectMap;
class ServerEnvironment : public Environment
{
public:
- ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
+ ServerEnvironment(ServerMap *map, ServerScripting *scriptIface,
Server *server, const std::string &path_world);
~ServerEnvironment();
@@ -203,7 +203,7 @@ public:
ServerMap & getServerMap();
//TODO find way to remove this fct!
- GameScripting* getScriptIface()
+ ServerScripting* getScriptIface()
{ return m_script; }
Server *getGameDef()
@@ -381,7 +381,7 @@ private:
// The map
ServerMap *m_map;
// Lua state
- GameScripting* m_script;
+ ServerScripting* m_script;
// Server definition
Server *m_server;
// World path
diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp
index 41ccf0d2d..9beb0afa6 100644
--- a/src/unittest/test.cpp
+++ b/src/unittest/test.cpp
@@ -19,10 +19,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "test.h"
-#include "log.h"
#include "nodedef.h"
#include "itemdef.h"
#include "gamedef.h"
+#include "mods.h"
content_t t_CONTENT_STONE;
content_t t_CONTENT_GRASS;
@@ -59,6 +59,13 @@ public:
void defineSomeNodes();
+ virtual const std::vector<ModSpec> &getMods() const
+ {
+ static std::vector<ModSpec> testmodspec;
+ return testmodspec;
+ }
+ virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
+
private:
IItemDefManager *m_itemdef;
INodeDefManager *m_nodedef;