#include "UpdateAttributesPacket.h" #include #include "PacketListener.h" #include "java/InputOutputStream/DataInputStream.h" #include "java/InputOutputStream/DataOutputStream.h" #include "minecraft/world/entity/ai/attributes/Attribute.h" #include "minecraft/world/entity/ai/attributes/AttributeInstance.h" #include "minecraft/world/entity/ai/attributes/AttributeModifier.h" UpdateAttributesPacket::UpdateAttributesPacket() { entityId = 0; } UpdateAttributesPacket::UpdateAttributesPacket( int entityId, std::unordered_set* values) { this->entityId = entityId; for (auto it = values->begin(); it != values->end(); ++it) { AttributeInstance* value = *it; std::unordered_set mods; value->getModifiers(mods); attributes.insert(new AttributeSnapshot(value->getAttribute()->getId(), value->getBaseValue(), &mods)); } } UpdateAttributesPacket::~UpdateAttributesPacket() { // Delete modifiers - these are always copies, either on construction or on // read for (auto it = attributes.begin(); it != attributes.end(); ++it) { delete (*it); } } void UpdateAttributesPacket::read(DataInputStream* dis) { entityId = dis->readInt(); int attributeCount = dis->readInt(); for (int i = 0; i < attributeCount; i++) { eATTRIBUTE_ID id = static_cast(dis->readShort()); double base = dis->readDouble(); std::unordered_set modifiers = std::unordered_set(); int modifierCount = dis->readShort(); for (int j = 0; j < modifierCount; j++) { eMODIFIER_ID id = static_cast(dis->readInt()); double amount = dis->readDouble(); uint8_t operation = dis->readByte(); modifiers.insert(new AttributeModifier( id, /*"Unknown synced attribute modifier",*/ amount, operation)); } attributes.insert(new AttributeSnapshot(id, base, &modifiers)); // modifiers is copied in AttributeSnapshot ctor so delete contents for (auto it = modifiers.begin(); it != modifiers.end(); ++it) { delete *it; } } } void UpdateAttributesPacket::write(DataOutputStream* dos) { dos->writeInt(entityId); dos->writeInt(attributes.size()); for (auto it = attributes.begin(); it != attributes.end(); ++it) { AttributeSnapshot* attribute = (*it); std::unordered_set* modifiers = attribute->getModifiers(); dos->writeShort(attribute->getId()); dos->writeDouble(attribute->getBase()); dos->writeShort(modifiers->size()); for (auto it2 = modifiers->begin(); it2 != modifiers->end(); ++it2) { AttributeModifier* modifier = (*it2); dos->writeInt(modifier->getId()); dos->writeDouble(modifier->getAmount()); dos->writeByte(modifier->getOperation()); } } } void UpdateAttributesPacket::handle(PacketListener* listener) { listener->handleUpdateAttributes(shared_from_this()); } int UpdateAttributesPacket::getEstimatedSize() { return 4 + 4 + attributes.size() * (8 + 8 + 8); } int UpdateAttributesPacket::getEntityId() { return entityId; } std::unordered_set UpdateAttributesPacket::getValues() { return attributes; } UpdateAttributesPacket::AttributeSnapshot::AttributeSnapshot( eATTRIBUTE_ID id, double base, std::unordered_set* modifiers) { this->id = id; this->base = base; for (auto it = modifiers->begin(); it != modifiers->end(); ++it) { this->modifiers.insert(new AttributeModifier( (*it)->getId(), (*it)->getAmount(), (*it)->getOperation())); } } UpdateAttributesPacket::AttributeSnapshot::~AttributeSnapshot() { for (auto it = modifiers.begin(); it != modifiers.end(); ++it) { delete (*it); } } eATTRIBUTE_ID UpdateAttributesPacket::AttributeSnapshot::getId() { return id; } double UpdateAttributesPacket::AttributeSnapshot::getBase() { return base; } std::unordered_set* UpdateAttributesPacket::AttributeSnapshot::getModifiers() { return &modifiers; }