Skip to content
Permalink
Browse files

ContentCAO: Fix broken attachments on join (#8701)

What happened:
1) Object data is received. Client begins to read the data
2) Client initializes all its children (gob_cmd_update_infant)
3) Children try to attach to parent (yet not added)
4) Parent initializes, is added to the environment

And somewhere in between, Irrlicht wrecks up the attachments due to the missing matrix node.

The solution here is to:
1) Use the same structure as ServerActiveObject
2) Attach all children after the parent is really initialized
  • Loading branch information...
SmallJoker committed Jul 29, 2019
1 parent 50052fc commit 4aa9a669cb184b77213e8df82eb20eda5aad9004
@@ -20,8 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once

#include "irr_aabb3d.h"
#include "irr_v3d.h"
#include <string>


enum ActiveObjectType {
ACTIVEOBJECT_TYPE_INVALID = 0,
ACTIVEOBJECT_TYPE_TEST = 1,
@@ -98,6 +100,16 @@ class ActiveObject


virtual bool collideWithObjects() const = 0;


virtual void setAttachment(int parent_id, const std::string &bone, v3f position,
v3f rotation) {}
virtual void getAttachment(int *parent_id, std::string *bone, v3f *position,
v3f *rotation) const {}
virtual void clearChildAttachments() {}
virtual void clearParentAttachment() {}
virtual void addAttachmentChild(int child_id) {}
virtual void removeAttachmentChild(int child_id) {}
protected:
u16 m_id; // 0 is invalid, "no id"
};
@@ -47,8 +47,6 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
m_texturesource(texturesource),
m_client(client)
{
char zero = 0;
memset(attachement_parent_ids, zero, sizeof(attachement_parent_ids));
}

ClientEnvironment::~ClientEnvironment()
@@ -392,7 +390,17 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
<<std::endl;
}

addActiveObject(obj);
u16 new_id = addActiveObject(obj);
// Object initialized:
if ((obj = getActiveObject(new_id))) {
// Final step is to update all children which are already known
// Data provided by GENERIC_CMD_SPAWN_INFANT
const auto &children = obj->getAttachmentChildIds();
for (auto c_id : children) {
if (auto *o = getActiveObject(c_id))
o->updateAttachments();
}
}
}

void ClientEnvironment::processActiveObjectMessage(u16 id, const std::string &data)
@@ -138,8 +138,6 @@ class ClientEnvironment : public Environment
std::vector<PointedThing> &objects
);

u16 attachement_parent_ids[USHRT_MAX + 1];

const std::list<std::string> &getPlayerNames() { return m_player_names; }
void addPlayerName(const std::string &name) { m_player_names.push_back(name); }
void removePlayerName(const std::string &name) { m_player_names.remove(name); }
@@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h"
#include "activeobject.h"
#include <unordered_map>
#include <unordered_set>


class ClientEnvironment;
class ITextureSource;
@@ -51,8 +53,12 @@ class ClientActiveObject : public ActiveObject
virtual scene::ISceneNode *getSceneNode() { return NULL; }
virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() { return NULL; }
virtual bool isLocalPlayer() const {return false;}

virtual ClientActiveObject *getParent() const { return nullptr; };
virtual void setAttachments() {}
virtual const std::unordered_set<int> &getAttachmentChildIds() const
{ static std::unordered_set<int> rv; return rv; }
virtual void updateAttachments() {};

virtual bool doShowSelectionBox(){return true;}

// Step object in time

0 comments on commit 4aa9a66

Please sign in to comment.
You can’t perform that action at this time.