// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.protocol;

import java.util.Objects;
import com.hypixel.hytale.protocol.io.ValidationResult;
import java.util.Arrays;
import java.util.Iterator;
import java.util.HashMap;
import com.hypixel.hytale.protocol.io.ProtocolException;
import com.hypixel.hytale.protocol.io.VarInt;
import com.hypixel.hytale.protocol.io.PacketIO;
import io.netty.buffer.ByteBuf;
import java.util.UUID;
import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;

public class ComponentUpdate
{
    public static final int NULLABLE_BIT_FIELD_SIZE = 3;
    public static final int FIXED_BLOCK_SIZE = 159;
    public static final int VARIABLE_FIELD_COUNT = 13;
    public static final int VARIABLE_BLOCK_START = 211;
    public static final int MAX_SIZE = 1677721600;
    @Nonnull
    public ComponentUpdateType type;
    @Nullable
    public Nameplate nameplate;
    @Nullable
    public int[] entityUIComponents;
    @Nullable
    public CombatTextUpdate combatTextUpdate;
    @Nullable
    public Model model;
    @Nullable
    public PlayerSkin skin;
    @Nullable
    public ItemWithAllMetadata item;
    public int blockId;
    public float entityScale;
    @Nullable
    public Equipment equipment;
    @Nullable
    public Map<Integer, EntityStatUpdate[]> entityStatUpdates;
    @Nullable
    public ModelTransform transform;
    @Nullable
    public MovementStates movementStates;
    @Nullable
    public EntityEffectUpdate[] entityEffectUpdates;
    @Nullable
    public Map<InteractionType, Integer> interactions;
    @Nullable
    public ColorLight dynamicLight;
    public int hitboxCollisionConfigIndex;
    public int repulsionConfigIndex;
    @Nonnull
    public UUID predictionId;
    @Nullable
    public int[] soundEventIds;
    @Nullable
    public String interactionHint;
    @Nullable
    public MountedUpdate mounted;
    @Nullable
    public String[] activeAnimations;
    
    public ComponentUpdate() {
        this.type = ComponentUpdateType.Nameplate;
        this.predictionId = new UUID(0L, 0L);
    }
    
    public ComponentUpdate(@Nonnull final ComponentUpdateType type, @Nullable final Nameplate nameplate, @Nullable final int[] entityUIComponents, @Nullable final CombatTextUpdate combatTextUpdate, @Nullable final Model model, @Nullable final PlayerSkin skin, @Nullable final ItemWithAllMetadata item, final int blockId, final float entityScale, @Nullable final Equipment equipment, @Nullable final Map<Integer, EntityStatUpdate[]> entityStatUpdates, @Nullable final ModelTransform transform, @Nullable final MovementStates movementStates, @Nullable final EntityEffectUpdate[] entityEffectUpdates, @Nullable final Map<InteractionType, Integer> interactions, @Nullable final ColorLight dynamicLight, final int hitboxCollisionConfigIndex, final int repulsionConfigIndex, @Nonnull final UUID predictionId, @Nullable final int[] soundEventIds, @Nullable final String interactionHint, @Nullable final MountedUpdate mounted, @Nullable final String[] activeAnimations) {
        this.type = ComponentUpdateType.Nameplate;
        this.predictionId = new UUID(0L, 0L);
        this.type = type;
        this.nameplate = nameplate;
        this.entityUIComponents = entityUIComponents;
        this.combatTextUpdate = combatTextUpdate;
        this.model = model;
        this.skin = skin;
        this.item = item;
        this.blockId = blockId;
        this.entityScale = entityScale;
        this.equipment = equipment;
        this.entityStatUpdates = entityStatUpdates;
        this.transform = transform;
        this.movementStates = movementStates;
        this.entityEffectUpdates = entityEffectUpdates;
        this.interactions = interactions;
        this.dynamicLight = dynamicLight;
        this.hitboxCollisionConfigIndex = hitboxCollisionConfigIndex;
        this.repulsionConfigIndex = repulsionConfigIndex;
        this.predictionId = predictionId;
        this.soundEventIds = soundEventIds;
        this.interactionHint = interactionHint;
        this.mounted = mounted;
        this.activeAnimations = activeAnimations;
    }
    
    public ComponentUpdate(@Nonnull final ComponentUpdate other) {
        this.type = ComponentUpdateType.Nameplate;
        this.predictionId = new UUID(0L, 0L);
        this.type = other.type;
        this.nameplate = other.nameplate;
        this.entityUIComponents = other.entityUIComponents;
        this.combatTextUpdate = other.combatTextUpdate;
        this.model = other.model;
        this.skin = other.skin;
        this.item = other.item;
        this.blockId = other.blockId;
        this.entityScale = other.entityScale;
        this.equipment = other.equipment;
        this.entityStatUpdates = other.entityStatUpdates;
        this.transform = other.transform;
        this.movementStates = other.movementStates;
        this.entityEffectUpdates = other.entityEffectUpdates;
        this.interactions = other.interactions;
        this.dynamicLight = other.dynamicLight;
        this.hitboxCollisionConfigIndex = other.hitboxCollisionConfigIndex;
        this.repulsionConfigIndex = other.repulsionConfigIndex;
        this.predictionId = other.predictionId;
        this.soundEventIds = other.soundEventIds;
        this.interactionHint = other.interactionHint;
        this.mounted = other.mounted;
        this.activeAnimations = other.activeAnimations;
    }
    
