mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-26 13:56:43 +01:00
Plugins: mods.content and read_content read the server's Mods on a dedicated server
A server plugin with mods.read could call reskate.mods.content, but the server's game had no content of its own, so it got nil and "not available". A mode that keeps its data in mods (a race reading start and finish from a park mod) could only read it in the players' games. The server now answers from every mod folder in its Mods, by name, as it finds its maps there; it has no load order or mods.json. A hidden folder (.reskate_plugin_data) and names a plugin could not ask for are left out, and a mod's title is its manifest.json's "name". The listing and reading moved from plugin_game_runtime.cpp into plugin_content.cpp, which the game and the server share, so both keep the same limits: the folders the manifest's "content" names, 1000 files, four folders deep, 1 MB a file, nothing outside the mod's folder. The game's side is unchanged apart from calling it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYabE7FCPgj3SaWeF92EML
This commit is contained in:
1 parent
f763792732
commit
0706730e79
8 files changed
+246
-54
No files matched your search
@@ -211,6 +211,10 @@ int run(const std::filesystem::path &fixtures) {
|
||||
local ok, why = pcall(reskate.server.parks)
|
||||
reskate.console.print(ok and "blind listed parks" or "blind parks refused: " .. tostring(why))
|
||||
end)
|
||||
reskate.console.command("blind content", "mod content without mods.read", function()
|
||||
local ok, why = pcall(reskate.mods.content, "parks")
|
||||
reskate.console.print(ok and "blind listed content" or "blind content refused: " .. tostring(why))
|
||||
end)
|
||||
)");
|
||||
|
||||
// One that says what the level is, and when it changes.
|
||||
@@ -251,6 +255,22 @@ int run(const std::filesystem::path &fixtures) {
|
||||
end)
|
||||
)");
|
||||
|
||||
// One that reads the parks folder of the mods the server has, as a game's plugin reads its
|
||||
// enabled mods'.
|
||||
write(root / "Plugins" / "reader" / "reskate-plugin.json",
|
||||
R"({"api": 1, "entry": "plugin/main.lua", "side": "server", "permissions": ["console", "mods.read"], "content": ["parks"]})");
|
||||
write(root / "Plugins" / "reader" / "plugin" / "main.lua", R"(
|
||||
reskate.console.command("reader", "mod content, for the test", function()
|
||||
for _, f in ipairs(assert(reskate.mods.content("parks"))) do
|
||||
reskate.console.print(string.format("content %s (%s) %s %d", f.mod, f.title, f.path, f.size))
|
||||
end
|
||||
local text = assert(reskate.mods.read_content("mixed park", "parks", "grom.park.json"))
|
||||
reskate.console.print("read " .. #text .. " " .. tostring(text:find('"reskate-park"', 1, true) ~= nil))
|
||||
local missing, why = reskate.mods.read_content("mixed park", "parks", "nothing.json")
|
||||
reskate.console.print("missing " .. tostring(missing) .. " " .. why)
|
||||
end)
|
||||
)");
|
||||
|
||||
std::vector<std::string> log;
|
||||
SteamTransport transport;
|
||||
Host host(config, transport, [&](const std::string &line) { log.push_back(line); });
|
||||
@@ -350,6 +370,20 @@ int run(const std::filesystem::path &fixtures) {
|
||||
plugin_command("blind parks");
|
||||
check(has(log, "blind parks refused: ") && has(log, "server.parks"), "A plugin without server.parks listed the parks");
|
||||
|
||||
// The mods the server has, read through mods.content as a game reads its enabled mods.
|
||||
const auto size_of = [&](const char *mod, const char *file) {
|
||||
return std::to_string(std::filesystem::file_size(root / "Mods" / mod / "parks" / file));
|
||||
};
|
||||
plugin_command("reader");
|
||||
check(has(log, "content mixed park (mixed park) grom.park.json " + size_of("mixed park", "grom.park.json")) &&
|
||||
has(log, "content popular skate 2 street park (popular skate 2 street park) bam.park.json " +
|
||||
size_of("popular skate 2 street park", "bam.park.json")),
|
||||
"The server's mods' parks folders were not listed");
|
||||
check(has(log, "read " + size_of("mixed park", "grom.park.json") + " true"), "A park mod's file was not read");
|
||||
check(has(log, "missing nil not found"), "A missing file was not \"not found\"");
|
||||
plugin_command("blind content");
|
||||
check(has(log, "blind content refused: ") && has(log, "mods.read"), "A plugin without mods.read listed the mods' content");
|
||||
|
||||
// The level, as players' games name it, and its change heard when the server changes it.
|
||||
const auto *first = find_level(config.map);
|
||||
const auto other = std::find_if(levels().begin(), levels().end(), [&](const auto &l) { return l.asset != first->asset; });
|
||||
|
||||
Reference in new issue
Block a user