4.7.0 bug with Packet PacketPlayOutEntityDestroy
ItzAmirreza opened this issue ยท 6 comments
Describe the bug
A clear and concise description of what the bug is.
Since I upgraded my plugin to 1.17 (and 4.7.0 relatively), there is a bug with some users having issues with destroy entity packet.
com.comphenix.protocol.reflect.FieldAccessException: No field with type int exists in class PacketPlayOutEntityDestroy.
at com.comphenix.protocol.reflect.StructureModifier.writeInternal(StructureModifier.java:365) ~[?:?]
at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:345) ~[?:?]
at me.deadlight.ezchestshop.Utils.ASHologram.destroy(ASHologram.java:102) ~[?:?]
at me.deadlight.ezchestshop.Listeners.PlayerLookingAtChestShop$1.run(PlayerLookingAtChestShop.java:145) ~[?:?]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:100) ~[patched_1.17.1.jar:git-Purpur-1265]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[patched_1.17.1.jar:git-Purpur-1265]
at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.17.1.jar:git-Purpur-1265]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
at java.lang.Thread.run(Unknown Source) [?:?]
and for another user(1.16.5 user):
https://cdn.discordapp.com/attachments/846870343142473779/864878648158978098/unknown.png
both of the servers above are using v4.7.0 protocollib, and having this problem, but people with v4.6.0 don't have this problem (except 1.17 users that can't use v4.6.0).
I found out how I can fix the problem for each version:
if I use this code:
destroyEntityPacket.getIntegers().write(0, entityID);
ONLY 1.17 users don't have this problem. but 1.17.1 users as you can see above have this error.
Now if I use destroyEntityPacket.getIntegerArrays().write(0, new int[]{entityID});
which puts the list of entities in a array, none of 1.16.x users experience this problem but 1.17 users will have this error in their console:
[15:40:46 WARN]: [EzChestShop] Plugin EzChestShop v1.3.0 generated an exception while executing task 916
com.comphenix.protocol.reflect.FieldAccessException: No field with type [I exists in class PacketPlayOutEntityDestroy.
at com.comphenix.protocol.reflect.StructureModifier.writeInternal(StructureModifier.java:365) ~[?:?]
at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:345) ~[?:?]
at me.deadlight.ezchestshop.Utils.ASHologram.destroy(ASHologram.java:100) ~[?:?]
at me.deadlight.ezchestsh
I hope you can reproduce the problem.
Here is the line that I'm using for fixing the 1.17 users issue, but seems it doesn't work with all versions
https://github.com/ItzAmirreza/EzChestShop/blob/4167896624849fabde2daf2dd6bcc5cd68d82cc7/src/main/java/me/deadlight/ezchestshop/Utils/ASHologram.java#L102
the way to fix is the PacketPlayOutEntityDestroy use org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntList for 1.17.1
You shuld try to get the list with getIntLists() and write your int ids to it
153dd61#diff-e3cd915ab71a0d6279c7965559c993472f6dfcbccf3e9315be155e9c76288d13R390
But this only fixes the problem for 1.17.1 users, what about users with older versions like 1.16.5?
Strange thing is, 1.17 is different from 1.17.1 and 1.17.1 works like versions lower than 1.17.
I assume it's a bug associated with protocol
Use writeSafley instand of write to write only if the field exist, or use an normal if clausel to use the right Methode for the right version.
Its not a bug from protocollib its more like different version of spigot use different methode to work with.
Greetings, I'm having the same problem
Platform: purpur 1.17.1
Protocollib ver: 4.7.0
I have MMOItems dev version 6.6.0 (latest to date) installed, it has a damage indicator. This error kept on spamming my console whenever a player is taking damage:
[01:12:57 ERROR]: Could not pass event EntityDamageByEntityEvent to MMOItems v6.6.0 com.comphenix.protocol.reflect.FieldAccessException: No field with type int exists in class PacketPlayOutEntityDestroy. at com.comphenix.protocol.reflect.StructureModifier.writeInternal(StructureModifier.java:365) ~[?:?] at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:345) ~[?:?] at com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.packet.WrapperPlayServerEntityDestroy.setEntity_1_17(WrapperPlayServerEntityDestroy.java:63) ~[?:?] at com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.PacketHelper.sendDestroyEntitiesPacket(PacketHelper.java:135) ~[?:?] at com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.ProtocolLibHookImpl.sendDestroyEntitiesPacket(ProtocolLibHookImpl.java:218) ~[?:?] at com.gmail.filoghost.holographicdisplays.object.CraftVisibilityManager.sendDestroyPacketIfNear(CraftVisibilityManager.java:172) ~[?:?] at com.gmail.filoghost.holographicdisplays.object.CraftVisibilityManager.hideTo(CraftVisibilityManager.java:106) ~[?:?] at net.Indyuce.mmoitems.comp.holograms.HolographicDisplaysPlugin.displayIndicator(HolographicDisplaysPlugin.java:20) ~[?:?] at net.Indyuce.mmoitems.comp.holograms.HologramSupport.displayIndicator(HologramSupport.java:71) ~[?:?] at net.Indyuce.mmoitems.comp.holograms.HologramSupport$1.a(HologramSupport.java:42) ~[?:?] at com.destroystokyo.paper.event.executor.MethodHandleEventExecutor.execute(MethodHandleEventExecutor.java:40) ~[patched_1.17.1.jar:git-Purpur-1267] at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:624) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.callEvent(CraftEventFactory.java:242) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.callEntityDamageEvent(CraftEventFactory.java:1097) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.handleEntityDamageEvent(CraftEventFactory.java:981) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.handleEntityDamageEvent(CraftEventFactory.java:936) ~[patched_1.17.1.jar:git-Purpur-1267] at org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory.handleLivingEntityDamageEvent(CraftEventFactory.java:1129) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.world.entity.LivingEntity.damageEntity0(LivingEntity.java:2083) ~[?:?] at net.minecraft.world.entity.player.Player.damageEntity0(Player.java:1057) ~[?:?] at net.minecraft.world.entity.LivingEntity.hurt(LivingEntity.java:1374) ~[?:?] at net.minecraft.world.entity.player.Player.hurt(Player.java:964) ~[?:?] at net.minecraft.server.level.ServerPlayer.hurt(ServerPlayer.java:1025) ~[?:?] at net.minecraft.world.entity.Mob.doHurtTarget(Mob.java:1638) ~[?:?] at net.minecraft.world.entity.monster.Zombie.doHurtTarget(Zombie.java:383) ~[?:?] at net.minecraft.world.entity.ai.goal.MeleeAttackGoal.checkAndPerformAttack(MeleeAttackGoal.java:142) ~[?:?] at net.minecraft.world.entity.ai.goal.MeleeAttackGoal.tick(MeleeAttackGoal.java:134) ~[?:?] at net.minecraft.world.entity.ai.goal.ZombieAttackGoal.tick(ZombieAttackGoal.java:28) ~[?:?] at net.minecraft.world.entity.ai.goal.WrappedGoal.tick(WrappedGoal.java:53) ~[?:?] at net.minecraft.world.entity.ai.goal.GoalSelector.tick(GoalSelector.java:151) ~[?:?] at net.minecraft.world.entity.Mob.serverAiStep(Mob.java:877) ~[?:?] at net.minecraft.world.entity.LivingEntity.aiStep(LivingEntity.java:3216) ~[?:?] at net.minecraft.world.entity.Mob.aiStep(Mob.java:658) ~[?:?] at net.minecraft.world.entity.monster.Monster.aiStep(Monster.java:43) ~[?:?] at net.minecraft.world.entity.monster.Zombie.aiStep(Zombie.java:287) ~[?:?] at net.minecraft.world.entity.LivingEntity.tick(LivingEntity.java:2942) ~[?:?] at net.minecraft.world.entity.Mob.tick(Mob.java:420) ~[?:?] at net.minecraft.world.entity.monster.Zombie.tick(Zombie.java:280) ~[?:?] at net.minecraft.server.level.ServerLevel.tickNonPassenger(ServerLevel.java:1190) ~[?:?] at net.minecraft.world.level.Level.guardEntityTick(Level.java:1034) ~[?:?] at net.minecraft.server.level.ServerLevel.lambda$tick$7(ServerLevel.java:807) ~[?:?] at net.minecraft.world.level.entity.EntityTickList.forEach(EntityTickList.java:40) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.server.level.ServerLevel.tick(ServerLevel.java:788) ~[?:?] at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1629) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:492) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1480) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1270) ~[patched_1.17.1.jar:git-Purpur-1267] at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319) ~[patched_1.17.1.jar:git-Purpur-1267] at java.lang.Thread.run(Unknown Source) [?:?]
I've isolated the problem to MMOItems' damage indicator, the error disappears when the indicator is disabled or when protocollib is removed.
hope I contributed to the problem.
Use writeSafley instand of write to write only if the field exist, or use an normal if clausel to use the right Methode for the right version.
Its not a bug from protocollib its more like different version of spigot use different methode to work with.
I'll try, but before testing It would you mind explaining what does writeSafely mean and how does it help to fix the problem? Shall I use an array of entities in the value or just an Entity id? From my perspective of understanding, you mean it's better If I use each of them depending on different versions, but I have no idea which versions and when they appear. As you can see in the above, it even happens for 1.16.5, but for example my server is 1.16.5 too (uses older protocol version) and everything is fine.
Alright just checked wiki.vg/protocol for destroy entity packet, seems now 1.17 has a new packet called destroy entity instead of destroy entities which was previously used by other versions. also it doesn't need arraylist as it only get sent once for each entity and only accepts an entityID. I don't think it's protocol problem now, but it would be better if protocol could implement a feature so we won't have this problem in the future. For people who experience the same thing, you can use my code to fix the problem:
#simply check if the version is 1.17 or not
if (Utils.is1_17) {
destroyEntityPacket.getIntegers().writeSafely(0, eID);
} else {
destroyEntityPacket.getIntegers().writeSafely(0, 1);
destroyEntityPacket.getIntegerArrays().writeSafely(0, new int[]{eID});
}
Regards.
EDIT:
they changed it back to what it was in 1.17.1