1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

Allow dynamic_add_media at mod load time

This commit is contained in:
sfan5 2024-01-22 20:37:26 +01:00
parent 6c8ae2b72a
commit af69d4f7a9
6 changed files with 50 additions and 21 deletions

View file

@ -545,9 +545,8 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
if (!getEnv(L))
throw LuaError("Dynamic media cannot be added before server has started up");
Server *server = getServer(L);
const bool at_startup = !getEnv(L);
std::string filepath;
std::string to_player;
@ -562,7 +561,16 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
}
if (filepath.empty())
luaL_typerror(L, 1, "non-empty string");
luaL_checktype(L, 2, LUA_TFUNCTION);
if (at_startup) {
if (!lua_isnoneornil(L, 2))
throw LuaError("must be called without callback at load-time");
// In order to keep edge cases to a minimum actually use an empty function.
int err = luaL_loadstring(L, "");
SANITY_CHECK(err == 0);
lua_replace(L, 2);
} else {
luaL_checktype(L, 2, LUA_TFUNCTION);
}
CHECK_SECURE_PATH(L, filepath.c_str(), false);

View file

@ -3582,6 +3582,13 @@ bool Server::dynamicAddMedia(std::string filepath,
}
}
if (!m_env && (!to_player.empty() || ephemeral)) {
errorstream << "Server::dynamicAddMedia(): "
"adding ephemeral or player-specific media at startup is nonsense"
<< std::endl;
return false;
}
// Load the file and add it to our media cache
std::string filedata, raw_hash;
bool ok = addMediaFile(filename, filepath, &filedata, &raw_hash);
@ -3618,19 +3625,20 @@ bool Server::dynamicAddMedia(std::string filepath,
m_media[filename].no_announce = true;
}
// Push file to existing clients
NetworkPacket pkt(TOCLIENT_MEDIA_PUSH, 0);
pkt << raw_hash << filename << (bool)ephemeral;
NetworkPacket legacy_pkt = pkt;
// Newer clients get asked to fetch the file (asynchronous)
pkt << token;
// Older clients have an awful hack that just throws the data at them
legacy_pkt.putLongString(filedata);
std::unordered_set<session_t> delivered, waiting;
{
// Push file to existing clients
if (m_env) {
NetworkPacket pkt(TOCLIENT_MEDIA_PUSH, 0);
pkt << raw_hash << filename << static_cast<bool>(ephemeral);
NetworkPacket legacy_pkt = pkt;
// Newer clients get asked to fetch the file (asynchronous)
pkt << token;
// Older clients have an awful hack that just throws the data at them
legacy_pkt.putLongString(filedata);
ClientInterface::AutoLock clientlock(m_clients);
for (auto &pair : m_clients.getClientList()) {
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {