From d2803b726594b954a292d2a1574055e30903abd7 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 3 May 2023 10:53:49 -0400 Subject: [PATCH] Allow 'invalid' LevelEvents --- .../mc/protocol/codec/MinecraftCodec.java | 6 +- .../protocol/codec/MinecraftCodecHelper.java | 11 ++- .../data/game/level/event/LevelEvent.java | 83 +---------------- .../data/game/level/event/LevelEventType.java | 88 +++++++++++++++++++ .../game/level/event/UnknownLevelEvent.java | 14 +++ .../level/event/UnknownLevelEventData.java | 13 +++ .../level/ClientboundLevelEventPacket.java | 85 ++++++++++-------- 7 files changed, 175 insertions(+), 125 deletions(-) create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEventType.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEvent.java create mode 100644 src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEventData.java diff --git a/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodec.java b/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodec.java index cbe25e13..92eacae7 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodec.java +++ b/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodec.java @@ -1,7 +1,7 @@ package com.github.steveice10.mc.protocol.codec; import com.github.steveice10.mc.protocol.data.ProtocolState; -import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; +import com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType; import com.github.steveice10.mc.protocol.data.game.level.sound.BuiltinSound; import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundAwardStatsPacket; @@ -185,11 +185,11 @@ import java.util.HashMap; import java.util.Map; public class MinecraftCodec { - private static final Int2ObjectMap LEVEL_EVENTS = new Int2ObjectOpenHashMap<>(); + private static final Int2ObjectMap LEVEL_EVENTS = new Int2ObjectOpenHashMap<>(); private static final Map SOUND_NAMES = new HashMap<>(); static { - for (LevelEvent levelEvent : LevelEvent.values()) { + for (LevelEventType levelEvent : LevelEventType.values()) { LEVEL_EVENTS.put(levelEvent.getId(), levelEvent); } diff --git a/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodecHelper.java b/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodecHelper.java index c6cc5ec3..8d7c851e 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodecHelper.java +++ b/src/main/java/com/github/steveice10/mc/protocol/codec/MinecraftCodecHelper.java @@ -29,6 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType; import com.github.steveice10.mc.protocol.data.game.level.LightUpdateData; import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType; import com.github.steveice10.mc.protocol.data.game.level.event.LevelEvent; +import com.github.steveice10.mc.protocol.data.game.level.event.LevelEventType; +import com.github.steveice10.mc.protocol.data.game.level.event.UnknownLevelEvent; import com.github.steveice10.mc.protocol.data.game.level.particle.BlockParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.DustColorTransitionParticleData; import com.github.steveice10.mc.protocol.data.game.level.particle.DustParticleData; @@ -88,7 +90,7 @@ public class MinecraftCodecHelper extends BasePacketCodecHelper { private static final int POSITION_Y_SHIFT = 0xFFF; private static final int POSITION_WRITE_SHIFT = 0x3FFFFFF; - private final Int2ObjectMap levelEvents; + private final Int2ObjectMap levelEvents; private final Map soundNames; protected CompoundTag registry; @@ -623,7 +625,12 @@ public class MinecraftCodecHelper extends BasePacketCodecHelper { } public LevelEvent readLevelEvent(ByteBuf buf) { - return this.levelEvents.get(buf.readInt()); + int id = buf.readInt(); + LevelEventType type = this.levelEvents.get(id); + if (type != null) { + return type; + } + return new UnknownLevelEvent(id); } public void writeLevelEvent(ByteBuf buf, LevelEvent event) { diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEvent.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEvent.java index 29f54303..378d3c83 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEvent.java +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEvent.java @@ -1,84 +1,5 @@ package com.github.steveice10.mc.protocol.data.game.level.event; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -public enum LevelEvent { - BLOCK_DISPENSER_DISPENSE(1000), - BLOCK_DISPENSER_FAIL(1001), - BLOCK_DISPENSER_LAUNCH(1002), - ENTITY_ENDEREYE_LAUNCH(1003), - ENTITY_FIREWORK_SHOOT(1004), - BLOCK_IRON_DOOR_OPEN(1005), - BLOCK_WOODEN_DOOR_OPEN(1006), - BLOCK_WOODEN_TRAPDOOR_OPEN(1007), - BLOCK_FENCE_GATE_OPEN(1008), - BLOCK_FIRE_EXTINGUISH(1009), - RECORD(1010), - STOP_RECORD(1011), // As of 1.19.4 - ENTITY_GHAST_WARN(1015), - ENTITY_GHAST_SHOOT(1016), - ENTITY_ENDERDRAGON_SHOOT(1017), - ENTITY_BLAZE_SHOOT(1018), - ENTITY_ZOMBIE_ATTACK_DOOR_WOOD(1019), - ENTITY_ZOMBIE_ATTACK_DOOR_IRON(1020), - ENTITY_ZOMBIE_BREAK_DOOR_WOOD(1021), - ENTITY_WITHER_BREAK_BLOCK(1022), - ENTITY_WITHER_SPAWN(1023), // Global level event - ENTITY_WITHER_SHOOT(1024), - ENTITY_BAT_TAKEOFF(1025), - ENTITY_ZOMBIE_INFECT(1026), - ENTITY_ZOMBIE_VILLAGER_CONVERTED(1027), - ENTITY_ENDERDRAGON_DEATH(1028), // Global level event - BLOCK_ANVIL_DESTROY(1029), - BLOCK_ANVIL_USE(1030), - BLOCK_ANVIL_LAND(1031), - BLOCK_PORTAL_TRAVEL(1032), - BLOCK_CHORUS_FLOWER_GROW(1033), - BLOCK_CHORUS_FLOWER_DEATH(1034), - BLOCK_BREWING_STAND_BREW(1035), - BLOCK_IRON_TRAPDOOR_CLOSE(1036), - BLOCK_IRON_TRAPDOOR_OPEN(1037), - BLOCK_END_PORTAL_SPAWN(1038), // Global level event - ENTITY_PHANTOM_BITE(1039), - ENTITY_ZOMBIE_CONVERTED_TO_DROWNED(1040), - ENTITY_HUSK_CONVERTED_TO_ZOMBIE(1041), - BLOCK_GRINDSTONE_USE(1042), - ITEM_BOOK_PAGE_TURN(1043), - BLOCK_SMITHING_TABLE_USE(1044), - POINTED_DRIPSTONE_LAND(1045), - DRIP_LAVA_INTO_CAULDRON(1046), - DRIP_WATER_INTO_CAULDRON(1047), - ENTITY_SKELETON_CONVERTED_TO_STRAY(1048), - - COMPOSTER(1500), - BLOCK_LAVA_EXTINGUISH(1501), - BLOCK_REDSTONE_TORCH_BURNOUT(1502), - BLOCK_END_PORTAL_FRAME_FILL(1503), - DRIPSTONE_DRIP(1504), - BONEMEAL_GROW_WITH_SOUND(1505), - - SMOKE(2000), - BREAK_BLOCK(2001), - BREAK_SPLASH_POTION(2002), - BREAK_EYE_OF_ENDER(2003), - MOB_SPAWN(2004), - BONEMEAL_GROW(2005), - ENDERDRAGON_FIREBALL_EXPLODE(2006), - BREAK_SPLASH_POTION2(2007), // Mojank - EXPLOSION(2008), - EVAPORATE(2009), - - END_GATEWAY_SPAWN(3000), - ENTITY_ENDERDRAGON_GROWL(3001), - ELECTRIC_SPARK(3002), - WAX_ON(3003), - WAX_OFF(3004), - SCRAPE(3005), - SCULK_BLOCK_CHARGE(3006), - SCULK_SHRIEKER_SHRIEK(3007); - - @Getter - private final int id; +public interface LevelEvent { + int getId(); } diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEventType.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEventType.java new file mode 100644 index 00000000..1971208f --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/LevelEventType.java @@ -0,0 +1,88 @@ +package com.github.steveice10.mc.protocol.data.game.level.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum LevelEventType implements LevelEvent { + BLOCK_DISPENSER_DISPENSE(1000), + BLOCK_DISPENSER_FAIL(1001), + BLOCK_DISPENSER_LAUNCH(1002), + ENTITY_ENDEREYE_LAUNCH(1003), + ENTITY_FIREWORK_SHOOT(1004), + BLOCK_IRON_DOOR_OPEN(1005), + BLOCK_WOODEN_DOOR_OPEN(1006), + BLOCK_WOODEN_TRAPDOOR_OPEN(1007), + BLOCK_FENCE_GATE_OPEN(1008), + BLOCK_FIRE_EXTINGUISH(1009), + RECORD(1010), + STOP_RECORD(1011), // As of 1.19.4 + ENTITY_GHAST_WARN(1015), + ENTITY_GHAST_SHOOT(1016), + ENTITY_ENDERDRAGON_SHOOT(1017), + ENTITY_BLAZE_SHOOT(1018), + ENTITY_ZOMBIE_ATTACK_DOOR_WOOD(1019), + ENTITY_ZOMBIE_ATTACK_DOOR_IRON(1020), + ENTITY_ZOMBIE_BREAK_DOOR_WOOD(1021), + ENTITY_WITHER_BREAK_BLOCK(1022), + ENTITY_WITHER_SPAWN(1023), // Global level event + ENTITY_WITHER_SHOOT(1024), + ENTITY_BAT_TAKEOFF(1025), + ENTITY_ZOMBIE_INFECT(1026), + ENTITY_ZOMBIE_VILLAGER_CONVERTED(1027), + ENTITY_ENDERDRAGON_DEATH(1028), // Global level event + BLOCK_ANVIL_DESTROY(1029), + BLOCK_ANVIL_USE(1030), + BLOCK_ANVIL_LAND(1031), + BLOCK_PORTAL_TRAVEL(1032), + BLOCK_CHORUS_FLOWER_GROW(1033), + BLOCK_CHORUS_FLOWER_DEATH(1034), + BLOCK_BREWING_STAND_BREW(1035), + BLOCK_IRON_TRAPDOOR_CLOSE(1036), + BLOCK_IRON_TRAPDOOR_OPEN(1037), + BLOCK_END_PORTAL_SPAWN(1038), // Global level event + ENTITY_PHANTOM_BITE(1039), + ENTITY_ZOMBIE_CONVERTED_TO_DROWNED(1040), + ENTITY_HUSK_CONVERTED_TO_ZOMBIE(1041), + BLOCK_GRINDSTONE_USE(1042), + ITEM_BOOK_PAGE_TURN(1043), + BLOCK_SMITHING_TABLE_USE(1044), + POINTED_DRIPSTONE_LAND(1045), + DRIP_LAVA_INTO_CAULDRON(1046), + DRIP_WATER_INTO_CAULDRON(1047), + ENTITY_SKELETON_CONVERTED_TO_STRAY(1048), + + COMPOSTER(1500), + BLOCK_LAVA_EXTINGUISH(1501), + BLOCK_REDSTONE_TORCH_BURNOUT(1502), + BLOCK_END_PORTAL_FRAME_FILL(1503), + DRIPSTONE_DRIP(1504), + BONEMEAL_GROW_WITH_SOUND(1505), + + SMOKE(2000), + BREAK_BLOCK(2001), + BREAK_SPLASH_POTION(2002), + BREAK_EYE_OF_ENDER(2003), + MOB_SPAWN(2004), + BONEMEAL_GROW(2005), + ENDERDRAGON_FIREBALL_EXPLODE(2006), + BREAK_SPLASH_POTION2(2007), // Mojank + EXPLOSION(2008), + EVAPORATE(2009), + + END_GATEWAY_SPAWN(3000), + ENTITY_ENDERDRAGON_GROWL(3001), + ELECTRIC_SPARK(3002), + WAX_ON(3003), + WAX_OFF(3004), + SCRAPE(3005), + SCULK_BLOCK_CHARGE(3006), + SCULK_SHRIEKER_SHRIEK(3007); + + private final int id; + + @Override + public int getId() { + return id; + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEvent.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEvent.java new file mode 100644 index 00000000..e9bdf6dd --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEvent.java @@ -0,0 +1,14 @@ +package com.github.steveice10.mc.protocol.data.game.level.event; + +public final class UnknownLevelEvent implements LevelEvent { + private final int id; + + public UnknownLevelEvent(int id) { + this.id = id; + } + + @Override + public int getId() { + return id; + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEventData.java b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEventData.java new file mode 100644 index 00000000..a1bda843 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/data/game/level/event/UnknownLevelEventData.java @@ -0,0 +1,13 @@ +package com.github.steveice10.mc.protocol.data.game.level.event; + +public final class UnknownLevelEventData implements LevelEventData { + private final int data; + + public UnknownLevelEventData(int data) { + this.data = data; + } + + public int getData() { + return data; + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelEventPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelEventPacket.java index 922d2a06..55105e8b 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelEventPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundLevelEventPacket.java @@ -11,6 +11,7 @@ import lombok.NonNull; import lombok.With; import org.cloudburstmc.math.vector.Vector3i; +import javax.annotation.Nonnull; import java.io.IOException; @Data @@ -19,53 +20,57 @@ import java.io.IOException; public class ClientboundLevelEventPacket implements MinecraftPacket { private final @NonNull LevelEvent event; private final @NonNull Vector3i position; - private final LevelEventData data; + private final @Nonnull LevelEventData data; private final boolean broadcast; public ClientboundLevelEventPacket(@NonNull LevelEvent event, @NonNull Vector3i position, @NonNull LevelEventData data) { this(event, position, data, false); } - public ClientboundLevelEventPacket(ByteBuf in, MinecraftCodecHelper helper) throws IOException { + public ClientboundLevelEventPacket(ByteBuf in, MinecraftCodecHelper helper) { this.event = helper.readLevelEvent(in); this.position = helper.readPosition(in); int value = in.readInt(); - switch (this.event) { - case BLOCK_FIRE_EXTINGUISH: - this.data = FireExtinguishData.from(value); - break; - case RECORD: - this.data = new RecordEventData(value); - break; - case SMOKE: - this.data = new SmokeEventData(Direction.from(Math.abs(value % 6))); - break; - case BREAK_BLOCK: - this.data = new BreakBlockEventData(value); - break; - case BREAK_SPLASH_POTION: - case BREAK_SPLASH_POTION2: - this.data = new BreakPotionEventData(value); - break; - case BONEMEAL_GROW: - case BONEMEAL_GROW_WITH_SOUND: - this.data = new BonemealGrowEventData(value); - break; - case COMPOSTER: - this.data = value > 0 ? ComposterEventData.FILL_SUCCESS : ComposterEventData.FILL; - break; - case ENDERDRAGON_FIREBALL_EXPLODE: - this.data = value == 1 ? DragonFireballEventData.HAS_SOUND : DragonFireballEventData.NO_SOUND; - break; - case ELECTRIC_SPARK: - this.data = value >= 0 && value < 6 ? new ElectricSparkData(Direction.from(value)) : null; - break; - case SCULK_BLOCK_CHARGE: - this.data = new SculkBlockChargeEventData(value); - break; - default: - this.data = null; - break; + if (this.event instanceof LevelEventType) { + switch ((LevelEventType) this.event) { + case BLOCK_FIRE_EXTINGUISH: + this.data = FireExtinguishData.from(value); + break; + case RECORD: + this.data = new RecordEventData(value); + break; + case SMOKE: + this.data = new SmokeEventData(Direction.from(Math.abs(value % 6))); + break; + case BREAK_BLOCK: + this.data = new BreakBlockEventData(value); + break; + case BREAK_SPLASH_POTION: + case BREAK_SPLASH_POTION2: + this.data = new BreakPotionEventData(value); + break; + case BONEMEAL_GROW: + case BONEMEAL_GROW_WITH_SOUND: + this.data = new BonemealGrowEventData(value); + break; + case COMPOSTER: + this.data = value > 0 ? ComposterEventData.FILL_SUCCESS : ComposterEventData.FILL; + break; + case ENDERDRAGON_FIREBALL_EXPLODE: + this.data = value == 1 ? DragonFireballEventData.HAS_SOUND : DragonFireballEventData.NO_SOUND; + break; + case ELECTRIC_SPARK: + this.data = value >= 0 && value < 6 ? new ElectricSparkData(Direction.from(value)) : null; + break; + case SCULK_BLOCK_CHARGE: + this.data = new SculkBlockChargeEventData(value); + break; + default: + this.data = new UnknownLevelEventData(value); + break; + } + } else { + this.data = new UnknownLevelEventData(value); } this.broadcast = in.readBoolean(); @@ -75,7 +80,7 @@ public class ClientboundLevelEventPacket implements MinecraftPacket { public void serialize(ByteBuf out, MinecraftCodecHelper helper) throws IOException { helper.writeLevelEvent(out, this.event); helper.writePosition(out, this.position); - int value = 0; + int value; if (this.data instanceof FireExtinguishData) { value = ((FireExtinguishData) this.data).ordinal(); } else if (this.data instanceof RecordEventData) { @@ -96,6 +101,8 @@ public class ClientboundLevelEventPacket implements MinecraftPacket { value = ((ElectricSparkData) this.data).getDirection().ordinal(); } else if (this.data instanceof SculkBlockChargeEventData) { value = ((SculkBlockChargeEventData) data).getLevelValue(); + } else { + value = ((UnknownLevelEventData) data).getData(); } out.writeInt(value);