Allow 'invalid' LevelEvents

This commit is contained in:
Camotoy 2023-05-03 10:53:49 -04:00
parent 3176d9b81a
commit d2803b7265
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
7 changed files with 175 additions and 125 deletions

View file

@ -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<LevelEvent> LEVEL_EVENTS = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<LevelEventType> LEVEL_EVENTS = new Int2ObjectOpenHashMap<>();
private static final Map<String, BuiltinSound> SOUND_NAMES = new HashMap<>();
static {
for (LevelEvent levelEvent : LevelEvent.values()) {
for (LevelEventType levelEvent : LevelEventType.values()) {
LEVEL_EVENTS.put(levelEvent.getId(), levelEvent);
}

View file

@ -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<LevelEvent> levelEvents;
private final Int2ObjectMap<LevelEventType> levelEvents;
private final Map<String, BuiltinSound> 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) {

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);