1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Enable dynamic_add_media to take the file data instead of a path

This commit is contained in:
sfan5 2024-01-23 21:15:09 +01:00
parent c90ebad46b
commit d4b107e2e8
8 changed files with 167 additions and 67 deletions

View file

@ -483,6 +483,17 @@ bool check_field_or_nil(lua_State *L, int index, int type, const char *fieldname
bool getstringfield(lua_State *L, int table,
const char *fieldname, std::string &result)
{
std::string_view sv;
if (getstringfield(L, table, fieldname, sv)) {
result = sv;
return true;
}
return false;
}
bool getstringfield(lua_State *L, int table,
const char *fieldname, std::string_view &result)
{
lua_getfield(L, table, fieldname);
bool got = false;
@ -491,7 +502,7 @@ bool getstringfield(lua_State *L, int table,
size_t len = 0;
const char *ptr = lua_tolstring(L, -1, &len);
if (ptr) {
result.assign(ptr, len);
result = std::string_view(ptr, len);
got = true;
}
}

View file

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include <vector>
#include <unordered_map>
#include <string_view>
#include "irrlichttypes_bloated.h"
#include "common/c_types.h"
@ -67,11 +67,11 @@ v3s16 getv3s16field_default(lua_State *L, int table,
bool getstringfield(lua_State *L, int table,
const char *fieldname, std::string &result);
bool getstringfield(lua_State *L, int table,
const char *fieldname, std::string_view &result);
size_t getstringlistfield(lua_State *L, int table,
const char *fieldname,
std::vector<std::string> *result);
void read_groups(lua_State *L, int index,
std::unordered_map<std::string, int> &result);
bool getboolfield(lua_State *L, int table,
const char *fieldname, bool &result);
bool getfloatfield(lua_State *L, int table,

View file

@ -548,19 +548,22 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
Server *server = getServer(L);
const bool at_startup = !getEnv(L);
std::string filename, filepath, to_player;
bool ephemeral = false;
std::string tmp;
Server::DynamicMediaArgs args;
if (lua_istable(L, 1)) {
getstringfield(L, 1, "filename", filename);
getstringfield(L, 1, "filepath", filepath);
getstringfield(L, 1, "to_player", to_player);
getboolfield(L, 1, "ephemeral", ephemeral);
getstringfield(L, 1, "filename", args.filename);
if (getstringfield(L, 1, "filepath", tmp))
args.filepath = tmp;
args.data.emplace();
if (!getstringfield(L, 1, "filedata", *args.data))
args.data.reset();
getstringfield(L, 1, "to_player", args.to_player);
getboolfield(L, 1, "ephemeral", args.ephemeral);
} else {
filepath = readParam<std::string>(L, 1);
tmp = readParam<std::string>(L, 1);
args.filepath = tmp;
}
if (filepath.empty())
luaL_typerror(L, 1, "non-empty string");
if (at_startup) {
if (!lua_isnoneornil(L, 2))
throw LuaError("must be called without callback at load-time");
@ -572,13 +575,27 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
luaL_checktype(L, 2, LUA_TFUNCTION);
}
CHECK_SECURE_PATH(L, filepath.c_str(), false);
// validate
if (args.filepath) {
if (args.filepath->empty())
throw LuaError("filepath must be non-empty");
if (args.data)
throw LuaError("cannot provide both filepath and filedata");
} else if (args.data) {
if (args.filename.empty())
throw LuaError("filename required");
} else {
throw LuaError("either filepath or filedata must be provided");
}
u32 token = server->getScriptIface()->allocateDynamicMediaCallback(L, 2);
if (args.filepath)
CHECK_SECURE_PATH(L, args.filepath->c_str(), false);
bool ok = server->dynamicAddMedia(filename, filepath, token, to_player, ephemeral);
args.token = server->getScriptIface()->allocateDynamicMediaCallback(L, 2);
bool ok = server->dynamicAddMedia(args);
if (!ok)
server->getScriptIface()->freeDynamicMediaCallback(token);
server->getScriptIface()->freeDynamicMediaCallback(args.token);
lua_pushboolean(L, ok);
return 1;