Failure when offering ItemStack custom data

When attempting to modify an ItemStack’s custom data using:
itemStack.get().offer(RustDataKeys.HAMMER_MODE, HammerMode.UPGRADE);
it is unsuccessful.

Mutable data manipulator class

package com.oblivionnetworks.rustmc.api.data.manipulator.mutable;

import com.google.common.base.Objects;
import com.oblivionnetworks.rustmc.api.data.RustDataKeys;
import com.oblivionnetworks.rustmc.api.data.manipulator.immutable.ImmutableBuildingHammerData;
import com.oblivionnetworks.rustmc.api.services.building.HammerMode;
import com.oblivionnetworks.rustmc.api.services.building.StructureTier;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.manipulator.mutable.common.AbstractData;
import org.spongepowered.api.data.merge.MergeFunction;
import org.spongepowered.api.data.value.mutable.Value;

import javax.annotation.Nonnull;
import java.util.Optional;

public class BuildingHammerData extends AbstractData<BuildingHammerData, ImmutableBuildingHammerData> {
    private HammerMode mode;
    private StructureTier upgradeToTier;

    public BuildingHammerData(@Nonnull HammerMode mode, @Nonnull StructureTier upgradeToTier) {
        this.mode = mode;
        this.upgradeToTier = upgradeToTier;
    }

    public Value<HammerMode> mode() {
        return Sponge.getRegistry().getValueFactory().createValue(RustDataKeys.HAMMER_MODE, this.mode);
    }

    public Value<StructureTier> upgradeToTier() {
        return Sponge.getRegistry().getValueFactory().createValue(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this.upgradeToTier);
    }

    @Override
    protected void registerGettersAndSetters() {
        registerFieldGetter(RustDataKeys.HAMMER_MODE, this::getMode);
        registerFieldSetter(RustDataKeys.HAMMER_MODE, this::setMode);
        registerKeyValue(RustDataKeys.HAMMER_MODE, this::mode);

        registerFieldGetter(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this::getUpgradeToTier);
        registerFieldSetter(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this::setUpgradeToTier);
        registerKeyValue(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this::upgradeToTier);
    }

    @Override
    public Optional<BuildingHammerData> fill(DataHolder dataHolder, MergeFunction overlap) {
        BuildingHammerData buildingHammerData = overlap.merge(copy(), from(dataHolder.toContainer()).orElse(null));
        if (buildingHammerData == null) return Optional.empty();
        return Optional.of(buildingHammerData
                .set(RustDataKeys.HAMMER_MODE, this.mode)
                .set(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this.upgradeToTier));
    }

    @Override
    public Optional<BuildingHammerData> from(DataContainer container) {
        if (!container.contains(RustDataKeys.HAMMER_MODE.getQuery(), RustDataKeys.HAMMER_UPGRADE_TO_TIER.getQuery())) {
            return Optional.empty();
        }

        final HammerMode mode = container.getObject(RustDataKeys.HAMMER_MODE.getQuery(), HammerMode.class).get();
        final StructureTier upgradeToTier = container.getObject(RustDataKeys.HAMMER_UPGRADE_TO_TIER.getQuery(), StructureTier.class).get();

        this.mode = mode;
        this.upgradeToTier = upgradeToTier;

        return Optional.of(this);
    }

    @Override
    public BuildingHammerData copy() {
        return new BuildingHammerData(this.mode, this.upgradeToTier);
    }

    @Override
    public ImmutableBuildingHammerData asImmutable() {
        return new ImmutableBuildingHammerData(this.mode, this.upgradeToTier);
    }

    @Override
    public int getContentVersion() {
        return 1;
    }

    @Override
    public DataContainer toContainer() {
        return super.toContainer()
                .set(RustDataKeys.HAMMER_MODE, mode)
                .set(RustDataKeys.HAMMER_UPGRADE_TO_TIER, upgradeToTier);
    }

    @Override
    public String toString() {
        return Objects.toStringHelper(this)
                .add("HammerMode", this.mode)
                .add("UpgradeToTier", this.upgradeToTier)
                .toString();
    }

    public HammerMode getMode() {
        return mode;
    }

    public StructureTier getUpgradeToTier() {
        return upgradeToTier;
    }

    public void setMode(HammerMode mode) {
        this.mode = mode;
    }

    public void setUpgradeToTier(StructureTier upgradeToTier) {
        this.upgradeToTier = upgradeToTier;
    }
}

Immutable data manipulator class

package com.oblivionnetworks.rustmc.api.data.manipulator.immutable;

import com.oblivionnetworks.rustmc.api.data.RustDataKeys;
import com.oblivionnetworks.rustmc.api.data.manipulator.mutable.BuildingHammerData;
import com.oblivionnetworks.rustmc.api.services.building.HammerMode;
import com.oblivionnetworks.rustmc.api.services.building.StructureTier;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.MemoryDataContainer;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.manipulator.immutable.common.AbstractImmutableData;
import org.spongepowered.api.data.value.BaseValue;
import org.spongepowered.api.data.value.immutable.ImmutableValue;

import java.util.Optional;

public class ImmutableBuildingHammerData extends AbstractImmutableData<ImmutableBuildingHammerData, BuildingHammerData> {
    private HammerMode mode;
    private StructureTier upgradeToTier;

    public ImmutableBuildingHammerData(@Nonnull HammerMode mode, @Nonnull StructureTier upgradeToTier) {
        this.mode = mode;
        this.upgradeToTier = upgradeToTier;
    }

    public ImmutableValue<HammerMode> mode() {
        return Sponge.getRegistry().getValueFactory().createValue(RustDataKeys.HAMMER_MODE, this.mode).asImmutable();
    }

    public ImmutableValue<StructureTier> upgradeToTier() {
        return Sponge.getRegistry().getValueFactory().createValue(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this.upgradeToTier).asImmutable();
    }

    @Override
    protected void registerGetters() {
        registerFieldGetter(RustDataKeys.HAMMER_MODE, this::getMode);
        registerKeyValue(RustDataKeys.HAMMER_MODE, this::mode);

        registerFieldGetter(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this::getUpgradeToTier);
        registerKeyValue(RustDataKeys.HAMMER_UPGRADE_TO_TIER, this::upgradeToTier);
    }

    @Override
    public <E> Optional<ImmutableBuildingHammerData> with(Key<? extends BaseValue<E>> key, E value) {
        if (this.supports(key)) {
            return Optional.of(asMutable().set(key, value).asImmutable());
        } else {
            return Optional.empty();
        }
    }

    @Override
    public BuildingHammerData asMutable() {
        return new BuildingHammerData(this.mode, this.upgradeToTier);
    }

    @Override
    public int getContentVersion() {
        return 1;
    }

    @Override
    public DataContainer toContainer() {
        return new MemoryDataContainer()
                .set(RustDataKeys.HAMMER_MODE, mode)
                .set(RustDataKeys.HAMMER_UPGRADE_TO_TIER, upgradeToTier);
    }

    public HammerMode getMode() {
        return mode;
    }

    public StructureTier getUpgradeToTier() {
        return upgradeToTier;
    }
}

Data builder class

package com.oblivionnetworks.rustmc.api.data.builder;

import com.oblivionnetworks.rustmc.api.data.RustDataKeys;
import com.oblivionnetworks.rustmc.api.data.manipulator.immutable.ImmutableBuildingHammerData;
import com.oblivionnetworks.rustmc.api.data.manipulator.mutable.BuildingHammerData;
import com.oblivionnetworks.rustmc.api.services.building.HammerMode;
import com.oblivionnetworks.rustmc.api.services.building.StructureTier;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.manipulator.DataManipulatorBuilder;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.api.data.persistence.InvalidDataException;

import java.util.Optional;

public class BuildingHammerDataBuilder extends AbstractDataBuilder<BuildingHammerData> implements DataManipulatorBuilder<BuildingHammerData, ImmutableBuildingHammerData> {
    public BuildingHammerDataBuilder() {
        super(BuildingHammerData.class, 1);
    }

    @Override
    public BuildingHammerData create() {
        return new BuildingHammerData(HammerMode.INVALID, StructureTier.INVALID);
    }

    @Override
    public Optional<BuildingHammerData> createFrom(DataHolder dataHolder) {
        return Optional.of(dataHolder.get(BuildingHammerData.class).orElse(new BuildingHammerData(HammerMode.INVALID, StructureTier.INVALID)));
    }

    @Override
    public Optional<BuildingHammerData> buildContent(DataView container) throws InvalidDataException {
        if (!container.contains(RustDataKeys.HAMMER_MODE.getQuery(), RustDataKeys.HAMMER_UPGRADE_TO_TIER.getQuery())) {
            return Optional.empty();
        }

        final HammerMode mode = container.getObject(RustDataKeys.HAMMER_MODE.getQuery(), HammerMode.class).get();
        final StructureTier upgradeToTier = container.getObject(RustDataKeys.HAMMER_UPGRADE_TO_TIER.getQuery(), StructureTier.class).get();
        return Optional.of(new BuildingHammerData(mode, upgradeToTier));
    }
}

@gabizou Do you know what the issue might be?

I should also mention, it works the first time but not after that.

Need to offer the manipulator to the item stack first, before offering the key (there’s a big change that I’m working on that will affect a huge amount of the backend of how custom data works.

When I do it like that it says it doesn’t support the key I provided.
java.lang.IllegalArgumentException: This data manipulator doesn't support the following key: Key{Value:Value<HammerMode>, Query: RustBuildingHammerMode}

EDIT: Works when I use my own setters instead of offer()

Call regissterFieldGettersAndSetters in the constructor of the manipulator and the immutable variant (registerFeildGetters).

1 Like