From 2e24d604047b30cc89ba0feacf3f1cfc15a41b78 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 6 Nov 2024 17:31:31 +0300 Subject: [PATCH 1/6] add rules & add 'show-content-access' rule --- res/scripts/stdcmd.lua | 32 ++++++++++++++ res/scripts/stdlib.lua | 58 ++++++++++++++++++++++++ src/frontend/hud.cpp | 14 +++++- src/frontend/hud.hpp | 6 +++ src/logic/scripting/lua/libs/libhud.cpp | 59 +++++++++++++++---------- src/logic/scripting/scripting.cpp | 5 +++ src/logic/scripting/scripting_hud.cpp | 10 ++++- 7 files changed, 156 insertions(+), 28 deletions(-) diff --git a/res/scripts/stdcmd.lua b/res/scripts/stdcmd.lua index 6dec6ca4..930be637 100644 --- a/res/scripts/stdcmd.lua +++ b/res/scripts/stdcmd.lua @@ -223,3 +223,35 @@ console.add_command( fragment:place({x, y, z}, rotation) end ) + +console.add_command( + "rule.set name:str value:bool", + "Set rule value", + function(args, kwargs) + local name = args[1] + local value = args[2] + rules.set(name, value) + return "rule '"..name.."' set to "..tostring(value) + end +) + +console.add_command( + "rule.list", + "Show registered rules list", + function(args, kwargs) + local names = "" + for name, rule in pairs(rules.rules) do + if #names > 0 then + names = names .. "\n " + else + names = " " + end + local value = rule.value + if value == nil then + value = "not set" + end + names = names .. name .. ":\t" .. tostring(value) + end + return "registered rules:\n" .. names + end +) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 8a4f3513..be43f57d 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -168,6 +168,64 @@ end math.randomseed(time.uptime() * 1536227939) +rules = {nexid = 1, rules = {}} +local _rules = rules + +function _rules.get_rule(name) + local rule = _rules.rules[name] + if rule == nil then + rule = {listeners={}} + _rules.rules[name] = rule + end + return rule +end + +function _rules.get(name) + local rule = _rules.rules[name] + if rule == nil then + return nil + end + return rule.value +end + +function _rules.set(name, value) + local rule = _rules.get_rule(name) + rule.value = value + for _, handler in pairs(rule.listeners) do + handler(value) + end +end + +function _rules.listen(name, handler) + local rule = _rules.get_rule(name) + local id = _rules.nexid + _rules.nextid = _rules.nexid + 1 + rule.listeners[utf8.encode(id)] = handler + return id +end + +function _rules.create(name, value, handler) + print(name, value, handler) + _rules.set(name, value) + return _rules.listen(name, handler) +end + +function _rules.unlisten(name, id) + local rule = _rules.get_rule(name) + rule.listeners[utf8.encode(id)] = nil +end + +function _rules.clear() + _rules.rules = {} + _rules.nextid = 1 +end + +function __vc_create_hud_rules() + _rules.create("show-content-access", hud._is_content_access(), function(value) + hud._set_content_access(value) + end) +end + -- --------- Deprecated functions ------ -- local function wrap_deprecated(func, name, alternatives) return function (...) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index d71ebffd..90f76918 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -348,7 +348,7 @@ void Hud::update(bool visible) { } glm::vec2 invSize = contentAccessPanel->getSize(); - contentAccessPanel->setVisible(inventoryView != nullptr); + contentAccessPanel->setVisible(inventoryView != nullptr && showContentPanel); contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height)); contentAccess->setMinSize(glm::vec2(1, Window::height)); hotbarView->setVisible(visible && !(secondUI && !inventoryView)); @@ -553,7 +553,9 @@ void Hud::updateElementsPosition(const Viewport& viewport) { const uint height = viewport.getHeight(); if (inventoryOpen) { - float caWidth = inventoryView ? contentAccess->getSize().x : 0.0f; + float caWidth = inventoryView && showContentPanel + ? contentAccess->getSize().x + : 0.0f; contentAccessPanel->setPos(glm::vec2(width-caWidth, 0)); glm::vec2 invSize = inventoryView ? inventoryView->getSize() : glm::vec2(); @@ -628,3 +630,11 @@ std::shared_ptr Hud::getBlockInventory() { } return blockUI->getInventory(); } + +bool Hud::isContentAccess() const { + return showContentPanel; +} + +void Hud::setContentAccess(bool flag) { + showContentPanel = flag; +} diff --git a/src/frontend/hud.hpp b/src/frontend/hud.hpp index c2c38049..5ae762a1 100644 --- a/src/frontend/hud.hpp +++ b/src/frontend/hud.hpp @@ -105,6 +105,8 @@ class Hud : public util::ObjectsKeeper { glm::ivec3 blockPos {}; /// @brief Id of the block open (used to detect block destruction or replacement) blockid_t currentblockid = 0; + /// @brief Show content access panel + bool showContentPanel = true; /// @brief UI element will be dynamicly positioned near to inventory or in screen center std::shared_ptr secondUI = nullptr; @@ -172,6 +174,10 @@ public: std::shared_ptr getBlockInventory(); + bool isContentAccess() const; + + void setContentAccess(bool flag); + static bool showGeneratorMinimap; /// @brief Runtime updating debug visualization texture diff --git a/src/logic/scripting/lua/libs/libhud.cpp b/src/logic/scripting/lua/libs/libhud.cpp index 91edca3e..2fd4cb29 100644 --- a/src/logic/scripting/lua/libs/libhud.cpp +++ b/src/logic/scripting/lua/libs/libhud.cpp @@ -22,21 +22,21 @@ namespace scripting { } using namespace scripting; -static int l_hud_open_inventory(lua::State*) { +static int l_open_inventory(lua::State*) { if (!hud->isInventoryOpen()) { hud->openInventory(); } return 0; } -static int l_hud_close_inventory(lua::State*) { +static int l_close_inventory(lua::State*) { if (hud->isInventoryOpen()) { hud->closeInventory(); } return 0; } -static int l_hud_open_block(lua::State* L) { +static int l_open_block(lua::State* L) { auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); auto z = lua::tointeger(L, 3); @@ -69,7 +69,7 @@ static int l_hud_open_block(lua::State* L) { return 2; } -static int l_hud_show_overlay(lua::State* L) { +static int l_show_overlay(lua::State* L) { auto name = lua::require_string(L, 1); bool playerInventory = lua::toboolean(L, 2); @@ -93,29 +93,29 @@ static UiDocument* require_layout(const char* name) { return layout; } -static int l_hud_open_permanent(lua::State* L) { +static int l_open_permanent(lua::State* L) { auto layout = require_layout(lua::require_string(L, 1)); hud->openPermanent(layout); return 0; } -static int l_hud_close(lua::State* L) { +static int l_close(lua::State* L) { auto layout = require_layout(lua::require_string(L, 1)); hud->remove(layout->getRoot()); return 0; } -static int l_hud_pause(lua::State*) { +static int l_pause(lua::State*) { hud->setPause(true); return 0; } -static int l_hud_resume(lua::State*) { +static int l_resume(lua::State*) { hud->setPause(false); return 0; } -static int l_hud_get_block_inventory(lua::State* L) { +static int l_get_block_inventory(lua::State* L) { auto inventory = hud->getBlockInventory(); if (inventory == nullptr) { return lua::pushinteger(L, 0); @@ -124,30 +124,41 @@ static int l_hud_get_block_inventory(lua::State* L) { } } -static int l_hud_get_player(lua::State* L) { +static int l_get_player(lua::State* L) { auto player = hud->getPlayer(); return lua::pushinteger(L, player->getId()); } -static int l_hud_is_paused(lua::State* L) { +static int l_is_paused(lua::State* L) { return lua::pushboolean(L, hud->isPause()); } -static int l_hud_is_inventory_open(lua::State* L) { +static int l_is_inventory_open(lua::State* L) { return lua::pushboolean(L, hud->isInventoryOpen()); } +static int l_is_content_access(lua::State* L) { + return lua::pushboolean(L, hud->isContentAccess()); +} + +static int l_set_content_access(lua::State* L) { + hud->setContentAccess(lua::toboolean(L, 1)); + return 0; +} + const luaL_Reg hudlib[] = { - {"open_inventory", lua::wrap}, - {"close_inventory", lua::wrap}, - {"open_block", lua::wrap}, - {"open_permanent", lua::wrap}, - {"show_overlay", lua::wrap}, - {"get_block_inventory", lua::wrap}, - {"close", lua::wrap}, - {"pause", lua::wrap}, - {"resume", lua::wrap}, - {"is_paused", lua::wrap}, - {"is_inventory_open", lua::wrap}, - {"get_player", lua::wrap}, + {"open_inventory", lua::wrap}, + {"close_inventory", lua::wrap}, + {"open_block", lua::wrap}, + {"open_permanent", lua::wrap}, + {"show_overlay", lua::wrap}, + {"get_block_inventory", lua::wrap}, + {"close", lua::wrap}, + {"pause", lua::wrap}, + {"resume", lua::wrap}, + {"is_paused", lua::wrap}, + {"is_inventory_open", lua::wrap}, + {"get_player", lua::wrap}, + {"_is_content_access", lua::wrap}, + {"_set_content_access", lua::wrap}, {NULL, NULL}}; diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index a8143d24..c0d7dc97 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -204,6 +204,11 @@ void scripting::cleanup() { } lua::pop(L); + lua::getglobal(L, "rules"); + lua::getfield(L, "clear"); + lua::call_nothrow(L, 0); + lua::pop(L); + if (lua::getglobal(L, "__scripts_cleanup")) { lua::call_nothrow(L, 0); } diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index f065a692..0d970e0d 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -21,8 +21,14 @@ void scripting::on_frontend_init(Hud* hud, WorldRenderer* renderer) { scripting::hud = hud; scripting::renderer = renderer; - lua::openlib(lua::get_main_state(), "hud", hudlib); - lua::openlib(lua::get_main_state(), "particles", particleslib); + auto L = lua::get_main_state(); + + lua::openlib(L, "hud", hudlib); + lua::openlib(L, "particles", particleslib); + + if (lua::getglobal(L, "__vc_create_hud_rules")) { + lua::call_nothrow(L, 0, 0); + } for (auto& pack : engine->getContentPacks()) { lua::emit_event( From 5e9b290aea0777786b4ee4aaefc3106de100ea67 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 6 Nov 2024 18:01:00 +0300 Subject: [PATCH 2/6] add 'cheat-commands' rule --- res/layouts/console.xml.lua | 16 ++++++++++++++++ res/scripts/stdcmd.lua | 16 +++++++++++++--- res/scripts/stdlib.lua | 10 ++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/res/layouts/console.xml.lua b/res/layouts/console.xml.lua index 791e1fb2..711f0435 100644 --- a/res/layouts/console.xml.lua +++ b/res/layouts/console.xml.lua @@ -52,6 +52,22 @@ function submit(text) add_to_history(text) setup_variables() + text = text:trim() + local name + for s in text:gmatch("%S+") do + name = s + break + end + if name == nil then + name = text + end + if not rules.get("cheat-commands") and table.has(console.cheats, name) then + console.log("cheat commands are disabled") + document.prompt.text = "" + document.prompt.focused = true + return + end + document.log.caret = -1 local status, result = pcall(console.execute, text) if result then diff --git a/res/scripts/stdcmd.lua b/res/scripts/stdcmd.lua index 930be637..1df86dd6 100644 --- a/res/scripts/stdcmd.lua +++ b/res/scripts/stdcmd.lua @@ -28,17 +28,17 @@ console.add_command( function(args, kwargs) local name = args[1] if #name == 0 then - local commands = console.get_commands_list() table.sort(commands) local str = "Available commands:" for i,k in ipairs(commands) do - str = str .. "\n " .. build_scheme(console.get_command_info(k)) + if rules.get("cheat-commands") or not table.has(console.cheats, k) then + str = str .. "\n " .. build_scheme(console.get_command_info(k)) + end end return str .. "\nuse 'help '" - end local command = console.get_command_info(name) @@ -255,3 +255,13 @@ console.add_command( return "registered rules:\n" .. names end ) + +console.cheats = { + "blocks.fill", + "tp", + "fragment.place", + "time.set", + "time.daycycle", + "entity.despawn", + "player.respawn" +} diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index be43f57d..22038fea 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -103,6 +103,9 @@ function time.post_runnable(runnable) table.insert(__post_runnables, runnable) end +--- Console library extension --- +console.cheats = {} + local log_element = Document.new("core:console").log function console.log(...) local args = {...} @@ -205,9 +208,10 @@ function _rules.listen(name, handler) end function _rules.create(name, value, handler) - print(name, value, handler) _rules.set(name, value) - return _rules.listen(name, handler) + if handler ~= nil then + return _rules.listen(name, handler) + end end function _rules.unlisten(name, id) @@ -218,6 +222,8 @@ end function _rules.clear() _rules.rules = {} _rules.nextid = 1 + + _rules.create("cheat-commands", true) end function __vc_create_hud_rules() From 22fa082fc6299ffa3196d62c67e01b849c35b8eb Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 6 Nov 2024 18:43:22 +0300 Subject: [PATCH 3/6] fix fatal error on editing texbox not having any consumer --- src/graphics/ui/elements/TextBox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 128d3ea6..7477d2f3 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -504,7 +504,7 @@ void TextBox::performEditingKeyboardEvents(keycode key) { paste(L"\n"); } else { defocus(); - if (validate()) { + if (validate() && consumer) { consumer(label->getText()); } } From 6602584c13ee911e0e4bb6f06d342a6530f137b6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 6 Nov 2024 18:54:20 +0300 Subject: [PATCH 4/6] add more cheating-related rules --- res/scripts/stdlib.lua | 15 ++++++++++++ src/frontend/debug_panel.cpp | 31 ++++++++++++++----------- src/frontend/hud.cpp | 27 ++++++++++++++++----- src/frontend/hud.hpp | 6 ++++- src/logic/scripting/lua/libs/libhud.cpp | 6 +++++ 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 22038fea..d64bbf53 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -230,6 +230,21 @@ function __vc_create_hud_rules() _rules.create("show-content-access", hud._is_content_access(), function(value) hud._set_content_access(value) end) + _rules.create("allow-flight", true, function(value) + input.set_enabled("player.flight", value) + end) + _rules.create("allow-noclip", true, function(value) + input.set_enabled("player.noclip", value) + end) + _rules.create("allow-destruct", true, function(value) + input.set_enabled("player.attack", value) + end) + _rules.create("allow-cheat-movement", true, function(value) + input.set_enabled("player.cheat", value) + end) + _rules.create("allow-debug-cheats", true, function(value) + hud._set_debug_cheats(value) + end) end -- --------- Deprecated functions ------ -- diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index cd0869b1..b3d6aca0 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -42,7 +42,8 @@ static std::shared_ptr