From 26deb26f173ca2e7011ff5af294d2f677518b9eb Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Tue, 30 Jul 2024 21:25:50 +0200 Subject: [PATCH] Sounds: Partial revert of #14436 and #14341 (#14889) This reverts functional changes of: * commit bf52d1e6 (#14436) * commit 63a98538 (#14341) --- doc/lua_api.md | 16 ---------- src/network/clientpackethandler.cpp | 2 ++ src/server.cpp | 46 +++-------------------------- src/server.h | 3 -- 4 files changed, 6 insertions(+), 61 deletions(-) diff --git a/doc/lua_api.md b/doc/lua_api.md index c1322ed5f..e0413bb76 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -1103,7 +1103,6 @@ Table used to specify how a sound is played: -- its end in `-start_time` seconds. -- It is unspecified what happens if `loop` is false and `start_time` is -- smaller than minus the sound's length. - -- Available since feature `sound_params_start_time`. loop = false, @@ -1117,21 +1116,6 @@ Table used to specify how a sound is played: -- Attach the sound to an object. -- Can't be used together with `pos`. - -- For backward compatibility, sounds continue playing at the last location - -- of the object if an object is removed (for example if an entity dies). - -- It is not recommended to rely on this. - -- For death sounds, prefer playing a positional sound instead. - - -- If you want to stop a sound when an entity dies or is deactivated, - -- store the handle and call `minetest.sound_stop` in `on_die` / `on_deactivate`. - - -- Ephemeral sounds are entirely unaffected by the object being removed - -- or leaving the active object range. - - -- Non-ephemeral sounds stop playing on clients if objects leave - -- the active object range; they should start playing again if objects - --- come back into range (but due to a known bug, they don't yet). - to_player = name, -- Only play for this player. -- Can't be used together with `exclude_player`. diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 90f2bed5b..e2bcb51b5 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -471,6 +471,8 @@ void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt) for (u16 i = 0; i < removed_count; i++) { *pkt >> id; m_env.removeActiveObject(id); + // Object-attached sounds MUST NOT be removed here because they might + // have started to play immediately before the entity was removed. } // Read added objects diff --git a/src/server.cpp b/src/server.cpp index 937cbe90a..6e42b22a0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2054,19 +2054,10 @@ void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersa // Removed objects pkt << static_cast(removed_objects.size()); - std::vector sounds_to_stop; - for (auto &it : removed_objects) { const auto [gone, id] = it; ServerActiveObject *obj = m_env->getActiveObject(id); - // Stop sounds if objects go out of range. - // This fixes https://github.com/minetest/minetest/issues/8094. - // We may not remove sounds if an entity was removed on the server. - // See https://github.com/minetest/minetest/issues/14422. - if (!gone) // just out of range for client, not gone on server? - sounds_to_stop.push_back(id); - pkt << id; // Remove from known objects @@ -2075,8 +2066,10 @@ void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersa obj->m_known_by_count--; } - if (!sounds_to_stop.empty()) - stopAttachedSounds(client->peer_id, sounds_to_stop); + // Note: Do yet NOT stop or remove object-attached sounds where the object goes out + // of range (client side). Such sounds would need to be re-sent when coming into range. + // Currently, the client will initiate m_playing_sounds clean ups indirectly by + // "Server::handleCommand_RemovedSounds". // Added objects pkt << static_cast(added_objects.size()); @@ -2260,37 +2253,6 @@ void Server::fadeSound(s32 handle, float step, float gain) m_playing_sounds.erase(it); } -void Server::stopAttachedSounds(session_t peer_id, - const std::vector &object_ids) -{ - assert(peer_id != PEER_ID_INEXISTENT); - assert(!object_ids.empty()); - - auto cb = [&] (const s32 id, ServerPlayingSound &sound) -> bool { - if (!CONTAINS(object_ids, sound.object)) - return false; - - auto clients_it = sound.clients.find(peer_id); - if (clients_it == sound.clients.end()) - return false; - - NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4); - pkt << id; - Send(peer_id, &pkt); - - sound.clients.erase(clients_it); - // delete if client list empty - return sound.clients.empty(); - }; - - for (auto it = m_playing_sounds.begin(); it != m_playing_sounds.end(); ) { - if (cb(it->first, it->second)) - it = m_playing_sounds.erase(it); - else - ++it; - } -} - void Server::sendRemoveNode(v3s16 p, std::unordered_set *far_players, float far_d_nodes) { diff --git a/src/server.h b/src/server.h index 16c1ea4cc..6d439cc67 100644 --- a/src/server.h +++ b/src/server.h @@ -239,9 +239,6 @@ public: s32 playSound(ServerPlayingSound ¶ms, bool ephemeral=false); void stopSound(s32 handle); void fadeSound(s32 handle, float step, float gain); - // Stop all sounds attached to given objects, for a certain client - void stopAttachedSounds(session_t peer_id, - const std::vector &object_ids); // Envlock std::set getPlayerEffectivePrivs(const std::string &name);