    @Nonnull
    public static ComponentUpdate deserialize(@Nonnull final ByteBuf buf, final int offset) {
        final ComponentUpdate obj = new ComponentUpdate();
        final byte[] nullBits = PacketIO.readBytes(buf, offset, 3);
        obj.type = ComponentUpdateType.fromValue(buf.getByte(offset + 3));
        obj.blockId = buf.getIntLE(offset + 4);
        obj.entityScale = buf.getFloatLE(offset + 8);
        if ((nullBits[0] & 0x1) != 0x0) {
            obj.transform = ModelTransform.deserialize(buf, offset + 12);
        }
        if ((nullBits[0] & 0x2) != 0x0) {
            obj.movementStates = MovementStates.deserialize(buf, offset + 61);
        }
        if ((nullBits[0] & 0x4) != 0x0) {
            obj.dynamicLight = ColorLight.deserialize(buf, offset + 83);
        }
        obj.hitboxCollisionConfigIndex = buf.getIntLE(offset + 87);
        obj.repulsionConfigIndex = buf.getIntLE(offset + 91);
        obj.predictionId = PacketIO.readUUID(buf, offset + 95);
        if ((nullBits[0] & 0x8) != 0x0) {
            obj.mounted = MountedUpdate.deserialize(buf, offset + 111);
        }
        if ((nullBits[0] & 0x10) != 0x0) {
            final int varPos0 = offset + 211 + buf.getIntLE(offset + 159);
            obj.nameplate = Nameplate.deserialize(buf, varPos0);
        }
        if ((nullBits[0] & 0x20) != 0x0) {
            final int varPos2 = offset + 211 + buf.getIntLE(offset + 163);
            final int entityUIComponentsCount = VarInt.peek(buf, varPos2);
            if (entityUIComponentsCount < 0) {
                throw ProtocolException.negativeLength("EntityUIComponents", entityUIComponentsCount);
            }
            if (entityUIComponentsCount > 4096000) {
                throw ProtocolException.arrayTooLong("EntityUIComponents", entityUIComponentsCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos2);
            if (varPos2 + varIntLen + entityUIComponentsCount * 4L > buf.readableBytes()) {
                throw ProtocolException.bufferTooSmall("EntityUIComponents", varPos2 + varIntLen + entityUIComponentsCount * 4, buf.readableBytes());
            }
            obj.entityUIComponents = new int[entityUIComponentsCount];
            for (int i = 0; i < entityUIComponentsCount; ++i) {
                obj.entityUIComponents[i] = buf.getIntLE(varPos2 + varIntLen + i * 4);
            }
        }
        if ((nullBits[0] & 0x40) != 0x0) {
            final int varPos3 = offset + 211 + buf.getIntLE(offset + 167);
            obj.combatTextUpdate = CombatTextUpdate.deserialize(buf, varPos3);
        }
        if ((nullBits[0] & 0x80) != 0x0) {
            final int varPos4 = offset + 211 + buf.getIntLE(offset + 171);
            obj.model = Model.deserialize(buf, varPos4);
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int varPos5 = offset + 211 + buf.getIntLE(offset + 175);
            obj.skin = PlayerSkin.deserialize(buf, varPos5);
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int varPos6 = offset + 211 + buf.getIntLE(offset + 179);
            obj.item = ItemWithAllMetadata.deserialize(buf, varPos6);
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int varPos7 = offset + 211 + buf.getIntLE(offset + 183);
            obj.equipment = Equipment.deserialize(buf, varPos7);
        }
        if ((nullBits[1] & 0x8) != 0x0) {
            final int varPos8 = offset + 211 + buf.getIntLE(offset + 187);
            final int entityStatUpdatesCount = VarInt.peek(buf, varPos8);
            if (entityStatUpdatesCount < 0) {
                throw ProtocolException.negativeLength("EntityStatUpdates", entityStatUpdatesCount);
            }
            if (entityStatUpdatesCount > 4096000) {
                throw ProtocolException.dictionaryTooLarge("EntityStatUpdates", entityStatUpdatesCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos8);
            obj.entityStatUpdates = new HashMap<Integer, EntityStatUpdate[]>(entityStatUpdatesCount);
            int dictPos = varPos8 + varIntLen;
            for (int j = 0; j < entityStatUpdatesCount; ++j) {
                final int key = buf.getIntLE(dictPos);
                dictPos += 4;
                final int valLen = VarInt.peek(buf, dictPos);
                if (valLen < 0) {
                    throw ProtocolException.negativeLength("val", valLen);
                }
                if (valLen > 64) {
                    throw ProtocolException.arrayTooLong("val", valLen, 64);
                }
                final int valVarLen = VarInt.length(buf, dictPos);
                if (dictPos + valVarLen + valLen * 13L > buf.readableBytes()) {
                    throw ProtocolException.bufferTooSmall("val", dictPos + valVarLen + valLen * 13, buf.readableBytes());
                }
                dictPos += valVarLen;
                final EntityStatUpdate[] val = new EntityStatUpdate[valLen];
                for (int valIdx = 0; valIdx < valLen; ++valIdx) {
                    val[valIdx] = EntityStatUpdate.deserialize(buf, dictPos);
                    dictPos += EntityStatUpdate.computeBytesConsumed(buf, dictPos);
                }
                if (obj.entityStatUpdates.put(key, val) != null) {
                    throw ProtocolException.duplicateKey("entityStatUpdates", key);
                }
            }
        }
        if ((nullBits[1] & 0x10) != 0x0) {
            final int varPos9 = offset + 211 + buf.getIntLE(offset + 191);
            final int entityEffectUpdatesCount = VarInt.peek(buf, varPos9);
            if (entityEffectUpdatesCount < 0) {
                throw ProtocolException.negativeLength("EntityEffectUpdates", entityEffectUpdatesCount);
            }
            if (entityEffectUpdatesCount > 4096000) {
                throw ProtocolException.arrayTooLong("EntityEffectUpdates", entityEffectUpdatesCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos9);
            if (varPos9 + varIntLen + entityEffectUpdatesCount * 12L > buf.readableBytes()) {
                throw ProtocolException.bufferTooSmall("EntityEffectUpdates", varPos9 + varIntLen + entityEffectUpdatesCount * 12, buf.readableBytes());
            }
            obj.entityEffectUpdates = new EntityEffectUpdate[entityEffectUpdatesCount];
            int elemPos = varPos9 + varIntLen;
            for (int j = 0; j < entityEffectUpdatesCount; ++j) {
                obj.entityEffectUpdates[j] = EntityEffectUpdate.deserialize(buf, elemPos);
                elemPos += EntityEffectUpdate.computeBytesConsumed(buf, elemPos);
            }
        }
        if ((nullBits[1] & 0x20) != 0x0) {
            final int varPos10 = offset + 211 + buf.getIntLE(offset + 195);
            final int interactionsCount = VarInt.peek(buf, varPos10);
            if (interactionsCount < 0) {
                throw ProtocolException.negativeLength("Interactions", interactionsCount);
            }
            if (interactionsCount > 4096000) {
                throw ProtocolException.dictionaryTooLarge("Interactions", interactionsCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos10);
            obj.interactions = new HashMap<InteractionType, Integer>(interactionsCount);
            int dictPos = varPos10 + varIntLen;
            for (int j = 0; j < interactionsCount; ++j) {
                final InteractionType key2 = InteractionType.fromValue(buf.getByte(dictPos));
                ++dictPos;
                final int val2 = buf.getIntLE(dictPos);
                dictPos += 4;
                if (obj.interactions.put(key2, val2) != null) {
                    throw ProtocolException.duplicateKey("interactions", key2);
                }
            }
        }
        if ((nullBits[1] & 0x40) != 0x0) {
            final int varPos11 = offset + 211 + buf.getIntLE(offset + 199);
            final int soundEventIdsCount = VarInt.peek(buf, varPos11);
            if (soundEventIdsCount < 0) {
                throw ProtocolException.negativeLength("SoundEventIds", soundEventIdsCount);
            }
            if (soundEventIdsCount > 4096000) {
                throw ProtocolException.arrayTooLong("SoundEventIds", soundEventIdsCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos11);
            if (varPos11 + varIntLen + soundEventIdsCount * 4L > buf.readableBytes()) {
                throw ProtocolException.bufferTooSmall("SoundEventIds", varPos11 + varIntLen + soundEventIdsCount * 4, buf.readableBytes());
            }
            obj.soundEventIds = new int[soundEventIdsCount];
            for (int i = 0; i < soundEventIdsCount; ++i) {
                obj.soundEventIds[i] = buf.getIntLE(varPos11 + varIntLen + i * 4);
            }
        }
        if ((nullBits[1] & 0x80) != 0x0) {
            final int varPos12 = offset + 211 + buf.getIntLE(offset + 203);
            final int interactionHintLen = VarInt.peek(buf, varPos12);
            if (interactionHintLen < 0) {
                throw ProtocolException.negativeLength("InteractionHint", interactionHintLen);
            }
            if (interactionHintLen > 4096000) {
                throw ProtocolException.stringTooLong("InteractionHint", interactionHintLen, 4096000);
            }
            obj.interactionHint = PacketIO.readVarString(buf, varPos12, PacketIO.UTF8);
        }
        if ((nullBits[2] & 0x1) != 0x0) {
            final int varPos13 = offset + 211 + buf.getIntLE(offset + 207);
            final int activeAnimationsCount = VarInt.peek(buf, varPos13);
            if (activeAnimationsCount < 0) {
                throw ProtocolException.negativeLength("ActiveAnimations", activeAnimationsCount);
            }
            if (activeAnimationsCount > 4096000) {
                throw ProtocolException.arrayTooLong("ActiveAnimations", activeAnimationsCount, 4096000);
            }
            final int varIntLen = VarInt.length(buf, varPos13);
            final int activeAnimationsBitfieldSize = (activeAnimationsCount + 7) / 8;
            final byte[] activeAnimationsBitfield = PacketIO.readBytes(buf, varPos13 + varIntLen, activeAnimationsBitfieldSize);
            obj.activeAnimations = new String[activeAnimationsCount];
            int elemPos2 = varPos13 + varIntLen + activeAnimationsBitfieldSize;
            for (int k = 0; k < activeAnimationsCount; ++k) {
                if ((activeAnimationsBitfield[k / 8] & 1 << k % 8) != 0x0) {
                    final int strLen = VarInt.peek(buf, elemPos2);
                    if (strLen < 0) {
                        throw ProtocolException.negativeLength("activeAnimations[" + k, strLen);
                    }
                    if (strLen > 4096000) {
                        throw ProtocolException.stringTooLong("activeAnimations[" + k, strLen, 4096000);
                    }
                    final int strVarLen = VarInt.length(buf, elemPos2);
                    obj.activeAnimations[k] = PacketIO.readVarString(buf, elemPos2);
                    elemPos2 += strVarLen + strLen;
                }
            }
        }
        return obj;
    }
    
    public static int computeBytesConsumed(@Nonnull final ByteBuf buf, final int offset) {
        final byte[] nullBits = PacketIO.readBytes(buf, offset, 3);
        int maxEnd = 211;
        if ((nullBits[0] & 0x10) != 0x0) {
            final int fieldOffset0 = buf.getIntLE(offset + 159);
            int pos0 = offset + 211 + fieldOffset0;
            pos0 += Nameplate.computeBytesConsumed(buf, pos0);
            if (pos0 - offset > maxEnd) {
                maxEnd = pos0 - offset;
            }
        }
        if ((nullBits[0] & 0x20) != 0x0) {
            final int fieldOffset2 = buf.getIntLE(offset + 163);
            int pos2 = offset + 211 + fieldOffset2;
            final int arrLen = VarInt.peek(buf, pos2);
            pos2 += VarInt.length(buf, pos2) + arrLen * 4;
            if (pos2 - offset > maxEnd) {
                maxEnd = pos2 - offset;
            }
        }
        if ((nullBits[0] & 0x40) != 0x0) {
            final int fieldOffset3 = buf.getIntLE(offset + 167);
            int pos3 = offset + 211 + fieldOffset3;
            pos3 += CombatTextUpdate.computeBytesConsumed(buf, pos3);
            if (pos3 - offset > maxEnd) {
                maxEnd = pos3 - offset;
            }
        }
        if ((nullBits[0] & 0x80) != 0x0) {
            final int fieldOffset4 = buf.getIntLE(offset + 171);
            int pos4 = offset + 211 + fieldOffset4;
            pos4 += Model.computeBytesConsumed(buf, pos4);
            if (pos4 - offset > maxEnd) {
                maxEnd = pos4 - offset;
            }
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int fieldOffset5 = buf.getIntLE(offset + 175);
            int pos5 = offset + 211 + fieldOffset5;
            pos5 += PlayerSkin.computeBytesConsumed(buf, pos5);
            if (pos5 - offset > maxEnd) {
                maxEnd = pos5 - offset;
            }
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int fieldOffset6 = buf.getIntLE(offset + 179);
            int pos6 = offset + 211 + fieldOffset6;
            pos6 += ItemWithAllMetadata.computeBytesConsumed(buf, pos6);
            if (pos6 - offset > maxEnd) {
                maxEnd = pos6 - offset;
            }
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int fieldOffset7 = buf.getIntLE(offset + 183);
            int pos7 = offset + 211 + fieldOffset7;
            pos7 += Equipment.computeBytesConsumed(buf, pos7);
            if (pos7 - offset > maxEnd) {
                maxEnd = pos7 - offset;
            }
        }
        if ((nullBits[1] & 0x8) != 0x0) {
            final int fieldOffset8 = buf.getIntLE(offset + 187);
            int pos8 = offset + 211 + fieldOffset8;
            final int dictLen = VarInt.peek(buf, pos8);
            pos8 += VarInt.length(buf, pos8);
            for (int i = 0; i < dictLen; ++i) {
                pos8 += 4;
                final int al = VarInt.peek(buf, pos8);
                pos8 += VarInt.length(buf, pos8);
                for (int j = 0; j < al; ++j) {
                    pos8 += EntityStatUpdate.computeBytesConsumed(buf, pos8);
                }
            }
            if (pos8 - offset > maxEnd) {
                maxEnd = pos8 - offset;
            }
        }
        if ((nullBits[1] & 0x10) != 0x0) {
            final int fieldOffset9 = buf.getIntLE(offset + 191);
            int pos9 = offset + 211 + fieldOffset9;
            final int arrLen = VarInt.peek(buf, pos9);
            pos9 += VarInt.length(buf, pos9);
            for (int i = 0; i < arrLen; ++i) {
                pos9 += EntityEffectUpdate.computeBytesConsumed(buf, pos9);
            }
            if (pos9 - offset > maxEnd) {
                maxEnd = pos9 - offset;
            }
        }
        if ((nullBits[1] & 0x20) != 0x0) {
            final int fieldOffset10 = buf.getIntLE(offset + 195);
            int pos10 = offset + 211 + fieldOffset10;
            final int dictLen = VarInt.peek(buf, pos10);
            pos10 += VarInt.length(buf, pos10);
            for (int i = 0; i < dictLen; ++i) {
                ++pos10;
                pos10 += 4;
            }
            if (pos10 - offset > maxEnd) {
                maxEnd = pos10 - offset;
            }
        }
        if ((nullBits[1] & 0x40) != 0x0) {
            final int fieldOffset11 = buf.getIntLE(offset + 199);
            int pos11 = offset + 211 + fieldOffset11;
            final int arrLen = VarInt.peek(buf, pos11);
            pos11 += VarInt.length(buf, pos11) + arrLen * 4;
            if (pos11 - offset > maxEnd) {
                maxEnd = pos11 - offset;
            }
        }
        if ((nullBits[1] & 0x80) != 0x0) {
            final int fieldOffset12 = buf.getIntLE(offset + 203);
            int pos12 = offset + 211 + fieldOffset12;
            final int sl = VarInt.peek(buf, pos12);
            pos12 += VarInt.length(buf, pos12) + sl;
            if (pos12 - offset > maxEnd) {
                maxEnd = pos12 - offset;
            }
        }
        if ((nullBits[2] & 0x1) != 0x0) {
            final int fieldOffset13 = buf.getIntLE(offset + 207);
            int pos13 = offset + 211 + fieldOffset13;
            final int arrLen = VarInt.peek(buf, pos13);
            pos13 += VarInt.length(buf, pos13);
            final int bitfieldSize = (arrLen + 7) / 8;
            final byte[] bitfield = PacketIO.readBytes(buf, pos13, bitfieldSize);
            pos13 += bitfieldSize;
            for (int k = 0; k < arrLen; ++k) {
                if ((bitfield[k / 8] & 1 << k % 8) != 0x0) {
                    final int sl2 = VarInt.peek(buf, pos13);
                    pos13 += VarInt.length(buf, pos13) + sl2;
                }
            }
            if (pos13 - offset > maxEnd) {
                maxEnd = pos13 - offset;
            }
        }
        return maxEnd;
    }
    
    public void serialize(@Nonnull final ByteBuf buf) {
        final int startPos = buf.writerIndex();
        final byte[] nullBits = new byte[3];
        if (this.transform != null) {
            final byte[] array = nullBits;
            final int n = 0;
            array[n] |= 0x1;
        }
        if (this.movementStates != null) {
            final byte[] array2 = nullBits;
            final int n2 = 0;
            array2[n2] |= 0x2;
        }
        if (this.dynamicLight != null) {
            final byte[] array3 = nullBits;
            final int n3 = 0;
            array3[n3] |= 0x4;
        }
        if (this.mounted != null) {
            final byte[] array4 = nullBits;
            final int n4 = 0;
            array4[n4] |= 0x8;
        }
        if (this.nameplate != null) {
            final byte[] array5 = nullBits;
            final int n5 = 0;
            array5[n5] |= 0x10;
        }
        if (this.entityUIComponents != null) {
            final byte[] array6 = nullBits;
            final int n6 = 0;
            array6[n6] |= 0x20;
        }
        if (this.combatTextUpdate != null) {
            final byte[] array7 = nullBits;
            final int n7 = 0;
            array7[n7] |= 0x40;
        }
        if (this.model != null) {
            final byte[] array8 = nullBits;
            final int n8 = 0;
            array8[n8] |= (byte)128;
        }
        if (this.skin != null) {
            final byte[] array9 = nullBits;
            final int n9 = 1;
            array9[n9] |= 0x1;
        }
        if (this.item != null) {
            final byte[] array10 = nullBits;
            final int n10 = 1;
            array10[n10] |= 0x2;
        }
        if (this.equipment != null) {
            final byte[] array11 = nullBits;
            final int n11 = 1;
            array11[n11] |= 0x4;
        }
        if (this.entityStatUpdates != null) {
            final byte[] array12 = nullBits;
            final int n12 = 1;
            array12[n12] |= 0x8;
        }
        if (this.entityEffectUpdates != null) {
            final byte[] array13 = nullBits;
            final int n13 = 1;
            array13[n13] |= 0x10;
        }
        if (this.interactions != null) {
            final byte[] array14 = nullBits;
            final int n14 = 1;
            array14[n14] |= 0x20;
        }
        if (this.soundEventIds != null) {
            final byte[] array15 = nullBits;
            final int n15 = 1;
            array15[n15] |= 0x40;
        }
        if (this.interactionHint != null) {
            final byte[] array16 = nullBits;
            final int n16 = 1;
            array16[n16] |= (byte)128;
        }
        if (this.activeAnimations != null) {
            final byte[] array17 = nullBits;
            final int n17 = 2;
            array17[n17] |= 0x1;
        }
        buf.writeBytes(nullBits);
        buf.writeByte(this.type.getValue());
        buf.writeIntLE(this.blockId);
        buf.writeFloatLE(this.entityScale);
        if (this.transform != null) {
            this.transform.serialize(buf);
        }
        else {
            buf.writeZero(49);
        }
        if (this.movementStates != null) {
            this.movementStates.serialize(buf);
        }
        else {
            buf.writeZero(22);
        }
        if (this.dynamicLight != null) {
            this.dynamicLight.serialize(buf);
        }
        else {
            buf.writeZero(4);
        }
        buf.writeIntLE(this.hitboxCollisionConfigIndex);
        buf.writeIntLE(this.repulsionConfigIndex);
        PacketIO.writeUUID(buf, this.predictionId);
        if (this.mounted != null) {
            this.mounted.serialize(buf);
        }
        else {
            buf.writeZero(48);
        }
        final int nameplateOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int entityUIComponentsOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int combatTextUpdateOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int modelOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int skinOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int itemOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int equipmentOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int entityStatUpdatesOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int entityEffectUpdatesOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int interactionsOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int soundEventIdsOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int interactionHintOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int activeAnimationsOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int varBlockStart = buf.writerIndex();
        if (this.nameplate != null) {
            buf.setIntLE(nameplateOffsetSlot, buf.writerIndex() - varBlockStart);
            this.nameplate.serialize(buf);
        }
        else {
            buf.setIntLE(nameplateOffsetSlot, -1);
        }
        if (this.entityUIComponents != null) {
            buf.setIntLE(entityUIComponentsOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.entityUIComponents.length > 4096000) {
                throw ProtocolException.arrayTooLong("EntityUIComponents", this.entityUIComponents.length, 4096000);
            }
            VarInt.write(buf, this.entityUIComponents.length);
            for (final int item : this.entityUIComponents) {
                buf.writeIntLE(item);
            }
        }
        else {
            buf.setIntLE(entityUIComponentsOffsetSlot, -1);
        }
        if (this.combatTextUpdate != null) {
            buf.setIntLE(combatTextUpdateOffsetSlot, buf.writerIndex() - varBlockStart);
            this.combatTextUpdate.serialize(buf);
        }
        else {
            buf.setIntLE(combatTextUpdateOffsetSlot, -1);
        }
        if (this.model != null) {
            buf.setIntLE(modelOffsetSlot, buf.writerIndex() - varBlockStart);
            this.model.serialize(buf);
        }
        else {
            buf.setIntLE(modelOffsetSlot, -1);
        }
        if (this.skin != null) {
            buf.setIntLE(skinOffsetSlot, buf.writerIndex() - varBlockStart);
            this.skin.serialize(buf);
        }
        else {
            buf.setIntLE(skinOffsetSlot, -1);
        }
        if (this.item != null) {
            buf.setIntLE(itemOffsetSlot, buf.writerIndex() - varBlockStart);
            this.item.serialize(buf);
        }
        else {
            buf.setIntLE(itemOffsetSlot, -1);
        }
        if (this.equipment != null) {
            buf.setIntLE(equipmentOffsetSlot, buf.writerIndex() - varBlockStart);
            this.equipment.serialize(buf);
        }
        else {
            buf.setIntLE(equipmentOffsetSlot, -1);
        }
        if (this.entityStatUpdates != null) {
            buf.setIntLE(entityStatUpdatesOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.entityStatUpdates.size() > 4096000) {
                throw ProtocolException.dictionaryTooLarge("EntityStatUpdates", this.entityStatUpdates.size(), 4096000);
            }
            VarInt.write(buf, this.entityStatUpdates.size());
            for (final Map.Entry<Integer, EntityStatUpdate[]> e : this.entityStatUpdates.entrySet()) {
                buf.writeIntLE(e.getKey());
                VarInt.write(buf, e.getValue().length);
                for (final EntityStatUpdate arrItem : e.getValue()) {
                    arrItem.serialize(buf);
                }
            }
        }
        else {
            buf.setIntLE(entityStatUpdatesOffsetSlot, -1);
        }
        if (this.entityEffectUpdates != null) {
            buf.setIntLE(entityEffectUpdatesOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.entityEffectUpdates.length > 4096000) {
                throw ProtocolException.arrayTooLong("EntityEffectUpdates", this.entityEffectUpdates.length, 4096000);
            }
            VarInt.write(buf, this.entityEffectUpdates.length);
            for (final EntityEffectUpdate item2 : this.entityEffectUpdates) {
                item2.serialize(buf);
            }
        }
        else {
            buf.setIntLE(entityEffectUpdatesOffsetSlot, -1);
        }
        if (this.interactions != null) {
            buf.setIntLE(interactionsOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.interactions.size() > 4096000) {
                throw ProtocolException.dictionaryTooLarge("Interactions", this.interactions.size(), 4096000);
            }
            VarInt.write(buf, this.interactions.size());
            for (final Map.Entry<InteractionType, Integer> e2 : this.interactions.entrySet()) {
                buf.writeByte(e2.getKey().getValue());
                buf.writeIntLE(e2.getValue());
            }
        }
        else {
            buf.setIntLE(interactionsOffsetSlot, -1);
        }
        if (this.soundEventIds != null) {
            buf.setIntLE(soundEventIdsOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.soundEventIds.length > 4096000) {
                throw ProtocolException.arrayTooLong("SoundEventIds", this.soundEventIds.length, 4096000);
            }
            VarInt.write(buf, this.soundEventIds.length);
            for (final int item : this.soundEventIds) {
                buf.writeIntLE(item);
            }
        }
        else {
            buf.setIntLE(soundEventIdsOffsetSlot, -1);
        }
        if (this.interactionHint != null) {
            buf.setIntLE(interactionHintOffsetSlot, buf.writerIndex() - varBlockStart);
            PacketIO.writeVarString(buf, this.interactionHint, 4096000);
        }
        else {
            buf.setIntLE(interactionHintOffsetSlot, -1);
        }
        if (this.activeAnimations != null) {
            buf.setIntLE(activeAnimationsOffsetSlot, buf.writerIndex() - varBlockStart);
            if (this.activeAnimations.length > 4096000) {
                throw ProtocolException.arrayTooLong("ActiveAnimations", this.activeAnimations.length, 4096000);
            }
            VarInt.write(buf, this.activeAnimations.length);
            final int activeAnimationsBitfieldSize = (this.activeAnimations.length + 7) / 8;
            final byte[] activeAnimationsBitfield = new byte[activeAnimationsBitfieldSize];
            for (int i = 0; i < this.activeAnimations.length; ++i) {
                if (this.activeAnimations[i] != null) {
                    final byte[] array19 = activeAnimationsBitfield;
                    final int n19 = i / 8;
                    array19[n19] |= (byte)(1 << i % 8);
                }
            }
            buf.writeBytes(activeAnimationsBitfield);
            for (int i = 0; i < this.activeAnimations.length; ++i) {
                if (this.activeAnimations[i] != null) {
                    PacketIO.writeVarString(buf, this.activeAnimations[i], 4096000);
                }
            }
        }
        else {
            buf.setIntLE(activeAnimationsOffsetSlot, -1);
        }
    }
    
    public int computeSize() {
        int size = 211;
        if (this.nameplate != null) {
            size += this.nameplate.computeSize();
        }
        if (this.entityUIComponents != null) {
            size += VarInt.size(this.entityUIComponents.length) + this.entityUIComponents.length * 4;
        }
        if (this.combatTextUpdate != null) {
            size += this.combatTextUpdate.computeSize();
        }
        if (this.model != null) {
            size += this.model.computeSize();
        }
        if (this.skin != null) {
            size += this.skin.computeSize();
        }
        if (this.item != null) {
            size += this.item.computeSize();
        }
        if (this.equipment != null) {
            size += this.equipment.computeSize();
        }
        if (this.entityStatUpdates != null) {
            int entityStatUpdatesSize = 0;
            for (final Map.Entry<Integer, EntityStatUpdate[]> kvp : this.entityStatUpdates.entrySet()) {
                entityStatUpdatesSize += 4 + VarInt.size(kvp.getValue().length) + Arrays.stream(kvp.getValue()).mapToInt(inner -> inner.computeSize()).sum();
            }
            size += VarInt.size(this.entityStatUpdates.size()) + entityStatUpdatesSize;
        }
        if (this.entityEffectUpdates != null) {
            int entityEffectUpdatesSize = 0;
            for (final EntityEffectUpdate elem : this.entityEffectUpdates) {
                entityEffectUpdatesSize += elem.computeSize();
            }
            size += VarInt.size(this.entityEffectUpdates.length) + entityEffectUpdatesSize;
        }
        if (this.interactions != null) {
            size += VarInt.size(this.interactions.size()) + this.interactions.size() * 5;
        }
        if (this.soundEventIds != null) {
            size += VarInt.size(this.soundEventIds.length) + this.soundEventIds.length * 4;
        }
        if (this.interactionHint != null) {
            size += PacketIO.stringSize(this.interactionHint);
        }
        if (this.activeAnimations != null) {
            int activeAnimationsSize = 0;
            for (final String elem2 : this.activeAnimations) {
                if (elem2 != null) {
                    activeAnimationsSize += PacketIO.stringSize(elem2);
                }
            }
            size += VarInt.size(this.activeAnimations.length) + (this.activeAnimations.length + 7) / 8 + activeAnimationsSize;
        }
        return size;
    }
    
    public static ValidationResult validateStructure(@Nonnull final ByteBuf buffer, final int offset) {
        if (buffer.readableBytes() - offset < 211) {
            return ValidationResult.error("Buffer too small: expected at least 211 bytes");
        }
        final byte[] nullBits = PacketIO.readBytes(buffer, offset, 3);
        if ((nullBits[0] & 0x10) != 0x0) {
            final int nameplateOffset = buffer.getIntLE(offset + 159);
            if (nameplateOffset < 0) {
                return ValidationResult.error("Invalid offset for Nameplate");
            }
            int pos = offset + 211 + nameplateOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Nameplate");
            }
            final ValidationResult nameplateResult = Nameplate.validateStructure(buffer, pos);
            if (!nameplateResult.isValid()) {
                return ValidationResult.error("Invalid Nameplate: " + nameplateResult.error());
            }
            pos += Nameplate.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[0] & 0x20) != 0x0) {
            final int entityUIComponentsOffset = buffer.getIntLE(offset + 163);
            if (entityUIComponentsOffset < 0) {
                return ValidationResult.error("Invalid offset for EntityUIComponents");
            }
            int pos = offset + 211 + entityUIComponentsOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for EntityUIComponents");
            }
            final int entityUIComponentsCount = VarInt.peek(buffer, pos);
            if (entityUIComponentsCount < 0) {
                return ValidationResult.error("Invalid array count for EntityUIComponents");
            }
            if (entityUIComponentsCount > 4096000) {
                return ValidationResult.error("EntityUIComponents exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            pos += entityUIComponentsCount * 4;
            if (pos > buffer.writerIndex()) {
                return ValidationResult.error("Buffer overflow reading EntityUIComponents");
            }
        }
        if ((nullBits[0] & 0x40) != 0x0) {
            final int combatTextUpdateOffset = buffer.getIntLE(offset + 167);
            if (combatTextUpdateOffset < 0) {
                return ValidationResult.error("Invalid offset for CombatTextUpdate");
            }
            int pos = offset + 211 + combatTextUpdateOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for CombatTextUpdate");
            }
            final ValidationResult combatTextUpdateResult = CombatTextUpdate.validateStructure(buffer, pos);
            if (!combatTextUpdateResult.isValid()) {
                return ValidationResult.error("Invalid CombatTextUpdate: " + combatTextUpdateResult.error());
            }
            pos += CombatTextUpdate.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[0] & 0x80) != 0x0) {
            final int modelOffset = buffer.getIntLE(offset + 171);
            if (modelOffset < 0) {
                return ValidationResult.error("Invalid offset for Model");
            }
            int pos = offset + 211 + modelOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Model");
            }
            final ValidationResult modelResult = Model.validateStructure(buffer, pos);
            if (!modelResult.isValid()) {
                return ValidationResult.error("Invalid Model: " + modelResult.error());
            }
            pos += Model.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int skinOffset = buffer.getIntLE(offset + 175);
            if (skinOffset < 0) {
                return ValidationResult.error("Invalid offset for Skin");
            }
            int pos = offset + 211 + skinOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Skin");
            }
            final ValidationResult skinResult = PlayerSkin.validateStructure(buffer, pos);
            if (!skinResult.isValid()) {
                return ValidationResult.error("Invalid Skin: " + skinResult.error());
            }
            pos += PlayerSkin.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int itemOffset = buffer.getIntLE(offset + 179);
            if (itemOffset < 0) {
                return ValidationResult.error("Invalid offset for Item");
            }
            int pos = offset + 211 + itemOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Item");
            }
            final ValidationResult itemResult = ItemWithAllMetadata.validateStructure(buffer, pos);
            if (!itemResult.isValid()) {
                return ValidationResult.error("Invalid Item: " + itemResult.error());
            }
            pos += ItemWithAllMetadata.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int equipmentOffset = buffer.getIntLE(offset + 183);
            if (equipmentOffset < 0) {
                return ValidationResult.error("Invalid offset for Equipment");
            }
            int pos = offset + 211 + equipmentOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Equipment");
            }
            final ValidationResult equipmentResult = Equipment.validateStructure(buffer, pos);
            if (!equipmentResult.isValid()) {
                return ValidationResult.error("Invalid Equipment: " + equipmentResult.error());
            }
            pos += Equipment.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x8) != 0x0) {
            final int entityStatUpdatesOffset = buffer.getIntLE(offset + 187);
            if (entityStatUpdatesOffset < 0) {
                return ValidationResult.error("Invalid offset for EntityStatUpdates");
            }
            int pos = offset + 211 + entityStatUpdatesOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for EntityStatUpdates");
            }
            final int entityStatUpdatesCount = VarInt.peek(buffer, pos);
            if (entityStatUpdatesCount < 0) {
                return ValidationResult.error("Invalid dictionary count for EntityStatUpdates");
            }
            if (entityStatUpdatesCount > 4096000) {
                return ValidationResult.error("EntityStatUpdates exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            for (int i = 0; i < entityStatUpdatesCount; ++i) {
                pos += 4;
                if (pos > buffer.writerIndex()) {
                    return ValidationResult.error("Buffer overflow reading key");
                }
                final int valueArrCount = VarInt.peek(buffer, pos);
                if (valueArrCount < 0) {
                    return ValidationResult.error("Invalid array count for value");
                }
                pos += VarInt.length(buffer, pos);
                for (int valueArrIdx = 0; valueArrIdx < valueArrCount; ++valueArrIdx) {
                    pos += EntityStatUpdate.computeBytesConsumed(buffer, pos);
                }
            }
        }
        if ((nullBits[1] & 0x10) != 0x0) {
            final int entityEffectUpdatesOffset = buffer.getIntLE(offset + 191);
            if (entityEffectUpdatesOffset < 0) {
                return ValidationResult.error("Invalid offset for EntityEffectUpdates");
            }
            int pos = offset + 211 + entityEffectUpdatesOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for EntityEffectUpdates");
            }
            final int entityEffectUpdatesCount = VarInt.peek(buffer, pos);
            if (entityEffectUpdatesCount < 0) {
                return ValidationResult.error("Invalid array count for EntityEffectUpdates");
            }
            if (entityEffectUpdatesCount > 4096000) {
                return ValidationResult.error("EntityEffectUpdates exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            for (int i = 0; i < entityEffectUpdatesCount; ++i) {
                final ValidationResult structResult = EntityEffectUpdate.validateStructure(buffer, pos);
                if (!structResult.isValid()) {
                    return ValidationResult.error("Invalid EntityEffectUpdate in EntityEffectUpdates[" + i + "]: " + structResult.error());
                }
                pos += EntityEffectUpdate.computeBytesConsumed(buffer, pos);
            }
        }
        if ((nullBits[1] & 0x20) != 0x0) {
            final int interactionsOffset = buffer.getIntLE(offset + 195);
            if (interactionsOffset < 0) {
                return ValidationResult.error("Invalid offset for Interactions");
            }
            int pos = offset + 211 + interactionsOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for Interactions");
            }
            final int interactionsCount = VarInt.peek(buffer, pos);
            if (interactionsCount < 0) {
                return ValidationResult.error("Invalid dictionary count for Interactions");
            }
            if (interactionsCount > 4096000) {
                return ValidationResult.error("Interactions exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            for (int i = 0; i < interactionsCount; ++i) {
                ++pos;
                pos += 4;
                if (pos > buffer.writerIndex()) {
                    return ValidationResult.error("Buffer overflow reading value");
                }
            }
        }
        if ((nullBits[1] & 0x40) != 0x0) {
            final int soundEventIdsOffset = buffer.getIntLE(offset + 199);
            if (soundEventIdsOffset < 0) {
                return ValidationResult.error("Invalid offset for SoundEventIds");
            }
            int pos = offset + 211 + soundEventIdsOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for SoundEventIds");
            }
            final int soundEventIdsCount = VarInt.peek(buffer, pos);
            if (soundEventIdsCount < 0) {
                return ValidationResult.error("Invalid array count for SoundEventIds");
            }
            if (soundEventIdsCount > 4096000) {
                return ValidationResult.error("SoundEventIds exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            pos += soundEventIdsCount * 4;
            if (pos > buffer.writerIndex()) {
                return ValidationResult.error("Buffer overflow reading SoundEventIds");
            }
        }
        if ((nullBits[1] & 0x80) != 0x0) {
            final int interactionHintOffset = buffer.getIntLE(offset + 203);
            if (interactionHintOffset < 0) {
                return ValidationResult.error("Invalid offset for InteractionHint");
            }
            int pos = offset + 211 + interactionHintOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for InteractionHint");
            }
            final int interactionHintLen = VarInt.peek(buffer, pos);
            if (interactionHintLen < 0) {
                return ValidationResult.error("Invalid string length for InteractionHint");
            }
            if (interactionHintLen > 4096000) {
                return ValidationResult.error("InteractionHint exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            pos += interactionHintLen;
            if (pos > buffer.writerIndex()) {
                return ValidationResult.error("Buffer overflow reading InteractionHint");
            }
        }
        if ((nullBits[2] & 0x1) != 0x0) {
            final int activeAnimationsOffset = buffer.getIntLE(offset + 207);
            if (activeAnimationsOffset < 0) {
                return ValidationResult.error("Invalid offset for ActiveAnimations");
            }
            int pos = offset + 211 + activeAnimationsOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for ActiveAnimations");
            }
            final int activeAnimationsCount = VarInt.peek(buffer, pos);
            if (activeAnimationsCount < 0) {
                return ValidationResult.error("Invalid array count for ActiveAnimations");
            }
            if (activeAnimationsCount > 4096000) {
                return ValidationResult.error("ActiveAnimations exceeds max length 4096000");
            }
            pos += VarInt.length(buffer, pos);
            for (int i = 0; i < activeAnimationsCount; ++i) {
                final int strLen = VarInt.peek(buffer, pos);
                if (strLen < 0) {
                    return ValidationResult.error("Invalid string length in ActiveAnimations");
                }
                pos += VarInt.length(buffer, pos);
                pos += strLen;
                if (pos > buffer.writerIndex()) {
                    return ValidationResult.error("Buffer overflow reading string in ActiveAnimations");
                }
            }
        }
        return ValidationResult.OK;
    }
    
    public ComponentUpdate clone() {
        final ComponentUpdate copy = new ComponentUpdate();
        copy.type = this.type;
        copy.nameplate = ((this.nameplate != null) ? this.nameplate.clone() : null);
        copy.entityUIComponents = (int[])((this.entityUIComponents != null) ? Arrays.copyOf(this.entityUIComponents, this.entityUIComponents.length) : null);
        copy.combatTextUpdate = ((this.combatTextUpdate != null) ? this.combatTextUpdate.clone() : null);
        copy.model = ((this.model != null) ? this.model.clone() : null);
        copy.skin = ((this.skin != null) ? this.skin.clone() : null);
        copy.item = ((this.item != null) ? this.item.clone() : null);
        copy.blockId = this.blockId;
        copy.entityScale = this.entityScale;
        copy.equipment = ((this.equipment != null) ? this.equipment.clone() : null);
        Map.Entry<Integer, EntityStatUpdate[]> e = null;
        if (this.entityStatUpdates != null) {
            final Map<Integer, EntityStatUpdate[]> m = new HashMap<Integer, EntityStatUpdate[]>();
            final Iterator<Map.Entry<Integer, EntityStatUpdate[]>> iterator = this.entityStatUpdates.entrySet().iterator();
            while (iterator.hasNext()) {
                e = iterator.next();
                m.put(e.getKey(), Arrays.stream(e.getValue()).map(x -> x.clone()).toArray(EntityStatUpdate[]::new));
            }
            copy.entityStatUpdates = m;
        }
        copy.transform = ((this.transform != null) ? this.transform.clone() : null);
        copy.movementStates = ((this.movementStates != null) ? this.movementStates.clone() : null);
        copy.entityEffectUpdates = (EntityEffectUpdate[])((this.entityEffectUpdates != null) ? ((EntityEffectUpdate[])Arrays.stream(this.entityEffectUpdates).map(e -> e.clone()).toArray(EntityEffectUpdate[]::new)) : null);
        copy.interactions = ((this.interactions != null) ? new HashMap<InteractionType, Integer>(this.interactions) : null);
        copy.dynamicLight = ((this.dynamicLight != null) ? this.dynamicLight.clone() : null);
        copy.hitboxCollisionConfigIndex = this.hitboxCollisionConfigIndex;
        copy.repulsionConfigIndex = this.repulsionConfigIndex;
        copy.predictionId = this.predictionId;
        copy.soundEventIds = (int[])((this.soundEventIds != null) ? Arrays.copyOf(this.soundEventIds, this.soundEventIds.length) : null);
        copy.interactionHint = this.interactionHint;
        copy.mounted = ((this.mounted != null) ? this.mounted.clone() : null);
        copy.activeAnimations = (String[])((this.activeAnimations != null) ? ((String[])Arrays.copyOf(this.activeAnimations, this.activeAnimations.length)) : null);
        return copy;
    }
    
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof final ComponentUpdate other) {
            return Objects.equals(this.type, other.type) && Objects.equals(this.nameplate, other.nameplate) && Arrays.equals(this.entityUIComponents, other.entityUIComponents) && Objects.equals(this.combatTextUpdate, other.combatTextUpdate) && Objects.equals(this.model, other.model) && Objects.equals(this.skin, other.skin) && Objects.equals(this.item, other.item) && this.blockId == other.blockId && this.entityScale == other.entityScale && Objects.equals(this.equipment, other.equipment) && Objects.equals(this.entityStatUpdates, other.entityStatUpdates) && Objects.equals(this.transform, other.transform) && Objects.equals(this.movementStates, other.movementStates) && Arrays.equals(this.entityEffectUpdates, other.entityEffectUpdates) && Objects.equals(this.interactions, other.interactions) && Objects.equals(this.dynamicLight, other.dynamicLight) && this.hitboxCollisionConfigIndex == other.hitboxCollisionConfigIndex && this.repulsionConfigIndex == other.repulsionConfigIndex && Objects.equals(this.predictionId, other.predictionId) && Arrays.equals(this.soundEventIds, other.soundEventIds) && Objects.equals(this.interactionHint, other.interactionHint) && Objects.equals(this.mounted, other.mounted) && Arrays.equals(this.activeAnimations, other.activeAnimations);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        int result = 1;
        result = 31 * result + Objects.hashCode(this.type);
        result = 31 * result + Objects.hashCode(this.nameplate);
        result = 31 * result + Arrays.hashCode(this.entityUIComponents);
        result = 31 * result + Objects.hashCode(this.combatTextUpdate);
        result = 31 * result + Objects.hashCode(this.model);
        result = 31 * result + Objects.hashCode(this.skin);
        result = 31 * result + Objects.hashCode(this.item);
        result = 31 * result + Integer.hashCode(this.blockId);
        result = 31 * result + Float.hashCode(this.entityScale);
        result = 31 * result + Objects.hashCode(this.equipment);
        result = 31 * result + Objects.hashCode(this.entityStatUpdates);
        result = 31 * result + Objects.hashCode(this.transform);
        result = 31 * result + Objects.hashCode(this.movementStates);
        result = 31 * result + Arrays.hashCode(this.entityEffectUpdates);
        result = 31 * result + Objects.hashCode(this.interactions);
        result = 31 * result + Objects.hashCode(this.dynamicLight);
        result = 31 * result + Integer.hashCode(this.hitboxCollisionConfigIndex);
        result = 31 * result + Integer.hashCode(this.repulsionConfigIndex);
        result = 31 * result + Objects.hashCode(this.predictionId);
        result = 31 * result + Arrays.hashCode(this.soundEventIds);
        result = 31 * result + Objects.hashCode(this.interactionHint);
        result = 31 * result + Objects.hashCode(this.mounted);
        result = 31 * result + Arrays.hashCode(this.activeAnimations);
        return result;
    }
}
