mirror of
https://github.com/minetest/minetest.git
synced 2024-11-13 03:03:44 +01:00
Server: avoid re-use of recent ParticleSpawner and Sound IDs (#14045)
This improves the reliability when removing and re-adding handles quickly. Looping through the entire ID range avoids collisions caused by any race condition.
This commit is contained in:
parent
d6a8b546e4
commit
a7e5456099
@ -2171,12 +2171,18 @@ void Server::SendPlayerSpeed(session_t peer_id, const v3f &added_vel)
|
|||||||
|
|
||||||
inline s32 Server::nextSoundId()
|
inline s32 Server::nextSoundId()
|
||||||
{
|
{
|
||||||
s32 ret = m_next_sound_id;
|
s32 free_id = m_playing_sounds_id_last_used;
|
||||||
if (m_next_sound_id == INT32_MAX)
|
while (free_id == 0 || m_playing_sounds.find(free_id) != m_playing_sounds.end()) {
|
||||||
m_next_sound_id = 0; // signed overflow is undefined
|
if (free_id == INT32_MAX)
|
||||||
else
|
free_id = 0; // signed overflow is undefined
|
||||||
m_next_sound_id++;
|
else
|
||||||
return ret;
|
free_id++;
|
||||||
|
|
||||||
|
if (free_id == m_playing_sounds_id_last_used)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m_playing_sounds_id_last_used = free_id;
|
||||||
|
return free_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Server::playSound(ServerPlayingSound ¶ms, bool ephemeral)
|
s32 Server::playSound(ServerPlayingSound ¶ms, bool ephemeral)
|
||||||
@ -2232,6 +2238,8 @@ s32 Server::playSound(ServerPlayingSound ¶ms, bool ephemeral)
|
|||||||
|
|
||||||
// old clients will still use this, so pick a reserved ID (-1)
|
// old clients will still use this, so pick a reserved ID (-1)
|
||||||
const s32 id = ephemeral ? -1 : nextSoundId();
|
const s32 id = ephemeral ? -1 : nextSoundId();
|
||||||
|
if (id == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
float gain = params.gain * params.spec.gain;
|
float gain = params.gain * params.spec.gain;
|
||||||
NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0);
|
NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0);
|
||||||
|
@ -695,7 +695,7 @@ private:
|
|||||||
Sounds
|
Sounds
|
||||||
*/
|
*/
|
||||||
std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
|
std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
|
||||||
s32 m_next_sound_id = 0; // positive values only
|
s32 m_playing_sounds_id_last_used = 0; // positive values only
|
||||||
s32 nextSoundId();
|
s32 nextSoundId();
|
||||||
|
|
||||||
ModStorageDatabase *m_mod_storage_database = nullptr;
|
ModStorageDatabase *m_mod_storage_database = nullptr;
|
||||||
|
@ -1637,16 +1637,16 @@ u32 ServerEnvironment::addParticleSpawner(float exptime)
|
|||||||
// Timers with lifetime 0 do not expire
|
// Timers with lifetime 0 do not expire
|
||||||
float time = exptime > 0.f ? exptime : PARTICLE_SPAWNER_NO_EXPIRY;
|
float time = exptime > 0.f ? exptime : PARTICLE_SPAWNER_NO_EXPIRY;
|
||||||
|
|
||||||
u32 id = 0;
|
u32 free_id = m_particle_spawners_id_last_used;
|
||||||
for (;;) { // look for unused particlespawner id
|
while (free_id == 0 || m_particle_spawners.find(free_id) != m_particle_spawners.end()) {
|
||||||
id++;
|
if (free_id == m_particle_spawners_id_last_used)
|
||||||
std::unordered_map<u32, float>::iterator f = m_particle_spawners.find(id);
|
return 0; // full
|
||||||
if (f == m_particle_spawners.end()) {
|
free_id++;
|
||||||
m_particle_spawners[id] = time;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return id;
|
|
||||||
|
m_particle_spawners_id_last_used = free_id;
|
||||||
|
m_particle_spawners[free_id] = time;
|
||||||
|
return free_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id)
|
u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id)
|
||||||
|
@ -512,6 +512,7 @@ private:
|
|||||||
// Particles
|
// Particles
|
||||||
IntervalLimiter m_particle_management_interval;
|
IntervalLimiter m_particle_management_interval;
|
||||||
std::unordered_map<u32, float> m_particle_spawners;
|
std::unordered_map<u32, float> m_particle_spawners;
|
||||||
|
u32 m_particle_spawners_id_last_used = 0;
|
||||||
std::unordered_map<u32, u16> m_particle_spawner_attachments;
|
std::unordered_map<u32, u16> m_particle_spawner_attachments;
|
||||||
|
|
||||||
// Environment metrics
|
// Environment metrics
|
||||||
|
Loading…
Reference in New Issue
Block a user