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

View File

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

View File

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

View File

@ -1649,7 +1649,18 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id);
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);
p.pos.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;
{ // 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);
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
p.pos.end.serialize(os);
p.vel.end.serialize(os);
p.acc.end.serialize(os);
p.exptime.end.serialize(os);
p.size.end.serialize(os);
// final tween frames of older properties
p.pos.end.serialize(os);
p.vel.end.serialize(os);
p.acc.end.serialize(os);
p.exptime.end.serialize(os);
p.size.end.serialize(os);
}
// else: fields are already written by serialize() very early
// properties for legacy texture field
p.texture.serialize(os, protocol_version, true);