From c607bee19e286165fd497d57d2bb2b8ac5986f36 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 4 Sep 2022 16:22:12 +0200 Subject: [PATCH] Allow looped animation to be used safely with old clients fixes #12657 --- src/client/particles.cpp | 1 + src/particles.cpp | 4 ++-- src/tileanimation.cpp | 14 ++++++++++---- src/tileanimation.h | 4 ++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/client/particles.cpp b/src/client/particles.cpp index 95d3c2021..85baee7cd 100644 --- a/src/client/particles.cpp +++ b/src/client/particles.cpp @@ -555,6 +555,7 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, // synchronize animation length with particle life if desired if (pp.animation.type != TAT_NONE) { + // FIXME: this should be moved into a TileAnimationParams class method if (pp.animation.type == TAT_VERTICAL_FRAMES && pp.animation.vertical_frames.length < 0) { auto& a = pp.animation.vertical_frames; diff --git a/src/particles.cpp b/src/particles.cpp index 19b3418b7..e495ecd03 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -127,7 +127,7 @@ void ParticleParameters::serialize(std::ostream &os, u16 protocol_ver) const os << serializeString32(texture.string); writeU8(os, vertical); writeU8(os, collision_removal); - animation.serialize(os, 6); /* NOT the protocol ver */ + animation.serialize(os, protocol_ver); writeU8(os, glow); writeU8(os, object_collision); writeU16(os, node.param0); @@ -160,7 +160,7 @@ void ParticleParameters::deSerialize(std::istream &is, u16 protocol_ver) texture.string = deSerializeString32(is); vertical = readU8(is); collision_removal = readU8(is); - animation.deSerialize(is, 6); /* NOT the protocol ver */ + animation.deSerialize(is, protocol_ver); glow = readU8(is); object_collision = readU8(is); diff --git a/src/tileanimation.cpp b/src/tileanimation.cpp index a79a36e57..025d27d91 100644 --- a/src/tileanimation.cpp +++ b/src/tileanimation.cpp @@ -19,21 +19,27 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tileanimation.h" #include "util/serialize.h" -void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) const +void TileAnimationParams::serialize(std::ostream &os, u16 protocol_ver) const { + // The particle code overloads the length parameter so that negative numbers + // indicate an extra feature which old clients don't understand (crash). + // In hindsight it would have been better to use an extra parameter for this + // but we're stuck with this now. + const bool need_abs = protocol_ver < 40; + writeU8(os, type); if (type == TAT_VERTICAL_FRAMES) { writeU16(os, vertical_frames.aspect_w); writeU16(os, vertical_frames.aspect_h); - writeF32(os, vertical_frames.length); + writeF32(os, need_abs ? fabs(vertical_frames.length) : vertical_frames.length); } else if (type == TAT_SHEET_2D) { writeU8(os, sheet_2d.frames_w); writeU8(os, sheet_2d.frames_h); - writeF32(os, sheet_2d.frame_length); + writeF32(os, need_abs ? fabs(sheet_2d.frame_length) : sheet_2d.frame_length); } } -void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version) +void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_ver) { type = (TileAnimationType) readU8(is); diff --git a/src/tileanimation.h b/src/tileanimation.h index 0449de0b8..45b91655e 100644 --- a/src/tileanimation.h +++ b/src/tileanimation.h @@ -50,8 +50,8 @@ struct TileAnimationParams } sheet_2d; }; - void serialize(std::ostream &os, u16 protocol_version) const; - void deSerialize(std::istream &is, u16 protocol_version); + void serialize(std::ostream &os, u16 protocol_ver) const; + void deSerialize(std::istream &is, u16 protocol_ver); void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms, v2u32 *frame_size) const; void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const;