]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Prevent attached models from disappearing during parent reload (#4128)
authorFoghrye4 <foghrye4@gmail.com>
Sat, 8 Oct 2016 12:51:25 +0000 (16:51 +0400)
committerNer'zhul <nerzhul@users.noreply.github.com>
Sat, 8 Oct 2016 12:51:25 +0000 (14:51 +0200)
src/content_cao.cpp
src/content_sao.cpp
src/content_sao.h
src/genericobject.cpp
src/genericobject.h
src/script/lua_api/l_object.cpp
src/serverobject.h

index 33dae68224ba5e71d1af39386016365cbe2192a9..207a630d7102ec824eb1c5bfd0d3cb1751913215 100644 (file)
@@ -1567,8 +1567,7 @@ void GenericCAO::processMessage(const std::string &data)
        std::istringstream is(data, std::ios::binary);
        // command
        u8 cmd = readU8(is);
-       if(cmd == GENERIC_CMD_SET_PROPERTIES)
-       {
+       if (cmd == GENERIC_CMD_SET_PROPERTIES) {
                m_prop = gob_read_set_properties(is);
 
                m_selection_box = m_prop.collisionbox;
@@ -1587,9 +1586,7 @@ void GenericCAO::processMessage(const std::string &data)
                        m_prop.nametag = m_name;
 
                expireVisuals();
-       }
-       else if(cmd == GENERIC_CMD_UPDATE_POSITION)
-       {
+       } else if (cmd == GENERIC_CMD_UPDATE_POSITION) {
                // Not sent by the server if this object is an attachment.
                // We might however get here if the server notices the object being detached before the client.
                m_position = readV3F1000(is);
@@ -1619,12 +1616,10 @@ void GenericCAO::processMessage(const std::string &data)
                        pos_translator.init(m_position);
                }
                updateNodePos();
-       }
-       else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) {
+       } else if (cmd == GENERIC_CMD_SET_TEXTURE_MOD) {
                std::string mod = deSerializeString(is);
                updateTextures(mod);
-       }
-       else if(cmd == GENERIC_CMD_SET_SPRITE) {
+       } else if (cmd == GENERIC_CMD_SET_SPRITE) {
                v2s16 p = readV2S16(is);
                int num_frames = readU16(is);
                float framelength = readF1000(is);
@@ -1636,8 +1631,7 @@ void GenericCAO::processMessage(const std::string &data)
                m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
 
                updateTexturePos();
-       }
-       else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) {
+       } else if (cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) {
                float override_speed = readF1000(is);
                float override_jump = readF1000(is);
                float override_gravity = readF1000(is);
@@ -1655,8 +1649,7 @@ void GenericCAO::processMessage(const std::string &data)
                        player->physics_override_sneak = sneak;
                        player->physics_override_sneak_glitch = sneak_glitch;
                }
-       }
-       else if(cmd == GENERIC_CMD_SET_ANIMATION) {
+       } else if (cmd == GENERIC_CMD_SET_ANIMATION) {
                // TODO: change frames send as v2s32 value
                v2f range = readV2F1000(is);
                if (!m_is_local_player) {
@@ -1690,8 +1683,7 @@ void GenericCAO::processMessage(const std::string &data)
                                        updateAnimation();
                        }
                }
-       }
-       else if(cmd == GENERIC_CMD_SET_BONE_POSITION) {
+       } else if (cmd == GENERIC_CMD_SET_BONE_POSITION) {
                std::string bone = deSerializeString(is);
                v3f position = readV3F1000(is);
                v3f rotation = readV3F1000(is);
@@ -1724,8 +1716,7 @@ void GenericCAO::processMessage(const std::string &data)
                }
 
                updateAttachments();
-       }
-       else if(cmd == GENERIC_CMD_PUNCHED) {
+       } else if (cmd == GENERIC_CMD_PUNCHED) {
                /*s16 damage =*/ readS16(is);
                s16 result_hp = readS16(is);
 
@@ -1753,8 +1744,7 @@ void GenericCAO::processMessage(const std::string &data)
                                updateTextures("^[brighten");
                        }
                }
