Sponge: PotionEffect Retrieval Bug

Created on 29 Mar 2017  路  7Comments  路  Source: SpongePowered/Sponge

Sponge API: 6.0.0-20170323.180311-60
Sponge Forge Build: spongeforge-1.11.2-2227-6.0.0-BETA-2244
Forge Build: forge-1.11.2-13.20.0.2227-universal
Java Version: 1.8.0_121-b13

I've seem to have found a bug, which simon816 has confirmed on the forums, with the with DataSerializable in regards to PotiotionEffects.

Here is the original post:

I have the following code, which saves a player's potion effects:

public static void saveOriginalPotionEffects(List<PotionEffect> potionEffects, String arenaName, String userName) throws ObjectMappingException {

    int i = 1;

    for(PotionEffect potionEffect: potionEffects){

        UnversalConfigs.getConfig(ArenaConfig).getNode("Arena", arenaName, "Contestants", userName, "Potion Effects","Effect "+i).setValue(TypeToken.of(PotionEffect.class),potionEffect);

        UnversalConfigs.saveConfig(ArenaConfig);

        i++;
    }
}

I have no issue with the code above, but when I try to retrieve the data with the code below, I receive a Could not translate DataSerializable of type: org.spongepowered.api.effect.potion.PotionEffect error. This might be a programmer end error, but I coudn't get any further after troubleshooting the issue to line PotionEffect potionEffect = node.getNode("Effect "+i).getValue(TypeToken.of(PotionEffect.class));Any help would be greatly appreciated. Thanks!

public static List<PotionEffect> fetchOriginalPotionEffects(String arenaName, String userName) throws ObjectMappingException{

    List<PotionEffect> potionEffects = Lists.newArrayList();

    CommentedConfigurationNode node = UnversalConfigs.getConfig(ArenaConfig).getNode("Arena", arenaName, "Contestants", userName, "Potion Effects");

    int NOPE = getNumOfPotionEffects(arenaName,userName);

    for(int i = 1; i<= NOPE;i++){

        PotionEffect potionEffect = node.getNode("Effect "+i).getValue(TypeToken.of(PotionEffect.class));

        potionEffects.add(potionEffect);

    }

    return potionEffects;
}

simon816's bug replication code:

try {
    PotionEffect effect = PotionEffect.of(PotionEffectTypes.JUMP_BOOST, 1, 10);
    SimpleCommentedConfigurationNode node = SimpleCommentedConfigurationNode.root();
    node.getNode("test").setValue(TypeToken.of(PotionEffect.class), effect);
    PotionEffect effect2 = node.getNode("test").getValue(TypeToken.of(PotionEffect.class));
} catch (ObjectMappingException e) {
    e.printStackTrace();
}
pr pending data bug

All 7 comments

I think I accidentally managed to find the core issue.

When trying to to get a PotionEffect from a DataContainer with this code:

PotionEffect effect = PotionEffect.of(PotionEffectTypes.ABSORPTION, 0, 100);
PotionEffect.builder().build(effect.toContainer());

I get this error:

[17:11:12 ERROR] [STDERR]: org.spongepowered.api.data.persistence.InvalidDataException: Could not deserialize something correctly, likely due to bad type data.
[17:11:12 ERROR] [STDERR]:      at org.spongepowered.api.data.persistence.AbstractDataBuilder.build(AbstractDataBuilder.java:89)
[17:11:12 ERROR] [STDERR]:      at test.code.Main.main(Main.java:2)
[17:11:13 ERROR] [STDERR]: Caused by: org.spongepowered.api.data.persistence.InvalidDataException: The container has an invalid potion type name: effect.absorption
[17:11:13 ERROR] [STDERR]:      at org.spongepowered.common.effect.potion.SpongePotionBuilder.buildContent(SpongePotionBuilder.java:75)
[17:11:13 ERROR] [STDERR]:      at org.spongepowered.api.data.persistence.AbstractDataBuilder.build(AbstractDataBuilder.java:87)
[17:11:13 ERROR] [STDERR]:      ... 2 more

(Stacktrace shortened and simplified)

Not sure what format SpongePotionBuilder expects but it's not effect.absorbtion.

If so, that's great! Thank you for taking the time to test this :D

As I said I accidentally stumbled over it. I was trying to bypass the issue that container.getSerializableList(POTION_EFFECTS, PotionEffect.class) did always return Optional.empty() and resorted to getting it as a DataView list and using streams to convert it to PotionEffects. Where I called PotionEffect.builder().build(potionContainer) and it crashed.

Bumping up report.

I'd like to point out, that in SF 1.12.2-2586-7.1.0-BETA-2900 the following code still returns Optional.empty()

DataContainer container = DataContainer.createNew(SafetyMode.ALL_DATA_CLONED);
container.set("potions", player.get(Keys.POTION_EFFECTS).orElse(Collections.emptyList()));
container.getSerializableList("potions", PotionEffect.class); // = Optional.empty()

While the container contains all potion data!

Updated code:

DataContainer container = DataContainer.createNew(DataView.SafetyMode.ALL_DATA_CLONED);
DataQuery pot = DataQuery.of("PotionType");
container.set(pot, player.get(Keys.POTION_EFFECTS).orElse(Collections.emptyList()));
container.getSerializableList(pot, PotionEffect.class);
Was this page helpful?
0 / 5 - 0 ratings