Skip to content

Commit

Permalink
Merge pull request #346 from spelunky-fyi/Console
Browse files Browse the repository at this point in the history
Better console output
  • Loading branch information
Dregu authored Oct 15, 2023
2 parents 62b67af + 5df01ea commit 16f752a
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 15 deletions.
7 changes: 6 additions & 1 deletion docs/game_data/spel2.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions docs/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def print_lf(lf):

print("\n# Unsafe mode")
print(
"Setting `meta.unsafe = true` enables the rest of the standard Lua libraries like unrestricted `io` and `os`, loading dlls with require and `package.loadlib`. Using unsafe scripts requires users to enable the option in the overlunky.ini file which is found in the Spelunky 2 installation directory."
"Setting `meta.unsafe = true` enables the rest of the standard Lua libraries like unrestricted `io`, `os`, `ffi` and `debug`, loading dlls with require, `package.loadlib`, the [network functions](#Network-functions) and some [debug functions](#Debug-functions). Using unsafe scripts requires users to enable the option in the overlunky.ini file which is found in the Spelunky 2 installation directory."
)

print("\n# Modules")
Expand Down Expand Up @@ -393,7 +393,14 @@ def print_lf(lf):
cat = "Message functions"
elif any(
subs in func["name"]
for subs in ["get_rva", "get_virtual_rva", "raise", "dump_network"]
for subs in [
"get_rva",
"get_virtual_rva",
"raise",
"dump_network",
"dump",
"dump_string",
]
):
cat = "Debug functions"
elif any(subs in func["name"] for subs in ["_option"]):
Expand Down
11 changes: 10 additions & 1 deletion docs/src/includes/_globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,15 @@ If you set such a callback and then play the same sound yourself you have to wai
## Debug functions


### dump


> Search script examples for [dump](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=dump)
#### table dump(object object, optional<int> depth)

Dump the object (table, container, class) as a recursive table, for pretty printing in console. Don't use this for anything except debug printing. Unsafe.

### dump_network


Expand Down Expand Up @@ -1983,7 +1992,7 @@ Prinspect to ingame console.
#### nil console_print(string message)

Print a log message to ingame console.
Print a log message to ingame console with a comment identifying the script that sent it.

### log_print

