diff --git a/res/layouts/console.xml.lua b/res/layouts/console.xml.lua index 7f5ccd0e3..6aef32caf 100644 --- a/res/layouts/console.xml.lua +++ b/res/layouts/console.xml.lua @@ -1,12 +1,19 @@ history = session.get_entry("commands_history") history_pointer = #history +local warnings_all = {} + local warning_id = 0 events.on("core:warning", function (wtype, text) + local full = wtype..": "..text + if table.has(warnings_all, full) then + return + end document.problemsLog:add(gui.template("problem", { - type="warning", text=wtype..": "..text, id=tostring(warning_id) + type="warning", text=full, id=tostring(warning_id) })) warning_id = warning_id + 1 + table.insert(warnings_all, full) end) function setup_variables() diff --git a/src/logic/scripting/lua/libs/libfile.cpp b/src/logic/scripting/lua/libs/libfile.cpp index 80ce633e2..2c0c2f9e8 100644 --- a/src/logic/scripting/lua/libs/libfile.cpp +++ b/src/logic/scripting/lua/libs/libfile.cpp @@ -8,6 +8,7 @@ #include "files/files.hpp" #include "util/stringutil.hpp" #include "api_lua.hpp" +#include "../lua_engine.hpp" namespace fs = std::filesystem; using namespace scripting; @@ -47,17 +48,31 @@ static int l_read(lua::State* L) { ); } +static std::set writeable_entry_points { + "world", "export", "config" +}; + +static fs::path get_writeable_path(lua::State* L) { + std::string rawpath = lua::require_string(L, 1); + fs::path path = resolve_path(rawpath); + auto entryPoint = rawpath.substr(0, rawpath.find(':')); + if (writeable_entry_points.find(entryPoint) == writeable_entry_points.end()) { + lua::emit_event(L, "core:warning", [=](auto L) { + lua::pushstring(L, "writing to read-only entry point"); + lua::pushstring(L, entryPoint); + return 2; + }); + } + return path; +} + static int l_write(lua::State* L) { - fs::path path = resolve_path(lua::require_string(L, 1)); + fs::path path = get_writeable_path(L); std::string text = lua::require_string(L, 2); files::write_string(path, text); return 1; } -static std::set writeable_entry_points { - "world", "export", "config" -}; - static int l_remove(lua::State* L) { std::string rawpath = lua::require_string(L, 1); fs::path path = resolve_path(rawpath); @@ -155,15 +170,9 @@ static int read_bytes_from_table( } static int l_write_bytes(lua::State* L) { - int pathIndex = 1; - - if (!lua::isstring(L, pathIndex)) { - throw std::runtime_error("string expected"); - } - - fs::path path = resolve_path(lua::require_string(L, pathIndex)); + fs::path path = get_writeable_path(L); - if (auto bytearray = lua::touserdata(L, -1)) { + if (auto bytearray = lua::touserdata(L, 2)) { auto& bytes = bytearray->data(); return lua::pushboolean( L, files::write_bytes(path, bytes.data(), bytes.size())