mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-30 19:22:14 +00:00
tmp
This commit is contained in:
parent
7935a63ed4
commit
0fb8e1b398
19 changed files with 284 additions and 17 deletions
|
@ -1883,6 +1883,10 @@ mgvalleys_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500),
|
|||
# This support is experimental and API can change.
|
||||
enable_client_modding (Client modding) [client] bool false
|
||||
|
||||
# Where to enable server-sent client-side modding (SSCSM).
|
||||
# Warning: Experimental.
|
||||
enable_sscsm (Client modding) enum off off,singleplayer,localhost,lan,worldwide
|
||||
|
||||
# Replaces the default main menu with a custom one.
|
||||
main_menu_script (Main menu script) [client] string
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "mapnode.h"
|
||||
#include "item_visuals_manager.h"
|
||||
#include "script/sscsm/sscsm_controller.h"
|
||||
#include "script/sscsm/sscsm_events.h"
|
||||
|
||||
extern gui::IGUIEnvironment* guienv;
|
||||
|
||||
|
@ -139,6 +140,42 @@ Client::Client(
|
|||
m_mesh_grid = { g_settings->getU16("client_mesh_chunk") };
|
||||
|
||||
m_sscsm_controller = SSCSMController::create();
|
||||
|
||||
{
|
||||
auto event1 = std::make_unique<SSCSMEventUpdateVFSFiles>();
|
||||
//TODO: read files
|
||||
event1->files.emplace_back("/client_builtin/sscsm_client/init.lua",
|
||||
R"=+=(
|
||||
print("client builtin: loading")
|
||||
)=+=");
|
||||
|
||||
//TODO: checksum
|
||||
|
||||
m_sscsm_controller->runEvent(this, std::move(event1));
|
||||
|
||||
// load client builtin immediately
|
||||
auto event2 = std::make_unique<SSCSMEventLoadMods>();
|
||||
event2->init_paths.emplace_back("/client_builtin/sscsm_client/init.lua");
|
||||
m_sscsm_controller->runEvent(this, std::move(event2));
|
||||
}
|
||||
|
||||
{
|
||||
//TODO: network packets
|
||||
|
||||
std::string enable_sscsm = g_settings->get("enable_sscsm");
|
||||
if (enable_sscsm == "singleplayer") {
|
||||
auto event1 = std::make_unique<SSCSMEventUpdateVFSFiles>();
|
||||
event1->files.emplace_back("/mods/sscsm_test0/init.lua",
|
||||
R"=+=(
|
||||
print("sscsm_test0: loading")
|
||||
)=+=");
|
||||
m_sscsm_controller->runEvent(this, std::move(event1));
|
||||
|
||||
auto event2 = std::make_unique<SSCSMEventLoadMods>();
|
||||
event2->init_paths.emplace_back("/client_builtin/sscsm_client/init.lua");
|
||||
m_sscsm_controller->runEvent(this, std::move(event2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::migrateModStorage()
|
||||
|
|
|
@ -121,6 +121,7 @@ void set_default_settings()
|
|||
settings->setDefault("curl_verify_cert", "true");
|
||||
settings->setDefault("enable_remote_media_server", "true");
|
||||
settings->setDefault("enable_client_modding", "false");
|
||||
settings->setDefault("enable_sscsm", "off");
|
||||
settings->setDefault("max_out_chat_queue_size", "20");
|
||||
settings->setDefault("pause_on_lost_focus", "false");
|
||||
settings->setDefault("enable_split_login_register", "true");
|
||||
|
|
|
@ -21,6 +21,7 @@ set(client_SCRIPT_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_client.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_pause_menu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_sscsm.cpp
|
||||
|
||||
${client_SCRIPT_COMMON_SRCS}
|
||||
${client_SCRIPT_CPP_API_SRCS}
|
||||
|
|
|
@ -22,5 +22,6 @@ set(client_SCRIPT_CPP_API_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/s_client_common.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_pause_menu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_sscsm.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
|
|
|
@ -43,11 +43,12 @@ extern "C" {
|
|||
|
||||
enum class ScriptingType: u8 {
|
||||
Async, // either mainmenu (client) or ingame (server)
|
||||
Client,
|
||||
Client, // CPCSM
|
||||
MainMenu,
|
||||
Server,
|
||||
Emerge,
|
||||
PauseMenu,
|
||||
SSCSM,
|
||||
};
|
||||
|
||||
class Server;
|
||||
|
@ -58,6 +59,7 @@ class EmergeThread;
|
|||
class IGameDef;
|
||||
class Environment;
|
||||
class GUIEngine;
|
||||
class SSCSMEnvironment;
|
||||
class ServerActiveObject;
|
||||
struct PlayerHPChangeReason;
|
||||
|
||||
|
@ -158,6 +160,9 @@ protected:
|
|||
#if CHECK_CLIENT_BUILD()
|
||||
GUIEngine* getGuiEngine() { return m_guiengine; }
|
||||
void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
|
||||
|
||||
SSCSMEnvironment *getSSCSMEnv() { return m_sscsm_environment; }
|
||||
void setSSCSMEnv(SSCSMEnvironment *env) { m_sscsm_environment = env; }
|
||||
#endif
|
||||
|
||||
EmergeThread* getEmergeThread() { return m_emerge; }
|
||||
|
@ -184,6 +189,7 @@ private:
|
|||
Environment *m_environment = nullptr;
|
||||
#if CHECK_CLIENT_BUILD()
|
||||
GUIEngine *m_guiengine = nullptr;
|
||||
SSCSMEnvironment *m_sscsm_environment = nullptr;
|
||||
#endif
|
||||
EmergeThread *m_emerge = nullptr;
|
||||
|
||||
|
|
29
src/script/cpp_api/s_sscsm.cpp
Normal file
29
src/script/cpp_api/s_sscsm.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "s_sscsm.h"
|
||||
|
||||
#include "s_internal.h"
|
||||
#include "script/sscsm/sscsm_environment.h"
|
||||
|
||||
void ScriptApiSSCSM::load_mods(const std::vector<std::string> &init_paths)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void ScriptApiSSCSM::environment_step(float dtime)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
// Get core.registered_globalsteps
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "registered_globalsteps");
|
||||
// Call callbacks
|
||||
lua_pushnumber(L, dtime);
|
||||
try {
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
} catch (LuaError &e) {
|
||||
getSSCSMEnv()->setFatalError(e);
|
||||
}
|
||||
}
|
15
src/script/cpp_api/s_sscsm.h
Normal file
15
src/script/cpp_api/s_sscsm.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
class ScriptApiSSCSM : virtual public ScriptApiBase
|
||||
{
|
||||
public:
|
||||
void load_mods(const std::vector<std::string> &init_paths);
|
||||
|
||||
void environment_step(float dtime);
|
||||
};
|
|
@ -43,4 +43,5 @@ set(client_SCRIPT_LUA_API_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/l_particles_local.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_pause_menu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_sscsm.cpp
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -58,6 +58,11 @@ GUIEngine *ModApiBase::getGuiEngine(lua_State *L)
|
|||
{
|
||||
return getScriptApiBase(L)->getGuiEngine();
|
||||
}
|
||||
|
||||
SSCSMEnvironment *ModApiBase::getSSCSMEnv(lua_State *L)
|
||||
{
|
||||
return getScriptApiBase(L)->getSSCSMEnv();
|
||||
}
|
||||
#endif
|
||||
|
||||
EmergeThread *ModApiBase::getEmergeThread(lua_State *L)
|
||||
|
|
|
@ -23,6 +23,7 @@ class EmergeThread;
|
|||
class ScriptApiBase;
|
||||
class Server;
|
||||
class Environment;
|
||||
class SSCSMEnvironment;
|
||||
class ServerInventoryManager;
|
||||
|
||||
class ModApiBase : protected LuaHelper {
|
||||
|
@ -33,6 +34,7 @@ public:
|
|||
#if CHECK_CLIENT_BUILD()
|
||||
static Client* getClient(lua_State *L);
|
||||
static GUIEngine* getGuiEngine(lua_State *L);
|
||||
static SSCSMEnvironment *getSSCSMEnv(lua_State *L);
|
||||
#endif // !SERVER
|
||||
static EmergeThread* getEmergeThread(lua_State *L);
|
||||
|
||||
|
|
46
src/script/lua_api/l_sscsm.cpp
Normal file
46
src/script/lua_api/l_sscsm.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "l_sscsm.h"
|
||||
|
||||
#include "common/c_content.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "l_internal.h"
|
||||
#include "log.h"
|
||||
#include "script/sscsm/sscsm_environment.h"
|
||||
#include "mapnode.h"
|
||||
|
||||
// print(text)
|
||||
int ModApiSSCSM::l_print(lua_State *L)
|
||||
{
|
||||
// TODO: send request to main process
|
||||
std::string text = luaL_checkstring(L, 1);
|
||||
rawstream << text << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_node_or_nil(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
int ModApiSSCSM::l_get_node_or_nil(lua_State *L)
|
||||
{
|
||||
// pos
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
|
||||
// Do it
|
||||
bool pos_ok = true;
|
||||
MapNode n = getSSCSMEnv(L)->requestGetNode(pos); //TODO: add pos_ok to request
|
||||
if (pos_ok) {
|
||||
// Return node
|
||||
pushnode(L, n);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ModApiSSCSM::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(print);
|
||||
API_FCT(get_node_or_nil);
|
||||
}
|
20
src/script/lua_api/l_sscsm.h
Normal file
20
src/script/lua_api/l_sscsm.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
class ModApiSSCSM : public ModApiBase
|
||||
{
|
||||
private:
|
||||
// print(text)
|
||||
static int l_print(lua_State *L);
|
||||
|
||||
// get_node_or_nil(pos)
|
||||
static int l_get_node_or_nil(lua_State *L);
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
17
src/script/scripting_sscsm.cpp
Normal file
17
src/script/scripting_sscsm.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "scripting_sscsm.h"
|
||||
|
||||
SSCSMScripting::SSCSMScripting(SSCSMEnvironment *env)
|
||||
{
|
||||
setSSCSMEnv(env);
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
||||
void SSCSMScripting::initializeModApi(lua_State *L, int top)
|
||||
{
|
||||
//TODO
|
||||
}
|
25
src/script/scripting_sscsm.h
Normal file
25
src/script/scripting_sscsm.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-FileCopyrightText: 2025 Luanti authors
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "cpp_api/s_sscsm.h"
|
||||
#include "cpp_api/s_security.h"
|
||||
|
||||
class SSCSMScripting :
|
||||
virtual public ScriptApiBase,
|
||||
public ScriptApiSSCSM,
|
||||
public ScriptApiSecurity
|
||||
{
|
||||
public:
|
||||
SSCSMScripting(SSCSMEnvironment *env);
|
||||
|
||||
protected:
|
||||
bool checkPathInternal(const std::string &abs_path, bool write_required,
|
||||
bool *write_allowed) { return false; };
|
||||
|
||||
private:
|
||||
void initializeModApi(lua_State *L, int top);
|
||||
};
|
|
@ -1,5 +1,7 @@
|
|||
file(GLOB client_SCRIPT_SSCSM_HDRS "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
|
||||
|
||||
set(client_SCRIPT_SSCSM_SRCS
|
||||
${client_SCRIPT_SSCSM_HDRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sscsm_controller.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sscsm_environment.cpp
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
#include "sscsm_stupid_channel.h"
|
||||
|
||||
|
||||
SSCSMEnvironment::SSCSMEnvironment(std::shared_ptr<StupidChannel> channel) :
|
||||
Thread("SSCSMEnvironment-thread"),
|
||||
m_channel(std::move(channel)),
|
||||
m_script(std::make_unique<SSCSMScripting>(this))
|
||||
{
|
||||
}
|
||||
|
||||
void *SSCSMEnvironment::run()
|
||||
{
|
||||
while (true) {
|
||||
|
@ -28,6 +35,21 @@ SerializedSSCSMAnswer SSCSMEnvironment::exchange(SerializedSSCSMRequest req)
|
|||
return m_channel->exchangeA(std::move(req));
|
||||
}
|
||||
|
||||
void SSCSMEnvironment::updateVFSFiles(std::vector<std::pair<std::string, std::string>> &&files)
|
||||
{
|
||||
for (auto &&p : files) {
|
||||
m_vfs.emplace(std::move(p.first), std::move(p.second));
|
||||
}
|
||||
}
|
||||
|
||||
void SSCSMEnvironment::setFatalError(const std::string &reason)
|
||||
{
|
||||
//TODO
|
||||
// what to do on error?
|
||||
// probably send a request
|
||||
errorstream << "SSCSMEnvironment::setFatalError() reason: " << reason << std::endl;
|
||||
}
|
||||
|
||||
std::unique_ptr<ISSCSMEvent> SSCSMEnvironment::requestPollNextEvent()
|
||||
{
|
||||
auto request = SSCSMRequestPollNextEvent{};
|
||||
|
|
|
@ -9,22 +9,36 @@
|
|||
#include "threading/thread.h"
|
||||
#include "sscsm_controller.h"
|
||||
#include "sscsm_irequest.h"
|
||||
#include "../scripting_sscsm.h"
|
||||
|
||||
// The thread that runs SSCSM code.
|
||||
// Meant to be replaced by a sandboxed process.
|
||||
class SSCSMEnvironment : public Thread
|
||||
{
|
||||
std::shared_ptr<StupidChannel> m_channel;
|
||||
std::unique_ptr<SSCSMScripting> m_script;
|
||||
// virtual file system.
|
||||
// TODO: decide and doc how paths look like, maybe:
|
||||
// /client_builtin/subdir/foo.lua
|
||||
// /server_builtin/subdir/foo.lua
|
||||
// /mods/modname/subdir/foo.lua
|
||||
std::unordered_map<std::string, std::string> m_vfs;
|
||||
|
||||
void *run() override;
|
||||
|
||||
SerializedSSCSMAnswer exchange(SerializedSSCSMRequest req);
|
||||
|
||||
public:
|
||||
SSCSMEnvironment(std::shared_ptr<StupidChannel> channel) :
|
||||
Thread("SSCSMEnvironment-thread"),
|
||||
m_channel(std::move(channel))
|
||||
SSCSMEnvironment(std::shared_ptr<StupidChannel> channel);
|
||||
|
||||
SSCSMScripting *getScript() { return m_script.get(); }
|
||||
|
||||
void updateVFSFiles(std::vector<std::pair<std::string, std::string>> &&files);
|
||||
|
||||
void setFatalError(const std::string &reason);
|
||||
void setFatalError(const LuaError &e)
|
||||
{
|
||||
setFatalError(std::string("Lua: ") + e.what());
|
||||
}
|
||||
|
||||
std::unique_ptr<ISSCSMEvent> requestPollNextEvent();
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
#include "sscsm_ievent.h"
|
||||
#include "debug.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "sscsm_environment.h"
|
||||
#include "mapnode.h"
|
||||
|
||||
struct SSCSMEventTearDown : public ISSCSMEvent
|
||||
{
|
||||
|
@ -19,14 +17,35 @@ struct SSCSMEventTearDown : public ISSCSMEvent
|
|||
}
|
||||
};
|
||||
|
||||
struct SSCSMEventOnStep final : public ISSCSMEvent
|
||||
struct SSCSMEventUpdateVFSFiles : public ISSCSMEvent
|
||||
{
|
||||
// pairs are virtual path and file content
|
||||
std::vector<std::pair<std::string, std::string>> files;
|
||||
|
||||
void exec(SSCSMEnvironment *env) override
|
||||
{
|
||||
env->updateVFSFiles(std::move(files));
|
||||
}
|
||||
};
|
||||
|
||||
struct SSCSMEventLoadMods : public ISSCSMEvent
|
||||
{
|
||||
// paths to init.lua files, in load order
|
||||
std::vector<std::string> init_paths;
|
||||
|
||||
void exec(SSCSMEnvironment *env) override
|
||||
{
|
||||
env->getScript()->load_mods(init_paths);
|
||||
}
|
||||
};
|
||||
|
||||
struct SSCSMEventOnStep : public ISSCSMEvent
|
||||
{
|
||||
f32 dtime;
|
||||
|
||||
void exec(SSCSMEnvironment *env) override
|
||||
{
|
||||
// example
|
||||
env->requestGetNode(v3s16(0, 0, 0));
|
||||
env->getScript()->environment_step(dtime);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue