Mojira Archive
MC-90198

Applying effect with amplifier higher than 127 before current potion effect ends causes timer to stay at 0:00

The bug

Applying the same effect you already have but with an amplifier higher than 127 causes the timer to reach 0:00 and remain like this but you still have the potion effect.

How to reproduce

  1. Type the command
    /effect give @s minecraft:strength 10
    
  2. Before the timer of the effect reaches 0:00, type the command
    /effect give @s minecraft:strength 30 128
    

    → The effect's timer should remain at 0:00, but you would still have the effect

Code analysis

The following is based on a decompiled version of Minecraft 1.9 using MCP 9.24 beta.

This is a valid report because the method net.minecraft.client.network.NetHandlerPlayClient.handleEntityEffect(SPacketEntityEffect) is not reading the amplifier correctly. The packet stores the amplifier as unsigned byte (0 to 255), however the client reads it as signed byte (-128 to 127). Because of this the client thinks the amplifier is lower and does not extend the duration of the effect. The effect remains however as the client does not receive a SPacketRemoveEntityEffect packet, because for the server, the potion duration was extended.

public void handleEntityEffect(SPacketEntityEffect packetIn)
{
    PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.gameController);
    Entity entity = this.clientWorldController.getEntityByID(packetIn.getEntityId());

    if (entity instanceof EntityLivingBase)
    {
        Potion potion = Potion.getPotionById(packetIn.getEffectId());

        if (potion != null)
        {
            // Replaced this
            //PotionEffect potioneffect = new PotionEffect(potion, packetIn.getDuration(), packetIn.getAmplifier(), packetIn.func_186984_g(), packetIn.func_179707_f());
            PotionEffect potioneffect = new PotionEffect(potion, packetIn.getDuration(), Byte.toUnsignedInt(packetIn.getAmplifier()), packetIn.func_186984_g(), packetIn.func_179707_f());
            
            potioneffect.setPotionDurationMax(packetIn.func_149429_c());
            ((EntityLivingBase)entity).addPotionEffect(potioneffect);
        }
    }
}