diff --git a/protocol/build.gradle.kts b/protocol/build.gradle.kts index 3ef6c1901..9a5044bf1 100644 --- a/protocol/build.gradle.kts +++ b/protocol/build.gradle.kts @@ -5,7 +5,7 @@ plugins { jacoco } -version = "1.21.7-SNAPSHOT" +version = "1.21.9-SNAPSHOT" description = "MCProtocolLib is a simple library for communicating with Minecraft clients and servers." dependencies { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java index 3d56b94ad..61ec4515a 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java @@ -155,7 +155,7 @@ public void packetReceived(Session session, Packet packet) { session.send(new ServerboundKeepAlivePacket(keepAlivePacket.getPingId())); } else if (packet instanceof ClientboundFinishConfigurationPacket) { session.switchInboundState(() -> protocol.setInboundState(ProtocolState.GAME)); - session.send(new ServerboundFinishConfigurationPacket()); + session.send(ServerboundFinishConfigurationPacket.INSTANCE); session.switchOutboundState(() -> protocol.setOutboundState(ProtocolState.GAME)); } else if (packet instanceof ClientboundSelectKnownPacks) { if (session.getFlag(MinecraftConstants.SEND_BLANK_KNOWN_PACKS_RESPONSE, true)) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodec.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodec.java index ee83c2ec9..71fc1349a 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodec.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftCodec.java @@ -19,12 +19,14 @@ import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundKeepAlivePacket; import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundPongPacket; import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundResourcePackPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundCodeOfConductPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundResetChatPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundSelectKnownPacks; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundShowDialogConfigurationPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundUpdateEnabledFeaturesPacket; +import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundAcceptCodeOfConductPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundFinishConfigurationPacket; import org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound.ServerboundSelectKnownPacks; import org.geysermc.mcprotocollib.protocol.packet.cookie.clientbound.ClientboundCookieRequestPacket; @@ -37,10 +39,11 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCooldownPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCustomChatCompletionsPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDebugSamplePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug.ClientboundDebugSamplePacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDeleteChatPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundDisguisedChatPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundGameTestHighlightPosPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundPlayerInfoRemovePacket; @@ -63,6 +66,10 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundTickingStepPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug.ClientboundDebugBlockValuePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug.ClientboundDebugChunkValuePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug.ClientboundDebugEntityValuePacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug.ClientboundDebugEventPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAddEntityPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundAnimatePacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundDamageEventPacket; @@ -160,7 +167,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientTickEndPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundCommandSuggestionPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundConfigurationAcknowledgedPacket; -import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundDebugSampleSubscriptionPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundDebugSubscriptionRequestPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundLockDifficultyPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundPlayerLoadedPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; @@ -224,8 +231,8 @@ public class MinecraftCodec { public static final PacketCodec CODEC = PacketCodec.builder() - .protocolVersion(772) - .minecraftVersion("1.21.7") + .protocolVersion(773) + .minecraftVersion("1.21.9") .state(ProtocolState.HANDSHAKE, MinecraftPacketRegistry.builder() .registerServerboundPacket(ClientIntentionPacket.class, ClientIntentionPacket::new) ) @@ -266,15 +273,17 @@ public class MinecraftCodec { .registerClientboundPacket(ClientboundServerLinksPacket.class, ClientboundServerLinksPacket::new) .registerClientboundPacket(ClientboundClearDialogPacket.class, ClientboundClearDialogPacket::new) .registerClientboundPacket(ClientboundShowDialogConfigurationPacket.class, ClientboundShowDialogConfigurationPacket::new) + .registerClientboundPacket(ClientboundCodeOfConductPacket.class, ClientboundCodeOfConductPacket::new) .registerServerboundPacket(ServerboundClientInformationPacket.class, ServerboundClientInformationPacket::new) .registerServerboundPacket(ServerboundCookieResponsePacket.class, ServerboundCookieResponsePacket::new) .registerServerboundPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new) - .registerServerboundPacket(ServerboundFinishConfigurationPacket.class, ServerboundFinishConfigurationPacket::new) + .registerServerboundPacket(ServerboundFinishConfigurationPacket.class, (buf) -> ServerboundFinishConfigurationPacket.INSTANCE) .registerServerboundPacket(ServerboundKeepAlivePacket.class, ServerboundKeepAlivePacket::new) .registerServerboundPacket(ServerboundPongPacket.class, ServerboundPongPacket::new) .registerServerboundPacket(ServerboundResourcePackPacket.class, ServerboundResourcePackPacket::new) .registerServerboundPacket(ServerboundSelectKnownPacks.class, ServerboundSelectKnownPacks::new) .registerServerboundPacket(ServerboundCustomClickActionPacket.class, ServerboundCustomClickActionPacket::new) + .registerServerboundPacket(ServerboundAcceptCodeOfConductPacket.class, (buf) -> ServerboundAcceptCodeOfConductPacket.INSTANCE) ).state(ProtocolState.GAME, MinecraftPacketRegistry.builder() .registerClientboundPacket(ClientboundDelimiterPacket.class, ClientboundDelimiterPacket::new) .registerClientboundPacket(ClientboundAddEntityPacket.class, ClientboundAddEntityPacket::new) @@ -302,6 +311,10 @@ public class MinecraftCodec { .registerClientboundPacket(ClientboundCustomChatCompletionsPacket.class, ClientboundCustomChatCompletionsPacket::new) .registerClientboundPacket(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket::new) .registerClientboundPacket(ClientboundDamageEventPacket.class, ClientboundDamageEventPacket::new) + .registerClientboundPacket(ClientboundDebugBlockValuePacket.class, ClientboundDebugBlockValuePacket::new) + .registerClientboundPacket(ClientboundDebugChunkValuePacket.class, ClientboundDebugChunkValuePacket::new) + .registerClientboundPacket(ClientboundDebugEntityValuePacket.class, ClientboundDebugEntityValuePacket::new) + .registerClientboundPacket(ClientboundDebugEventPacket.class, ClientboundDebugEventPacket::new) .registerClientboundPacket(ClientboundDebugSamplePacket.class, ClientboundDebugSamplePacket::new) .registerClientboundPacket(ClientboundDeleteChatPacket.class, ClientboundDeleteChatPacket::new) .registerClientboundPacket(ClientboundDisconnectPacket.class, ClientboundDisconnectPacket::new) @@ -311,6 +324,7 @@ public class MinecraftCodec { .registerClientboundPacket(ClientboundExplodePacket.class, ClientboundExplodePacket::new) .registerClientboundPacket(ClientboundForgetLevelChunkPacket.class, ClientboundForgetLevelChunkPacket::new) .registerClientboundPacket(ClientboundGameEventPacket.class, ClientboundGameEventPacket::new) + .registerClientboundPacket(ClientboundGameTestHighlightPosPacket.class, ClientboundGameTestHighlightPosPacket::new) .registerClientboundPacket(ClientboundHorseScreenOpenPacket.class, ClientboundHorseScreenOpenPacket::new) .registerClientboundPacket(ClientboundHurtAnimationPacket.class, ClientboundHurtAnimationPacket::new) .registerClientboundPacket(ClientboundInitializeBorderPacket.class, ClientboundInitializeBorderPacket::new) @@ -432,7 +446,7 @@ public class MinecraftCodec { .registerServerboundPacket(ServerboundContainerSlotStateChangedPacket.class, ServerboundContainerSlotStateChangedPacket::new) .registerServerboundPacket(ServerboundCookieResponsePacket.class, ServerboundCookieResponsePacket::new) .registerServerboundPacket(ServerboundCustomPayloadPacket.class, ServerboundCustomPayloadPacket::new) - .registerServerboundPacket(ServerboundDebugSampleSubscriptionPacket.class, ServerboundDebugSampleSubscriptionPacket::new) + .registerServerboundPacket(ServerboundDebugSubscriptionRequestPacket.class, ServerboundDebugSubscriptionRequestPacket::new) .registerServerboundPacket(ServerboundEditBookPacket.class, ServerboundEditBookPacket::new) .registerServerboundPacket(ServerboundEntityTagQuery.class, ServerboundEntityTagQuery::new) .registerServerboundPacket(ServerboundInteractPacket.class, ServerboundInteractPacket::new) diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java index 2b6daaf31..5f0fddb9d 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java @@ -41,6 +41,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.EntityEvent; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.CopperGolemState; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; @@ -49,10 +50,12 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.WeatheringCopperState; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.BlockBreakStage; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.ResolvableProfile; import org.geysermc.mcprotocollib.protocol.data.game.inventory.VillagerTrade; import org.geysermc.mcprotocollib.protocol.data.game.item.HashedStack; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; @@ -76,8 +79,10 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.PowerParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.SculkChargeParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ShriekParticleData; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.SpellParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.TrailParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.VibrationParticleData; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.positionsource.BlockPositionSource; @@ -107,6 +112,24 @@ import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.TagSlotDisplay; import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.WithRemainderSlotDisplay; import org.geysermc.mcprotocollib.protocol.data.game.statistic.StatisticCategory; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugBeeInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugBrainDump; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugBreezeInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugEntityBlockIntersection; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugGameEventInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugGameEventListenerInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugGoalInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugHiveInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugNeighborUpdateInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugOrientationInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugPathInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugPoiInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugRaidsInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugStructuresInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugVillageSectionsInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DedicatedServerTickTimeInfo; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -119,6 +142,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.OptionalInt; import java.util.Set; import java.util.UUID; import java.util.function.BiConsumer; @@ -667,6 +691,70 @@ public static void writeVec3i(ByteBuf buf, Vector3i vec) { MinecraftTypes.writeVarInt(buf, vec.getZ()); } + public static Vector3d readLpVec3(ByteBuf buf) { + int first = buf.readUnsignedByte(); + if (first == 0) { + return Vector3d.ZERO; + } + + int second = buf.readUnsignedByte(); + long third = buf.readUnsignedInt(); + long packed = third << 16 | second << 8 | first; + long magicMultiplier = first & 3; + if ((first & 4) == 4) { + magicMultiplier |= (MinecraftTypes.readVarInt(buf) & 0xFFFFFFFFL) << 2; + } + + return Vector3d.from( + unpackLpVec3Component(packed >> 3) * magicMultiplier, + unpackLpVec3Component(packed >> 18) * magicMultiplier, + unpackLpVec3Component(packed >> 33) * magicMultiplier + ); + } + + private static double unpackLpVec3Component(long packed) { + return Math.min(packed & 32767L, 32766.0) * 2.0 / 32766.0 - 1.0; + } + + public static void writeLpVec3(ByteBuf buf, Vector3d vec) { + double sanitizedX = sanitizeLpVec3Component(vec.getX()); + double sanitizedY = sanitizeLpVec3Component(vec.getY()); + double sanitizedZ = sanitizeLpVec3Component(vec.getZ()); + double maxVal = Math.max(Math.abs(sanitizedX), Math.max(Math.abs(sanitizedY), Math.abs(sanitizedZ))); + if (maxVal < 3.051944088384301E-5) { + buf.writeByte(0); + return; + } + long scale = (long) Math.ceil(maxVal); + boolean scaleTooLargeForBits = (scale & 3L) != scale; + long scaleBits = scaleTooLargeForBits ? scale & 3L | 4L : scale; + long encodedX = packLpVec3Component(sanitizedX / scale) << 3; + long encodedY = packLpVec3Component(sanitizedY / scale) << 18; + long encodedZ = packLpVec3Component(sanitizedZ / scale) << 33; + long packed = scaleBits | encodedX | encodedY | encodedZ; + buf.writeByte((byte) packed); + buf.writeByte((byte) (packed >> 8)); + buf.writeInt((int) (packed >> 16)); + if (scaleTooLargeForBits) { + MinecraftTypes.writeVarInt(buf, (int) (scale >> 2)); + } + } + + private static double sanitizeLpVec3Component(double d) { + if (Double.isNaN(d)) { + return 0.0; + } else if (d < -1.7179869183E10) { + return -1.7179869183E10; + } else if (d > 1.7179869183E10) { + return 1.7179869183E10; + } + return d; + } + + private static long packLpVec3Component(double d) { + return Math.round((d * 0.5 + 0.5) * 32766.0); + } + public static Vector3i readPosition(ByteBuf buf) { long val = buf.readLong(); @@ -782,6 +870,22 @@ public static void writeArmadilloState(ByteBuf buf, ArmadilloState state) { MinecraftTypes.writeEnum(buf, state); } + public static CopperGolemState readCopperGolemState(ByteBuf buf) { + return CopperGolemState.from(MinecraftTypes.readVarInt(buf)); + } + + public static void writeCopperGolemState(ByteBuf buf, CopperGolemState state) { + MinecraftTypes.writeEnum(buf, state); + } + + public static WeatheringCopperState readWeatheringCopperState(ByteBuf buf) { + return WeatheringCopperState.from(MinecraftTypes.readVarInt(buf)); + } + + public static void writeWeatheringCopperState(ByteBuf buf, WeatheringCopperState state) { + MinecraftTypes.writeEnum(buf, state); + } + private static void writeEnum(ByteBuf buf, Enum e) { MinecraftTypes.writeVarInt(buf, e.ordinal()); } @@ -903,6 +1007,7 @@ public static void writeParticle(ByteBuf buf, Particle particle) { public static ParticleData readParticleData(ByteBuf buf, ParticleType type) { return switch (type) { case BLOCK, BLOCK_MARKER, FALLING_DUST, DUST_PILLAR, BLOCK_CRUMBLE -> new BlockParticleData(MinecraftTypes.readVarInt(buf)); + case DRAGON_BREATH -> new PowerParticleData(buf.readFloat()); case DUST -> { int color = buf.readInt(); float scale = buf.readFloat(); @@ -914,7 +1019,12 @@ public static ParticleData readParticleData(ByteBuf buf, ParticleType type) { float scale = buf.readFloat(); yield new DustColorTransitionParticleData(color, scale, newColor); } - case ENTITY_EFFECT, TINTED_LEAVES -> new ColorParticleData(buf.readInt()); + case EFFECT, INSTANT_EFFECT -> { + int color = buf.readInt(); + float power = buf.readFloat(); + yield new SpellParticleData(color, power); + } + case ENTITY_EFFECT, TINTED_LEAVES, FLASH -> new ColorParticleData(buf.readInt()); case ITEM -> new ItemParticleData(MinecraftTypes.readItemStack(buf)); case SCULK_CHARGE -> new SculkChargeParticleData(buf.readFloat()); case SHRIEK -> new ShriekParticleData(MinecraftTypes.readVarInt(buf)); @@ -1332,6 +1442,269 @@ public static void writeSlotDisplay(ByteBuf buf, SlotDisplay display) { } } + public static DebugInfo readDebugSubscriptionUpdate(ByteBuf buf, DebugSubscriptions type) { + if (type == DebugSubscriptions.DEDICATED_SERVER_TICK_TIME) { + // This throws an NPE in vanilla, currently just returning for leniency + return DedicatedServerTickTimeInfo.INSTANCE; + } + + if (buf.readBoolean()) { + return MinecraftTypes.readDebugSubscription(buf, type); + } else { + return null; + } + } + + public static void writeDebugSubscriptionUpdate(ByteBuf buf, DebugSubscriptions type, DebugInfo debugInfo) { + if (type == DebugSubscriptions.DEDICATED_SERVER_TICK_TIME) { + // This throws an NPE in vanilla, currently just returning for leniency + return; + } + + boolean present = debugInfo != null; + buf.writeBoolean(present); + if (!present) return; + + MinecraftTypes.writeDebugSubscription(buf, type, debugInfo); + } + + public static DebugInfo readDebugSubscription(ByteBuf buf, DebugSubscriptions type) { + DebugInfo info; + switch (type) { + case BEES -> { + Vector3i hivePos = MinecraftTypes.readNullable(buf, MinecraftTypes::readPosition); + Vector3i flowerPos = MinecraftTypes.readNullable(buf, MinecraftTypes::readPosition); + int travelTicks = MinecraftTypes.readVarInt(buf); + List blacklistedHives = MinecraftTypes.readList(buf, MinecraftTypes::readPosition); + info = new DebugBeeInfo(hivePos, flowerPos, travelTicks, blacklistedHives); + } + case BRAINS -> { + String name = MinecraftTypes.readString(buf); + String profession = MinecraftTypes.readString(buf); + int xp = buf.readInt(); + float health = buf.readFloat(); + float maxHealth = buf.readFloat(); + String inventory = MinecraftTypes.readString(buf); + boolean wantsGolem = buf.readBoolean(); + int angerLevel = buf.readInt(); + List activities = MinecraftTypes.readList(buf, MinecraftTypes::readString); + List behaviors = MinecraftTypes.readList(buf, MinecraftTypes::readString); + List memories = MinecraftTypes.readList(buf, MinecraftTypes::readString); + List gossips = MinecraftTypes.readList(buf, MinecraftTypes::readString); + List pois = MinecraftTypes.readList(buf, MinecraftTypes::readPosition); + List potentialPois = MinecraftTypes.readList(buf, MinecraftTypes::readPosition); + info = new DebugBrainDump(name, profession, xp, health, maxHealth, inventory, wantsGolem, angerLevel, + activities, behaviors, memories, gossips, pois, potentialPois); + } + case BREEZES -> { + OptionalInt attackTarget = buf.readBoolean() ? OptionalInt.of(MinecraftTypes.readVarInt(buf)) : OptionalInt.empty(); + Vector3i jumpTarget = MinecraftTypes.readNullable(buf, MinecraftTypes::readPosition); + info = new DebugBreezeInfo(attackTarget, jumpTarget); + } + case GOAL_SELECTORS -> { + List goals = MinecraftTypes.readList(buf, in -> { + int priority = MinecraftTypes.readVarInt(in); + boolean isRunning = in.readBoolean(); + String name = MinecraftTypes.readString(in, 255); + return new DebugGoalInfo.DebugGoal(priority, isRunning, name); + }); + info = new DebugGoalInfo(goals); + } + case ENTITY_PATHS -> { + boolean reached = buf.readBoolean(); + int nextNodeIndex = buf.readInt(); + Vector3i target = MinecraftTypes.readPosition(buf); + List nodes = MinecraftTypes.readList(buf, MinecraftTypes::readDebugPathNode); + + List targetNodes = MinecraftTypes.readList(buf, MinecraftTypes::readDebugPathNode); + DebugPathInfo.Node[] openSet = new DebugPathInfo.Node[MinecraftTypes.readVarInt(buf)]; + for (int i = 0; i < openSet.length; i++) { + openSet[i] = MinecraftTypes.readDebugPathNode(buf); + } + DebugPathInfo.Node[] closedSet = new DebugPathInfo.Node[MinecraftTypes.readVarInt(buf)]; + for (int i = 0; i < closedSet.length; i++) { + closedSet[i] = MinecraftTypes.readDebugPathNode(buf); + } + DebugPathInfo.Path.DebugData debugData = new DebugPathInfo.Path.DebugData(targetNodes, openSet, closedSet); + + DebugPathInfo.Path path = new DebugPathInfo.Path(reached, nextNodeIndex, target, nodes, debugData); + float maxNodeDistance = buf.readFloat(); + info = new DebugPathInfo(path, maxNodeDistance); + } + case ENTITY_BLOCK_INTERSECTIONS -> info = DebugEntityBlockIntersection.from(MinecraftTypes.readVarInt(buf)); + case BEE_HIVES -> { + int blockType = MinecraftTypes.readVarInt(buf); + int occupantCount = MinecraftTypes.readVarInt(buf); + int honeyLevel = MinecraftTypes.readVarInt(buf); + boolean sedated = buf.readBoolean(); + info = new DebugHiveInfo(blockType, occupantCount, honeyLevel, sedated); + } + case POIS -> info = new DebugPoiInfo(MinecraftTypes.readPosition(buf), MinecraftTypes.readVarInt(buf), MinecraftTypes.readVarInt(buf)); + case REDSTONE_WIRE_ORIENTATIONS -> info = new DebugOrientationInfo(MinecraftTypes.readVarInt(buf)); + case VILLAGE_SECTIONS -> info = DebugVillageSectionsInfo.INSTANCE; + case RAIDS -> info = new DebugRaidsInfo(MinecraftTypes.readList(buf, MinecraftTypes::readPosition)); + case STRUCTURES -> { + List structures = MinecraftTypes.readList(buf, in -> { + Vector3i min = MinecraftTypes.readPosition(in); + Vector3i max = MinecraftTypes.readPosition(in); + DebugStructuresInfo.BoundingBox boundingBox = new DebugStructuresInfo.BoundingBox(min, max); + + List pieces = MinecraftTypes.readList(in, bufx -> { + Vector3i pieceMin = MinecraftTypes.readPosition(bufx); + Vector3i pieceMax = MinecraftTypes.readPosition(bufx); + DebugStructuresInfo.BoundingBox pieceBoundingBox = new DebugStructuresInfo.BoundingBox(pieceMin, pieceMax); + boolean isStart = bufx.readBoolean(); + return new DebugStructuresInfo.StructureInfo.Piece(pieceBoundingBox, isStart); + }); + return new DebugStructuresInfo.StructureInfo(boundingBox, pieces); + }); + info = new DebugStructuresInfo(structures); + } + case GAME_EVENT_LISTENERS -> info = new DebugGameEventListenerInfo(MinecraftTypes.readVarInt(buf)); + case NEIGHBOR_UPDATES -> info = new DebugNeighborUpdateInfo(MinecraftTypes.readPosition(buf)); + case GAME_EVENTS -> info = new DebugGameEventInfo(MinecraftTypes.readVarInt(buf), MinecraftTypes.readPosition(buf)); + default -> info = null; + } + return info; + } + + public static void writeDebugSubscription(ByteBuf buf, DebugSubscriptions type, DebugInfo debugInfo) { + if (type == DebugSubscriptions.DEDICATED_SERVER_TICK_TIME) { + // This throws an NPE in vanilla, currently just returning for leniency + return; + } + + switch (debugInfo.getType()) { + case BEES -> { + DebugBeeInfo beeInfo = (DebugBeeInfo) debugInfo; + + MinecraftTypes.writeNullable(buf, beeInfo.hivePos(), MinecraftTypes::writePosition); + MinecraftTypes.writeNullable(buf, beeInfo.flowerPos(), MinecraftTypes::writePosition); + MinecraftTypes.writeVarInt(buf, beeInfo.travelTicks()); + MinecraftTypes.writeList(buf, beeInfo.blacklistedHives(), MinecraftTypes::writePosition); + } + case BRAINS -> { + DebugBrainDump brainDump = (DebugBrainDump) debugInfo; + + MinecraftTypes.writeString(buf, brainDump.name()); + MinecraftTypes.writeString(buf, brainDump.profession()); + buf.writeInt(brainDump.xp()); + buf.writeFloat(brainDump.health()); + buf.writeFloat(brainDump.maxHealth()); + MinecraftTypes.writeString(buf, brainDump.inventory()); + buf.writeBoolean(brainDump.wantsGolem()); + buf.writeInt(brainDump.angerLevel()); + MinecraftTypes.writeList(buf, brainDump.activities(), MinecraftTypes::writeString); + MinecraftTypes.writeList(buf, brainDump.behaviors(), MinecraftTypes::writeString); + MinecraftTypes.writeList(buf, brainDump.memories(), MinecraftTypes::writeString); + MinecraftTypes.writeList(buf, brainDump.gossips(), MinecraftTypes::writeString); + MinecraftTypes.writeList(buf, brainDump.pois(), MinecraftTypes::writePosition); + MinecraftTypes.writeList(buf, brainDump.potentialPois(), MinecraftTypes::writePosition); + } + case BREEZES -> { + DebugBreezeInfo breezeInfo = (DebugBreezeInfo) debugInfo; + + buf.writeBoolean(breezeInfo.attackTarget().isPresent()); + if (breezeInfo.attackTarget().isPresent()) { + MinecraftTypes.writeVarInt(buf, breezeInfo.attackTarget().getAsInt()); + } + MinecraftTypes.writeNullable(buf, breezeInfo.jumpTarget(), MinecraftTypes::writePosition); + } + case GOAL_SELECTORS -> { + DebugGoalInfo goalInfo = (DebugGoalInfo) debugInfo; + + MinecraftTypes.writeList(buf, goalInfo.goals(), (out, goal) -> { + MinecraftTypes.writeVarInt(out, goal.priority()); + out.writeBoolean(goal.isRunning()); + MinecraftTypes.writeString(out, goal.name()); + }); + } + case ENTITY_PATHS -> { + DebugPathInfo pathInfo = (DebugPathInfo) debugInfo; + + buf.writeBoolean(pathInfo.path().reached()); + buf.writeInt(pathInfo.path().nextNodeIndex()); + MinecraftTypes.writePosition(buf, pathInfo.path().target()); + MinecraftTypes.writeList(buf, pathInfo.path().nodes(), MinecraftTypes::writeDebugPathNode); + MinecraftTypes.writeList(buf, pathInfo.path().debugData().targetNodes(), MinecraftTypes::writeDebugPathNode); + + MinecraftTypes.writeVarInt(buf, pathInfo.path().debugData().openSet().length); + for (DebugPathInfo.Node node : pathInfo.path().debugData().openSet()) { + MinecraftTypes.writeDebugPathNode(buf, node); + } + + MinecraftTypes.writeVarInt(buf, pathInfo.path().debugData().closedSet().length); + for (DebugPathInfo.Node node : pathInfo.path().debugData().closedSet()) { + MinecraftTypes.writeDebugPathNode(buf, node); + } + + buf.writeFloat(pathInfo.maxNodeDistance()); + } + case ENTITY_BLOCK_INTERSECTIONS -> MinecraftTypes.writeVarInt(buf, ((DebugEntityBlockIntersection) debugInfo).ordinal()); + case BEE_HIVES -> { + DebugHiveInfo hiveInfo = (DebugHiveInfo) debugInfo; + + MinecraftTypes.writeVarInt(buf, hiveInfo.blockType()); + MinecraftTypes.writeVarInt(buf, hiveInfo.occupantCount()); + MinecraftTypes.writeVarInt(buf, hiveInfo.honeyLevel()); + buf.writeBoolean(hiveInfo.sedated()); + } + case POIS -> { + DebugPoiInfo poiInfo = (DebugPoiInfo) debugInfo; + + MinecraftTypes.writePosition(buf, poiInfo.pos()); + MinecraftTypes.writeVarInt(buf, poiInfo.poiType()); + MinecraftTypes.writeVarInt(buf, poiInfo.freeTicketCount()); + } + case REDSTONE_WIRE_ORIENTATIONS -> MinecraftTypes.writeVarInt(buf, ((DebugOrientationInfo) debugInfo).orientationId()); + case RAIDS -> MinecraftTypes.writeList(buf, ((DebugRaidsInfo) debugInfo).positions(), MinecraftTypes::writePosition); + case STRUCTURES -> { + DebugStructuresInfo structuresInfo = (DebugStructuresInfo) debugInfo; + + MinecraftTypes.writeList(buf, structuresInfo.info(), (out, structureInfo) -> { + MinecraftTypes.writePosition(out, structureInfo.boundingBox().min()); + MinecraftTypes.writePosition(out, structureInfo.boundingBox().max()); + MinecraftTypes.writeList(out, structureInfo.pieces(), (bufx, pieceInfo) -> { + MinecraftTypes.writePosition(bufx, pieceInfo.boundingBox().min()); + MinecraftTypes.writePosition(bufx, pieceInfo.boundingBox().max()); + bufx.writeBoolean(pieceInfo.isStart()); + }); + }); + } + case GAME_EVENT_LISTENERS -> MinecraftTypes.writeVarInt(buf, ((DebugGameEventListenerInfo) debugInfo).listenerRadius()); + case NEIGHBOR_UPDATES -> MinecraftTypes.writePosition(buf, ((DebugNeighborUpdateInfo) debugInfo).pos()); + case GAME_EVENTS -> { + DebugGameEventInfo gameEventInfo = (DebugGameEventInfo) debugInfo; + + MinecraftTypes.writeVarInt(buf, gameEventInfo.eventId()); + MinecraftTypes.writePosition(buf, gameEventInfo.pos()); + } + } + } + + public static DebugPathInfo.Node readDebugPathNode(ByteBuf buf) { + int x = buf.readInt(); + int y = buf.readInt(); + int z = buf.readInt(); + float walkedDistance = buf.readFloat(); + float costMalus = buf.readFloat(); + boolean closed = buf.readBoolean(); + DebugPathInfo.PathType pathType = DebugPathInfo.PathType.from(MinecraftTypes.readVarInt(buf)); + float f = buf.readFloat(); + return new DebugPathInfo.Node(x, y, z, walkedDistance, costMalus, closed, pathType, f); + } + + public static void writeDebugPathNode(ByteBuf buf, DebugPathInfo.Node node) { + buf.writeInt(node.x()); + buf.writeInt(node.y()); + buf.writeInt(node.z()); + buf.writeFloat(node.walkedDistance()); + buf.writeFloat(node.costMalus()); + buf.writeBoolean(node.closed()); + MinecraftTypes.writeVarInt(buf, node.type().ordinal()); + buf.writeFloat(node.f()); + } + public static DataPalette readDataPalette(ByteBuf buf, PaletteType paletteType, int registrySize) { int bitsPerEntry = buf.readByte() & 0xFF; Palette palette = MinecraftTypes.readPalette(buf, paletteType, bitsPerEntry); @@ -1432,6 +1805,62 @@ public static void writeFixedBitSet(ByteBuf buf, BitSet bitSet, int length) { } } + public static GameProfile readStaticGameProfile(ByteBuf buf) { + GameProfile profile = new GameProfile(MinecraftTypes.readUUID(buf), MinecraftTypes.readString(buf)); + profile.setProperties(MinecraftTypes.readList(buf, MinecraftTypes::readProperty)); + return profile; + } + + public static void writeStaticGameProfile(ByteBuf buf, GameProfile profile) { + MinecraftTypes.writeUUID(buf, profile.getId()); + MinecraftTypes.writeString(buf, profile.getName()); + MinecraftTypes.writeList(buf, profile.getProperties(), MinecraftTypes::writeProperty); + } + + public static GameProfile readDynamicGameProfile(ByteBuf buf) { + String name = MinecraftTypes.readNullable(buf, MinecraftTypes::readString); + UUID id = MinecraftTypes.readNullable(buf, MinecraftTypes::readUUID); + GameProfile profile = new GameProfile(id, name); + + List properties = MinecraftTypes.readList(buf, MinecraftTypes::readProperty); + profile.setProperties(properties); + + return profile; + } + + public static void writeDynamicGameProfile(ByteBuf buf, GameProfile profile) { + MinecraftTypes.writeNullable(buf, profile.getName(), MinecraftTypes::writeString); + MinecraftTypes.writeNullable(buf, profile.getId(), MinecraftTypes::writeUUID); + + MinecraftTypes.writeList(buf, profile.getProperties(), MinecraftTypes::writeProperty); + } + + public static ResolvableProfile readResolvableProfile(ByteBuf buf) { + boolean dynamic = !buf.readBoolean(); + GameProfile profile = dynamic ? MinecraftTypes.readDynamicGameProfile(buf) : MinecraftTypes.readStaticGameProfile(buf); + Key body = MinecraftTypes.readNullable(buf, MinecraftTypes::readResourceLocation); + Key cape = MinecraftTypes.readNullable(buf, MinecraftTypes::readResourceLocation); + Key elytra = MinecraftTypes.readNullable(buf, MinecraftTypes::readResourceLocation); + GameProfile.TextureModel model = MinecraftTypes.readNullable(buf, in -> { + return in.readBoolean() ? GameProfile.TextureModel.SLIM : GameProfile.TextureModel.WIDE; + }); + return new ResolvableProfile(profile, body, cape, elytra, model, dynamic); + } + + public static void writeResolvableProfile(ByteBuf buf, ResolvableProfile profile) { + buf.writeBoolean(!profile.isDynamic()); + if (!profile.isDynamic()) { + MinecraftTypes.writeStaticGameProfile(buf, profile.getProfile()); + } else { + MinecraftTypes.writeDynamicGameProfile(buf, profile.getProfile()); + } + + MinecraftTypes.writeNullable(buf, profile.getBody(), MinecraftTypes::writeResourceLocation); + MinecraftTypes.writeNullable(buf, profile.getCape(), MinecraftTypes::writeResourceLocation); + MinecraftTypes.writeNullable(buf, profile.getElytra(), MinecraftTypes::writeResourceLocation); + MinecraftTypes.writeNullable(buf, profile.getModel(), (out, model) -> out.writeBoolean(model == GameProfile.TextureModel.SLIM)); + } + public static GameProfile.Property readProperty(ByteBuf buf) { String name = MinecraftTypes.readString(buf); String value = MinecraftTypes.readString(buf); @@ -1479,4 +1908,6 @@ public static void writeSoundEvent(ByteBuf buf, Sound soundEvent) { buf.writeFloat(soundEvent.getRange()); } } + + } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/WeightedList.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/WeightedList.java new file mode 100644 index 000000000..eaffa5fe4 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/WeightedList.java @@ -0,0 +1,63 @@ +package org.geysermc.mcprotocollib.protocol.data.game; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.checkerframework.checker.index.qual.NonNegative; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; + +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; + +@Data +@AllArgsConstructor +public class WeightedList { + private final List> entries; + + public WeightedList(ByteBuf in, Function reader) { + entries = MinecraftTypes.readList(in, input -> new Entry<>(input, reader)); + } + + public void write(ByteBuf out, BiConsumer writer) { + MinecraftTypes.writeList(out, entries, (output, entry) -> entry.write(out, writer)); + } + + public WeightedList with(T value, @NonNegative int weight) { + add(value, weight); + return this; + } + + public void add(T value, @NonNegative int weight) { + add(new Entry<>(value, weight)); + } + + public void add(Entry entry) { + entries.add(entry); + } + + public Entry get(int index) { + return entries.get(index); + } + + public boolean contains(T value) { + for (Entry entry : entries) { + if (entry.value.equals(value)) { + return true; + } + } + return false; + } + + public record Entry(T value, @NonNegative int weight) { + + public Entry(ByteBuf in, Function reader) { + this(reader.apply(in), MinecraftTypes.readVarInt(in)); + } + + public void write(ByteBuf out, BiConsumer writer) { + writer.accept(value, out); + MinecraftTypes.writeVarInt(out, weight); + } + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBeeInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBeeInfo.java new file mode 100644 index 000000000..da9a34c54 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBeeInfo.java @@ -0,0 +1,14 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public record DebugBeeInfo(@Nullable Vector3i hivePos, @Nullable Vector3i flowerPos, int travelTicks, + List blacklistedHives) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.BEES; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBrainDump.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBrainDump.java new file mode 100644 index 000000000..cf419ea6f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBrainDump.java @@ -0,0 +1,15 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +import java.util.List; + +public record DebugBrainDump(String name, String profession, int xp, float health, float maxHealth, + String inventory, boolean wantsGolem, int angerLevel, List activities, + List behaviors, List memories, List gossips, + List pois, List potentialPois) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.BRAINS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBreezeInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBreezeInfo.java new file mode 100644 index 000000000..dca79f4f8 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugBreezeInfo.java @@ -0,0 +1,13 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; +import org.jetbrains.annotations.Nullable; + +import java.util.OptionalInt; + +public record DebugBreezeInfo(OptionalInt attackTarget, @Nullable Vector3i jumpTarget) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.BREEZES; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugEntityBlockIntersection.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugEntityBlockIntersection.java new file mode 100644 index 000000000..fe9d5e05b --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugEntityBlockIntersection.java @@ -0,0 +1,18 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public enum DebugEntityBlockIntersection implements DebugInfo { + IN_BLOCK, + IN_FLUID, + IN_AIR; + + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.ENTITY_BLOCK_INTERSECTIONS; + } + + private static final DebugEntityBlockIntersection[] VALUES = values(); + + public static DebugEntityBlockIntersection from(int id) { + return id >= 0 && id < VALUES.length ? VALUES[id] : VALUES[0]; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventInfo.java new file mode 100644 index 000000000..afc364b74 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventInfo.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +public record DebugGameEventInfo(int eventId, Vector3i pos) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.GAME_EVENTS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventListenerInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventListenerInfo.java new file mode 100644 index 000000000..3ad137cd7 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGameEventListenerInfo.java @@ -0,0 +1,8 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public record DebugGameEventListenerInfo(int listenerRadius) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.GAME_EVENT_LISTENERS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGoalInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGoalInfo.java new file mode 100644 index 000000000..ed51a468f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugGoalInfo.java @@ -0,0 +1,12 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import java.util.List; + +public record DebugGoalInfo(List goals) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.GOAL_SELECTORS; + } + + public record DebugGoal(int priority, boolean isRunning, String name) {} +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugHiveInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugHiveInfo.java new file mode 100644 index 000000000..594f4266c --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugHiveInfo.java @@ -0,0 +1,8 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public record DebugHiveInfo(int blockType, int occupantCount, int honeyLevel, boolean sedated) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.BEE_HIVES; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugInfo.java new file mode 100644 index 000000000..cba95ac93 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugInfo.java @@ -0,0 +1,5 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public interface DebugInfo { + DebugSubscriptions getType(); +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugNeighborUpdateInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugNeighborUpdateInfo.java new file mode 100644 index 000000000..38e7aea58 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugNeighborUpdateInfo.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +public record DebugNeighborUpdateInfo(Vector3i pos) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.NEIGHBOR_UPDATES; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugOrientationInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugOrientationInfo.java new file mode 100644 index 000000000..3f1ba2765 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugOrientationInfo.java @@ -0,0 +1,8 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public record DebugOrientationInfo(int orientationId) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.REDSTONE_WIRE_ORIENTATIONS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPathInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPathInfo.java new file mode 100644 index 000000000..b23161d19 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPathInfo.java @@ -0,0 +1,55 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +import java.util.List; + +public record DebugPathInfo(Path path, float maxNodeDistance) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.ENTITY_PATHS; + } + + public record Path(boolean reached, int nextNodeIndex, Vector3i target, List nodes, + DebugData debugData) { + public record DebugData(List targetNodes, Node[] openSet, Node[] closedSet) {} + } + + public record Node(int x, int y, int z, float walkedDistance, float costMalus, + boolean closed, PathType type, float f) {} + + public enum PathType { + BLOCKED, + OPEN, + WALKABLE, + WALKABLE_DOOR, + TRAPDOOR, + POWDER_SNOW, + DANGER_POWDER_SNOW, + FENCE, + LAVA, + WATER, + WATER_BORDER, + RAIL, + UNPASSABLE_RAIL, + DANGER_FIRE, + DAMAGE_FIRE, + DANGER_OTHER, + DAMAGE_OTHER, + DOOR_OPEN, + DOOR_WOOD_CLOSED, + DOOR_IRON_CLOSED, + BREACH, + LEAVES, + STICKY_HONEY, + COCOA, + DAMAGE_CAUTIOUS, + DANGER_TRAPDOOR; + + private static final PathType[] VALUES = values(); + + public static PathType from(int id) { + return VALUES[id]; + } + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPoiInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPoiInfo.java new file mode 100644 index 000000000..cfdc8b30d --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugPoiInfo.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +public record DebugPoiInfo(Vector3i pos, int poiType, int freeTicketCount) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.POIS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugRaidsInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugRaidsInfo.java new file mode 100644 index 000000000..972576bce --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugRaidsInfo.java @@ -0,0 +1,12 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +import java.util.List; + +public record DebugRaidsInfo(List positions) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.RAIDS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugStructuresInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugStructuresInfo.java new file mode 100644 index 000000000..0e975860f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugStructuresInfo.java @@ -0,0 +1,18 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +import org.cloudburstmc.math.vector.Vector3i; + +import java.util.List; + +public record DebugStructuresInfo(List info) implements DebugInfo { + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.STRUCTURES; + } + + public record StructureInfo(BoundingBox boundingBox, List pieces) { + public record Piece(BoundingBox boundingBox, boolean isStart) {} + } + + public record BoundingBox(Vector3i min, Vector3i max) {} +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugSubscriptions.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugSubscriptions.java new file mode 100644 index 000000000..eee7e51cf --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugSubscriptions.java @@ -0,0 +1,26 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public enum DebugSubscriptions { + DEDICATED_SERVER_TICK_TIME, + BEES, + BRAINS, + BREEZES, + GOAL_SELECTORS, + ENTITY_PATHS, + ENTITY_BLOCK_INTERSECTIONS, + BEE_HIVES, + POIS, + REDSTONE_WIRE_ORIENTATIONS, + VILLAGE_SECTIONS, + RAIDS, + STRUCTURES, + GAME_EVENT_LISTENERS, + NEIGHBOR_UPDATES, + GAME_EVENTS; + + private static final DebugSubscriptions[] VALUES = values(); + + public static DebugSubscriptions from(int id) { + return VALUES[id]; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugVillageSectionsInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugVillageSectionsInfo.java new file mode 100644 index 000000000..1ff91b62b --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DebugVillageSectionsInfo.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public record DebugVillageSectionsInfo() implements DebugInfo { + public static final DebugVillageSectionsInfo INSTANCE = new DebugVillageSectionsInfo(); + + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.VILLAGE_SECTIONS; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DedicatedServerTickTimeInfo.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DedicatedServerTickTimeInfo.java new file mode 100644 index 000000000..cedc2dd2e --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/DedicatedServerTickTimeInfo.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.debug; + +public record DedicatedServerTickTimeInfo() implements DebugInfo { + public static final DedicatedServerTickTimeInfo INSTANCE = new DedicatedServerTickTimeInfo(); + + @Override + public DebugSubscriptions getType() { + return DebugSubscriptions.DEDICATED_SERVER_TICK_TIME; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/RemoteDebugSampleType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/RemoteDebugSampleType.java similarity index 77% rename from protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/RemoteDebugSampleType.java rename to protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/RemoteDebugSampleType.java index 81264db8d..79be9794d 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/RemoteDebugSampleType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/debug/RemoteDebugSampleType.java @@ -1,4 +1,4 @@ -package org.geysermc.mcprotocollib.protocol.data.game; +package org.geysermc.mcprotocollib.protocol.data.game.debug; public enum RemoteDebugSampleType { TICK_TIME; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/CopperGolemState.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/CopperGolemState.java new file mode 100644 index 000000000..1ca295a77 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/CopperGolemState.java @@ -0,0 +1,15 @@ +package org.geysermc.mcprotocollib.protocol.data.game.entity.metadata; + +public enum CopperGolemState { + IDLE, + GETTING_ITEM, + GETTING_NO_ITEM, + DROPPING_ITEM, + DROPPING_NO_ITEM; + + private static final CopperGolemState[] VALUES = values(); + + public static CopperGolemState from(int id) { + return VALUES[id]; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java index ba43ef47a..429e1f667 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java @@ -7,7 +7,6 @@ import org.cloudburstmc.math.imaginary.Quaternionf; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.nbt.NbtMap; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; @@ -17,6 +16,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.LongEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.ResolvableProfile; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; @@ -45,7 +45,6 @@ public class MetadataTypes { public static final MetadataType> OPTIONAL_LIVING_ENTITY_REFERENCE = register(id -> new MetadataType<>(id, optionalReader(MinecraftTypes::readUUID), optionalWriter(MinecraftTypes::writeUUID), ObjectEntityMetadata::new)); public static final IntMetadataType BLOCK_STATE = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); public static final IntMetadataType OPTIONAL_BLOCK_STATE = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); - public static final MetadataType COMPOUND_TAG = register(id -> new MetadataType<>(id, MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectEntityMetadata::new)); public static final MetadataType PARTICLE = register(id -> new MetadataType<>(id, MinecraftTypes::readParticle, MinecraftTypes::writeParticle, ObjectEntityMetadata::new)); public static final MetadataType> PARTICLES = register(id -> new MetadataType<>(id, listReader(MinecraftTypes::readParticle), listWriter(MinecraftTypes::writeParticle), ObjectEntityMetadata::new)); public static final MetadataType VILLAGER_DATA = register(id -> new MetadataType<>(id, MinecraftTypes::readVillagerData, MinecraftTypes::writeVillagerData, ObjectEntityMetadata::new)); @@ -62,8 +61,11 @@ public class MetadataTypes { public static final MetadataType> PAINTING_VARIANT = register(id -> new MetadataType<>(id, MinecraftTypes::readPaintingVariant, MinecraftTypes::writePaintingVariant, ObjectEntityMetadata::new)); public static final MetadataType SNIFFER_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readSnifferState, MinecraftTypes::writeSnifferState, ObjectEntityMetadata::new)); public static final MetadataType ARMADILLO_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readArmadilloState, MinecraftTypes::writeArmadilloState, ObjectEntityMetadata::new)); + public static final MetadataType COPPER_GOLEM_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readCopperGolemState, MinecraftTypes::writeCopperGolemState, ObjectEntityMetadata::new)); + public static final MetadataType WEATHERING_COPPER_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readWeatheringCopperState, MinecraftTypes::writeWeatheringCopperState, ObjectEntityMetadata::new)); public static final MetadataType VECTOR3 = register(id -> new MetadataType<>(id, MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new)); public static final MetadataType QUATERNION = register(id -> new MetadataType<>(id, MinecraftTypes::readQuaternion, MinecraftTypes::writeQuaternion, ObjectEntityMetadata::new)); + public static final MetadataType RESOLVABLE_PROFILE = register(id -> new MetadataType<>(id, MinecraftTypes::readResolvableProfile, MinecraftTypes::writeResolvableProfile, ObjectEntityMetadata::new)); public static > T register(Int2ObjectFunction factory) { T value = factory.apply(VALUES.size()); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/WeatheringCopperState.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/WeatheringCopperState.java new file mode 100644 index 000000000..27530fec9 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/WeatheringCopperState.java @@ -0,0 +1,14 @@ +package org.geysermc.mcprotocollib.protocol.data.game.entity.metadata; + +public enum WeatheringCopperState { + UNAFFECTED, + EXPOSED, + WEATHERED, + OXIDIZED; + + private static final WeatheringCopperState[] VALUES = values(); + + public static WeatheringCopperState from(int id) { + return VALUES[id]; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/player/ResolvableProfile.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/player/ResolvableProfile.java new file mode 100644 index 000000000..5200049f3 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/player/ResolvableProfile.java @@ -0,0 +1,25 @@ +package org.geysermc.mcprotocollib.protocol.data.game.entity.player; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import net.kyori.adventure.key.Key; +import org.geysermc.mcprotocollib.auth.GameProfile; +import org.jetbrains.annotations.Nullable; + +@Data +@With +@AllArgsConstructor +public class ResolvableProfile { + private final GameProfile profile; + private final @Nullable Key body; + private final @Nullable Key cape; + private final @Nullable Key elytra; + private final @Nullable GameProfile.TextureModel model; + private final boolean dynamic; + + public ResolvableProfile(GameProfile profile) { + // A profile is dynamic in Java 1.21.9 when it is missing UUID, name, or properties (empty properties are fine) + this(profile, null, null, null, null, !profile.isComplete() || profile.getProperties() == null); + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/type/EntityType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/type/EntityType.java index e68cc7729..89862200b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/type/EntityType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/type/EntityType.java @@ -30,6 +30,7 @@ public enum EntityType { CHEST_MINECART, CHICKEN, COD, + COPPER_GOLEM, COMMAND_BLOCK_MINECART, COW, CREAKING, @@ -84,6 +85,7 @@ public enum EntityType { MAGMA_CUBE, MANGROVE_BOAT, MANGROVE_CHEST_BOAT, + MANNEQUIN, MARKER, MINECART, MOOSHROOM, diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BeehiveOccupant.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BeehiveOccupant.java index a7d74a2a1..4055cfb79 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BeehiveOccupant.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BeehiveOccupant.java @@ -3,13 +3,13 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; @Data @AllArgsConstructor @Builder(toBuilder = true) public class BeehiveOccupant { - private final NbtMap entityData; + private final TypedEntityData entityData; private final int ticksInHive; private final int minTicksInHive; } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java index 07878074e..b9f399347 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java @@ -7,14 +7,16 @@ import net.kyori.adventure.text.Component; import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.mcprotocollib.auth.GameProfile; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant; +import org.geysermc.mcprotocollib.protocol.data.game.entity.player.ResolvableProfile; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.BooleanDataComponent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.IntDataComponent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.ObjectDataComponent; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; import java.util.ArrayList; @@ -73,9 +75,9 @@ public class DataComponentTypes { public static final DataComponentType WRITTEN_BOOK_CONTENT = register(id -> new DataComponentType<>(id, "written_book_content", ItemTypes::readWrittenBookContent, ItemTypes::writeWrittenBookContent, ObjectDataComponent::new)); public static final DataComponentType TRIM = register(id -> new DataComponentType<>(id, "trim", ItemTypes::readArmorTrim, ItemTypes::writeArmorTrim, ObjectDataComponent::new)); public static final DataComponentType DEBUG_STICK_STATE = register(id -> new DataComponentType<>(id, "debug_stick_state", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); - public static final DataComponentType ENTITY_DATA = register(id -> new DataComponentType<>(id, "entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType> ENTITY_DATA = register(id -> new DataComponentType<>(id, "entity_data", buf -> ItemTypes.readTypedEntityData(buf, ItemTypes::readEntityType), (buf, data) -> ItemTypes.writeTypedEntityData(buf, data, ItemTypes::writeEntityType), ObjectDataComponent::new)); public static final DataComponentType BUCKET_ENTITY_DATA = register(id -> new DataComponentType<>(id, "bucket_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); - public static final DataComponentType BLOCK_ENTITY_DATA = register(id -> new DataComponentType<>(id, "block_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType> BLOCK_ENTITY_DATA = register(id -> new DataComponentType<>(id, "block_entity_data", buf -> ItemTypes.readTypedEntityData(buf, ItemTypes::readBlockEntityType), (buf, data) -> ItemTypes.writeTypedEntityData(buf, data, ItemTypes::writeBlockEntityType), ObjectDataComponent::new)); public static final DataComponentType INSTRUMENT = register(id -> new DataComponentType<>(id, "instrument", ItemTypes::readInstrumentComponent, ItemTypes::writeInstrumentComponent, ObjectDataComponent::new)); public static final DataComponentType PROVIDES_TRIM_MATERIAL = register(id -> new DataComponentType<>(id, "provides_trim_material", ItemTypes::readProvidesTrimMaterial, ItemTypes::writeProvidesTrimMaterial, ObjectDataComponent::new)); public static final IntComponentType OMINOUS_BOTTLE_AMPLIFIER = register(id -> new IntComponentType(id, "ominous_bottle_amplifier", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); @@ -85,7 +87,7 @@ public class DataComponentTypes { public static final DataComponentType LODESTONE_TRACKER = register(id -> new DataComponentType<>(id, "lodestone_tracker", ItemTypes::readLodestoneTarget, ItemTypes::writeLodestoneTarget, ObjectDataComponent::new)); public static final DataComponentType FIREWORK_EXPLOSION = register(id -> new DataComponentType<>(id, "firework_explosion", ItemTypes::readFireworkExplosion, ItemTypes::writeFireworkExplosion, ObjectDataComponent::new)); public static final DataComponentType FIREWORKS = register(id -> new DataComponentType<>(id, "fireworks", ItemTypes::readFireworks, ItemTypes::writeFireworks, ObjectDataComponent::new)); - public static final DataComponentType PROFILE = register(id -> new DataComponentType<>(id, "profile", ItemTypes::readResolvableProfile, ItemTypes::writeResolvableProfile, ObjectDataComponent::new)); + public static final DataComponentType PROFILE = register(id -> new DataComponentType<>(id, "profile", MinecraftTypes::readResolvableProfile, MinecraftTypes::writeResolvableProfile, ObjectDataComponent::new)); public static final DataComponentType NOTE_BLOCK_SOUND = register(id -> new DataComponentType<>(id, "note_block_sound", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new)); public static final DataComponentType> BANNER_PATTERNS = register(id -> new DataComponentType<>(id, "banner_patterns", listReader(ItemTypes::readBannerPatternLayer), listWriter(ItemTypes::writeBannerPatternLayer), ObjectDataComponent::new)); public static final IntComponentType BASE_COLOR = register(id -> new IntComponentType(id, "base_color", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemTypes.java index 3765608db..ce6ed233b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemTypes.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/ItemTypes.java @@ -7,19 +7,19 @@ import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; -import org.geysermc.mcprotocollib.auth.GameProfile; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot; import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation; +import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType; +import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.function.BiConsumer; import java.util.function.Function; @@ -507,6 +507,31 @@ public static void writeTrimPattern(ByteBuf buf, ArmorTrim.TrimPattern pattern) buf.writeBoolean(pattern.decal()); } + public static > TypedEntityData readTypedEntityData(ByteBuf buf, Function reader) { + return new TypedEntityData<>(reader.apply(buf), MinecraftTypes.readCompoundTag(buf)); + } + + public static void writeTypedEntityData(ByteBuf buf, TypedEntityData typedEntityData, BiConsumer writer) { + writer.accept(buf, typedEntityData.type()); + MinecraftTypes.writeAnyTag(buf, typedEntityData.tag()); + } + + public static EntityType readEntityType(ByteBuf buf) { + return EntityType.from(MinecraftTypes.readVarInt(buf)); + } + + public static void writeEntityType(ByteBuf buf, EntityType state) { + MinecraftTypes.writeVarInt(buf, state.ordinal()); + } + + public static BlockEntityType readBlockEntityType(ByteBuf buf) { + return BlockEntityType.from(MinecraftTypes.readVarInt(buf)); + } + + public static void writeBlockEntityType(ByteBuf buf, BlockEntityType state) { + MinecraftTypes.writeVarInt(buf, state.ordinal()); + } + public static InstrumentComponent readInstrumentComponent(ByteBuf buf) { Holder instrumentHolder = null; Key instrumentLocation = null; @@ -670,24 +695,6 @@ public static void writeFireworkExplosion(ByteBuf buf, Fireworks.FireworkExplosi buf.writeBoolean(explosion.isHasTwinkle()); } - public static GameProfile readResolvableProfile(ByteBuf buf) { - String name = MinecraftTypes.readNullable(buf, MinecraftTypes::readString); - UUID id = MinecraftTypes.readNullable(buf, MinecraftTypes::readUUID); - GameProfile profile = new GameProfile(id, name); - - List properties = MinecraftTypes.readList(buf, MinecraftTypes::readProperty); - profile.setProperties(properties); - - return profile; - } - - public static void writeResolvableProfile(ByteBuf buf, GameProfile profile) { - MinecraftTypes.writeNullable(buf, profile.getName(), MinecraftTypes::writeString); - MinecraftTypes.writeNullable(buf, profile.getId(), MinecraftTypes::writeUUID); - - MinecraftTypes.writeList(buf, profile.getProperties(), MinecraftTypes::writeProperty); - } - public static BannerPatternLayer readBannerPatternLayer(ByteBuf buf) { return new BannerPatternLayer(MinecraftTypes.readHolder(buf, ItemTypes::readBannerPattern), MinecraftTypes.readVarInt(buf)); } @@ -725,11 +732,11 @@ public static void writeBlockStateProperties(ByteBuf buf, BlockStateProperties p } public static BeehiveOccupant readBeehiveOccupant(ByteBuf buf) { - return new BeehiveOccupant(MinecraftTypes.readCompoundTag(buf), MinecraftTypes.readVarInt(buf), MinecraftTypes.readVarInt(buf)); + return new BeehiveOccupant(ItemTypes.readTypedEntityData(buf, ItemTypes::readEntityType), MinecraftTypes.readVarInt(buf), MinecraftTypes.readVarInt(buf)); } public static void writeBeehiveOccupant(ByteBuf buf, BeehiveOccupant occupant) { - MinecraftTypes.writeAnyTag(buf, occupant.getEntityData()); + ItemTypes.writeTypedEntityData(buf, occupant.getEntityData(), ItemTypes::writeEntityType); MinecraftTypes.writeVarInt(buf, occupant.getTicksInHive()); MinecraftTypes.writeVarInt(buf, occupant.getMinTicksInHive()); } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/TypedEntityData.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/TypedEntityData.java new file mode 100644 index 000000000..0b3e4a2a2 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/TypedEntityData.java @@ -0,0 +1,9 @@ +package org.geysermc.mcprotocollib.protocol.data.game.item.component; + +import lombok.Builder; +import org.cloudburstmc.nbt.NbtMap; + +@Builder(toBuilder = true) +public record TypedEntityData(T type, NbtMap tag) { + // TODO: Improve this implementation, too bulky in DataComponentTypes +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/block/BlockEntityType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/block/BlockEntityType.java index 11ad5e936..823af28d4 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/block/BlockEntityType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/block/BlockEntityType.java @@ -43,13 +43,15 @@ public enum BlockEntityType { SCULK_CATALYST, SCULK_SHRIEKER, CHISELED_BOOKSHELF, + SHELF, BRUSHABLE_BLOCK, DECORATED_POT, CRAFTER, TRIAL_SPAWNER, VAULT, TEST_BLOCK, - TEST_INSTANCE_BLOCK; + TEST_INSTANCE_BLOCK, + COPPER_GOLEM_STATUE; private static final BlockEntityType[] VALUES = values(); diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/ParticleType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/ParticleType.java index 568d67a2c..5f327a369 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/ParticleType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/ParticleType.java @@ -6,6 +6,7 @@ public enum ParticleType { BLOCK_MARKER, BUBBLE, CLOUD, + COPPER_FIRE_FLAME, CRIT, DAMAGE_INDICATOR, DRAGON_BREATH, diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/PowerParticleData.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/PowerParticleData.java new file mode 100644 index 000000000..f12be0206 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/PowerParticleData.java @@ -0,0 +1,10 @@ +package org.geysermc.mcprotocollib.protocol.data.game.level.particle; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class PowerParticleData implements ParticleData { + private final float power; +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/SpellParticleData.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/SpellParticleData.java new file mode 100644 index 000000000..9476e9e74 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/particle/SpellParticleData.java @@ -0,0 +1,11 @@ +package org.geysermc.mcprotocollib.protocol.data.game.level.particle; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SpellParticleData implements ParticleData { + private final int color; + private final float power; +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/sound/BuiltinSound.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/sound/BuiltinSound.java index 3448a6da4..e329a1c0c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/sound/BuiltinSound.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/level/sound/BuiltinSound.java @@ -81,6 +81,7 @@ public enum BuiltinSound implements Sound { ITEM_ARMOR_EQUIP_GOLD("item.armor.equip_gold"), ITEM_ARMOR_EQUIP_IRON("item.armor.equip_iron"), ITEM_ARMOR_EQUIP_LEATHER("item.armor.equip_leather"), + ITEM_ARMOR_EQUIP_COPPER("item.armor.equip_copper"), ITEM_ARMOR_EQUIP_NETHERITE("item.armor.equip_netherite"), ITEM_ARMOR_EQUIP_TURTLE("item.armor.equip_turtle"), ITEM_ARMOR_EQUIP_WOLF("item.armor.equip_wolf"), @@ -362,8 +363,38 @@ public enum BuiltinSound implements Sound { BLOCK_COPPER_PLACE("block.copper.place"), BLOCK_COPPER_HIT("block.copper.hit"), BLOCK_COPPER_FALL("block.copper.fall"), + BLOCK_COPPER_CHEST_CLOSE("block.copper_chest.close"), + BLOCK_COPPER_CHEST_OPEN("block.copper_chest.open"), + BLOCK_COPPER_CHEST_WEATHERED_CLOSE("block.copper_chest_weathered.close"), + BLOCK_COPPER_CHEST_WEATHERED_OPEN("block.copper_chest_weathered.open"), + BLOCK_COPPER_CHEST_OXIDIZED_CLOSE("block.copper_chest_oxidized.close"), + BLOCK_COPPER_CHEST_OXIDIZED_OPEN("block.copper_chest_oxidized.open"), BLOCK_COPPER_DOOR_CLOSE("block.copper_door.close"), BLOCK_COPPER_DOOR_OPEN("block.copper_door.open"), + ENTITY_COPPER_GOLEM_STEP("entity.copper_golem.step"), + ENTITY_COPPER_GOLEM_HURT("entity.copper_golem.hurt"), + ENTITY_COPPER_GOLEM_DEATH("entity.copper_golem.death"), + ENTITY_COPPER_GOLEM_WEATHERED_STEP("entity.copper_golem_weathered.step"), + ENTITY_COPPER_GOLEM_WEATHERED_HURT("entity.copper_golem_weathered.hurt"), + ENTITY_COPPER_GOLEM_WEATHERED_DEATH("entity.copper_golem_weathered.death"), + ENTITY_COPPER_GOLEM_OXIDIZED_STEP("entity.copper_golem_oxidized.step"), + ENTITY_COPPER_GOLEM_OXIDIZED_HURT("entity.copper_golem_oxidized.hurt"), + ENTITY_COPPER_GOLEM_OXIDIZED_DEATH("entity.copper_golem_oxidized.death"), + ENTITY_COPPER_GOLEM_SPIN("entity.copper_golem.spin"), + ENTITY_COPPER_GOLEM_WEATHERED_SPIN("entity.copper_golem_weathered.spin"), + ENTITY_COPPER_GOLEM_OXIDIZED_SPIN("entity.copper_golem_oxidized.spin"), + ENTITY_COPPER_GOLEM_NO_ITEM_GET("entity.copper_golem.no_item_get"), + ENTITY_COPPER_GOLEM_NO_ITEM_NO_GET("entity.copper_golem.no_item_no_get"), + ENTITY_COPPER_GOLEM_ITEM_DROP("entity.copper_golem.item_drop"), + ENTITY_COPPER_GOLEM_ITEM_NO_DROP("entity.copper_golem.item_no_drop"), + ENTITY_COPPER_GOLEM_BECOME_STATUE("entity.copper_golem_become_statue"), + BLOCK_COPPER_GOLEM_STATUE_BREAK("block.copper_golem_statue.break"), + BLOCK_COPPER_GOLEM_STATUE_PLACE("block.copper_golem_statue.place"), + BLOCK_COPPER_GOLEM_STATUE_HIT("block.copper_golem_statue.hit"), + BLOCK_COPPER_GOLEM_STATUE_STEP("block.copper_golem_statue.step"), + BLOCK_COPPER_GOLEM_STATUE_FALL("block.copper_golem_statue.fall"), + ENTITY_COPPER_GOLEM_SPAWN("entity.copper_golem.spawn"), + ENTITY_COPPER_GOLEM_SHEAR("entity.copper_golem.shear"), BLOCK_COPPER_GRATE_BREAK("block.copper_grate.break"), BLOCK_COPPER_GRATE_STEP("block.copper_grate.step"), BLOCK_COPPER_GRATE_PLACE("block.copper_grate.place"), @@ -1305,6 +1336,17 @@ public enum BuiltinSound implements Sound { ENTITY_SHEEP_SHEAR("entity.sheep.shear"), ENTITY_SHEEP_STEP("entity.sheep.step"), ITEM_SHEARS_SNIP("item.shears.snip"), + BLOCK_SHELF_ACTIVATE("block.shelf.activate"), + BLOCK_SHELF_BREAK("block.shelf.break"), + BLOCK_SHELF_DEACTIVATE("block.shelf.deactivate"), + BLOCK_SHELF_FALL("block.shelf.fall"), + BLOCK_SHELF_HIT("block.shelf.hit"), + BLOCK_SHELF_MULTI_SWAP("block.shelf.multi_swap"), + BLOCK_SHELF_PLACE("block.shelf.place"), + BLOCK_SHELF_PLACE_ITEM("block.shelf.place_item"), + BLOCK_SHELF_SINGLE_SWAP("block.shelf.single_swap"), + BLOCK_SHELF_STEP("block.shelf.step"), + BLOCK_SHELF_TAKE_ITEM("block.shelf.take_item"), ITEM_SHIELD_BLOCK("item.shield.block"), ITEM_SHIELD_BREAK("item.shield.break"), BLOCK_SHROOMLIGHT_BREAK("block.shroomlight.break"), @@ -1605,6 +1647,7 @@ public enum BuiltinSound implements Sound { BLOCK_HANGING_SIGN_WAXED_INTERACT_FAIL("block.hanging_sign.waxed_interact_fail"), BLOCK_SIGN_WAXED_INTERACT_FAIL("block.sign.waxed_interact_fail"), BLOCK_WATER_AMBIENT("block.water.ambient"), + WEATHER_END_FLASH("weather.end_flash"), WEATHER_RAIN("weather.rain"), WEATHER_RAIN_ABOVE("weather.rain.above"), BLOCK_WET_GRASS_BREAK("block.wet_grass.break"), diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundCodeOfConductPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundCodeOfConductPacket.java new file mode 100644 index 000000000..bbab2438a --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/clientbound/ClientboundCodeOfConductPacket.java @@ -0,0 +1,29 @@ +package org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; + +@Data +@With +@AllArgsConstructor +public class ClientboundCodeOfConductPacket implements MinecraftPacket { + private final String codeOfConduct; + + public ClientboundCodeOfConductPacket(ByteBuf in) { + this.codeOfConduct = MinecraftTypes.readString(in); + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writeString(out, codeOfConduct); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundAcceptCodeOfConductPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundAcceptCodeOfConductPacket.java new file mode 100644 index 000000000..7055f6d6e --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundAcceptCodeOfConductPacket.java @@ -0,0 +1,20 @@ +package org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound; + +import io.netty.buffer.ByteBuf; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientTickEndPacket; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ServerboundAcceptCodeOfConductPacket implements MinecraftPacket { + public static final ServerboundAcceptCodeOfConductPacket INSTANCE = new ServerboundAcceptCodeOfConductPacket(); + + @Override + public void serialize(ByteBuf out) {} + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundFinishConfigurationPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundFinishConfigurationPacket.java index eaea88f96..0bc14781b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundFinishConfigurationPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/configuration/serverbound/ServerboundFinishConfigurationPacket.java @@ -1,18 +1,17 @@ package org.geysermc.mcprotocollib.protocol.packet.configuration.serverbound; import io.netty.buffer.ByteBuf; +import lombok.AccessLevel; import lombok.Data; import lombok.NoArgsConstructor; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; @Data -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class ServerboundFinishConfigurationPacket implements MinecraftPacket { + public static final ServerboundFinishConfigurationPacket INSTANCE = new ServerboundFinishConfigurationPacket(); - public ServerboundFinishConfigurationPacket(ByteBuf in) { - } - - public void serialize(ByteBuf buf) { + public void serialize(ByteBuf out) { } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java index 0c866047f..14126d648 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java @@ -13,7 +13,7 @@ public class ClientboundBundlePacket implements MinecraftPacket { private final List packets; @Override - public void serialize(ByteBuf buf) { + public void serialize(ByteBuf out) { } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundGameTestHighlightPosPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundGameTestHighlightPosPacket.java new file mode 100644 index 000000000..f6a5f4f23 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundGameTestHighlightPosPacket.java @@ -0,0 +1,35 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.cloudburstmc.math.vector.Vector3i; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; + +@Data +@With +@AllArgsConstructor +public class ClientboundGameTestHighlightPosPacket implements MinecraftPacket { + private final Vector3i absolutePos; + private final Vector3i relativePos; + + public ClientboundGameTestHighlightPosPacket(ByteBuf in) { + this.absolutePos = MinecraftTypes.readPosition(in); + this.relativePos = MinecraftTypes.readPosition(in); + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writePosition(out, this.absolutePos); + MinecraftTypes.writePosition(out, this.relativePos); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundRecipeBookSettingsPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundRecipeBookSettingsPacket.java index 76d3be053..5fd028fdd 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundRecipeBookSettingsPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundRecipeBookSettingsPacket.java @@ -23,15 +23,15 @@ public ClientboundRecipeBookSettingsPacket(ByteBuf in) { } @Override - public void serialize(ByteBuf buf) { - buf.writeBoolean(this.crafting.open()); - buf.writeBoolean(this.crafting.filtering()); - buf.writeBoolean(this.furnace.open()); - buf.writeBoolean(this.furnace.filtering()); - buf.writeBoolean(this.blastFurnace.open()); - buf.writeBoolean(this.blastFurnace.filtering()); - buf.writeBoolean(this.smoker.open()); - buf.writeBoolean(this.smoker.filtering()); + public void serialize(ByteBuf out) { + out.writeBoolean(this.crafting.open()); + out.writeBoolean(this.crafting.filtering()); + out.writeBoolean(this.furnace.open()); + out.writeBoolean(this.furnace.filtering()); + out.writeBoolean(this.blastFurnace.open()); + out.writeBoolean(this.blastFurnace.filtering()); + out.writeBoolean(this.smoker.open()); + out.writeBoolean(this.smoker.filtering()); } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugBlockValuePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugBlockValuePacket.java new file mode 100644 index 000000000..29077d16d --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugBlockValuePacket.java @@ -0,0 +1,39 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.cloudburstmc.math.vector.Vector3i; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; +import org.jetbrains.annotations.Nullable; + +@Data +@With +@AllArgsConstructor +public class ClientboundDebugBlockValuePacket implements MinecraftPacket { + private final Vector3i blockPos; + private final DebugSubscriptions subscriptionType; + private final @Nullable DebugInfo subscription; + + public ClientboundDebugBlockValuePacket(ByteBuf in) { + this.blockPos = MinecraftTypes.readPosition(in); + this.subscriptionType = DebugSubscriptions.from(MinecraftTypes.readVarInt(in)); + this.subscription = MinecraftTypes.readDebugSubscriptionUpdate(in, this.subscriptionType); + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writePosition(out, this.blockPos); + MinecraftTypes.writeVarInt(out, this.subscriptionType.ordinal()); + MinecraftTypes.writeDebugSubscriptionUpdate(out, this.subscriptionType, this.subscription); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugChunkValuePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugChunkValuePacket.java new file mode 100644 index 000000000..e974686f6 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugChunkValuePacket.java @@ -0,0 +1,43 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.cloudburstmc.math.vector.Vector3i; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; +import org.jetbrains.annotations.Nullable; + +@Data +@With +@AllArgsConstructor +public class ClientboundDebugChunkValuePacket implements MinecraftPacket { + private final int chunkX; + private final int chunkZ; + private final DebugSubscriptions subscriptionType; + private final @Nullable DebugInfo subscription; + + public ClientboundDebugChunkValuePacket(ByteBuf in) { + long chunkPos = in.readLong(); + this.chunkX = (int)chunkPos; + this.chunkZ = (int)(chunkPos >> 32); + + this.subscriptionType = DebugSubscriptions.from(MinecraftTypes.readVarInt(in)); + this.subscription = MinecraftTypes.readDebugSubscriptionUpdate(in, this.subscriptionType); + } + + @Override + public void serialize(ByteBuf out) { + out.writeLong(this.chunkX & 0xffffffffL | (this.chunkZ & 0xffffffffL) << 32); + MinecraftTypes.writeVarInt(out, this.subscriptionType.ordinal()); + MinecraftTypes.writeDebugSubscriptionUpdate(out, this.subscriptionType, this.subscription); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEntityValuePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEntityValuePacket.java new file mode 100644 index 000000000..cf659caeb --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEntityValuePacket.java @@ -0,0 +1,39 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.cloudburstmc.math.vector.Vector3i; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; +import org.jetbrains.annotations.Nullable; + +@Data +@With +@AllArgsConstructor +public class ClientboundDebugEntityValuePacket implements MinecraftPacket { + private final int entityId; + private final DebugSubscriptions subscriptionType; + private final @Nullable DebugInfo subscription; + + public ClientboundDebugEntityValuePacket(ByteBuf in) { + this.entityId = MinecraftTypes.readVarInt(in); + this.subscriptionType = DebugSubscriptions.from(MinecraftTypes.readVarInt(in)); + this.subscription = MinecraftTypes.readDebugSubscriptionUpdate(in, this.subscriptionType); + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writeVarInt(out, this.entityId); + MinecraftTypes.writeVarInt(out, this.subscriptionType.ordinal()); + MinecraftTypes.writeDebugSubscriptionUpdate(out, this.subscriptionType, this.subscription); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEventPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEventPacket.java new file mode 100644 index 000000000..9b9b78826 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugEventPacket.java @@ -0,0 +1,34 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugInfo; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; + +@Data +@With +@AllArgsConstructor +public class ClientboundDebugEventPacket implements MinecraftPacket { + private final DebugSubscriptions subscriptionType; + private final DebugInfo subscription; + + public ClientboundDebugEventPacket(ByteBuf in) { + this.subscriptionType = DebugSubscriptions.from(MinecraftTypes.readVarInt(in)); + this.subscription = MinecraftTypes.readDebugSubscription(in, this.subscriptionType); + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writeVarInt(out, this.subscriptionType.ordinal()); + MinecraftTypes.writeDebugSubscription(out, this.subscriptionType, this.subscription); + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundDebugSamplePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugSamplePacket.java similarity index 90% rename from protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundDebugSamplePacket.java rename to protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugSamplePacket.java index 95a27425c..b6074a0f9 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/ClientboundDebugSamplePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/debug/ClientboundDebugSamplePacket.java @@ -1,4 +1,4 @@ -package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound; +package org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.debug; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; @@ -6,7 +6,7 @@ import lombok.With; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; -import org.geysermc.mcprotocollib.protocol.data.game.RemoteDebugSampleType; +import org.geysermc.mcprotocollib.protocol.data.game.debug.RemoteDebugSampleType; @Data @With diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundAddEntityPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundAddEntityPacket.java index 9998e1849..bc17d3e1d 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundAddEntityPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundAddEntityPacket.java @@ -5,6 +5,7 @@ import lombok.Data; import lombok.NonNull; import lombok.With; +import org.cloudburstmc.math.vector.Vector3d; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; @@ -31,27 +32,25 @@ public class ClientboundAddEntityPacket implements MinecraftPacket { private final double x; private final double y; private final double z; + private final Vector3d movement; private final float yaw; private final float headYaw; private final float pitch; - private final double motionX; - private final double motionY; - private final double motionZ; public ClientboundAddEntityPacket(int entityId, @NonNull UUID uuid, @NonNull EntityType type, double x, double y, double z, float yaw, float pitch, float headYaw) { - this(entityId, uuid, type, EMPTY_DATA, x, y, z, yaw, headYaw, pitch, 0, 0, 0); + this(entityId, uuid, type, EMPTY_DATA, x, y, z, Vector3d.ZERO, yaw, headYaw, pitch); } public ClientboundAddEntityPacket(int entityId, @NonNull UUID uuid, @NonNull EntityType type, @NonNull ObjectData data, double x, double y, double z, float yaw, float pitch, float headYaw) { - this(entityId, uuid, type, data, x, y, z, yaw, headYaw, pitch, 0, 0, 0); + this(entityId, uuid, type, data, x, y, z, Vector3d.ZERO, yaw, headYaw, pitch); } public ClientboundAddEntityPacket(int entityId, @NonNull UUID uuid, @NonNull EntityType type, - double x, double y, double z, float yaw, float pitch, - float headYaw, double motionX, double motionY, double motionZ) { - this(entityId, uuid, type, EMPTY_DATA, x, y, z, yaw, headYaw, pitch, motionX, motionY, motionZ); + double x, double y, double z, Vector3d movement, float yaw, + float pitch, float headYaw) { + this(entityId, uuid, type, EMPTY_DATA, x, y, z, movement, yaw, headYaw, pitch); } public ClientboundAddEntityPacket(ByteBuf in) { @@ -61,6 +60,7 @@ public ClientboundAddEntityPacket(ByteBuf in) { this.x = in.readDouble(); this.y = in.readDouble(); this.z = in.readDouble(); + this.movement = MinecraftTypes.readLpVec3(in); this.pitch = in.readByte() * 360 / 256f; this.yaw = in.readByte() * 360 / 256f; this.headYaw = in.readByte() * 360 / 256f; @@ -83,10 +83,6 @@ public ClientboundAddEntityPacket(ByteBuf in) { this.data = new GenericObjectData(data); } } - - this.motionX = in.readShort() / 8000D; - this.motionY = in.readShort() / 8000D; - this.motionZ = in.readShort() / 8000D; } @Override @@ -97,6 +93,7 @@ public void serialize(ByteBuf out) { out.writeDouble(this.x); out.writeDouble(this.y); out.writeDouble(this.z); + MinecraftTypes.writeLpVec3(out, this.movement); out.writeByte((byte) (this.pitch * 256 / 360)); out.writeByte((byte) (this.yaw * 256 / 360)); out.writeByte((byte) (this.headYaw * 256 / 360)); @@ -115,10 +112,6 @@ public void serialize(ByteBuf out) { } MinecraftTypes.writeVarInt(out, data); - - out.writeShort((int) (this.motionX * 8000)); - out.writeShort((int) (this.motionY * 8000)); - out.writeShort((int) (this.motionZ * 8000)); } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundSetEntityMotionPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundSetEntityMotionPacket.java index 22bf214a6..3e4aac31b 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundSetEntityMotionPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/ClientboundSetEntityMotionPacket.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.With; +import org.cloudburstmc.math.vector.Vector3d; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; @@ -12,23 +13,17 @@ @AllArgsConstructor public class ClientboundSetEntityMotionPacket implements MinecraftPacket { private final int entityId; - private final double motionX; - private final double motionY; - private final double motionZ; + private final Vector3d movement; public ClientboundSetEntityMotionPacket(ByteBuf in) { this.entityId = MinecraftTypes.readVarInt(in); - this.motionX = in.readShort() / 8000D; - this.motionY = in.readShort() / 8000D; - this.motionZ = in.readShort() / 8000D; + this.movement = MinecraftTypes.readLpVec3(in); } @Override public void serialize(ByteBuf out) { MinecraftTypes.writeVarInt(out, this.entityId); - out.writeShort((int) (this.motionX * 8000)); - out.writeShort((int) (this.motionY * 8000)); - out.writeShort((int) (this.motionZ * 8000)); + MinecraftTypes.writeLpVec3(out, this.movement); } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/player/ClientboundPlayerRotationPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/player/ClientboundPlayerRotationPacket.java index 90e7d784b..056edea8f 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/player/ClientboundPlayerRotationPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/entity/player/ClientboundPlayerRotationPacket.java @@ -11,17 +11,23 @@ @AllArgsConstructor public class ClientboundPlayerRotationPacket implements MinecraftPacket { private final float yRot; + private final boolean relativeY; private final float xRot; + private final boolean relativeX; public ClientboundPlayerRotationPacket(ByteBuf in) { this.yRot = in.readFloat(); + this.relativeY = in.readBoolean(); this.xRot = in.readFloat(); + this.relativeX = in.readBoolean(); } @Override public void serialize(ByteBuf out) { out.writeFloat(this.yRot); + out.writeBoolean(this.relativeY); out.writeFloat(this.xRot); + out.writeBoolean(this.relativeX); } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundBlockEventPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundBlockEventPacket.java index 01c31471c..960275b0c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundBlockEventPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundBlockEventPacket.java @@ -40,15 +40,15 @@ public class ClientboundBlockEventPacket implements MinecraftPacket { private static final int NOTE_BLOCK = 109; private static final int STICKY_PISTON = 128; private static final int PISTON = 138; - private static final int MOB_SPAWNER = 185; - private static final int CHEST = 188; - private static final int ENDER_CHEST = 369; - private static final int TRAPPED_CHEST = 438; - private static final int END_GATEWAY = 635; - private static final int SHULKER_BOX_LOWER = 645; - private static final int SHULKER_BOX_HIGHER = 661; - private static final int BELL = 816; - private static final int DECORATED_POT = 1092; + private static final int MOB_SPAWNER = 197; + private static final int CHEST = 200; + private static final int ENDER_CHEST = 399; + private static final int TRAPPED_CHEST = 468; + private static final int END_GATEWAY = 665; + private static final int SHULKER_BOX_LOWER = 675; + private static final int SHULKER_BOX_HIGHER = 691; + private static final int BELL = 846; + private static final int DECORATED_POT = 1153; private static final Logger log = LoggerFactory.getLogger(ClientboundBlockEventPacket.class); private final @NonNull Vector3i position; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java index 056d36fbc..aa7a525b0 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundExplodePacket.java @@ -8,6 +8,7 @@ import org.cloudburstmc.math.vector.Vector3d; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.WeightedList; import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound; import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound; @@ -19,15 +20,21 @@ @AllArgsConstructor public class ClientboundExplodePacket implements MinecraftPacket { private final Vector3d center; + private final float radius; + private final int blockCount; private final @Nullable Vector3d playerKnockback; private final @NonNull Particle explosionParticle; private final @NonNull Sound explosionSound; + private final @NonNull WeightedList blockParticles; public ClientboundExplodePacket(ByteBuf in) { this.center = Vector3d.from(in.readDouble(), in.readDouble(), in.readDouble()); + this.radius = in.readFloat(); + this.blockCount = in.readInt(); this.playerKnockback = MinecraftTypes.readNullable(in, (input) -> Vector3d.from(input.readDouble(), input.readDouble(), input.readDouble())); this.explosionParticle = MinecraftTypes.readParticle(in); this.explosionSound = MinecraftTypes.readById(in, BuiltinSound::from, MinecraftTypes::readSoundEvent); + this.blockParticles = new WeightedList<>(in, BlockParticleInfo::new); } @Override @@ -35,6 +42,8 @@ public void serialize(ByteBuf out) { out.writeDouble(this.center.getX()); out.writeDouble(this.center.getY()); out.writeDouble(this.center.getZ()); + out.writeFloat(radius); + out.writeInt(blockCount); MinecraftTypes.writeNullable(out, this.playerKnockback, (output, playerKnockback) -> { output.writeDouble(playerKnockback.getX()); output.writeDouble(playerKnockback.getY()); @@ -47,10 +56,24 @@ public void serialize(ByteBuf out) { } else { MinecraftTypes.writeVarInt(out, ((BuiltinSound) this.explosionSound).ordinal() + 1); } + blockParticles.write(out, BlockParticleInfo::write); } @Override public boolean shouldRunOnGameThread() { return true; } + + public record BlockParticleInfo(Particle particle, float scaling, float speed) { + + public BlockParticleInfo(ByteBuf in) { + this(MinecraftTypes.readParticle(in), in.readFloat(), in.readFloat()); + } + + public void write(ByteBuf out) { + MinecraftTypes.writeParticle(out, particle); + out.writeFloat(scaling); + out.writeFloat(speed); + } + } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetDefaultSpawnPositionPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetDefaultSpawnPositionPacket.java index 804811184..6618d2e96 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetDefaultSpawnPositionPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetDefaultSpawnPositionPacket.java @@ -3,28 +3,30 @@ import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.NonNull; import lombok.With; -import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; @Data @With @AllArgsConstructor public class ClientboundSetDefaultSpawnPositionPacket implements MinecraftPacket { - private final @NonNull Vector3i position; - private final float angle; + private final GlobalPos globalPos; + private final float yaw; + private final float pitch; public ClientboundSetDefaultSpawnPositionPacket(ByteBuf in) { - this.position = MinecraftTypes.readPosition(in); - this.angle = in.readFloat(); + this.globalPos = MinecraftTypes.readGlobalPos(in); + this.yaw = in.readFloat(); + this.pitch = in.readFloat(); } @Override public void serialize(ByteBuf out) { - MinecraftTypes.writePosition(out, this.position); - out.writeFloat(this.angle); + MinecraftTypes.writeGlobalPos(out, this.globalPos); + out.writeFloat(this.yaw); + out.writeFloat(this.pitch); } @Override diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSampleSubscriptionPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSampleSubscriptionPacket.java deleted file mode 100644 index 6361cc616..000000000 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSampleSubscriptionPacket.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound; - -import io.netty.buffer.ByteBuf; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.With; -import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; -import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; -import org.geysermc.mcprotocollib.protocol.data.game.RemoteDebugSampleType; - -@Data -@With -@AllArgsConstructor -public class ServerboundDebugSampleSubscriptionPacket implements MinecraftPacket { - private final RemoteDebugSampleType debugSampleType; - - public ServerboundDebugSampleSubscriptionPacket(ByteBuf in) { - this.debugSampleType = RemoteDebugSampleType.from(MinecraftTypes.readVarInt(in)); - } - - @Override - public void serialize(ByteBuf out) { - MinecraftTypes.writeVarInt(out, this.debugSampleType.ordinal()); - } - - @Override - public boolean shouldRunOnGameThread() { - return true; - } -} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSubscriptionRequestPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSubscriptionRequestPacket.java new file mode 100644 index 000000000..25e214f3f --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/ingame/serverbound/ServerboundDebugSubscriptionRequestPacket.java @@ -0,0 +1,40 @@ +package org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.With; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftPacket; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.debug.DebugSubscriptions; + +import java.util.ArrayList; +import java.util.List; + +@Data +@With +@AllArgsConstructor +public class ServerboundDebugSubscriptionRequestPacket implements MinecraftPacket { + private final List subscriptions; + + public ServerboundDebugSubscriptionRequestPacket(ByteBuf in) { + this.subscriptions = new ArrayList<>(); + int length = MinecraftTypes.readVarInt(in); + for (int i = 0; i < length; i++) { + this.subscriptions.add(DebugSubscriptions.from(MinecraftTypes.readVarInt(in))); + } + } + + @Override + public void serialize(ByteBuf out) { + MinecraftTypes.writeVarInt(out, this.subscriptions.size()); + for (DebugSubscriptions subscription : this.subscriptions) { + MinecraftTypes.writeVarInt(out, subscription.ordinal()); + } + } + + @Override + public boolean shouldRunOnGameThread() { + return true; + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundLoginFinishedPacket.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundLoginFinishedPacket.java index ddff0d9f6..3a0203f28 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundLoginFinishedPacket.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/packet/login/clientbound/ClientboundLoginFinishedPacket.java @@ -16,16 +16,12 @@ public class ClientboundLoginFinishedPacket implements MinecraftPacket { private final @NonNull GameProfile profile; public ClientboundLoginFinishedPacket(ByteBuf in) { - GameProfile profile = new GameProfile(MinecraftTypes.readUUID(in), MinecraftTypes.readString(in)); - profile.setProperties(MinecraftTypes.readList(in, MinecraftTypes::readProperty)); - this.profile = profile; + this.profile = MinecraftTypes.readStaticGameProfile(in); } @Override public void serialize(ByteBuf out) { - MinecraftTypes.writeUUID(out, this.profile.getId()); - MinecraftTypes.writeString(out, this.profile.getName()); - MinecraftTypes.writeList(out, this.profile.getProperties(), MinecraftTypes::writeProperty); + MinecraftTypes.writeStaticGameProfile(out, profile); } @Override diff --git a/protocol/src/main/resources/networkCodec.nbt b/protocol/src/main/resources/networkCodec.nbt index 8c9498adf..ae4494d9e 100644 Binary files a/protocol/src/main/resources/networkCodec.nbt and b/protocol/src/main/resources/networkCodec.nbt differ