mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
[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:
parent
c9492b4d37
commit
2efae3ffd7
22
builtin/client/init.lua
Normal file
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)
|
62
builtin/client/register.lua
Normal file
62
builtin/client/register.lua
Normal file
@ -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
|
||||
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
|
||||
|
@ -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);
|
||||
|
||||
|
10
src/client.h
10
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);
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -4,7 +4,7 @@ add_subdirectory(lua_api)
|
||||
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/serverscripting.cpp
|
||||
${common_SCRIPT_COMMON_SRCS}
|
||||
${common_SCRIPT_CPP_API_SRCS}
|
||||
${common_SCRIPT_LUA_API_SRCS}
|
||||
@ -13,6 +13,7 @@ set(common_SCRIPT_SRCS
|
||||
# Used by client only
|
||||
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}
|
||||
|
54
src/script/clientscripting.cpp
Normal file
54
src/script/clientscripting.cpp
Normal file
@ -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);
|
||||
}
|
40
src/script/clientscripting.h
Normal file
40
src/script/clientscripting.h
Normal file
@ -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)
|
||||
|
||||
set(client_SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_client.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
|
||||
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 "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
|
||||
|
@ -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;
|
||||
};
|
||||
|
61
src/script/cpp_api/s_client.cpp
Normal file
61
src/script/cpp_api/s_client.cpp
Normal file
@ -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;
|
||||
}
|
36
src/script/cpp_api/s_client.h
Normal file
36
src/script/cpp_api/s_client.h
Normal file
@ -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);
|
||||
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
|
||||
|
@ -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)
|
||||
|
33
src/script/lua_api/l_client.cpp
Normal file
33
src/script/lua_api/l_client.cpp
Normal file
@ -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);
|
||||
}
|
36
src/script/lua_api/l_client.h
Normal file
36
src/script/lua_api/l_client.h
Normal file
@ -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 "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();
|
||||
|
@ -242,7 +242,7 @@ public:
|
||||
};
|
||||
|
||||
struct ScriptCallbackState {
|
||||
GameScripting *script;
|
||||
ServerScripting *script;
|
||||
int callback_ref;
|
||||
int args_ref;
|
||||
unsigned int refcount;
|
||||
|
@ -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[] =
|
||||
{
|
||||
|
@ -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);
|
@ -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
|
||||
|
@ -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";
|
||||
}
|
||||
|
10
src/server.h
10
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;
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user