From bba4563d89b6708d75a4053c69873dff0d747538 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 3 Jan 2019 17:04:26 +0100 Subject: [PATCH] Proselytize the network. Use IEEE F32 (#8030) * Proselytize the network. Use IEEE F32 * Remove unused V2F1000 functions --- doc/lua_api.txt | 6 +- src/client/content_cao.cpp | 76 +++++++++--------- src/content_sao.cpp | 10 +-- src/genericobject.cpp | 24 +++--- src/itemdef.cpp | 49 ++++++------ src/mapblock.cpp | 15 +--- src/network/clientpackethandler.cpp | 10 +-- src/network/networkpacket.cpp | 8 +- src/network/networkprotocol.h | 1 + src/nodedef.cpp | 115 +++++++++++----------------- src/nodedef.h | 3 + src/object_properties.cpp | 54 ++++++------- src/object_properties.h | 2 +- src/script/common/c_content.cpp | 16 +++- src/sound.h | 21 +++++ src/tileanimation.cpp | 8 +- src/tool.cpp | 12 +-- src/unittest/test_serialization.cpp | 17 +--- src/util/serialize.h | 52 ++++++------- 19 files changed, 237 insertions(+), 262 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ded7b580f..0b08282a0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5482,9 +5482,9 @@ Used by `ObjectRef` methods. Part of an Entity definition. -- 'inventory_image'. -- "item" is similar to "wielditem" but ignores the 'wield_image' parameter. - visual_size = {x = 1, y = 1}, - -- `x` multiplies horizontal (X and Z) visual size. - -- `y` multiplies vertical (Y) visual size. + visual_size = {x = 1, y = 1, z = 1}, + -- Multipliers for the visual size. If `z` is not specified, `x` will be used + -- to scale the entity along both horizontal axes. mesh = "model", diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index d2bd32afa..116a2e53b 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -357,24 +357,23 @@ void GenericCAO::initialize(const std::string &data) void GenericCAO::processInitData(const std::string &data) { std::istringstream is(data, std::ios::binary); - int num_messages = 0; - // version - u8 version = readU8(is); - // check version - if (version == 1) { // In PROTOCOL_VERSION 14 - m_name = deSerializeString(is); - m_is_player = readU8(is); - m_id = readU16(is); - m_position = readV3F1000(is); - m_rotation = readV3F1000(is); - m_hp = readS16(is); - num_messages = readU8(is); - } else { - errorstream<<"GenericCAO: Unsupported init data version" - <= 37 + m_name = deSerializeString(is); + m_is_player = readU8(is); + m_id = readU16(is); + m_position = readV3F32(is); + m_rotation = readV3F32(is); + m_hp = readS16(is); + const u8 num_messages = readU8(is); + for (int i = 0; i < num_messages; i++) { std::string message = deSerializeLongString(is); processMessage(message); @@ -546,7 +545,8 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); u8 li = m_last_light; m_spritenode->setColor(video::SColor(255,li,li,li)); - m_spritenode->setSize(m_prop.visual_size*BS); + m_spritenode->setSize(v2f(m_prop.visual_size.X, + m_prop.visual_size.Y) * BS); { const float txs = 1.0 / 1; const float tys = 1.0 / 1; @@ -622,9 +622,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_meshnode->grab(); mesh->drop(); - m_meshnode->setScale(v3f(m_prop.visual_size.X, - m_prop.visual_size.Y, - m_prop.visual_size.X)); + m_meshnode->setScale(m_prop.visual_size); u8 li = m_last_light; setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li)); @@ -643,9 +641,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_animated_meshnode->grab(); mesh->drop(); // The scene node took hold of it m_animated_meshnode->animateJoints(); // Needed for some animations - m_animated_meshnode->setScale(v3f(m_prop.visual_size.X, - m_prop.visual_size.Y, - m_prop.visual_size.X)); + m_animated_meshnode->setScale(m_prop.visual_size); u8 li = m_last_light; // set vertex colors to ensure alpha is set @@ -683,9 +679,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) m_wield_meshnode->setItem(item, m_client, (m_prop.visual == "wielditem")); - m_wield_meshnode->setScale( - v3f(m_prop.visual_size.X / 2, m_prop.visual_size.Y / 2, - m_prop.visual_size.X / 2)); + m_wield_meshnode->setScale(m_prop.visual_size / 2.0f); u8 li = m_last_light; m_wield_meshnode->setColor(video::SColor(255, li, li, li)); } else { @@ -1393,7 +1387,7 @@ void GenericCAO::processMessage(const std::string &data) } else if (cmd == GENERIC_CMD_SET_SPRITE) { v2s16 p = readV2S16(is); int num_frames = readU16(is); - float framelength = readF1000(is); + float framelength = readF32(is); bool select_horiz_by_yawpitch = readU8(is); m_tx_basepos = p; @@ -1403,9 +1397,9 @@ void GenericCAO::processMessage(const std::string &data) updateTexturePos(); } else if (cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) { - float override_speed = readF1000(is); - float override_jump = readF1000(is); - float override_gravity = readF1000(is); + float override_speed = readF32(is); + float override_jump = readF32(is); + float override_gravity = readF32(is); // these are sent inverted so we get true when the server sends nothing bool sneak = !readU8(is); bool sneak_glitch = !readU8(is); @@ -1424,11 +1418,11 @@ void GenericCAO::processMessage(const std::string &data) } } else if (cmd == GENERIC_CMD_SET_ANIMATION) { // TODO: change frames send as v2s32 value - v2f range = readV2F1000(is); + v2f range = readV2F32(is); if (!m_is_local_player) { m_animation_range = v2s32((s32)range.X, (s32)range.Y); - m_animation_speed = readF1000(is); - m_animation_blend = readF1000(is); + m_animation_speed = readF32(is); + m_animation_blend = readF32(is); // these are sent inverted so we get true when the server sends nothing m_animation_loop = !readU8(is); updateAnimation(); @@ -1437,8 +1431,8 @@ void GenericCAO::processMessage(const std::string &data) if(player->last_animation == NO_ANIM) { m_animation_range = v2s32((s32)range.X, (s32)range.Y); - m_animation_speed = readF1000(is); - m_animation_blend = readF1000(is); + m_animation_speed = readF32(is); + m_animation_blend = readF32(is); // these are sent inverted so we get true when the server sends nothing m_animation_loop = !readU8(is); } @@ -1457,12 +1451,12 @@ void GenericCAO::processMessage(const std::string &data) } } } else if (cmd == GENERIC_CMD_SET_ANIMATION_SPEED) { - m_animation_speed = readF1000(is); + m_animation_speed = readF32(is); updateAnimationSpeed(); } else if (cmd == GENERIC_CMD_SET_BONE_POSITION) { std::string bone = deSerializeString(is); - v3f position = readV3F1000(is); - v3f rotation = readV3F1000(is); + v3f position = readV3F32(is); + v3f rotation = readV3F32(is); m_bone_position[bone] = core::vector2d(position, rotation); updateBonePosition(); @@ -1482,8 +1476,8 @@ void GenericCAO::processMessage(const std::string &data) } m_attachment_bone = deSerializeString(is); - m_attachment_position = readV3F1000(is); - m_attachment_rotation = readV3F1000(is); + m_attachment_position = readV3F32(is); + m_attachment_rotation = readV3F32(is); // localplayer itself can't be attached to localplayer if (!m_is_local_player) { @@ -1510,7 +1504,7 @@ void GenericCAO::processMessage(const std::string &data) // As there is no definition, make a smoke puff ClientSimpleObject *simple = createSmokePuff( m_smgr, m_env, m_position, - m_prop.visual_size * BS); + v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS); m_env->addSimpleObject(simple); } else if (m_reset_textures_timer < 0) { // TODO: Execute defined fast response @@ -1581,7 +1575,7 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem, // As there is no definition, make a smoke puff ClientSimpleObject *simple = createSmokePuff( m_smgr, m_env, m_position, - m_prop.visual_size * BS); + v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS); m_env->addSimpleObject(simple); } // TODO: Execute defined fast response diff --git a/src/content_sao.cpp b/src/content_sao.cpp index cbe191384..ecacd7452 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -549,8 +549,8 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) os << serializeString(""); // name writeU8(os, 0); // is_player writeS16(os, getId()); //id - writeV3F1000(os, m_base_position); - writeV3F1000(os, m_rotation); + writeV3F32(os, m_base_position); + writeV3F32(os, m_rotation); writeS16(os, m_hp); std::ostringstream msg_os(std::ios::binary); @@ -873,7 +873,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p m_prop.pointable = true; // Start of default appearance, this should be overwritten by Lua m_prop.visual = "upright_sprite"; - m_prop.visual_size = v2f(1, 2); + m_prop.visual_size = v3f(1, 2, 1); m_prop.textures.clear(); m_prop.textures.emplace_back("player.png"); m_prop.textures.emplace_back("player_back.png"); @@ -947,8 +947,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) os << serializeString(m_player->getName()); // name writeU8(os, 1); // is_player writeS16(os, getId()); // id - writeV3F1000(os, m_base_position); - writeV3F1000(os, m_rotation); + writeV3F32(os, m_base_position); + writeV3F32(os, m_rotation); writeS16(os, getHP()); std::ostringstream msg_os(std::ios::binary); diff --git a/src/genericobject.cpp b/src/genericobject.cpp index ceec222aa..b1ec8ce4e 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -87,7 +87,7 @@ std::string gob_cmd_set_sprite( // parameters writeV2S16(os, p); writeU16(os, num_frames); - writeF1000(os, framelength); + writeF32(os, framelength); writeU8(os, select_horiz_by_yawpitch); return os.str(); } @@ -123,9 +123,9 @@ std::string gob_cmd_update_physics_override(float physics_override_speed, float // command writeU8(os, GENERIC_CMD_SET_PHYSICS_OVERRIDE); // parameters - writeF1000(os, physics_override_speed); - writeF1000(os, physics_override_jump); - writeF1000(os, physics_override_gravity); + writeF32(os, physics_override_speed); + writeF32(os, physics_override_jump); + writeF32(os, physics_override_gravity); // these are sent inverted so we get true when the server sends nothing writeU8(os, !sneak); writeU8(os, !sneak_glitch); @@ -139,9 +139,9 @@ std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_ // command writeU8(os, GENERIC_CMD_SET_ANIMATION); // parameters - writeV2F1000(os, frames); - writeF1000(os, frame_speed); - writeF1000(os, frame_blend); + writeV2F32(os, frames); + writeF32(os, frame_speed); + writeF32(os, frame_blend); // these are sent inverted so we get true when the server sends nothing writeU8(os, !frame_loop); return os.str(); @@ -153,7 +153,7 @@ std::string gob_cmd_update_animation_speed(float frame_speed) // command writeU8(os, GENERIC_CMD_SET_ANIMATION_SPEED); // parameters - writeF1000(os, frame_speed); + writeF32(os, frame_speed); return os.str(); } @@ -165,8 +165,8 @@ std::string gob_cmd_update_bone_position(const std::string &bone, v3f position, writeU8(os, GENERIC_CMD_SET_BONE_POSITION); // parameters os<= 36 - u8 version = 5; + // protocol_version >= 37 + u8 version = 6; writeU8(os, version); writeU8(os, type); os << serializeString(name); os << serializeString(description); os << serializeString(inventory_image); os << serializeString(wield_image); - writeV3F1000(os, wield_scale); + writeV3F32(os, wield_scale); writeS16(os, stack_max); writeU8(os, usable); writeU8(os, liquids_pointable); + std::string tool_capabilities_s; - if(tool_capabilities){ + if (tool_capabilities) { std::ostringstream tmp_os(std::ios::binary); tool_capabilities->serialize(tmp_os, protocol_version); tool_capabilities_s = tmp_os.str(); } os << serializeString(tool_capabilities_s); + writeU16(os, groups.size()); for (const auto &group : groups) { os << serializeString(group.first); writeS16(os, group.second); } + os << serializeString(node_placement_prediction); - os << serializeString(sound_place.name); - writeF1000(os, sound_place.gain); - writeF1000(os, range); - os << serializeString(sound_place_failed.name); - writeF1000(os, sound_place_failed.gain); + + // Version from ContentFeatures::serialize to keep in sync + sound_place.serialize(os, CONTENTFEATURES_VERSION); + sound_place_failed.serialize(os, CONTENTFEATURES_VERSION); + + writeF32(os, range); os << serializeString(palette_image); writeARGB8(os, color); - - writeF1000(os, sound_place.pitch); - writeF1000(os, sound_place_failed.pitch); os << serializeString(inventory_overlay); os << serializeString(wield_overlay); } @@ -174,7 +175,7 @@ void ItemDefinition::deSerialize(std::istream &is) // Deserialize int version = readU8(is); - if (version < 5) + if (version < 6) throw SerializationError("unsupported ItemDefinition version"); type = (enum ItemType)readU8(is); @@ -182,17 +183,18 @@ void ItemDefinition::deSerialize(std::istream &is) description = deSerializeString(is); inventory_image = deSerializeString(is); wield_image = deSerializeString(is); - wield_scale = readV3F1000(is); + wield_scale = readV3F32(is); stack_max = readS16(is); usable = readU8(is); liquids_pointable = readU8(is); + std::string tool_capabilities_s = deSerializeString(is); - if(!tool_capabilities_s.empty()) - { + if (!tool_capabilities_s.empty()) { std::istringstream tmp_is(tool_capabilities_s, std::ios::binary); tool_capabilities = new ToolCapabilities; tool_capabilities->deSerialize(tmp_is); } + groups.clear(); u32 groups_size = readU16(is); for(u32 i=0; i= 1) { - readF1000(is); // deprecated heat - readF1000(is); // deprecated humidity - } - } - catch(SerializationError &e) - { + + } catch(SerializationError &e) { warningstream<<"MapBlock::deSerializeNetworkSpecific(): Ignoring an error" <<": "<getString(0), pkt->getSize()); std::istringstream is(datastring, std::ios_base::binary); - v3f pos = readV3F1000(is); - v3f vel = readV3F1000(is); - v3f acc = readV3F1000(is); - float expirationtime = readF1000(is); - float size = readF1000(is); + v3f pos = readV3F32(is); + v3f vel = readV3F32(is); + v3f acc = readV3F32(is); + float expirationtime = readF32(is); + float size = readF32(is); bool collisiondetection = readU8(is); std::string texture = deSerializeLongString(is); diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index 530f0fe70..35a131a34 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -288,7 +288,7 @@ NetworkPacket& NetworkPacket::operator<<(float src) { checkDataSize(4); - writeF1000(&m_data[m_read_offset], src); + writeF32(&m_data[m_read_offset], src); m_read_offset += 4; return *this; @@ -383,7 +383,7 @@ NetworkPacket& NetworkPacket::operator>>(float& dst) { checkReadOffset(m_read_offset, 4); - dst = readF1000(&m_data[m_read_offset]); + dst = readF32(&m_data[m_read_offset]); m_read_offset += 4; return *this; @@ -393,7 +393,7 @@ NetworkPacket& NetworkPacket::operator>>(v2f& dst) { checkReadOffset(m_read_offset, 8); - dst = readV2F1000(&m_data[m_read_offset]); + dst = readV2F32(&m_data[m_read_offset]); m_read_offset += 8; return *this; @@ -403,7 +403,7 @@ NetworkPacket& NetworkPacket::operator>>(v3f& dst) { checkReadOffset(m_read_offset, 12); - dst = readV3F1000(&m_data[m_read_offset]); + dst = readV3F32(&m_data[m_read_offset]); m_read_offset += 12; return *this; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 96dfbe44f..703e96056 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -192,6 +192,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Redo detached inventory sending Add TOCLIENT_NODEMETA_CHANGED New network float format + ContentFeatures version 13 */ #define LATEST_PROTOCOL_VERSION 37 diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 70974a572..03a163bd3 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -74,7 +74,7 @@ void NodeBox::reset() void NodeBox::serialize(std::ostream &os, u16 protocol_version) const { // Protocol >= 36 - int version = 5; + const u8 version = 6; writeU8(os, version); switch (type) { @@ -84,19 +84,19 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const writeU16(os, fixed.size()); for (const aabb3f &nodebox : fixed) { - writeV3F1000(os, nodebox.MinEdge); - writeV3F1000(os, nodebox.MaxEdge); + writeV3F32(os, nodebox.MinEdge); + writeV3F32(os, nodebox.MaxEdge); } break; case NODEBOX_WALLMOUNTED: writeU8(os, type); - writeV3F1000(os, wall_top.MinEdge); - writeV3F1000(os, wall_top.MaxEdge); - writeV3F1000(os, wall_bottom.MinEdge); - writeV3F1000(os, wall_bottom.MaxEdge); - writeV3F1000(os, wall_side.MinEdge); - writeV3F1000(os, wall_side.MaxEdge); + writeV3F32(os, wall_top.MinEdge); + writeV3F32(os, wall_top.MaxEdge); + writeV3F32(os, wall_bottom.MinEdge); + writeV3F32(os, wall_bottom.MaxEdge); + writeV3F32(os, wall_side.MinEdge); + writeV3F32(os, wall_side.MaxEdge); break; case NODEBOX_CONNECTED: writeU8(os, type); @@ -104,8 +104,8 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const #define WRITEBOX(box) \ writeU16(os, (box).size()); \ for (const aabb3f &i: (box)) { \ - writeV3F1000(os, i.MinEdge); \ - writeV3F1000(os, i.MaxEdge); \ + writeV3F32(os, i.MinEdge); \ + writeV3F32(os, i.MaxEdge); \ }; WRITEBOX(fixed); @@ -133,7 +133,7 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const void NodeBox::deSerialize(std::istream &is) { int version = readU8(is); - if (version < 4) + if (version < 6) throw SerializationError("unsupported NodeBox version"); reset(); @@ -146,19 +146,19 @@ void NodeBox::deSerialize(std::istream &is) while(fixed_count--) { aabb3f box; - box.MinEdge = readV3F1000(is); - box.MaxEdge = readV3F1000(is); + box.MinEdge = readV3F32(is); + box.MaxEdge = readV3F32(is); fixed.push_back(box); } } else if(type == NODEBOX_WALLMOUNTED) { - wall_top.MinEdge = readV3F1000(is); - wall_top.MaxEdge = readV3F1000(is); - wall_bottom.MinEdge = readV3F1000(is); - wall_bottom.MaxEdge = readV3F1000(is); - wall_side.MinEdge = readV3F1000(is); - wall_side.MaxEdge = readV3F1000(is); + wall_top.MinEdge = readV3F32(is); + wall_top.MaxEdge = readV3F32(is); + wall_bottom.MinEdge = readV3F32(is); + wall_bottom.MaxEdge = readV3F32(is); + wall_side.MinEdge = readV3F32(is); + wall_side.MaxEdge = readV3F32(is); } else if (type == NODEBOX_CONNECTED) { @@ -166,8 +166,8 @@ void NodeBox::deSerialize(std::istream &is) count = readU16(is); \ (box).reserve(count); \ while (count--) { \ - v3f min = readV3F1000(is); \ - v3f max = readV3F1000(is); \ + v3f min = readV3F32(is); \ + v3f max = readV3F32(is); \ (box).emplace_back(min, max); }; } u16 count; @@ -179,16 +179,14 @@ void NodeBox::deSerialize(std::istream &is) READBOXES(connect_left); READBOXES(connect_back); READBOXES(connect_right); - if (version >= 5) { - READBOXES(disconnected_top); - READBOXES(disconnected_bottom); - READBOXES(disconnected_front); - READBOXES(disconnected_left); - READBOXES(disconnected_back); - READBOXES(disconnected_right); - READBOXES(disconnected); - READBOXES(disconnected_sides); - } + READBOXES(disconnected_top); + READBOXES(disconnected_bottom); + READBOXES(disconnected_front); + READBOXES(disconnected_left); + READBOXES(disconnected_back); + READBOXES(disconnected_right); + READBOXES(disconnected); + READBOXES(disconnected_sides); } } @@ -264,26 +262,6 @@ void TileDef::deSerialize(std::istream &is, u8 contentfeatures_version, align_style = ALIGN_STYLE_NODE; } - -/* - SimpleSoundSpec serialization -*/ - -static void serializeSimpleSoundSpec(const SimpleSoundSpec &ss, - std::ostream &os, u8 version) -{ - os<getBool("connected_glass"); @@ -419,8 +397,7 @@ void ContentFeatures::reset() void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const { - // protocol_version >= 36 - u8 version = 12; + const u8 version = CONTENTFEATURES_VERSION; writeU8(os, version); // general @@ -436,7 +413,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const // visual writeU8(os, drawtype); os << serializeString(mesh); - writeF1000(os, visual_scale); + writeF32(os, visual_scale); writeU8(os, 6); for (const TileDef &td : tiledef) td.serialize(os, protocol_version); @@ -456,10 +433,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU16(os, connects_to_ids.size()); for (u16 connects_to_id : connects_to_ids) writeU16(os, connects_to_id); - writeU8(os, post_effect_color.getAlpha()); - writeU8(os, post_effect_color.getRed()); - writeU8(os, post_effect_color.getGreen()); - writeU8(os, post_effect_color.getBlue()); + writeARGB8(os, post_effect_color); writeU8(os, leveled); // lighting @@ -495,9 +469,9 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const collision_box.serialize(os, protocol_version); // sound - serializeSimpleSoundSpec(sound_footstep, os, version); - serializeSimpleSoundSpec(sound_dig, os, version); - serializeSimpleSoundSpec(sound_dug, os, version); + sound_footstep.serialize(os, version); + sound_dig.serialize(os, version); + sound_dug.serialize(os, version); // legacy writeU8(os, legacy_facedir_simple); @@ -524,8 +498,8 @@ void ContentFeatures::correctAlpha(TileDef *tiles, int length) void ContentFeatures::deSerialize(std::istream &is) { // version detection - int version = readU8(is); - if (version < 12) + const u8 version = readU8(is); + if (version < CONTENTFEATURES_VERSION) throw SerializationError("unsupported ContentFeatures version"); // general @@ -543,7 +517,7 @@ void ContentFeatures::deSerialize(std::istream &is) // visual drawtype = (enum NodeDrawType) readU8(is); mesh = deSerializeString(is); - visual_scale = readF1000(is); + visual_scale = readF32(is); if (readU8(is) != 6) throw SerializationError("unsupported tile count"); for (TileDef &td : tiledef) @@ -565,10 +539,7 @@ void ContentFeatures::deSerialize(std::istream &is) connects_to_ids.clear(); for (u16 i = 0; i < connects_to_size; i++) connects_to_ids.push_back(readU16(is)); - post_effect_color.setAlpha(readU8(is)); - post_effect_color.setRed(readU8(is)); - post_effect_color.setGreen(readU8(is)); - post_effect_color.setBlue(readU8(is)); + post_effect_color = readARGB8(is); leveled = readU8(is); // lighting-related @@ -605,9 +576,9 @@ void ContentFeatures::deSerialize(std::istream &is) collision_box.deSerialize(is); // sounds - deSerializeSimpleSoundSpec(sound_footstep, is, version); - deSerializeSimpleSoundSpec(sound_dig, is, version); - deSerializeSimpleSoundSpec(sound_dug, is, version); + sound_footstep.deSerialize(is, version); + sound_dig.deSerialize(is, version); + sound_dug.deSerialize(is, version); // read legacy properties legacy_facedir_simple = readU8(is); diff --git a/src/nodedef.h b/src/nodedef.h index 51f930e55..60d91f8d9 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -35,6 +35,9 @@ class Client; #include "constants.h" // BS #include "tileanimation.h" +// PROTOCOL_VERSION >= 37 +static const u8 CONTENTFEATURES_VERSION = 13; + class IItemDefManager; class ITextureSource; class IShaderSource; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index d42fbcc6c..e08eca7c9 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -41,7 +41,7 @@ std::string ObjectProperties::dump() os << ", collisionbox=" << PP(collisionbox.MinEdge) << "," << PP(collisionbox.MaxEdge); os << ", visual=" << visual; os << ", mesh=" << mesh; - os << ", visual_size=" << PP2(visual_size); + os << ", visual_size=" << PP(visual_size); os << ", textures=["; for (const std::string &texture : textures) { os << "\"" << texture << "\" "; @@ -74,17 +74,17 @@ std::string ObjectProperties::dump() void ObjectProperties::serialize(std::ostream &os) const { - writeU8(os, 3); // version, protocol_version >= 36 + writeU8(os, 4); // PROTOCOL_VERSION >= 37 writeS16(os, hp_max); writeU8(os, physical); - writeF1000(os, weight); - writeV3F1000(os, collisionbox.MinEdge); - writeV3F1000(os, collisionbox.MaxEdge); - writeV3F1000(os, selectionbox.MinEdge); - writeV3F1000(os, selectionbox.MaxEdge); + writeF32(os, weight); + writeV3F32(os, collisionbox.MinEdge); + writeV3F32(os, collisionbox.MaxEdge); + writeV3F32(os, selectionbox.MinEdge); + writeV3F32(os, selectionbox.MaxEdge); writeU8(os, pointable); os << serializeString(visual); - writeV2F1000(os, visual_size); + writeV3F32(os, visual_size); writeU16(os, textures.size()); for (const std::string &texture : textures) { os << serializeString(texture); @@ -93,7 +93,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeV2S16(os, initial_sprite_basepos); writeU8(os, is_visible); writeU8(os, makes_footstep_sound); - writeF1000(os, automatic_rotate); + writeF32(os, automatic_rotate); // Added in protocol version 14 os << serializeString(mesh); writeU16(os, colors.size()); @@ -101,19 +101,19 @@ void ObjectProperties::serialize(std::ostream &os) const writeARGB8(os, color); } writeU8(os, collideWithObjects); - writeF1000(os, stepheight); + writeF32(os, stepheight); writeU8(os, automatic_face_movement_dir); - writeF1000(os, automatic_face_movement_dir_offset); + writeF32(os, automatic_face_movement_dir_offset); writeU8(os, backface_culling); os << serializeString(nametag); writeARGB8(os, nametag_color); - writeF1000(os, automatic_face_movement_max_rotation_per_sec); + writeF32(os, automatic_face_movement_max_rotation_per_sec); os << serializeString(infotext); os << serializeString(wield_item); writeS8(os, glow); writeU16(os, breath_max); - writeF1000(os, eye_height); - writeF1000(os, zoom_fov); + writeF32(os, eye_height); + writeF32(os, zoom_fov); writeU8(os, use_texture_alpha); // Add stuff only at the bottom. @@ -123,19 +123,19 @@ void ObjectProperties::serialize(std::ostream &os) const void ObjectProperties::deSerialize(std::istream &is) { int version = readU8(is); - if (version != 3) + if (version != 4) throw SerializationError("unsupported ObjectProperties version"); hp_max = readS16(is); physical = readU8(is); - weight = readF1000(is); - collisionbox.MinEdge = readV3F1000(is); - collisionbox.MaxEdge = readV3F1000(is); - selectionbox.MinEdge = readV3F1000(is); - selectionbox.MaxEdge = readV3F1000(is); + weight = readF32(is); + collisionbox.MinEdge = readV3F32(is); + collisionbox.MaxEdge = readV3F32(is); + selectionbox.MinEdge = readV3F32(is); + selectionbox.MaxEdge = readV3F32(is); pointable = readU8(is); visual = deSerializeString(is); - visual_size = readV2F1000(is); + visual_size = readV3F32(is); textures.clear(); u32 texture_count = readU16(is); for (u32 i = 0; i < texture_count; i++){ @@ -145,7 +145,7 @@ void ObjectProperties::deSerialize(std::istream &is) initial_sprite_basepos = readV2S16(is); is_visible = readU8(is); makes_footstep_sound = readU8(is); - automatic_rotate = readF1000(is); + automatic_rotate = readF32(is); mesh = deSerializeString(is); colors.clear(); u32 color_count = readU16(is); @@ -153,18 +153,18 @@ void ObjectProperties::deSerialize(std::istream &is) colors.push_back(readARGB8(is)); } collideWithObjects = readU8(is); - stepheight = readF1000(is); + stepheight = readF32(is); automatic_face_movement_dir = readU8(is); - automatic_face_movement_dir_offset = readF1000(is); + automatic_face_movement_dir_offset = readF32(is); backface_culling = readU8(is); nametag = deSerializeString(is); nametag_color = readARGB8(is); - automatic_face_movement_max_rotation_per_sec = readF1000(is); + automatic_face_movement_max_rotation_per_sec = readF32(is); infotext = deSerializeString(is); wield_item = deSerializeString(is); glow = readS8(is); breath_max = readU16(is); - eye_height = readF1000(is); - zoom_fov = readF1000(is); + eye_height = readF32(is); + zoom_fov = readF32(is); use_texture_alpha = readU8(is); } diff --git a/src/object_properties.h b/src/object_properties.h index d273b52f4..3175e6118 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -38,7 +38,7 @@ struct ObjectProperties bool pointable = true; std::string visual = "sprite"; std::string mesh = ""; - v2f visual_size = v2f(1, 1); + v3f visual_size = v3f(1, 1, 1); std::vector textures; std::vector colors; v2s16 spritediv = v2s16(1, 1); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 1d62ad98a..033549475 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -218,8 +218,18 @@ void read_object_properties(lua_State *L, int index, getstringfield(L, -1, "mesh", prop->mesh); lua_getfield(L, -1, "visual_size"); - if(lua_istable(L, -1)) - prop->visual_size = read_v2f(L, -1); + if (lua_istable(L, -1)) { + // Backwards compatibility: Also accept { x = ?, y = ? } + v2f scale_xy = read_v2f(L, -1); + + f32 scale_z = scale_xy.X; + lua_getfield(L, -1, "z"); + if (lua_isnumber(L, -1)) + scale_z = lua_tonumber(L, -1); + lua_pop(L, 1); + + prop->visual_size = v3f(scale_xy.X, scale_xy.Y, scale_z); + } lua_pop(L, 1); lua_getfield(L, -1, "textures"); @@ -331,7 +341,7 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "visual"); lua_pushlstring(L, prop->mesh.c_str(), prop->mesh.size()); lua_setfield(L, -2, "mesh"); - push_v2f(L, prop->visual_size); + push_v3f(L, prop->visual_size); lua_setfield(L, -2, "visual_size"); lua_newtable(L); diff --git a/src/sound.h b/src/sound.h index 81d918c81..6cbd55e8f 100644 --- a/src/sound.h +++ b/src/sound.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#include "util/serialize.h" #include "irrlichttypes_bloated.h" struct SimpleSoundSpec @@ -34,6 +35,26 @@ struct SimpleSoundSpec bool exists() const { return !name.empty(); } + // Take cf_version from ContentFeatures::serialize to + // keep in sync with item definitions + void serialize(std::ostream &os, u8 cf_version) const + { + os << serializeString(name); + writeF32(os, gain); + writeF32(os, pitch); + writeF32(os, fade); + // if (cf_version < ?) + // return; + } + + void deSerialize(std::istream &is, u8 cf_version) + { + name = deSerializeString(is); + gain = readF32(is); + pitch = readF32(is); + fade = readF32(is); + } + std::string name; float gain = 1.0f; float fade = 0.0f; diff --git a/src/tileanimation.cpp b/src/tileanimation.cpp index eaef7f8cb..930fd9473 100644 --- a/src/tileanimation.cpp +++ b/src/tileanimation.cpp @@ -25,11 +25,11 @@ void TileAnimationParams::serialize(std::ostream &os, u8 tiledef_version) const if (type == TAT_VERTICAL_FRAMES) { writeU16(os, vertical_frames.aspect_w); writeU16(os, vertical_frames.aspect_h); - writeF1000(os, vertical_frames.length); + writeF32(os, vertical_frames.length); } else if (type == TAT_SHEET_2D) { writeU8(os, sheet_2d.frames_w); writeU8(os, sheet_2d.frames_h); - writeF1000(os, sheet_2d.frame_length); + writeF32(os, sheet_2d.frame_length); } } @@ -40,11 +40,11 @@ void TileAnimationParams::deSerialize(std::istream &is, u8 tiledef_version) if (type == TAT_VERTICAL_FRAMES) { vertical_frames.aspect_w = readU16(is); vertical_frames.aspect_h = readU16(is); - vertical_frames.length = readF1000(is); + vertical_frames.length = readF32(is); } else if (type == TAT_SHEET_2D) { sheet_2d.frames_w = readU8(is); sheet_2d.frames_h = readU8(is); - sheet_2d.frame_length = readF1000(is); + sheet_2d.frame_length = readF32(is); } } diff --git a/src/tool.cpp b/src/tool.cpp index 568f0af54..becb574b0 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -55,8 +55,8 @@ void ToolGroupCap::fromJson(const Json::Value &json) void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const { - writeU8(os, 3); // protocol_version >= 36 - writeF1000(os, full_punch_interval); + writeU8(os, 4); // protocol_version >= 37 + writeF32(os, full_punch_interval); writeS16(os, max_drop_level); writeU32(os, groupcaps.size()); for (const auto &groupcap : groupcaps) { @@ -68,7 +68,7 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const writeU32(os, cap->times.size()); for (const auto &time : cap->times) { writeS16(os, time.first); - writeF1000(os, time.second); + writeF32(os, time.second); } } @@ -83,10 +83,10 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const void ToolCapabilities::deSerialize(std::istream &is) { int version = readU8(is); - if (version < 3) + if (version < 4) throw SerializationError("unsupported ToolCapabilities version"); - full_punch_interval = readF1000(is); + full_punch_interval = readF32(is); max_drop_level = readS16(is); groupcaps.clear(); u32 groupcaps_size = readU32(is); @@ -98,7 +98,7 @@ void ToolCapabilities::deSerialize(std::istream &is) u32 times_size = readU32(is); for(u32 i = 0; i < times_size; i++) { int level = readS16(is); - float time = readF1000(is); + float time = readF32(is); cap.times[level] = time; } groupcaps[name] = cap; diff --git a/src/unittest/test_serialization.cpp b/src/unittest/test_serialization.cpp index ca4116413..51e28f144 100644 --- a/src/unittest/test_serialization.cpp +++ b/src/unittest/test_serialization.cpp @@ -50,7 +50,7 @@ public: std::wstring teststring2_w; std::string teststring2_w_encoded; - static const u8 test_serialized_data[12 * 13]; + static const u8 test_serialized_data[12 * 13 - 8]; }; static TestSerialization g_test_instance; @@ -316,7 +316,6 @@ void TestSerialization::testStreamRead() UASSERT(readV3S16(is) == v3s16(4207, 604, -30)); UASSERT(readV2S32(is) == v2s32(1920, 1080)); UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855)); - UASSERT(readV2F1000(is) == v2f(500.656f, 350.345f)); UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455"); @@ -361,7 +360,6 @@ void TestSerialization::testStreamWrite() writeV3S16(os, v3s16(4207, 604, -30)); writeV2S32(os, v2s32(1920, 1080)); writeV3S32(os, v3s32(-400, 6400054, 290549855)); - writeV2F1000(os, v2f(500.65661f, 350.34567f)); os << serializeWideString(L"\x02~woof~\x5455"); @@ -403,7 +401,6 @@ void TestSerialization::testVecPut() putV3S16(&buf, v3s16(4207, 604, -30)); putV2S32(&buf, v2s32(1920, 1080)); putV3S32(&buf, v3s32(-400, 6400054, 290549855)); - putV2F1000(&buf, v2f(500.65661f, 350.34567f)); putWideString(&buf, L"\x02~woof~\x5455"); @@ -454,7 +451,6 @@ void TestSerialization::testBufReader() v3s16 v3s16_data; v2s32 v2s32_data; v3s32 v3s32_data; - v2f v2f_data; v3f v3f_data; std::string string_data; std::wstring widestring_data; @@ -481,7 +477,6 @@ void TestSerialization::testBufReader() UASSERT(buf.getV3S16() == v3s16(4207, 604, -30)); UASSERT(buf.getV2S32() == v2s32(1920, 1080)); UASSERT(buf.getV3S32() == v3s32(-400, 6400054, 290549855)); - UASSERT(buf.getV2F1000() == v2f(500.656f, 350.345f)); UASSERT(buf.getWideString() == L"\x02~woof~\x5455"); UASSERT(buf.getV3F1000() == v3f(500, 10024.2f, -192.54f)); UASSERT(buf.getARGB8() == video::SColor(255, 128, 50, 128)); @@ -526,7 +521,6 @@ void TestSerialization::testBufReader() EXCEPTION_CHECK(SerializationError, buf.getV3S16()); EXCEPTION_CHECK(SerializationError, buf.getV2S32()); EXCEPTION_CHECK(SerializationError, buf.getV3S32()); - EXCEPTION_CHECK(SerializationError, buf.getV2F1000()); EXCEPTION_CHECK(SerializationError, buf.getV3F1000()); EXCEPTION_CHECK(SerializationError, buf.getString()); @@ -568,7 +562,6 @@ void TestSerialization::testBufReader() UASSERT(buf.getV3S16NoEx(&v3s16_data)); UASSERT(buf.getV2S32NoEx(&v2s32_data)); UASSERT(buf.getV3S32NoEx(&v3s32_data)); - UASSERT(buf.getV2F1000NoEx(&v2f_data)); UASSERT(buf.getWideStringNoEx(&widestring_data)); UASSERT(buf.getV3F1000NoEx(&v3f_data)); UASSERT(buf.getARGB8NoEx(&scolor_data)); @@ -593,7 +586,6 @@ void TestSerialization::testBufReader() UASSERT(v3s16_data == v3s16(4207, 604, -30)); UASSERT(v2s32_data == v2s32(1920, 1080)); UASSERT(v3s32_data == v3s32(-400, 6400054, 290549855)); - UASSERT(v2f_data == v2f(500.656f, 350.345f)); UASSERT(widestring_data == L"\x02~woof~\x5455"); UASSERT(v3f_data == v3f(500, 10024.2f, -192.54f)); UASSERT(scolor_data == video::SColor(255, 128, 50, 128)); @@ -625,7 +617,6 @@ void TestSerialization::testBufReader() UASSERT(!buf.getV3S16NoEx(&v3s16_data)); UASSERT(!buf.getV2S32NoEx(&v2s32_data)); UASSERT(!buf.getV3S32NoEx(&v3s32_data)); - UASSERT(!buf.getV2F1000NoEx(&v2f_data)); UASSERT(!buf.getV3F1000NoEx(&v3f_data)); UASSERT(!buf.getStringNoEx(&string_data)); @@ -717,7 +708,7 @@ void TestSerialization::testFloatFormat() UASSERT(test_single(i)); } -const u8 TestSerialization::test_serialized_data[12 * 13] = { +const u8 TestSerialization::test_serialized_data[12 * 13 - 8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e, @@ -725,8 +716,8 @@ const u8 TestSerialization::test_serialized_data[12 * 13] = { 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10, 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70, - 0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00, + 0x5f, 0x00, 0x08, 0x00, + 0x02, 0x00, 0x7e, 0x00, 'w', 0x00, 'o', 0x00, 'o', 0x00, 'f', 0x00, // \x02~woof~\x5455 0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff, 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73, diff --git a/src/util/serialize.h b/src/util/serialize.h index 016491a2c..5eb2b5f2e 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -250,29 +250,29 @@ inline v3s32 readV3S32(const u8 *data) return p; } -inline v2f readV2F1000(const u8 *data) -{ - v2f p; - p.X = (float)readF1000(&data[0]); - p.Y = (float)readF1000(&data[4]); - return p; -} - inline v3f readV3F1000(const u8 *data) { v3f p; - p.X = (float)readF1000(&data[0]); - p.Y = (float)readF1000(&data[4]); - p.Z = (float)readF1000(&data[8]); + p.X = readF1000(&data[0]); + p.Y = readF1000(&data[4]); + p.Z = readF1000(&data[8]); + return p; +} + +inline v2f readV2F32(const u8 *data) +{ + v2f p; + p.X = readF32(&data[0]); + p.Y = readF32(&data[4]); return p; } inline v3f readV3F32(const u8 *data) { v3f p; - p.X = (float)readF32(&data[0]); - p.Y = (float)readF32(&data[4]); - p.Z = (float)readF32(&data[8]); + p.X = readF32(&data[0]); + p.Y = readF32(&data[4]); + p.Z = readF32(&data[8]); return p; } @@ -357,12 +357,6 @@ inline void writeV3S32(u8 *data, v3s32 p) writeS32(&data[8], p.Z); } -inline void writeV2F1000(u8 *data, v2f p) -{ - writeF1000(&data[0], p.X); - writeF1000(&data[4], p.Y); -} - inline void writeV3F1000(u8 *data, v3f p) { writeF1000(&data[0], p.X); @@ -370,6 +364,12 @@ inline void writeV3F1000(u8 *data, v3f p) writeF1000(&data[8], p.Z); } +inline void writeV2F32(u8 *data, v2f p) +{ + writeF32(&data[0], p.X); + writeF32(&data[4], p.Y); +} + inline void writeV3F32(u8 *data, v3f p) { writeF32(&data[0], p.X); @@ -411,8 +411,8 @@ MAKE_STREAM_READ_FXN(v2s16, V2S16, 4); MAKE_STREAM_READ_FXN(v3s16, V3S16, 6); MAKE_STREAM_READ_FXN(v2s32, V2S32, 8); MAKE_STREAM_READ_FXN(v3s32, V3S32, 12); -MAKE_STREAM_READ_FXN(v2f, V2F1000, 8); MAKE_STREAM_READ_FXN(v3f, V3F1000, 12); +MAKE_STREAM_READ_FXN(v2f, V2F32, 8); MAKE_STREAM_READ_FXN(v3f, V3F32, 12); MAKE_STREAM_READ_FXN(video::SColor, ARGB8, 4); @@ -430,8 +430,8 @@ MAKE_STREAM_WRITE_FXN(v2s16, V2S16, 4); MAKE_STREAM_WRITE_FXN(v3s16, V3S16, 6); MAKE_STREAM_WRITE_FXN(v2s32, V2S32, 8); MAKE_STREAM_WRITE_FXN(v3s32, V3S32, 12); -MAKE_STREAM_WRITE_FXN(v2f, V2F1000, 8); MAKE_STREAM_WRITE_FXN(v3f, V3F1000, 12); +MAKE_STREAM_WRITE_FXN(v2f, V2F32, 8); MAKE_STREAM_WRITE_FXN(v3f, V3F32, 12); MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4); @@ -527,7 +527,6 @@ public: MAKE_BUFREADER_GETNOEX_FXN(v3s16, V3S16, 6); MAKE_BUFREADER_GETNOEX_FXN(v2s32, V2S32, 8); MAKE_BUFREADER_GETNOEX_FXN(v3s32, V3S32, 12); - MAKE_BUFREADER_GETNOEX_FXN(v2f, V2F1000, 8); MAKE_BUFREADER_GETNOEX_FXN(v3f, V3F1000, 12); MAKE_BUFREADER_GETNOEX_FXN(video::SColor, ARGB8, 4); @@ -549,7 +548,6 @@ public: MAKE_BUFREADER_GET_FXN(v3s16, V3S16); MAKE_BUFREADER_GET_FXN(v2s32, V2S32); MAKE_BUFREADER_GET_FXN(v3s32, V3S32); - MAKE_BUFREADER_GET_FXN(v2f, V2F1000); MAKE_BUFREADER_GET_FXN(v3f, V3F1000); MAKE_BUFREADER_GET_FXN(video::SColor, ARGB8); MAKE_BUFREADER_GET_FXN(std::string, String); @@ -663,12 +661,6 @@ inline void putV3S32(std::vector *dest, v3s32 val) putS32(dest, val.Z); } -inline void putV2F1000(std::vector *dest, v2f val) -{ - putF1000(dest, val.X); - putF1000(dest, val.Y); -} - inline void putV3F1000(std::vector *dest, v3f val) { putF1000(dest, val.X);