mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Allow dynamic_add_media at mod load time
This commit is contained in:
parent
6c8ae2b72a
commit
af69d4f7a9
3
.gitignore
vendored
3
.gitignore
vendored
@ -92,11 +92,8 @@ cmake_install.cmake
|
|||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CPackConfig.cmake
|
CPackConfig.cmake
|
||||||
CPackSourceConfig.cmake
|
CPackSourceConfig.cmake
|
||||||
src/test_config.h
|
|
||||||
src/cmake_config.h
|
src/cmake_config.h
|
||||||
src/cmake_config_githash.h
|
src/cmake_config_githash.h
|
||||||
src/unittest/test_world/world.mt
|
|
||||||
games/devtest/mods/testnodes/textures/testnodes_generated_*.png
|
|
||||||
/locale/
|
/locale/
|
||||||
.directory
|
.directory
|
||||||
*.cbp
|
*.cbp
|
||||||
|
@ -35,6 +35,7 @@ core.features = {
|
|||||||
wallmounted_rotate = true,
|
wallmounted_rotate = true,
|
||||||
item_specific_pointabilities = true,
|
item_specific_pointabilities = true,
|
||||||
blocking_pointability_type = true,
|
blocking_pointability_type = true,
|
||||||
|
dynamic_add_media_startup = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
@ -5304,6 +5304,8 @@ Utilities
|
|||||||
item_specific_pointabilities = true,
|
item_specific_pointabilities = true,
|
||||||
-- Nodes `pointable` property can be `"blocking"` (5.9.0)
|
-- Nodes `pointable` property can be `"blocking"` (5.9.0)
|
||||||
blocking_pointability_type = true,
|
blocking_pointability_type = true,
|
||||||
|
-- dynamic_add_media can be called at startup when leaving callback as `nil` (5.9.0)
|
||||||
|
dynamic_add_media_startup = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -6621,6 +6623,9 @@ Server
|
|||||||
name twice is not possible/guaranteed to work. An exception to this is the
|
name twice is not possible/guaranteed to work. An exception to this is the
|
||||||
use of `to_player` to send the same, already existent file to multiple
|
use of `to_player` to send the same, already existent file to multiple
|
||||||
chosen players.
|
chosen players.
|
||||||
|
* You can also call this at startup time. In that case `callback` MUST
|
||||||
|
be `nil` and you cannot use `ephemeral` or `to_player`, as these logically
|
||||||
|
do not make sense.
|
||||||
* Clients will attempt to fetch files added this way via remote media,
|
* Clients will attempt to fetch files added this way via remote media,
|
||||||
this can make transfer of bigger files painless (if set up). Nevertheless
|
this can make transfer of bigger files painless (if set up). Nevertheless
|
||||||
it is advised not to use dynamic media for big media files.
|
it is advised not to use dynamic media for big media files.
|
||||||
|
@ -149,15 +149,25 @@ fractal = nil
|
|||||||
frac_emb = nil
|
frac_emb = nil
|
||||||
checker = nil
|
checker = nil
|
||||||
|
|
||||||
local textures_path = minetest.get_modpath( minetest.get_current_modname() ) .. "/textures/"
|
do
|
||||||
minetest.safe_file_write(
|
-- we used to write the textures to our mod folder. in order to avoid
|
||||||
|
-- duplicate errors delete them if they still exist.
|
||||||
|
local path = core.get_modpath(core.get_current_modname()) .. "/textures/"
|
||||||
|
os.remove(path .. "testnodes_generated_mb.png")
|
||||||
|
os.remove(path .. "testnodes_generated_ck.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
local textures_path = core.get_worldpath() .. "/"
|
||||||
|
core.safe_file_write(
|
||||||
textures_path .. "testnodes_generated_mb.png",
|
textures_path .. "testnodes_generated_mb.png",
|
||||||
encode_and_check(512, 512, "rgb", data_mb)
|
encode_and_check(512, 512, "rgb", data_mb)
|
||||||
)
|
)
|
||||||
minetest.safe_file_write(
|
core.safe_file_write(
|
||||||
textures_path .. "testnodes_generated_ck.png",
|
textures_path .. "testnodes_generated_ck.png",
|
||||||
encode_and_check(512, 512, "gray", data_ck)
|
encode_and_check(512, 512, "gray", data_ck)
|
||||||
)
|
)
|
||||||
|
core.dynamic_add_media(textures_path .. "testnodes_generated_mb.png")
|
||||||
|
core.dynamic_add_media(textures_path .. "testnodes_generated_ck.png")
|
||||||
|
|
||||||
minetest.register_node("testnodes:generated_png_mb", {
|
minetest.register_node("testnodes:generated_png_mb", {
|
||||||
description = S("Generated Mandelbrot PNG Test Node"),
|
description = S("Generated Mandelbrot PNG Test Node"),
|
||||||
|
@ -545,9 +545,8 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
|
|||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
if (!getEnv(L))
|
|
||||||
throw LuaError("Dynamic media cannot be added before server has started up");
|
|
||||||
Server *server = getServer(L);
|
Server *server = getServer(L);
|
||||||
|
const bool at_startup = !getEnv(L);
|
||||||
|
|
||||||
std::string filepath;
|
std::string filepath;
|
||||||
std::string to_player;
|
std::string to_player;
|
||||||
@ -562,7 +561,16 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
|
|||||||
}
|
}
|
||||||
if (filepath.empty())
|
if (filepath.empty())
|
||||||
luaL_typerror(L, 1, "non-empty string");
|
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);
|
CHECK_SECURE_PATH(L, filepath.c_str(), false);
|
||||||
|
|
||||||
|
@ -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
|
// Load the file and add it to our media cache
|
||||||
std::string filedata, raw_hash;
|
std::string filedata, raw_hash;
|
||||||
bool ok = addMediaFile(filename, filepath, &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;
|
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;
|
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);
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
for (auto &pair : m_clients.getClientList()) {
|
for (auto &pair : m_clients.getClientList()) {
|
||||||
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
|
if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
|
||||||
|
Loading…
Reference in New Issue
Block a user