[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
This commit is contained in:
Loic Blot 2017-01-21 15:02:08 +01:00 committed by Loïc Blot
parent c9492b4d37
commit 2efae3ffd7
37 changed files with 488 additions and 64 deletions

22
builtin/client/init.lua Normal file

@ -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)

@ -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()

@ -27,6 +27,7 @@ minetest = core
-- Load other files -- Load other files
local scriptdir = core.get_builtin_path() .. DIR_DELIM local scriptdir = core.get_builtin_path() .. DIR_DELIM
local gamepath = scriptdir .. "game" .. DIR_DELIM local gamepath = scriptdir .. "game" .. DIR_DELIM
local clientpath = scriptdir .. "client" .. DIR_DELIM
local commonpath = scriptdir .. "common" .. DIR_DELIM local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM local asyncpath = scriptdir .. "async" .. DIR_DELIM
@ -45,6 +46,8 @@ elseif INIT == "mainmenu" then
end end
elseif INIT == "async" then elseif INIT == "async" then
dofile(asyncpath .. "init.lua") dofile(asyncpath .. "init.lua")
elseif INIT == "client" then
dofile(clientpath .. "init.lua")
else else
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT))) error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
end end

@ -32,28 +32,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client.h" #include "client.h"
#include "network/clientopcodes.h" #include "network/clientopcodes.h"
#include "filesys.h" #include "filesys.h"
#include "porting.h"
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#include "mapblock.h" #include "mapblock.h"
#include "minimap.h" #include "minimap.h"
#include "settings.h" #include "mods.h"
#include "profiler.h" #include "profiler.h"
#include "gettext.h" #include "gettext.h"
#include "log.h"
#include "nodemetadata.h"
#include "itemdef.h"
#include "shader.h"
#include "clientmap.h" #include "clientmap.h"
#include "clientmedia.h" #include "clientmedia.h"
#include "sound.h"
#include "IMeshCache.h"
#include "config.h"
#include "version.h" #include "version.h"
#include "drawscene.h" #include "drawscene.h"
#include "database-sqlite3.h" #include "database-sqlite3.h"
#include "serialization.h" #include "serialization.h"
#include "guiscalingfilter.h" #include "guiscalingfilter.h"
#include "raycast.h" #include "script/clientscripting.h"
extern gui::IGUIEnvironment* guienv; extern gui::IGUIEnvironment* guienv;
@ -269,10 +261,36 @@ Client::Client(
m_cache_use_tangent_vertices = m_cache_enable_shaders && ( m_cache_use_tangent_vertices = m_cache_enable_shaders && (
g_settings->getBool("enable_bumpmapping") || g_settings->getBool("enable_bumpmapping") ||
g_settings->getBool("enable_parallax_occlusion")); 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() void Client::Stop()
{ {
m_script->on_shutdown();
//request all client managed threads to stop //request all client managed threads to stop
m_mesh_update_thread.stop(); m_mesh_update_thread.stop();
// Save local server map // Save local server map
@ -280,6 +298,8 @@ void Client::Stop()
infostream << "Local map saving ended." << std::endl; infostream << "Local map saving ended." << std::endl;
m_localdb->endSave(); m_localdb->endSave();
} }
delete m_script;
} }
bool Client::isShutdown() bool Client::isShutdown()
@ -1553,6 +1573,11 @@ void Client::typeChatMessage(const std::wstring &message)
if(message == L"") if(message == L"")
return; 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 // Send to others
sendChatMessage(message); sendChatMessage(message);

@ -305,6 +305,8 @@ private:
std::map<u16, u16> m_packets; std::map<u16, u16> m_packets;
}; };
class ClientScripting;
class Client : public con::PeerHandler, public InventoryManager, public IGameDef class Client : public con::PeerHandler, public InventoryManager, public IGameDef
{ {
public: public:
@ -328,6 +330,8 @@ public:
~Client(); ~Client();
void initMods();
/* /*
request all threads managed by client to be stopped request all threads managed by client to be stopped
*/ */
@ -428,6 +432,10 @@ public:
ClientEnvironment& getEnv() { return m_env; } ClientEnvironment& getEnv() { return m_env; }
ITextureSource *tsrc() { return getTextureSource(); } ITextureSource *tsrc() { return getTextureSource(); }
ISoundManager *sound() { return getSoundManager(); } 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) // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
void removeNode(v3s16 p); void removeNode(v3s16 p);
@ -692,6 +700,8 @@ private:
bool m_cache_enable_shaders; bool m_cache_enable_shaders;
bool m_cache_use_tangent_vertices; bool m_cache_use_tangent_vertices;
ClientScripting *m_script;
DISABLE_CLASS_COPY(Client); DISABLE_CLASS_COPY(Client);
}; };

@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "mapblock.h" // For getNodeBlockPos #include "mapblock.h" // For getNodeBlockPos
#include "map.h" #include "map.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "log.h" #include "log.h"
void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) { void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef) {

@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h" #include "nodedef.h"
#include "remoteplayer.h" #include "remoteplayer.h"
#include "server.h" #include "server.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "genericobject.h" #include "genericobject.h"
std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types; std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;

@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mg_schematic.h" #include "mg_schematic.h"
#include "nodedef.h" #include "nodedef.h"
#include "profiler.h" #include "profiler.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "server.h" #include "server.h"
#include "serverobject.h" #include "serverobject.h"
#include "settings.h" #include "settings.h"

@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h" #include "environment.h"
#include "collision.h" #include "collision.h"
#include "serverobject.h" #include "serverobject.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "server.h" #include "server.h"
#include "daynightratio.h" #include "daynightratio.h"
#include "emerge.h" #include "emerge.h"

@ -2222,6 +2222,8 @@ bool Game::connectToServer(const std::string &playername,
fps_control.last_time = device->getTimer()->getTime(); fps_control.last_time = device->getTimer()->getTime();
client->initMods();
while (device->run()) { while (device->run()) {
limitFps(&fps_control, &dtime); limitFps(&fps_control, &dtime);

@ -39,6 +39,7 @@ namespace irr { namespace scene {
class ISceneManager; class ISceneManager;
}} }}
struct ModSpec;
/* /*
An interface for fetching game-global definitions like tool and An interface for fetching game-global definitions like tool and
mapnode properties mapnode properties
@ -68,7 +69,11 @@ public:
ICraftDefManager *cdef() { return getCraftDefManager(); } ICraftDefManager *cdef() { return getCraftDefManager(); }
MtEventManager *event() { return getEventManager(); } 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 #endif

@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h" #include "filesys.h"
#include "gettime.h" #include "gettime.h"
#include "gettext.h" #include "gettext.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "porting.h" #include "porting.h"
#include "settings.h" #include "settings.h"
#include "client.h" #include "client.h"

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventorymanager.h" #include "inventorymanager.h"
#include "log.h" #include "log.h"
#include "serverenvironment.h" #include "serverenvironment.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "serverobject.h" #include "serverobject.h"
#include "settings.h" #include "settings.h"
#include "craftdef.h" #include "craftdef.h"

@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server.h" #include "server.h"
#include "util/strfnd.h" #include "util/strfnd.h"
#include "network/clientopcodes.h" #include "network/clientopcodes.h"
#include "script/clientscripting.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "util/srp.h" #include "util/srp.h"
#include "tileanimation.h" #include "tileanimation.h"
@ -411,7 +412,10 @@ void Client::handleCommand_ChatMessage(NetworkPacket* pkt)
message += (wchar_t)read_wchar; 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) void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt)

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h" #include "nodedef.h"
#include "player.h" #include "player.h"
#include "rollback_interface.h" #include "rollback_interface.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "settings.h" #include "settings.h"
#include "tool.h" #include "tool.h"
#include "version.h" #include "version.h"

@ -3,16 +3,17 @@ add_subdirectory(cpp_api)
add_subdirectory(lua_api) add_subdirectory(lua_api)
# Used by server and client # Used by server and client
set(common_SCRIPT_SRCS set(common_SCRIPT_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp ${CMAKE_CURRENT_SOURCE_DIR}/serverscripting.cpp
${common_SCRIPT_COMMON_SRCS} ${common_SCRIPT_COMMON_SRCS}
${common_SCRIPT_CPP_API_SRCS} ${common_SCRIPT_CPP_API_SRCS}
${common_SCRIPT_LUA_API_SRCS} ${common_SCRIPT_LUA_API_SRCS}
PARENT_SCOPE) PARENT_SCOPE)
# Used by client only # Used by client only
set(client_SCRIPT_SRCS set(client_SCRIPT_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/clientscripting.cpp
${client_SCRIPT_COMMON_SRCS} ${client_SCRIPT_COMMON_SRCS}
${client_SCRIPT_CPP_API_SRCS} ${client_SCRIPT_CPP_API_SRCS}
${client_SCRIPT_LUA_API_SRCS} ${client_SCRIPT_LUA_API_SRCS}

@ -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);
}

@ -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

@ -13,6 +13,7 @@ set(common_SCRIPT_CPP_API_SRCS
PARENT_SCOPE) PARENT_SCOPE)
set(client_SCRIPT_CPP_API_SRCS set(client_SCRIPT_CPP_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/s_client.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
PARENT_SCOPE) PARENT_SCOPE)

@ -23,12 +23,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_object.h" #include "lua_api/l_object.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "serverobject.h" #include "serverobject.h"
#include "debug.h"
#include "filesys.h" #include "filesys.h"
#include "log.h"
#include "mods.h" #include "mods.h"
#include "porting.h" #include "porting.h"
#include "util/string.h" #include "util/string.h"
#include "server.h"
#ifndef SERVER
#include "client.h"
#endif
extern "C" { extern "C" {
@ -69,7 +71,8 @@ public:
*/ */
ScriptApiBase::ScriptApiBase() : ScriptApiBase::ScriptApiBase() :
m_luastackmutex() m_luastackmutex(),
m_gamedef(NULL)
{ {
#ifdef SCRIPTAPI_LOCK_DEBUG #ifdef SCRIPTAPI_LOCK_DEBUG
m_lock_recursion_count = 0; m_lock_recursion_count = 0;
@ -113,7 +116,6 @@ ScriptApiBase::ScriptApiBase() :
// Default to false otherwise // Default to false otherwise
m_secure = false; m_secure = false;
m_server = NULL;
m_environment = NULL; m_environment = NULL;
m_guiengine = 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); // object_refs
lua_remove(L, -2); // core 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

@ -55,6 +55,10 @@ extern "C" {
setOriginFromTableRaw(index, __FUNCTION__) setOriginFromTableRaw(index, __FUNCTION__)
class Server; class Server;
#ifndef SERVER
class Client;
#endif
class IGameDef;
class Environment; class Environment;
class GUIEngine; class GUIEngine;
class ServerActiveObject; class ServerActiveObject;
@ -75,7 +79,11 @@ public:
void addObjectReference(ServerActiveObject *cobj); void addObjectReference(ServerActiveObject *cobj);
void removeObjectReference(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; } std::string getOrigin() { return m_last_run_mod; }
void setOriginDirect(const char *origin); void setOriginDirect(const char *origin);
@ -98,7 +106,7 @@ protected:
void scriptError(int result, const char *fxn); void scriptError(int result, const char *fxn);
void stackDump(std::ostream &o); void stackDump(std::ostream &o);
void setServer(Server* server) { m_server = server; } void setGameDef(IGameDef* gamedef) { m_gamedef = gamedef; }
Environment* getEnv() { return m_environment; } Environment* getEnv() { return m_environment; }
void setEnv(Environment* env) { m_environment = env; } void setEnv(Environment* env) { m_environment = env; }
@ -122,7 +130,7 @@ private:
lua_State* m_luastack; lua_State* m_luastack;
Server* m_server; IGameDef* m_gamedef;
Environment* m_environment; Environment* m_environment;
GUIEngine* m_guiengine; GUIEngine* m_guiengine;
}; };

@ -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;
}

@ -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

@ -382,9 +382,9 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI); lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1); ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
const Server *server = script->getServer(); const IGameDef *gamedef = script->getGameDef();
if (!gamedef)
if (!server) return false; return false;
// Get mod name // Get mod name
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_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 // Allow paths in mod path
// Don't bother if write access isn't important, since it will be handled later // Don't bother if write access isn't important, since it will be handled later
if (write_required || write_allowed != NULL) { if (write_required || write_allowed != NULL) {
const ModSpec *mod = server->getModSpec(mod_name); const ModSpec *mod = gamedef->getModSpec(mod_name);
if (mod) { if (mod) {
str = fs::AbsolutePath(mod->path); str = fs::AbsolutePath(mod->path);
if (!str.empty() && fs::PathStartsWith(abs_path, str)) { 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 // Allow read-only access to all mod directories
if (!write_required) { 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) { for (size_t i = 0; i < mods.size(); ++i) {
str = fs::AbsolutePath(mods[i].path); str = fs::AbsolutePath(mods[i].path);
if (!str.empty() && fs::PathStartsWith(abs_path, str)) { 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()) { if (!str.empty()) {
// Don't allow access to other paths in the world mod/game path. // 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 // These have to be blocked so you can't override a trusted mod

@ -23,5 +23,6 @@ set(common_SCRIPT_LUA_API_SRCS
PARENT_SCOPE) PARENT_SCOPE)
set(client_SCRIPT_LUA_API_SRCS set(client_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_client.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
PARENT_SCOPE) PARENT_SCOPE)

@ -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);
}

@ -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

@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_vmanip.h" #include "lua_api/l_vmanip.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "environment.h" #include "environment.h"
#include "server.h" #include "server.h"
#include "nodedef.h" #include "nodedef.h"
@ -49,7 +49,7 @@ struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider) u32 active_object_count, u32 active_object_count_wider)
{ {
GameScripting *scriptIface = env->getScriptIface(); ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck(); scriptIface->realityCheck();
lua_State *L = scriptIface->getStack(); 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) void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
{ {
GameScripting *scriptIface = env->getScriptIface(); ServerScripting *scriptIface = env->getScriptIface();
scriptIface->realityCheck(); scriptIface->realityCheck();
lua_State *L = scriptIface->getStack(); lua_State *L = scriptIface->getStack();

@ -242,7 +242,7 @@ public:
}; };
struct ScriptCallbackState { struct ScriptCallbackState {
GameScripting *script; ServerScripting *script;
int callback_ref; int callback_ref;
int args_ref; int args_ref;
unsigned int refcount; unsigned int refcount;

@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h" #include "content_sao.h"
#include "server.h" #include "server.h"
#include "hud.h" #include "hud.h"
#include "scripting_game.h" #include "serverscripting.h"
struct EnumString es_HudElementType[] = struct EnumString es_HudElementType[] =
{ {

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "scripting_game.h" #include "serverscripting.h"
#include "server.h" #include "server.h"
#include "log.h" #include "log.h"
#include "settings.h" #include "settings.h"
@ -47,9 +47,9 @@ extern "C" {
#include "lualib.h" #include "lualib.h"
} }
GameScripting::GameScripting(Server* server) ServerScripting::ServerScripting(Server* server)
{ {
setServer(server); setGameDef(server);
// setEnv(env) is called by ScriptApiEnv::initializeEnvironment() // setEnv(env) is called by ScriptApiEnv::initializeEnvironment()
// once the environment has been created // once the environment has been created
@ -80,7 +80,7 @@ GameScripting::GameScripting(Server* server)
infostream << "SCRIPTAPI: Initialized game modules" << std::endl; 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 // Initialize mod api modules
ModApiCraft::Initialize(L, top); ModApiCraft::Initialize(L, top);

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef SCRIPTING_GAME_H_ #ifndef SERVER_SCRIPTING_H_
#define SCRIPTING_GAME_H_ #define SERVER_SCRIPTING_H_
#include "cpp_api/s_base.h" #include "cpp_api/s_base.h"
#include "cpp_api/s_entity.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" #include "cpp_api/s_security.h"
/*****************************************************************************/ /*****************************************************************************/
/* Scripting <-> Game Interface */ /* Scripting <-> Server Game Interface */
/*****************************************************************************/ /*****************************************************************************/
class GameScripting : class ServerScripting:
virtual public ScriptApiBase, virtual public ScriptApiBase,
public ScriptApiDetached, public ScriptApiDetached,
public ScriptApiEntity, public ScriptApiEntity,
@ -44,7 +44,7 @@ class GameScripting :
public ScriptApiSecurity public ScriptApiSecurity
{ {
public: public:
GameScripting(Server* server); ServerScripting(Server* server);
// use ScriptApiBase::loadMod() to load mods // use ScriptApiBase::loadMod() to load mods

@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "nodedef.h" #include "nodedef.h"
#include "itemdef.h" #include "itemdef.h"
#include "craftdef.h" #include "craftdef.h"
@ -269,7 +269,7 @@ Server::Server(
// Initialize scripting // Initialize scripting
infostream<<"Server: Initializing Lua"<<std::endl; 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"; 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); modlist.push_back(it->name);
} }
std::string Server::getBuiltinLuaPath() const std::string Server::getBuiltinLuaPath()
{ {
return porting::path_share + DIR_DELIM + "builtin"; return porting::path_share + DIR_DELIM + "builtin";
} }

@ -53,7 +53,7 @@ class PlayerSAO;
class IRollbackManager; class IRollbackManager;
struct RollbackAction; struct RollbackAction;
class EmergeManager; class EmergeManager;
class GameScripting; class ServerScripting;
class ServerEnvironment; class ServerEnvironment;
struct SimpleSoundSpec; struct SimpleSoundSpec;
class ServerThread; class ServerThread;
@ -274,7 +274,7 @@ public:
Inventory* createDetachedInventory(const std::string &name, const std::string &player=""); Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
// Envlock and conlock should be locked when using scriptapi // Envlock and conlock should be locked when using scriptapi
GameScripting *getScriptIface(){ return m_script; } ServerScripting *getScriptIface(){ return m_script; }
// actions: time-reversed list // actions: time-reversed list
// Return value: success/failure // Return value: success/failure
@ -295,8 +295,8 @@ public:
IWritableNodeDefManager* getWritableNodeDefManager(); IWritableNodeDefManager* getWritableNodeDefManager();
IWritableCraftDefManager* getWritableCraftDefManager(); IWritableCraftDefManager* getWritableCraftDefManager();
const std::vector<ModSpec> &getMods() const { return m_mods; } virtual const std::vector<ModSpec> &getMods() const { return m_mods; }
const ModSpec* getModSpec(const std::string &modname) const; virtual const ModSpec* getModSpec(const std::string &modname) const;
void getModNames(std::vector<std::string> &modlist); void getModNames(std::vector<std::string> &modlist);
std::string getBuiltinLuaPath(); std::string getBuiltinLuaPath();
inline const std::string &getWorldPath() const { return m_path_world; } inline const std::string &getWorldPath() const { return m_path_world; }
@ -540,7 +540,7 @@ private:
// Scripting // Scripting
// Envlock and conlock should be locked when using Lua // Envlock and conlock should be locked when using Lua
GameScripting *m_script; ServerScripting *m_script;
// Item definition manager // Item definition manager
IWritableItemDefManager *m_itemdef; IWritableItemDefManager *m_itemdef;

@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h" #include "profiler.h"
#include "raycast.h" #include "raycast.h"
#include "remoteplayer.h" #include "remoteplayer.h"
#include "scripting_game.h" #include "serverscripting.h"
#include "server.h" #include "server.h"
#include "voxelalgorithms.h" #include "voxelalgorithms.h"
#include "util/serialize.h" #include "util/serialize.h"
@ -352,7 +352,7 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions,
*/ */
ServerEnvironment::ServerEnvironment(ServerMap *map, ServerEnvironment::ServerEnvironment(ServerMap *map,
GameScripting *scriptIface, Server *server, ServerScripting *scriptIface, Server *server,
const std::string &path_world) : const std::string &path_world) :
m_map(map), m_map(map),
m_script(scriptIface), m_script(scriptIface),

@ -33,7 +33,7 @@ class ServerEnvironment;
class ActiveBlockModifier; class ActiveBlockModifier;
class ServerActiveObject; class ServerActiveObject;
class Server; class Server;
class GameScripting; class ServerScripting;
/* /*
{Active, Loading} block modifier interface. {Active, Loading} block modifier interface.
@ -194,7 +194,7 @@ typedef UNORDERED_MAP<u16, ServerActiveObject *> ActiveObjectMap;
class ServerEnvironment : public Environment class ServerEnvironment : public Environment
{ {
public: public:
ServerEnvironment(ServerMap *map, GameScripting *scriptIface, ServerEnvironment(ServerMap *map, ServerScripting *scriptIface,
Server *server, const std::string &path_world); Server *server, const std::string &path_world);
~ServerEnvironment(); ~ServerEnvironment();
@ -203,7 +203,7 @@ public:
ServerMap & getServerMap(); ServerMap & getServerMap();
//TODO find way to remove this fct! //TODO find way to remove this fct!
GameScripting* getScriptIface() ServerScripting* getScriptIface()
{ return m_script; } { return m_script; }
Server *getGameDef() Server *getGameDef()
@ -381,7 +381,7 @@ private:
// The map // The map
ServerMap *m_map; ServerMap *m_map;
// Lua state // Lua state
GameScripting* m_script; ServerScripting* m_script;
// Server definition // Server definition
Server *m_server; Server *m_server;
// World path // World path

@ -19,10 +19,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "test.h" #include "test.h"
#include "log.h"
#include "nodedef.h" #include "nodedef.h"
#include "itemdef.h" #include "itemdef.h"
#include "gamedef.h" #include "gamedef.h"
#include "mods.h"
content_t t_CONTENT_STONE; content_t t_CONTENT_STONE;
content_t t_CONTENT_GRASS; content_t t_CONTENT_GRASS;
@ -59,6 +59,13 @@ public:
void defineSomeNodes(); 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: private:
IItemDefManager *m_itemdef; IItemDefManager *m_itemdef;
INodeDefManager *m_nodedef; INodeDefManager *m_nodedef;