-       }
-       else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) {
+       } else if (cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) {
                m_armor_groups.clear();
                int armor_groups_size = readU16(is);
                for(int i=0; i<armor_groups_size; i++)
@@ -1770,6 +1760,19 @@ void GenericCAO::processMessage(const std::string &data)
                if (m_nametag != NULL) {
                        m_nametag->nametag_color = m_prop.nametag_color;
                }
+       } else if (cmd == GENERIC_CMD_SPAWN_INFANT) {
+               u16 child_id = readU16(is);
+               u8 type = readU8(is);
+
+               if (GenericCAO *childobj = m_env->getGenericCAO(child_id)) {
+                       childobj->initialize(deSerializeLongString(is));
+               } else {
+                       m_env->addActiveObject(child_id, type, deSerializeLongString(is));
+               }
+       } else {
+               warningstream << FUNCTION_NAME
+                       << ": unknown command or outdated client \""
+                       << cmd << std::endl;
        }
 }
 
index 2317cbdfe1a0a3076dd6342f4055a35508093271..1664f59931068b794d4d3068c4c84526708ef6ec 100644 (file)
@@ -380,7 +380,7 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
                writeF1000(os, m_yaw);
                writeS16(os, m_hp);
 
-               writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
+               writeU8(os, 4 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here
                os<<serializeLongString(getPropertyPacket()); // message 1
                os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
                os<<serializeLongString(gob_cmd_update_animation(
@@ -391,6 +391,12 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
                                        (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
                }
                os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
+               for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin(); 
+                               (ii != m_attachment_child_ids.end()); ++ii) {
+                       if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) {
+                               os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version)));
+                       }
+               }
        }
        else
        {
@@ -618,7 +624,7 @@ void LuaEntitySAO::removeAttachmentChild(int child_id)
        m_attachment_child_ids.erase(child_id);
 }
 
-std::set<int> LuaEntitySAO::getAttachmentChildIds()
+UNORDERED_SET<int> LuaEntitySAO::getAttachmentChildIds()
 {
        return m_attachment_child_ids;
 }
@@ -860,7 +866,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
                writeF1000(os, m_player->getYaw());
                writeS16(os, getHP());
 
-               writeU8(os, 6 + m_bone_position.size()); // number of messages stuffed in here
+               writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here
                os<<serializeLongString(getPropertyPacket()); // message 1
                os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
                os<<serializeLongString(gob_cmd_update_animation(
@@ -874,6 +880,12 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
                                m_physics_override_jump, m_physics_override_gravity, m_physics_override_sneak,
                                m_physics_override_sneak_glitch)); // 5
                os << serializeLongString(gob_cmd_update_nametag_attributes(m_prop.nametag_color)); // 6 (GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only.
+               for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin(); 
+                               ii != m_attachment_child_ids.end(); ++ii) {
+                       if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) {
+                               os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version)));
+                       }
+               }
        }
        else
        {
@@ -1266,7 +1278,7 @@ void PlayerSAO::removeAttachmentChild(int child_id)
        m_attachment_child_ids.erase(child_id);
 }
 
-std::set<int> PlayerSAO::getAttachmentChildIds()
+UNORDERED_SET<int> PlayerSAO::getAttachmentChildIds()
 {
        return m_attachment_child_ids;
 }
index c97db4922788c1d0a57f6714f920b1bc1579ce9f..341ebb5da51489b0364508c892988c924739c697 100644 (file)
@@ -67,7 +67,7 @@ class LuaEntitySAO : public ServerActiveObject
        void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation);
        void addAttachmentChild(int child_id);
        void removeAttachmentChild(int child_id);
-       std::set<int> getAttachmentChildIds();
+       UNORDERED_SET<int> getAttachmentChildIds();
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
        /* LuaEntitySAO-specific */