Expand Down
2 changes: 1 addition & 1 deletion docs/src/includes/_home.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ end
```

# Unsafe mode
Setting `meta.unsafe = true` enables the rest of the standard Lua libraries like unrestricted `io` and `os`, loading dlls with require and `package.loadlib`. Using unsafe scripts requires users to enable the option in the overlunky.ini file which is found in the Spelunky 2 installation directory.
Setting `meta.unsafe = true` enables the rest of the standard Lua libraries like unrestricted `io`, `os`, `ffi` and `debug`, loading dlls with require, `package.loadlib`, the [network functions](#Network-functions) and some [debug functions](#Debug-functions). Using unsafe scripts requires users to enable the option in the overlunky.ini file which is found in the Spelunky 2 installation directory.

# Modules
You can load modules with `require "mymod"` or `require "mydir.mymod"`, just put `mymod.lua` in the same directory the script is, or in `mydir/` to keep things organized.
Expand Down
29 changes: 28 additions & 1 deletion src/game_api/lua_libs/lua_libs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ local function format(_, str)
return fmt and string.format(fmt, fn()) or tostring(fn())
else
error(err, 0)
end
end
end))
end
Expand Down Expand Up @@ -955,4 +955,31 @@ return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize =
block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end }
)serp";
lua["serpent"] = lua.require_script("serpent", serpent_code);

lua.script(R"##(
function dump(o, d, n)
local n = n or 0
local t = nil
if getmetatable(o) and (not d or n < d) then
t = {}
if o.pairs then
for k,v in pairs(o) do
t[k] = dump(v, d, n+1)
end
else
for k,v in pairs(getmetatable(o)) do
if k:sub(0, 2) ~= "__" and k ~= "class_cast" and k ~= "class_check" and k ~= "new" then
t[k] = dump(o[k], d, n+1)
end
end
end
else
t = o
end
return t
end
function dump_string(o, d)
return serpent.line(dump(o, d), {comment=false, indent=" "})
end
)##");
}
6 changes: 4 additions & 2 deletions src/game_api/script/lua_console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1046,8 +1046,10 @@ std::string LuaConsole::execute_raw(std::string code)
}
else
{
sol::function serpent = lua["serpent"]["block"];
return serpent(ret);
// sol::function serpent = lua["serpent"]["block"];
// return serpent(ret);
sol::function dump_string = lua["dump_string"];
return dump_string(ret, 2);
}
}
catch (const sol::error& e)
Expand Down
23 changes: 16 additions & 7 deletions src/game_api/script/lua_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,20 +363,28 @@ end

/// Standard lua print function, prints directly to the terminal but not to the game
lua["lua_print"] = lua["print"];

/// Print a log message on screen.
lua["print"] = [](std::string message) -> void
{
auto backend = LuaBackend::get_calling_backend();
bool is_console = !strcmp(backend->get_id(), "dev/lua_console");
backend->messages.push_back({message, std::chrono::system_clock::now(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f)});
if (backend->messages.size() > 20)
if (backend->messages.size() > 40 && !is_console)
backend->messages.pop_front();
backend->lua["lua_print"](message);
};

/// Print a log message to ingame console.
lua["console_print"] = [](std::string message) -> void
/// Print a log message to ingame console with a comment identifying the script that sent it.
lua["console_print"] = [&lua](std::string message) -> void
{
auto backend = LuaBackend::get_calling_backend();
bool is_console = !strcmp(backend->get_id(), "dev/lua_console");
if (is_console)
{
lua["print"](std::move(message));
return;
}
auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::tm time_buf;
localtime_s(&time_buf, &in_time_t);
Expand Down Expand Up @@ -405,6 +413,7 @@ end
/// Same as `print`
lua["message"] = [&lua](std::string message) -> void
{ lua["print"](message); };

/// Prints any type of object by first funneling it through `inspect`, no need for a manual `tostring` or `inspect`.
lua["prinspect"] = [&lua](sol::variadic_args objects) -> void
{
Expand All @@ -422,10 +431,14 @@ end
lua["print"](std::move(message));
}
};

/// Same as `prinspect`
lua["messpect"] = [&lua](sol::variadic_args objects) -> void
{ lua["prinspect"](objects); };

/// Dump the object (table, container, class) as a recursive table, for pretty printing in console. Don't use this for anything except debug printing. Unsafe.
// lua["dump"] = [](object object, optional<int> depth) -> table

/// Adds a command that can be used in the console.
lua["register_console_command"] = [](std::string name, sol::function cmd)
{
Expand Down Expand Up @@ -2772,7 +2785,6 @@ void add_partial_safe_libraries(sol::environment& env)
std::string fullpath = datadir + "/" + filename;
std::string dirpath = std::filesystem::path(fullpath).parent_path().string();
auto is_based = check_safe_io_path(fullpath, datadir);
DEBUG("io.open_data: safe:{} pack:{} based:{} mode:{} {}", is_safe, is_pack, is_based, mode.value_or("r"), fullpath);
if (is_safe && !is_based)
{
luaL_error(global_vm, "Attempted to open data file outside data directory");
Expand All @@ -2791,7 +2803,6 @@ void add_partial_safe_libraries(sol::environment& env)
std::string fullpath = std::string(backend->get_root()) + "/" + filename;
auto is_based = check_safe_io_path(fullpath, backend->get_root());
std::string dirpath = std::filesystem::path(fullpath).parent_path().string();
DEBUG("io.open_mod: safe:{} pack:{} based:{} mode:{} {}", is_safe, is_pack, is_based, mode.value_or("r"), fullpath);
if (is_safe)
{
if (!is_based)
Expand Down Expand Up @@ -2821,7 +2832,6 @@ void add_partial_safe_libraries(sol::environment& env)
std::string fullpath = datadir + "/" + filename;
std::string dirpath = std::filesystem::path(fullpath).parent_path().string();
auto is_based = check_safe_io_path(fullpath, datadir);
DEBUG("os.remove_data: safe:{} pack:{} based:{} {}", is_safe, is_pack, is_based, fullpath);
if (is_safe && !is_based)
{
luaL_error(global_vm, "Attempted to remove data file outside data directory");
Expand All @@ -2838,7 +2848,6 @@ void add_partial_safe_libraries(sol::environment& env)
std::string fullpath = std::string(backend->get_root()) + "/" + filename;
auto is_based = check_safe_io_path(fullpath, backend->get_root());
std::string dirpath = std::filesystem::path(fullpath).parent_path().string();
DEBUG("os.remove_mod: safe:{} pack:{} based:{} {}", is_safe, is_pack, is_based, fullpath);
if (is_safe)
{
if (!is_based)
Expand Down

0 comments on commit 16f752a

Please sign in to comment.