Skip to content

Commit

Permalink
ContentCAO: Fix broken attachments on join (#8701)
Browse files Browse the repository at this point in the history
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 4aa9a66
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 117 deletions.
12 changes: 12 additions & 0 deletions src/activeobject.h
Expand Up @@ -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,
Expand Down Expand Up @@ -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"
};
14 changes: 11 additions & 3 deletions src/client/clientenvironment.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions src/client/clientenvironment.h
Expand Up @@ -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); }
Expand Down
8 changes: 7 additions & 1 deletion src/client/clientobject.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4aa9a66

Please sign in to comment.