Particle spawner: Fix missing parameters

The changes done to clientpackethandler.cpp and server.cpp move the
compatibility code into a protocol version check so that older code
parts can easily be removed in the future (e.g. bump of minimal version).
This commit is contained in:
SmallJoker 2023-04-05 20:23:16 +02:00 committed by SmallJoker
parent f8e0778fc9
commit ba2fee0751
3 changed files with 105 additions and 67 deletions

@ -994,14 +994,22 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
p.amount = readU16(is); p.amount = readU16(is);
p.time = readF32(is); p.time = readF32(is);
// older protocols do not support tweening, and send only bool missing_end_values = false;
// static ranges, so we can't just use the normal serialization if (m_proto_ver >= 42) {
// functions for the older values. // All tweenable parameters
p.pos.start.legacyDeSerialize(is); p.pos.deSerialize(is);
p.vel.start.legacyDeSerialize(is); p.vel.deSerialize(is);
p.acc.start.legacyDeSerialize(is); p.acc.deSerialize(is);
p.exptime.start.legacyDeSerialize(is); p.exptime.deSerialize(is);
p.size.start.legacyDeSerialize(is); p.size.deSerialize(is);
} else {
p.pos.start.legacyDeSerialize(is);
p.vel.start.legacyDeSerialize(is);
p.acc.start.legacyDeSerialize(is);
p.exptime.start.legacyDeSerialize(is);
p.size.start.legacyDeSerialize(is);
missing_end_values = true;
}
p.collisiondetection = readU8(is); p.collisiondetection = readU8(is);
p.texture.string = deSerializeString32(is); p.texture.string = deSerializeString32(is);
@ -1017,8 +1025,6 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
p.glow = readU8(is); p.glow = readU8(is);
p.object_collision = readU8(is); p.object_collision = readU8(is);
bool legacy_format = true;
// This is kinda awful // This is kinda awful
do { do {
u16 tmp_param0 = readU16(is); u16 tmp_param0 = readU16(is);
@ -1028,25 +1034,30 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
p.node.param2 = readU8(is); p.node.param2 = readU8(is);
p.node_tile = readU8(is); p.node_tile = readU8(is);
// v >= 5.6.0 if (m_proto_ver < 42) {
f32 tmp_sbias = readF32(is); // v >= 5.6.0
if (is.eof()) f32 tmp_sbias = readF32(is);
break; if (is.eof())
break;
// initial bias must be stored separately in the stream to preserve // initial bias must be stored separately in the stream to preserve
// backwards compatibility with older clients, which do not support // backwards compatibility with older clients, which do not support
// a bias field in their range "format" // a bias field in their range "format"
p.pos.start.bias = tmp_sbias; p.pos.start.bias = tmp_sbias;
p.vel.start.bias = readF32(is); p.vel.start.bias = readF32(is);
p.acc.start.bias = readF32(is); p.acc.start.bias = readF32(is);
p.exptime.start.bias = readF32(is); p.exptime.start.bias = readF32(is);
p.size.start.bias = readF32(is); p.size.start.bias = readF32(is);
p.pos.end.deSerialize(is); p.pos.end.deSerialize(is);
p.vel.end.deSerialize(is); p.vel.end.deSerialize(is);
p.acc.end.deSerialize(is); p.acc.end.deSerialize(is);
p.exptime.end.deSerialize(is); p.exptime.end.deSerialize(is);
p.size.end.deSerialize(is); p.size.end.deSerialize(is);
missing_end_values = false;
}
// else: fields are already read by deSerialize() very early
// properties for legacy texture field // properties for legacy texture field
p.texture.deSerialize(is, m_proto_ver, true); p.texture.deSerialize(is, m_proto_ver, true);
@ -1077,11 +1088,9 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
newtex.deSerialize(is, m_proto_ver); newtex.deSerialize(is, m_proto_ver);
p.texpool.push_back(newtex); p.texpool.push_back(newtex);
} }
legacy_format = false;
} while(0); } while(0);
if (legacy_format) { if (missing_end_values) {
// there's no tweening data to be had, so we need to set the // there's no tweening data to be had, so we need to set the
// legacy params to constant values, otherwise everything old // legacy params to constant values, otherwise everything old
// will tween to zero // will tween to zero

@ -213,6 +213,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PROTOCOL VERSION 42: PROTOCOL VERSION 42:
TOSERVER_UPDATE_CLIENT_INFO added TOSERVER_UPDATE_CLIENT_INFO added
new fields for TOCLIENT_SET_LIGHTING and TOCLIENT_SET_SKY new fields for TOCLIENT_SET_LIGHTING and TOCLIENT_SET_SKY
Send forgotten TweenedParameter properties
[scheduled bump for 5.7.0] [scheduled bump for 5.7.0]
*/ */
@ -538,20 +539,33 @@ enum ToClientCommand
TOCLIENT_ADD_PARTICLESPAWNER = 0x47, TOCLIENT_ADD_PARTICLESPAWNER = 0x47,
/* /*
-- struct range<T> { T min, T max, f32 bias }; using range<T> = RangedParameter<T> {
-- struct tween<T> { T start, T end }; T min, max
f32 bias
}
using tween<T> = TweenedParameter<T> {
u8 style
u16 reps
f32 beginning
T start, end
}
u16 amount u16 amount
f32 spawntime f32 spawntime
v3f minpos if PROTOCOL_VERSION >= 42 {
v3f maxpos tween<T> pos, vel, acc, exptime, size
v3f minvel } else {
v3f maxvel v3f minpos
v3f minacc v3f maxpos
v3f maxacc v3f minvel
f32 minexptime v3f maxvel
f32 maxexptime v3f minacc
f32 minsize v3f maxacc
f32 maxsize f32 minexptime
f32 maxexptime
f32 minsize
f32 maxsize
}
u8 bool collisiondetection u8 bool collisiondetection
u32 len u32 len
u8[len] texture u8[len] texture
@ -562,18 +576,20 @@ enum ToClientCommand
u8 glow u8 glow
u8 object_collision u8 object_collision
f32 pos_start_bias if PROTOCOL_VERSION < 42 {
f32 vel_start_bias f32 pos_start_bias
f32 acc_start_bias f32 vel_start_bias
f32 exptime_start_bias f32 acc_start_bias
f32 size_start_bias f32 exptime_start_bias
f32 size_start_bias
range<v3f> pos_end range<v3f> pos_end
-- i.e v3f pos_end_min -- i.e v3f pos_end_min
-- v3f pos_end_max -- v3f pos_end_max
-- f32 pos_end_bias -- f32 pos_end_bias
range<v3f> vel_end range<v3f> vel_end
range<v3f> acc_end range<v3f> acc_end
}
tween<range<v3f>> drag tween<range<v3f>> drag
-- i.e. v3f drag_start_min -- i.e. v3f drag_start_min

@ -1649,7 +1649,18 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id); NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id);
pkt << p.amount << p.time; pkt << p.amount << p.time;
{ // serialize legacy fields
if (protocol_version >= 42) {
// Serialize entire thing
std::ostringstream os(std::ios_base::binary);
p.pos.serialize(os);
p.vel.serialize(os);
p.acc.serialize(os);
p.exptime.serialize(os);
p.size.serialize(os);
pkt.putRawString(os.str());
} else {
// serialize legacy fields only (compatibility)
std::ostringstream os(std::ios_base::binary); std::ostringstream os(std::ios_base::binary);
p.pos.start.legacySerialize(os); p.pos.start.legacySerialize(os);
p.vel.start.legacySerialize(os); p.vel.start.legacySerialize(os);
@ -1672,21 +1683,23 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
pkt << p.node.param0 << p.node.param2 << p.node_tile; pkt << p.node.param0 << p.node.param2 << p.node_tile;
{ // serialize new fields { // serialize new fields
// initial bias for older properties
pkt << p.pos.start.bias
<< p.vel.start.bias
<< p.acc.start.bias
<< p.exptime.start.bias
<< p.size.start.bias;
std::ostringstream os(std::ios_base::binary); std::ostringstream os(std::ios_base::binary);
if (protocol_version < 42) {
// initial bias for older properties
pkt << p.pos.start.bias
<< p.vel.start.bias
<< p.acc.start.bias
<< p.exptime.start.bias
<< p.size.start.bias;
// final tween frames of older properties // final tween frames of older properties
p.pos.end.serialize(os); p.pos.end.serialize(os);
p.vel.end.serialize(os); p.vel.end.serialize(os);
p.acc.end.serialize(os); p.acc.end.serialize(os);
p.exptime.end.serialize(os); p.exptime.end.serialize(os);
p.size.end.serialize(os); p.size.end.serialize(os);
}
// else: fields are already written by serialize() very early
// properties for legacy texture field // properties for legacy texture field
p.texture.serialize(os, protocol_version, true); p.texture.serialize(os, protocol_version, true);