Skip to content

Commit 40ad976

Browse files
committedFeb 1, 2021
Revise dynamic_add_media API to better accomodate future changes
1 parent a01a02f commit 40ad976

File tree

6 files changed

+68
-22
lines changed

6 files changed

+68
-22
lines changed
 

Diff for: ‎builtin/game/misc.lua

+23
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,26 @@ end
266266
function core.cancel_shutdown_requests()
267267
core.request_shutdown("", false, -1)
268268
end
269+
270+
271+
-- Callback handling for dynamic_add_media
272+
273+
local dynamic_add_media_raw = core.dynamic_add_media_raw
274+
core.dynamic_add_media_raw = nil
275+
function core.dynamic_add_media(filepath, callback)
276+
local ret = dynamic_add_media_raw(filepath)
277+
if ret == false then
278+
return ret
279+
end
280+
if callback == nil then
281+
core.log("deprecated", "Calling minetest.dynamic_add_media without "..
282+
"a callback is deprecated and will stop working in future versions.")
283+
else
284+
-- At the moment async loading is not actually implemented, so we
285+
-- immediately call the callback ourselves
286+
for _, name in ipairs(ret) do
287+
callback(name)
288+
end
289+
end
290+
return true
291+
end

Diff for: ‎doc/lua_api.txt

+12-10
Original file line numberDiff line numberDiff line change
@@ -5446,20 +5446,22 @@ Server
54465446
* Returns a code (0: successful, 1: no such player, 2: player is connected)
54475447
* `minetest.remove_player_auth(name)`: remove player authentication data
54485448
* Returns boolean indicating success (false if player nonexistant)
5449-
* `minetest.dynamic_add_media(filepath)`
5450-
* Adds the file at the given path to the media sent to clients by the server
5451-
on startup and also pushes this file to already connected clients.
5449+
* `minetest.dynamic_add_media(filepath, callback)`
5450+
* `filepath`: path to a media file on the filesystem
5451+
* `callback`: function with arguments `name`, where name is a player name
5452+
(previously there was no callback argument; omitting it is deprecated)
5453+
* Adds the file to the media sent to clients by the server on startup
5454+
and also pushes this file to already connected clients.
54525455
The file must be a supported image, sound or model format. It must not be
54535456
modified, deleted, moved or renamed after calling this function.
54545457
The list of dynamically added media is not persisted.
5455-
* Returns boolean indicating success (duplicate files count as error)
5456-
* The media will be ready to use (in e.g. entity textures, sound_play)
5457-
immediately after calling this function.
5458+
* Returns false on error, true if the request was accepted
5459+
* The given callback will be called for every player as soon as the
5460+
media is available on the client.
54585461
Old clients that lack support for this feature will not see the media
5459-
unless they reconnect to the server.
5460-
* Since media transferred this way does not use client caching or HTTP
5461-
transfers, dynamic media should not be used with big files or performance
5462-
will suffer.
5462+
unless they reconnect to the server. (callback won't be called)
5463+
* Since media transferred this way currently does not use client caching
5464+
or HTTP transfers, dynamic media should not be used with big files.
54635465

54645466
Bans
54655467
----

Diff for: ‎src/script/lua_api/l_server.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -452,19 +452,30 @@ int ModApiServer::l_sound_fade(lua_State *L)
452452
}
453453

454454
// dynamic_add_media(filepath)
455-
int ModApiServer::l_dynamic_add_media(lua_State *L)
455+
int ModApiServer::l_dynamic_add_media_raw(lua_State *L)
456456
{
457457
NO_MAP_LOCK_REQUIRED;
458458

459-
// Reject adding media before the server has started up
460459
if (!getEnv(L))
461460
throw LuaError("Dynamic media cannot be added before server has started up");
462461

463462
std::string filepath = readParam<std::string>(L, 1);
464463
CHECK_SECURE_PATH(L, filepath.c_str(), false);
465464

466-
bool ok = getServer(L)->dynamicAddMedia(filepath);
467-
lua_pushboolean(L, ok);
465+
std::vector<RemotePlayer*> sent_to;
466+
bool ok = getServer(L)->dynamicAddMedia(filepath, sent_to);
467+
if (ok) {
468+
// (see wrapper code in builtin)
469+
lua_createtable(L, sent_to.size(), 0);
470+
int i = 0;
471+
for (RemotePlayer *player : sent_to) {
472+
lua_pushstring(L, player->getName());
473+
lua_rawseti(L, -2, ++i);
474+
}
475+
} else {
476+
lua_pushboolean(L, false);
477+
}
478+
468479
return 1;
469480
}
470481