@@ -116,7 +116,7 @@ class LuaEntitySAO : public ServerActiveObject
        bool m_bone_position_sent;
 
        int m_attachment_parent_id;
-       std::set<int> m_attachment_child_ids;
+       UNORDERED_SET<int> m_attachment_child_ids;
        std::string m_attachment_bone;
        v3f m_attachment_position;
        v3f m_attachment_rotation;
@@ -210,7 +210,7 @@ class PlayerSAO : public ServerActiveObject
        void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation);
        void addAttachmentChild(int child_id);
        void removeAttachmentChild(int child_id);
-       std::set<int> getAttachmentChildIds();
+       UNORDERED_SET<int> getAttachmentChildIds();
        ObjectProperties* accessObjectProperties();
        void notifyObjectPropertiesModified();
 
@@ -320,7 +320,7 @@ class PlayerSAO : public ServerActiveObject
        bool m_bone_position_sent;
 
        int m_attachment_parent_id;
-       std::set<int> m_attachment_child_ids;
+       UNORDERED_SET<int> m_attachment_child_ids;
        std::string m_attachment_bone;
        v3f m_attachment_position;
        v3f m_attachment_rotation;
index 368cae1ff8b18d56264e69ca4b42c045e9812b6b..c4660cf44ff4e78b71ce4a99c2639a2c5a6cd46d 100644 (file)
@@ -182,3 +182,15 @@ std::string gob_cmd_update_nametag_attributes(video::SColor color)
        writeARGB8(os, color);
        return os.str();
 }
+
+std::string gob_cmd_update_infant(u16 id, u8 type, std::string client_initialization_data)
+{
+       std::ostringstream os(std::ios::binary);
+       // command 
+       writeU8(os, GENERIC_CMD_SPAWN_INFANT);
+       // parameters
+       writeU16(os, id);
+       writeU8(os, type);
+       os<<serializeLongString(client_initialization_data);
+       return os.str();
+}
index b92570831475025bb973fded7dc216ff05182a71..48e71db756204511d685159baec5e16b215f2b66 100644 (file)
@@ -35,7 +35,8 @@ enum GenericCMD {
        GENERIC_CMD_SET_BONE_POSITION,
        GENERIC_CMD_ATTACH_TO,
        GENERIC_CMD_SET_PHYSICS_OVERRIDE,
-       GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES
+       GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES,
+       GENERIC_CMD_SPAWN_INFANT
 };
 
 #include "object_properties.h"
@@ -77,5 +78,7 @@ std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f posit
 
 std::string gob_cmd_update_nametag_attributes(video::SColor color);
 
+std::string gob_cmd_update_infant(u16 id, u8 type, std::string client_initialization_data);
+
 #endif
 
index 4e1a1c1598c37bdb52a079c4600fecdd6e218446..34e175ad0b10e586bfafd469140bdccc1eb4adc5 100644 (file)
@@ -137,8 +137,8 @@ int ObjectRef::l_remove(lua_State *L)
        if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
                return 0;
 
-       std::set<int> child_ids = co->getAttachmentChildIds();
-       std::set<int>::iterator it;
+       UNORDERED_SET<int> child_ids = co->getAttachmentChildIds();
+       UNORDERED_SET<int>::iterator it;
        for (it = child_ids.begin(); it != child_ids.end(); ++it) {
                ServerActiveObject *child = env->getActiveObject(*it);
                child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
index 597eb63a8180be8bf76fd176a212eb16e6132606..9f8d5403c9eaeca7b8cce9cfdeefaba15919056c 100644 (file)
@@ -167,8 +167,8 @@ class ServerActiveObject : public ActiveObject
        {}
        virtual void removeAttachmentChild(int child_id)
        {}
-       virtual std::set<int> getAttachmentChildIds()
-       { return std::set<int>(); }
+       virtual UNORDERED_SET<int> getAttachmentChildIds()
+       { return UNORDERED_SET<int>(); }
        virtual ObjectProperties* accessObjectProperties()
        { return NULL; }
        virtual void notifyObjectPropertiesModified()