@@ -532,7 +543,7 @@ void ModApiServer::Initialize(lua_State *L, int top)
532543
API_FCT(sound_play);
533544
API_FCT(sound_stop);
534545
API_FCT(sound_fade);
535-
API_FCT(dynamic_add_media);
546+
API_FCT(dynamic_add_media_raw);
536547

537548
API_FCT(get_player_information);
538549
API_FCT(get_player_privs);

Diff for: ‎src/script/lua_api/l_server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class ModApiServer : public ModApiBase
7171
static int l_sound_fade(lua_State *L);
7272

7373
// dynamic_add_media(filepath)
74-
static int l_dynamic_add_media(lua_State *L);
74+
static int l_dynamic_add_media_raw(lua_State *L);
7575

7676
// get_player_privs(name, text)
7777
static int l_get_player_privs(lua_State *L);

Diff for: ‎src/server.cpp

+15-5
Original file line numberDiff line numberDiff line change
@@ -3465,7 +3465,8 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id)
34653465
SendDeleteParticleSpawner(peer_id, id);
34663466
}
34673467

3468-
bool Server::dynamicAddMedia(const std::string &filepath)
3468+
bool Server::dynamicAddMedia(const std::string &filepath,
3469+
std::vector<RemotePlayer*> &sent_to)
34693470
{
34703471
std::string filename = fs::GetFilenameFromPath(filepath.c_str());
34713472
if (m_media.find(filename) != m_media.end()) {
@@ -3485,9 +3486,17 @@ bool Server::dynamicAddMedia(const std::string &filepath)
34853486
pkt << raw_hash << filename << (bool) true;
34863487
pkt.putLongString(filedata);
34873488

3488-
auto client_ids = m_clients.getClientIDs(CS_DefinitionsSent);
3489-
for (session_t client_id : client_ids) {
3489+
m_clients.lock();
3490+
for (auto &pair : m_clients.getClientList()) {
3491+
if (pair.second->getState() < CS_DefinitionsSent)
3492+
continue;
3493+
if (pair.second->net_proto_version < 39)
3494+
continue;
3495+
3496+
if (auto player = m_env->getPlayer(pair.second->peer_id))
3497+
sent_to.emplace_back(player);
34903498
/*
3499+
FIXME: this is a very awful hack
34913500
The network layer only guarantees ordered delivery inside a channel.
34923501
Since the very next packet could be one that uses the media, we have
34933502
to push the media over ALL channels to ensure it is processed before
@@ -3496,9 +3505,10 @@ bool Server::dynamicAddMedia(const std::string &filepath)
34963505
- channel 1 (HUD)
34973506
- channel 0 (everything else: e.g. play_sound, object messages)
34983507
*/
3499-
m_clients.send(client_id, 1, &pkt, true);
3500-
m_clients.send(client_id, 0, &pkt, true);
3508+
m_clients.send(pair.second->peer_id, 1, &pkt, true);
3509+
m_clients.send(pair.second->peer_id, 0, &pkt, true);
35013510
}
3511+
m_clients.unlock();
35023512

35033513
return true;
35043514
}

Diff for: ‎src/server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
257257

258258
void deleteParticleSpawner(const std::string &playername, u32 id);
259259

260-
bool dynamicAddMedia(const std::string &filepath);
260+
bool dynamicAddMedia(const std::string &filepath, std::vector<RemotePlayer*> &sent_to);
261261

262262
ServerInventoryManager *getInventoryMgr() const { return m_inventory_mgr.get(); }
263263
void sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id);

0 commit comments

Comments
 (0)
Please sign in to comment.