Compare commits

...
37 Commits
Author SHA1 Message Date
retrooper 5f8efaaf0f Correction in documentation 2023-12-13 21:34:05 +01:00
retrooper 9b8de173e4 EntityMetadataProvider backwards compatibility 2023-12-13 21:30:24 +01:00
retrooper de4594fbdc EntityMetadataProvider abstraction has been completed (now provides a protocol version) 2023-12-13 21:26:09 +01:00
retrooper 5eae00ef0b Minor change to velocity module 2023-12-13 21:07:22 +01:00
retrooper 3c418473d8 Releasing 2.2.0
- Initialization Optimization on Spigot
- bStats support implemented for Velocity
- bStats support implemented for BungeeCord
2023-12-13 21:05:53 +01:00
retrooper 1e919053c6 Merge pull request #623 from booky10/dev/1.20.3
1.20.3/1.20.4 update
2023-12-12 22:39:15 +01:00
booky10 30ff648bad Add handling for unnamed simple components as serialized compounds 2023-12-09 00:57:17 +01:00
booky10 6c5d9beb76 Rewrite adventure nbt serialization
This will now skip building nbt objects and will directly build adventure components
2023-12-09 00:10:46 +01:00
retrooper 3e828ea9ee * Added 1.20.4 version constants
* GRASS -> SHORT_GRASS, but GRASS is deprecated.
* WrapperPlayServerTickingInfo -> WrapperPlayServerTickingState
* WrapperPlayServerTickingStep minor changes
2023-12-08 13:05:03 +01:00
booky10 4ef8b381d7 Fix NPE for adventure nbt deserialization if no translation args are present 2023-12-05 20:44:09 +01:00
booky10 24838cd7d9 Fix new particle type ids being ignored 2023-12-05 20:24:47 +01:00
booky10 e17b877b5f Add crafting and trial_spawner_state state values 2023-12-05 20:11:50 +01:00
booky10 8b85bc8d4d Some various fixes for packet wrappers 2023-12-05 20:03:35 +01:00
booky10 fca9ad22fe Fix wrong config packet type registration 2023-12-05 20:03:17 +01:00
booky10 667652bfb8 Add new resourcepack status for 1.20.3-pre3 2023-11-27 17:29:40 +01:00
booky10 2da42185e8 Rename grass to short_grass for 1.20.3-pre1 2023-11-20 20:23:55 +01:00
booky10 fd1b918956 Update packet structures for 1.20.3-pre1 2023-11-20 20:22:53 +01:00
booky10 828013bf77 Update packet ids for 1.20.3-pre1 2023-11-20 20:22:37 +01:00
booky10 6e30fb393a Move new entitytypes to bottom 2023-11-17 19:13:52 +01:00
booky10 cbfca6c5fa Update block/item tags to 1.20.3
Also fixes incorrect ordering
2023-11-17 18:26:12 +01:00
booky10 945ca46491 Fix missing fields for state types 2023-11-17 16:47:26 +01:00
booky10 f7d5252bf0 WIP new state types 2023-11-16 23:24:07 +01:00
booky10 a624a76427 Add new item types 2023-11-16 22:57:27 +01:00
booky10 39f9ed008c Add new particle types 2023-11-16 22:36:31 +01:00
booky10 a0096b3032 Add breeze and wind charge entity types 2023-11-16 22:31:23 +01:00
booky10 ae1a0258fe Add new game state change "reasons" 2023-11-16 22:22:23 +01:00
booky10 f863ad026f Update explosion packet 2023-11-16 22:17:07 +01:00
booky10 abea90564f Update vibration particle data 2023-11-16 22:01:28 +01:00
booky10 3bdd110864 Fix blockstate registry index not being incremented 2023-11-16 21:47:00 +01:00
booky10 b2e47f48a5 Use nbt-based component read/write methods 2023-11-16 21:45:09 +01:00
booky10 513de88321 Update serverbound jigsaw block packet 2023-11-16 20:11:13 +01:00
booky10 5a49cf2687 Implement packet wrappers for new serverbound packets 2023-11-16 18:49:29 +01:00
booky10 65fba0b83d Implement packet wrappers for new clientbound packets 2023-11-16 18:49:13 +01:00
booky10 5272557f58 Add dummy "style" command argument parser 2023-11-16 18:29:44 +01:00
booky10 51abf38d3f Fix names of command argument parsers 2023-11-16 18:28:55 +01:00
booky10 33abe17a2b Add block mappings for 1.20.3 2023-11-16 18:25:18 +01:00
booky10 593015dd0b Add new packet types 2023-11-16 18:21:29 +01:00
65 changed files with 32699 additions and 544 deletions

No files matched your search

@@ -18,10 +18,13 @@
package com.github.retrooper.packetevents;
import org.jetbrains.annotations.ApiStatus;
public final class PacketEvents {
private static PacketEventsAPI<?> API;
//Put these variable names anywhere else, they are really only for the injectors
@ApiStatus.Internal
public static String IDENTIFIER, ENCODER_NAME, DECODER_NAME, CONNECTION_HANDLER_NAME, SERVER_CHANNEL_HANDLER_NAME,
TIMEOUT_HANDLER_NAME;
@@ -38,7 +38,7 @@ public abstract class PacketEventsAPI<T> {
private final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
private static final LogManager LOG_MANAGER = new LogManager();
//TODO UPDATE
private static final PEVersion VERSION = new PEVersion(2, 1, 0);
private static final PEVersion VERSION = new PEVersion(2, 2, 0);
public EventManager getEventManager() {
return EVENT_MANAGER;
@@ -47,8 +47,8 @@ public enum ServerVersion {
V_1_18(757), V_1_18_1(757), V_1_18_2(758),
//1.19.1 and 1.19.2 have the same protocol version
V_1_19(759), V_1_19_1(760), V_1_19_2(760), V_1_19_3(761), V_1_19_4(762),
//1.20 and 1.20.1 have the same protocol version
V_1_20(763), V_1_20_1(763), V_1_20_2(764),
//1.20 and 1.20.1 have the same protocol version. 1.20.3 and 1.20.4 have the same protocol version.
V_1_20(763), V_1_20_1(763), V_1_20_2(764), V_1_20_3(765), V_1_20_4(765),
//TODO UPDATE Add server version constant
ERROR(-1, true);
@@ -93,70 +93,71 @@ public class Parsers {
packetWrapper -> Collections.singletonList(packetWrapper.readVarInt()),
(packetWrapper, properties) -> packetWrapper.writeVarInt((Integer) properties.get(0))
),
new Parser("brigadier:entity",
new Parser("minecraft:entity",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
),
new Parser("brigadier:game_profile", null, null),
new Parser("brigadier:block_pos", null, null),
new Parser("brigadier:column_pos", null, null),
new Parser("brigadier:vec3", null, null),
new Parser("brigadier:vec2", null, null),
new Parser("brigadier:block_state", null, null),
new Parser("brigadier:block_predicate", null, null),
new Parser("brigadier:item_stack", null, null),
new Parser("brigadier:item_predicate", null, null),
new Parser("brigadier:color", null, null),
new Parser("brigadier:component", null, null),
new Parser("brigadier:message", null, null),
new Parser("brigadier:nbt", null, null),
new Parser("brigadier:nbt_tag", null, null),
new Parser("brigadier:nbt_path", null, null),
new Parser("brigadier:objective", null, null),
new Parser("brigadier:objective_criteria", null, null),
new Parser("brigadier:operation", null, null),
new Parser("brigadier:particle", null, null),
new Parser("brigadier:angle", null, null),
new Parser("brigadier:rotation", null, null),
new Parser("brigadier:scoreboard_slot", null, null),
new Parser("brigadier:score_holder",
new Parser("minecraft:game_profile", null, null),
new Parser("minecraft:block_pos", null, null),
new Parser("minecraft:column_pos", null, null),
new Parser("minecraft:vec3", null, null),
new Parser("minecraft:vec2", null, null),
new Parser("minecraft:block_state", null, null),
new Parser("minecraft:block_predicate", null, null),
new Parser("minecraft:item_stack", null, null),
new Parser("minecraft:item_predicate", null, null),
new Parser("minecraft:color", null, null),
new Parser("minecraft:component", null, null),
new Parser("minecraft:style", null, null),
new Parser("minecraft:message", null, null),
new Parser("minecraft:nbt", null, null),
new Parser("minecraft:nbt_tag", null, null),
new Parser("minecraft:nbt_path", null, null),
new Parser("minecraft:objective", null, null),
new Parser("minecraft:objective_criteria", null, null),
new Parser("minecraft:operation", null, null),
new Parser("minecraft:particle", null, null),
new Parser("minecraft:angle", null, null),
new Parser("minecraft:rotation", null, null),
new Parser("minecraft:scoreboard_slot", null, null),
new Parser("minecraft:score_holder",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
),
new Parser("brigadier:swizzle", null, null),
new Parser("brigadier:team", null, null),
new Parser("brigadier:item_slot", null, null),
new Parser("brigadier:resource_location", null, null),
new Parser("brigadier:function", null, null),
new Parser("brigadier:entity_anchor", null, null),
new Parser("brigadier:int_range", null, null),
new Parser("brigadier:float_range", null, null),
new Parser("brigadier:dimension", null, null),
new Parser("brigadier:gamemode", null, null),
new Parser("brigadier:time",
new Parser("minecraft:swizzle", null, null),
new Parser("minecraft:team", null, null),
new Parser("minecraft:item_slot", null, null),
new Parser("minecraft:resource_location", null, null),
new Parser("minecraft:function", null, null),
new Parser("minecraft:entity_anchor", null, null),
new Parser("minecraft:int_range", null, null),
new Parser("minecraft:float_range", null, null),
new Parser("minecraft:dimension", null, null),
new Parser("minecraft:gamemode", null, null),
new Parser("minecraft:time",
packetWrapper -> Collections.singletonList(packetWrapper.readInt()),
(packetWrapper, properties) -> packetWrapper.writeInt((int) properties.get(0))
),
new Parser("brigadier:resource_or_tag",
new Parser("minecraft:resource_or_tag",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("brigadier:resource_or_tag_key",
new Parser("minecraft:resource_or_tag_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("brigadier:resource",
new Parser("minecraft:resource",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("brigadier:resource_key",
new Parser("minecraft:resource_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("brigadier:template_mirror", null, null),
new Parser("brigadier:template_rotation", null, null),
new Parser("brigadier:heightmap", null, null),
new Parser("brigadier:uuid", null, null)
new Parser("minecraft:template_mirror", null, null),
new Parser("minecraft:template_rotation", null, null),
new Parser("minecraft:heightmap", null, null),
new Parser("minecraft:uuid", null, null)
);
public static List<Parser> getParsers() {
@@ -32,8 +32,13 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.*;
import com.github.retrooper.packetevents.util.Quaternion4f;
import com.github.retrooper.packetevents.util.TypesBuilder;
import com.github.retrooper.packetevents.util.TypesBuilderData;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import java.util.HashMap;
import java.util.Map;
@@ -84,9 +89,13 @@ public class EntityDataTypes {
public static final EntityDataType<String> STRING = define("string", PacketWrapper::readString, PacketWrapper::writeString);
@Deprecated
public static final EntityDataType<String> COMPONENT = define("component", PacketWrapper::readComponentJSON, PacketWrapper::writeComponentJSON);
public static final EntityDataType<Component> ADV_COMPONENT = define("component", PacketWrapper::readComponent, PacketWrapper::writeComponent);
public static final EntityDataType<Optional<String>> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
@Deprecated
public static final EntityDataType<Optional<String>> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentJSONDeserializer(), writeOptionalComponentJSONSerializer());
public static final EntityDataType<Optional<Component>> OPTIONAL_ADV_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
public static final EntityDataType<ItemStack> ITEMSTACK = define("itemstack", PacketWrapper::readItemStack, PacketWrapper::writeItemStack);
@@ -256,26 +265,44 @@ public class EntityDataTypes {
};
}
private static <T> Function<PacketWrapper<?>, T> readOptionalComponentDeserializer() {
@Deprecated
private static Function<PacketWrapper<?>, Optional<String>> readOptionalComponentJSONDeserializer() {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
return (T) Optional.of(wrapper.readString());
return Optional.of(wrapper.readComponentJSON());
} else {
return (T) Optional.empty();
return Optional.empty();
}
};
}
private static <T> BiConsumer<PacketWrapper<?>, T> writeOptionalComponentSerializer() {
return (PacketWrapper<?> wrapper, T value) -> {
if (value instanceof Optional) {
Optional<String> optional = (Optional<String>) value;
if (optional.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeString(optional.get());
} else {
wrapper.writeBoolean(false);
}
@Deprecated
private static BiConsumer<PacketWrapper<?>, Optional<String>> writeOptionalComponentJSONSerializer() {
return (PacketWrapper<?> wrapper, Optional<String> value) -> {
if (value != null && value.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeComponentJSON(value.get());
} else {
wrapper.writeBoolean(false);
}
};
}
private static Function<PacketWrapper<?>, Optional<Component>> readOptionalComponentDeserializer() {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
return Optional.of(wrapper.readComponent());
} else {
return Optional.empty();
}
};
}
private static BiConsumer<PacketWrapper<?>, Optional<Component>> writeOptionalComponentSerializer() {
return (PacketWrapper<?> wrapper, Optional<Component> value) -> {
if (value != null && value.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeComponent(value.get());
} else {
wrapper.writeBoolean(false);
}
@@ -1,7 +1,35 @@
package com.github.retrooper.packetevents.protocol.entity.data;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import java.util.List;
/**
* This is an interface that provides a list of entity data.
* This allows custom addon libraries to implement metadata classes for various entities
* which can then be used in our API.
* @since 2.1.0
*/
public interface EntityMetadataProvider {
List<EntityData> entityData();
/**
* PacketEvents is retrieving the metadata of this specific entity.
* PacketEvents provides you with the protocol version that the library is running on
* to allow you tu specify different metadata depending on the version.
* You are free to ignore it at the cost of your features not working on all versions.
* @param version The protocol version of the format we expect the metadata to be in.
* @return Metadata (list of entity data)
*/
List<EntityData> entityData(ClientVersion version);
/**
* Similar to {@link #entityData(ClientVersion)} but does not provide a protocol version.
* It is not advised to use nor implement this.
* It is deprecated because it restricts you by not providing you the format in which the metadata should be.
* @return Metadata (list of entity data)
* @deprecated Does not specify format of metadata, therefore not advised to use this. It will assume the current latest version.
*/
@Deprecated
default List<EntityData> entityData() {
return entityData(ClientVersion.getLatest());
}
}
@@ -45,7 +45,8 @@ public class EntityTypes {
ClientVersion.V_1_17,
ClientVersion.V_1_19,
ClientVersion.V_1_19_3,
ClientVersion.V_1_19_4);
ClientVersion.V_1_19_4,
ClientVersion.V_1_20_3);
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings",
ClientVersion.V_1_8,
ClientVersion.V_1_9,
@@ -301,11 +302,16 @@ public class EntityTypes {
public static final EntityType MINECART_TNT = define("minecart_tnt", MINECART_ABSTRACT);
public static final EntityType MINECART_HOPPER = define("minecart_hopper", MINECART_ABSTRACT);
public static final EntityType MINECART_MOB_SPAWNER = define("minecart_mob_spawner", MINECART_ABSTRACT);
// Display type entities added in 1.19.4
// Added in 1.19.4
public static final EntityType DISPLAY = define("display", ENTITY);
public static final EntityType BLOCK_DISPLAY = define("block_display", DISPLAY);
public static final EntityType ITEM_DISPLAY = define("item_display", DISPLAY);
public static final EntityType TEXT_DISPLAY = define("text_display", DISPLAY);
public static final EntityType INTERACTION = define("interaction", DISPLAY);
public static final EntityType SNIFFER = define("sniffer", ABSTRACT_ANIMAL);
// Added in 1.20.3
public static final EntityType BREEZE = define("breeze", ABSTRACT_MONSTER);
public static final EntityType WIND_CHARGE = define("wind_charge", PROJECTILE_ABSTRACT);
}
@@ -27,7 +27,14 @@ import com.github.retrooper.packetevents.util.TypesBuilderData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class ItemTypes {
@@ -47,7 +54,8 @@ public class ItemTypes {
ClientVersion.V_1_19,
ClientVersion.V_1_19_3,
ClientVersion.V_1_19_4,
ClientVersion.V_1_20);
ClientVersion.V_1_20,
ClientVersion.V_1_20_3);
public static final ItemType GILDED_BLACKSTONE = builder("gilded_blackstone").setMaxAmount(64).setPlacedType(StateTypes.GILDED_BLACKSTONE).build();
public static final ItemType NETHER_BRICK_SLAB = builder("nether_brick_slab").setMaxAmount(64).setPlacedType(StateTypes.NETHER_BRICK_SLAB).build();
@@ -628,7 +636,11 @@ public class ItemTypes {
public static final ItemType RAW_COPPER_BLOCK = builder("raw_copper_block").setMaxAmount(64).setPlacedType(StateTypes.RAW_COPPER_BLOCK).build();
public static final ItemType LIGHT_GRAY_CARPET = builder("light_gray_carpet").setMaxAmount(64).setAttributes(ItemAttribute.FUEL).setPlacedType(StateTypes.LIGHT_GRAY_CARPET).build();
public static final ItemType MUSIC_DISC_WARD = builder("music_disc_ward").setMaxAmount(1).setAttributes(ItemAttribute.MUSIC_DISC).build();
public static final ItemType GRASS = builder("grass").setMaxAmount(64).setPlacedType(StateTypes.GRASS).build();
public static final ItemType SHORT_GRASS = builder("short_grass").setMaxAmount(64).setPlacedType(StateTypes.SHORT_GRASS).build();
@Deprecated
public static final ItemType GRASS = SHORT_GRASS;
public static final ItemType END_CRYSTAL = builder("end_crystal").setMaxAmount(64).build();
public static final ItemType VINDICATOR_SPAWN_EGG = builder("vindicator_spawn_egg").setMaxAmount(64).build();
public static final ItemType WHEAT = builder("wheat").setMaxAmount(64).build();
@@ -1310,6 +1322,66 @@ public class ItemTypes {
public static ItemType SHELTER_POTTERY_SHERD = builder("SHELTER_POTTERY_SHERD").setMaxAmount(64).build();
public static ItemType SKULL_POTTERY_SHERD = builder("SKULL_POTTERY_SHERD").setMaxAmount(64).build();
public static ItemType SNORT_POTTERY_SHERD = builder("SNORT_POTTERY_SHERD").setMaxAmount(64).build();
// 1.20.3 items
public static ItemType TUFF_SLAB = builder("tuff_slab").setMaxAmount(64).setPlacedType(StateTypes.TUFF_SLAB).build();
public static ItemType TUFF_STAIRS = builder("tuff_stairs").setMaxAmount(64).setPlacedType(StateTypes.TUFF_STAIRS).build();
public static ItemType TUFF_WALL = builder("tuff_wall").setMaxAmount(64).setPlacedType(StateTypes.TUFF_WALL).build();
public static ItemType CHISELED_TUFF = builder("chiseled_tuff").setMaxAmount(64).setPlacedType(StateTypes.CHISELED_TUFF).build();
public static ItemType POLISHED_TUFF = builder("polished_tuff").setMaxAmount(64).setPlacedType(StateTypes.POLISHED_TUFF).build();
public static ItemType POLISHED_TUFF_SLAB = builder("polished_tuff_slab").setMaxAmount(64).setPlacedType(StateTypes.POLISHED_TUFF_SLAB).build();
public static ItemType POLISHED_TUFF_STAIRS = builder("polished_tuff_stairs").setMaxAmount(64).setPlacedType(StateTypes.POLISHED_TUFF_STAIRS).build();
public static ItemType POLISHED_TUFF_WALL = builder("polished_tuff_wall").setMaxAmount(64).setPlacedType(StateTypes.POLISHED_TUFF_WALL).build();
public static ItemType TUFF_BRICKS = builder("tuff_bricks").setMaxAmount(64).setPlacedType(StateTypes.TUFF_BRICKS).build();
public static ItemType TUFF_BRICK_SLAB = builder("tuff_brick_slab").setMaxAmount(64).setPlacedType(StateTypes.TUFF_BRICK_SLAB).build();
public static ItemType TUFF_BRICK_STAIRS = builder("tuff_brick_stairs").setMaxAmount(64).setPlacedType(StateTypes.TUFF_BRICK_STAIRS).build();
public static ItemType TUFF_BRICK_WALL = builder("tuff_brick_wall").setMaxAmount(64).setPlacedType(StateTypes.TUFF_BRICK_WALL).build();
public static ItemType CHISELED_TUFF_BRICKS = builder("chiseled_tuff_bricks").setMaxAmount(64).setPlacedType(StateTypes.CHISELED_TUFF_BRICKS).build();
public static ItemType CHISELED_COPPER = builder("chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.CHISELED_COPPER).build();
public static ItemType EXPOSED_CHISELED_COPPER = builder("exposed_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_CHISELED_COPPER).build();
public static ItemType WEATHERED_CHISELED_COPPER = builder("weathered_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_CHISELED_COPPER).build();
public static ItemType OXIDIZED_CHISELED_COPPER = builder("oxidized_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_CHISELED_COPPER).build();
public static ItemType WAXED_CHISELED_COPPER = builder("waxed_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.WAXED_CHISELED_COPPER).build();
public static ItemType WAXED_EXPOSED_CHISELED_COPPER = builder("waxed_exposed_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_CHISELED_COPPER).build();
public static ItemType WAXED_WEATHERED_CHISELED_COPPER = builder("waxed_weathered_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_CHISELED_COPPER).build();
public static ItemType WAXED_OXIDIZED_CHISELED_COPPER = builder("waxed_oxidized_chiseled_copper").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_CHISELED_COPPER).build();
public static ItemType COPPER_DOOR = builder("copper_door").setMaxAmount(64).setPlacedType(StateTypes.COPPER_DOOR).build();
public static ItemType EXPOSED_COPPER_DOOR = builder("exposed_copper_door").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_DOOR).build();
public static ItemType WEATHERED_COPPER_DOOR = builder("weathered_copper_door").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_DOOR).build();
public static ItemType OXIDIZED_COPPER_DOOR = builder("oxidized_copper_door").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_DOOR).build();
public static ItemType WAXED_COPPER_DOOR = builder("waxed_copper_door").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_DOOR).build();
public static ItemType WAXED_EXPOSED_COPPER_DOOR = builder("waxed_exposed_copper_door").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_DOOR).build();
public static ItemType WAXED_WEATHERED_COPPER_DOOR = builder("waxed_weathered_copper_door").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_DOOR).build();
public static ItemType WAXED_OXIDIZED_COPPER_DOOR = builder("waxed_oxidized_copper_door").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_DOOR).build();
public static ItemType COPPER_TRAPDOOR = builder("copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.COPPER_TRAPDOOR).build();
public static ItemType EXPOSED_COPPER_TRAPDOOR = builder("exposed_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_TRAPDOOR).build();
public static ItemType WEATHERED_COPPER_TRAPDOOR = builder("weathered_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_TRAPDOOR).build();
public static ItemType OXIDIZED_COPPER_TRAPDOOR = builder("oxidized_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_TRAPDOOR).build();
public static ItemType WAXED_COPPER_TRAPDOOR = builder("waxed_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_TRAPDOOR).build();
public static ItemType WAXED_EXPOSED_COPPER_TRAPDOOR = builder("waxed_exposed_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_TRAPDOOR).build();
public static ItemType WAXED_WEATHERED_COPPER_TRAPDOOR = builder("waxed_weathered_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_TRAPDOOR).build();
public static ItemType WAXED_OXIDIZED_COPPER_TRAPDOOR = builder("waxed_oxidized_copper_trapdoor").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_TRAPDOOR).build();
public static ItemType CRAFTER = builder("crafter").setMaxAmount(64).setPlacedType(StateTypes.CRAFTER).build();
public static ItemType BREEZE_SPAWN_EGG = builder("breeze_spawn_egg").setMaxAmount(64).build();
public static ItemType COPPER_GRATE = builder("copper_grate").setMaxAmount(64).setPlacedType(StateTypes.COPPER_GRATE).build();
public static ItemType EXPOSED_COPPER_GRATE = builder("exposed_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_GRATE).build();
public static ItemType WEATHERED_COPPER_GRATE = builder("weathered_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_GRATE).build();
public static ItemType OXIDIZED_COPPER_GRATE = builder("oxidized_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_GRATE).build();
public static ItemType WAXED_COPPER_GRATE = builder("waxed_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_GRATE).build();
public static ItemType WAXED_EXPOSED_COPPER_GRATE = builder("waxed_exposed_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_GRATE).build();
public static ItemType WAXED_WEATHERED_COPPER_GRATE = builder("waxed_weathered_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_GRATE).build();
public static ItemType WAXED_OXIDIZED_COPPER_GRATE = builder("waxed_oxidized_copper_grate").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_GRATE).build();
public static ItemType COPPER_BULB = builder("copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.COPPER_BULB).build();
public static ItemType EXPOSED_COPPER_BULB = builder("exposed_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_BULB).build();
public static ItemType WEATHERED_COPPER_BULB = builder("weathered_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_BULB).build();
public static ItemType OXIDIZED_COPPER_BULB = builder("oxidized_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_BULB).build();
public static ItemType WAXED_COPPER_BULB = builder("waxed_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_BULB).build();
public static ItemType WAXED_EXPOSED_COPPER_BULB = builder("waxed_exposed_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_BULB).build();
public static ItemType WAXED_WEATHERED_COPPER_BULB = builder("waxed_weathered_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_BULB).build();
public static ItemType WAXED_OXIDIZED_COPPER_BULB = builder("waxed_oxidized_copper_bulb").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_BULB).build();
public static ItemType TRIAL_SPAWNER = builder("trial_spawner").setMaxAmount(64).setPlacedType(StateTypes.TRIAL_SPAWNER).build();
public static ItemType TRIAL_KEY = builder("trial_key").setMaxAmount(64).build();
/**
* @deprecated Burning furnace shows up as a missing texture, removed in 1.9
*/
@@ -1318,14 +1390,17 @@ public class ItemTypes {
/**
* @deprecated Fire was removed in 1.8 as an item
*/
@Deprecated
public static final ItemType FIRE = builder("fire").setMaxAmount(64).build();
/**
* @deprecated Nether portals were removed in 1.8 as an item
*/
@Deprecated
public static final ItemType NETHER_PORTAL = builder("nether_portal").setMaxAmount(1).build();
/**
* @deprecated End portals were removed in 1.8 as an item
*/
@Deprecated
public static final ItemType END_PORTAL = builder("end_portal").setMaxAmount(1).build();
public static Collection<ItemType> values() {
@@ -148,10 +148,14 @@ public class NBTCodec {
//PacketEvents end
public static NBTCompound readNBTFromBuffer(Object byteBuf, ServerVersion serverVersion) {
return (NBTCompound) readRawNBTFromBuffer(byteBuf, serverVersion);
}
public static NBT readRawNBTFromBuffer(Object byteBuf, ServerVersion serverVersion) {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
try {
boolean named = serverVersion.isOlderThan(ServerVersion.V_1_20_2);
return (NBTCompound) DefaultNBTSerializer.INSTANCE.deserializeTag(
final boolean named = serverVersion.isOlderThan(ServerVersion.V_1_20_2);
return DefaultNBTSerializer.INSTANCE.deserializeTag(
new ByteBufInputStream(byteBuf), named);
} catch (IOException e) {
e.printStackTrace();
@@ -166,7 +170,7 @@ public class NBTCodec {
Object slicedBuffer = ByteBufHelper.readSlice(byteBuf, length);
try (DataInputStream stream = new DataInputStream(
new GZIPInputStream(new ByteBufInputStream(slicedBuffer)))) {
return (NBTCompound) DefaultNBTSerializer.INSTANCE.deserializeTag(stream);
return DefaultNBTSerializer.INSTANCE.deserializeTag(stream);
}
}
catch (IOException ex) {
@@ -177,6 +181,10 @@ public class NBTCodec {
}
public static void writeNBTToBuffer(Object byteBuf, ServerVersion serverVersion, NBTCompound tag) {
writeNBTToBuffer(byteBuf, serverVersion, (NBT) tag);
}
public static void writeNBTToBuffer(Object byteBuf, ServerVersion serverVersion, NBT tag) {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
try (ByteBufOutputStream outputStream = new ByteBufOutputStream(byteBuf)) {
if (tag != null) {
@@ -2,7 +2,7 @@ package com.github.retrooper.packetevents.protocol.packettype;
/**
* A Marker interface used to indicate that this packet is originating on
* the server, and is bound for the client.
* the server, and is bound to the client.
*/
public interface ClientBoundPacket {
@@ -20,8 +20,46 @@ package com.github.retrooper.packetevents.protocol.packettype;
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.*;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.*;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_12;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_12_1;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_13;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_14;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_14_4;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_15;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_15_2;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_16;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_16_2;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_17;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_18;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_19;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_19_1;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_19_3;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_19_4;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_20_2;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_20_3;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_9;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_9_3;
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_20_2;
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_20_3;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_12;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_12_1;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_13;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_14;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_15_2;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_16;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_16_2;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_17;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_19;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_19_1;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_19_3;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_19_4;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_20_2;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_20_3;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_9;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.VersionMapper;
import org.jetbrains.annotations.Nullable;
@@ -53,7 +91,8 @@ public final class PacketType {
ClientVersion.V_1_19_1,
ClientVersion.V_1_19_3,
ClientVersion.V_1_19_4,
ClientVersion.V_1_20_2);
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3);
//TODO UPDATE Update packet type mappings (serverbound pt. 1)
private static final VersionMapper SERVERBOUND_PLAY_VERSION_MAPPER = new VersionMapper(
@@ -72,11 +111,18 @@ public final class PacketType {
ClientVersion.V_1_19_1,
ClientVersion.V_1_19_3,
ClientVersion.V_1_19_4,
ClientVersion.V_1_20_2);
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3);
//TODO UPDATE Update packet type mappings (config clientbound pt. 1)
private static final VersionMapper CLIENTBOUND_CONFIG_VERSION_MAPPER = new VersionMapper(
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3);
public static void prepare() {
PacketType.Play.Client.load();
PacketType.Play.Server.load();
PacketType.Configuration.Server.load();
PREPARED = true;
}
@@ -114,7 +160,7 @@ public final class PacketType {
if (side == PacketSide.CLIENT) {
return Configuration.Client.getById(packetID);
} else {
return Configuration.Server.getById(packetID);
return Configuration.Server.getById(version, packetID);
}
default:
return null;
@@ -330,7 +376,7 @@ public final class PacketType {
}
}
}
// Added in 1.20.2
public static class Configuration {
@@ -379,57 +425,79 @@ public final class PacketType {
}
}
public enum Server implements PacketTypeConstant, ClientBoundPacket {
public enum Server implements PacketTypeCommon, ClientBoundPacket {
PLUGIN_MESSAGE(0x00),
DISCONNECT(0x01),
CONFIGURATION_END(0x02),
KEEP_ALIVE(0x03),
PING(0x04),
REGISTRY_DATA(0x05),
RESOURCE_PACK_SEND(0x06),
UPDATE_ENABLED_FEATURES(0x07),
UPDATE_TAGS(0x08);
PLUGIN_MESSAGE,
DISCONNECT,
CONFIGURATION_END,
KEEP_ALIVE,
PING,
REGISTRY_DATA,
RESOURCE_PACK_SEND,
UPDATE_ENABLED_FEATURES,
UPDATE_TAGS,
private final int id;
// added in 1.20.3
RESOURCE_PACK_REMOVE;
Server(int id) {
this.id = id;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
private final int[] ids;
Server() {
this.ids = new int[CLIENTBOUND_CONFIG_VERSION_MAPPER.getVersions().length];
Arrays.fill(this.ids, -1);
}
public static void load() {
INDEX = 0;
loadPacketIds(ClientboundConfigPacketType_1_20_2.values());
loadPacketIds(ClientboundConfigPacketType_1_20_3.values());
// TODO UPDATE Update packet type mappings (config clientbound pt. 2)
}
private static void loadPacketIds(Enum<?>[] enumConstants) {
int index = INDEX;
for (Enum<?> constant : enumConstants) {
int id = constant.ordinal();
Configuration.Server value = Configuration.Server.valueOf(constant.name());
value.ids[index] = id;
Map<Integer, PacketTypeCommon> packetIdMap = PACKET_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
packetIdMap.put(id, value);
}
INDEX++;
}
public static @Nullable PacketTypeCommon getById(int packetId) {
switch (packetId) {
case 0x00:
return PLUGIN_MESSAGE;
case 0x01:
return DISCONNECT;
case 0x02:
return CONFIGURATION_END;
case 0x03:
return KEEP_ALIVE;
case 0x04:
return PING;
case 0x05:
return REGISTRY_DATA;
case 0x06:
return RESOURCE_PACK_SEND;
case 0x07:
return UPDATE_ENABLED_FEATURES;
case 0x08:
return UPDATE_TAGS;
default:
return null;
return getById(ClientVersion.getLatest(), packetId);
}
public static @Nullable PacketTypeCommon getById(ClientVersion version, int packetId) {
if (!PREPARED) {
PacketType.prepare();
}
int index = CLIENTBOUND_CONFIG_VERSION_MAPPER.getIndex(version);
Map<Integer, PacketTypeCommon> map = PACKET_TYPE_ID_MAP.get((byte) index);
return map.get(packetId);
}
@Deprecated
public int getId() {
return this.getId(ClientVersion.getLatest());
}
@Override
public int getId() {
return this.id;
public int getId(ClientVersion version) {
if (!PREPARED) {
PacketType.prepare();
}
int index = CLIENTBOUND_CONFIG_VERSION_MAPPER.getIndex(version);
return this.ids[index];
}
@Override
public PacketSide getSide() {
return PacketSide.CLIENT;
return PacketSide.SERVER;
}
}
}
@@ -498,7 +566,9 @@ public final class PacketType {
//Added in 1.20.2
CHUNK_BATCH_ACK,
CONFIGURATION_ACK,
DEBUG_PING;
DEBUG_PING,
//Added in 1.20.3
SLOT_STATE_CHANGE;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
@@ -515,7 +585,7 @@ public final class PacketType {
PacketType.prepare();
}
int index = SERVERBOUND_PLAY_VERSION_MAPPER.getIndex(version);
Map<Integer, PacketTypeCommon> packetIdMap = PACKET_TYPE_ID_MAP.computeIfAbsent((byte)index, k -> new HashMap<>());
Map<Integer, PacketTypeCommon> packetIdMap = PACKET_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
return packetIdMap.get(packetId);
}
@@ -550,6 +620,7 @@ public final class PacketType {
loadPacketIds(ServerboundPacketType_1_19_3.values());
loadPacketIds(ServerboundPacketType_1_19_4.values());
loadPacketIds(ServerboundPacketType_1_20_2.values());
loadPacketIds(ServerboundPacketType_1_20_3.values());
//TODO UPDATE Update packet type mappings (serverbound pt. 2)
}
@@ -704,16 +775,24 @@ public final class PacketType {
DISGUISED_CHAT,
PLAYER_INFO_REMOVE,
PLAYER_INFO_UPDATE,
//Added in 1.19.4
DAMAGE_EVENT,
HURT_ANIMATION,
BUNDLE,
CHUNK_BIOMES,
//Added in 1.20.2
CHUNK_BATCH_END,
CHUNK_BATCH_BEGIN,
DEBUG_PONG,
CONFIGURATION_START;
CONFIGURATION_START,
//Added in 1.20.3
RESET_SCORE,
RESOURCE_PACK_REMOVE,
TICKING_STATE,
TICKING_STEP;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
@@ -781,6 +860,7 @@ public final class PacketType {
loadPacketIds(ClientboundPacketType_1_19_3.values());
loadPacketIds(ClientboundPacketType_1_19_4.values());
loadPacketIds(ClientboundPacketType_1_20_2.values());
loadPacketIds(ClientboundPacketType_1_20_3.values());
//TODO UPDATE Update packet type mappings (clientbound pt. 2)
}
}
@@ -2,7 +2,7 @@ package com.github.retrooper.packetevents.protocol.packettype;
/**
* A Marker interface used to indicate that this packet is originating on
* the client, and is bound for the server.
* the client, and is bound to the server.
*/
public interface ServerBoundPacket {
}
@@ -0,0 +1,140 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.clientbound;
public enum ClientboundPacketType_1_20_3 {
BUNDLE,
SPAWN_ENTITY,
SPAWN_EXPERIENCE_ORB,
ENTITY_ANIMATION,
STATISTICS,
ACKNOWLEDGE_BLOCK_CHANGES,
BLOCK_BREAK_ANIMATION,
BLOCK_ENTITY_DATA,
BLOCK_ACTION,
BLOCK_CHANGE,
BOSS_BAR,
SERVER_DIFFICULTY,
CHUNK_BATCH_END,
CHUNK_BATCH_BEGIN,
CHUNK_BIOMES,
CLEAR_TITLES,
TAB_COMPLETE,
DECLARE_COMMANDS,
CLOSE_WINDOW,
WINDOW_ITEMS,
WINDOW_PROPERTY,
SET_SLOT,
SET_COOLDOWN,
CUSTOM_CHAT_COMPLETIONS,
PLUGIN_MESSAGE,
DAMAGE_EVENT,
DELETE_CHAT,
DISCONNECT,
DISGUISED_CHAT,
ENTITY_STATUS,
EXPLOSION,
UNLOAD_CHUNK,
CHANGE_GAME_STATE,
OPEN_HORSE_WINDOW,
HURT_ANIMATION,
INITIALIZE_WORLD_BORDER,
KEEP_ALIVE,
CHUNK_DATA,
EFFECT,
PARTICLE,
UPDATE_LIGHT,
JOIN_GAME,
MAP_DATA,
MERCHANT_OFFERS,
ENTITY_RELATIVE_MOVE,
ENTITY_RELATIVE_MOVE_AND_ROTATION,
ENTITY_ROTATION,
VEHICLE_MOVE,
OPEN_BOOK,
OPEN_WINDOW,
OPEN_SIGN_EDITOR,
PING,
DEBUG_PONG,
CRAFT_RECIPE_RESPONSE,
PLAYER_ABILITIES,
CHAT_MESSAGE,
END_COMBAT_EVENT,
ENTER_COMBAT_EVENT,
DEATH_COMBAT_EVENT,
PLAYER_INFO_REMOVE,
PLAYER_INFO_UPDATE,
FACE_PLAYER,
PLAYER_POSITION_AND_LOOK,
UNLOCK_RECIPES,
DESTROY_ENTITIES,
REMOVE_ENTITY_EFFECT,
RESET_SCORE, // New packet
RESOURCE_PACK_REMOVE, // New packet
RESOURCE_PACK_SEND,
RESPAWN,
ENTITY_HEAD_LOOK,
MULTI_BLOCK_CHANGE,
SELECT_ADVANCEMENTS_TAB,
SERVER_DATA,
ACTION_BAR,
WORLD_BORDER_CENTER,
WORLD_BORDER_LERP_SIZE,
WORLD_BORDER_SIZE,
WORLD_BORDER_WARNING_DELAY,
WORLD_BORDER_WARNING_REACH,
CAMERA,
HELD_ITEM_CHANGE,
UPDATE_VIEW_POSITION,
UPDATE_VIEW_DISTANCE,
SPAWN_POSITION,
DISPLAY_SCOREBOARD,
ENTITY_METADATA,
ATTACH_ENTITY,
ENTITY_VELOCITY,
ENTITY_EQUIPMENT,
SET_EXPERIENCE,
UPDATE_HEALTH,
SCOREBOARD_OBJECTIVE,
SET_PASSENGERS,
TEAMS,
UPDATE_SCORE,
UPDATE_SIMULATION_DISTANCE,
SET_TITLE_SUBTITLE,
TIME_UPDATE,
SET_TITLE_TEXT,
SET_TITLE_TIMES,
ENTITY_SOUND_EFFECT,
SOUND_EFFECT,
CONFIGURATION_START,
STOP_SOUND,
SYSTEM_CHAT_MESSAGE,
PLAYER_LIST_HEADER_AND_FOOTER,
NBT_QUERY_RESPONSE,
COLLECT_ITEM,
ENTITY_TELEPORT,
TICKING_STATE, // New packet
TICKING_STEP, // New packet
UPDATE_ADVANCEMENTS,
UPDATE_ATTRIBUTES,
ENTITY_EFFECT,
DECLARE_RECIPES,
TAGS,
}
@@ -0,0 +1,32 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.config.clientbound;
public enum ClientboundConfigPacketType_1_20_2 {
PLUGIN_MESSAGE,
DISCONNECT,
CONFIGURATION_END,
KEEP_ALIVE,
PING,
REGISTRY_DATA,
RESOURCE_PACK_SEND,
UPDATE_ENABLED_FEATURES,
UPDATE_TAGS,
}
@@ -0,0 +1,33 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.config.clientbound;
public enum ClientboundConfigPacketType_1_20_3 {
PLUGIN_MESSAGE,
DISCONNECT,
CONFIGURATION_END,
KEEP_ALIVE,
PING,
REGISTRY_DATA,
RESOURCE_PACK_REMOVE, // New packet
RESOURCE_PACK_SEND,
UPDATE_ENABLED_FEATURES,
UPDATE_TAGS,
}
@@ -0,0 +1,78 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.serverbound;
public enum ServerboundPacketType_1_20_3 {
TELEPORT_CONFIRM,
QUERY_BLOCK_NBT,
SET_DIFFICULTY,
CHAT_ACK,
CHAT_COMMAND,
CHAT_MESSAGE,
CHAT_SESSION_UPDATE,
CHUNK_BATCH_ACK,
CLIENT_STATUS,
CLIENT_SETTINGS,
TAB_COMPLETE,
CONFIGURATION_ACK,
CLICK_WINDOW_BUTTON,
CLICK_WINDOW,
CLOSE_WINDOW,
SLOT_STATE_CHANGE, // New packet
PLUGIN_MESSAGE,
EDIT_BOOK,
QUERY_ENTITY_NBT,
INTERACT_ENTITY,
GENERATE_STRUCTURE,
KEEP_ALIVE,
LOCK_DIFFICULTY,
PLAYER_POSITION,
PLAYER_POSITION_AND_ROTATION,
PLAYER_ROTATION,
PLAYER_FLYING,
VEHICLE_MOVE,
STEER_BOAT,
PICK_ITEM,
DEBUG_PING,
CRAFT_RECIPE_REQUEST,
PLAYER_ABILITIES,
PLAYER_DIGGING,
ENTITY_ACTION,
STEER_VEHICLE,
PONG,
SET_RECIPE_BOOK_STATE,
SET_DISPLAYED_RECIPE,
NAME_ITEM,
RESOURCE_PACK_STATUS,
ADVANCEMENT_TAB,
SELECT_TRADE,
SET_BEACON_EFFECT,
HELD_ITEM_CHANGE,
UPDATE_COMMAND_BLOCK,
UPDATE_COMMAND_BLOCK_MINECART,
CREATIVE_INVENTORY_ACTION,
UPDATE_JIGSAW_BLOCK,
UPDATE_STRUCTURE_BLOCK,
UPDATE_SIGN,
ANIMATION,
SPECTATE,
PLAYER_BLOCK_PLACEMENT,
USE_ITEM,
}
@@ -18,6 +18,10 @@
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
@@ -25,30 +29,54 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class ParticleVibrationData extends ParticleData {
public enum PositionType {
BLOCK("minecraft:block"), ENTITY("minecraft:entity");
private final String name;
public enum PositionType implements MappedEntity {
PositionType(String name) {
BLOCK(new ResourceLocation("minecraft:block")),
ENTITY(new ResourceLocation("minecraft:entity"));
private final ResourceLocation name;
PositionType(ResourceLocation name) {
this.name = name;
}
public String getName() {
@Override
public ResourceLocation getName() {
return name;
}
public static PositionType getByName(String name) {
for(PositionType type : values()) {
if(type.getName().equals(name)) {
public static PositionType getById(int id) {
switch (id) {
case 0x00:
return BLOCK;
case 0x01:
return ENTITY;
default:
throw new IllegalArgumentException("Illegal position type id: " + id);
}
}
public static @Nullable PositionType getByName(String name) {
return getByName(new ResourceLocation(name));
}
public static @Nullable PositionType getByName(ResourceLocation name) {
for (PositionType type : values()) {
if (type.getName().equals(name)) {
return type;
}
}
return null;
}
@Override
public int getId(ClientVersion version) {
return this.ordinal();
}
}
private Vector3i startingPosition;
private Vector3i startingPosition; // Removed in 1.19.4
private PositionType type;
private @Nullable Vector3i blockPosition;
private @Nullable Integer entityId;
@@ -107,28 +135,44 @@ public class ParticleVibrationData extends ParticleData {
}
public static ParticleVibrationData read(PacketWrapper<?> wrapper) {
Vector3i startingPos = wrapper.readBlockPosition();
String positionTypeName = wrapper.readString();
PositionType positionType = PositionType.getByName(positionTypeName);
if (positionType == PositionType.BLOCK) {
return new ParticleVibrationData(startingPos, wrapper.readBlockPosition(), wrapper.readVarInt());
Vector3i startingPos = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_19_4)
? Vector3i.zero() : wrapper.readBlockPosition();
PositionType positionType;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
positionType = PositionType.getById(wrapper.readVarInt());
} else {
String positionTypeName = wrapper.readString();
positionType = PositionType.getByName(positionTypeName);
if (positionType == null) {
throw new IllegalArgumentException("Unknown position type: " + positionTypeName);
}
}
else if (positionType == PositionType.ENTITY) {
return new ParticleVibrationData(startingPos, wrapper.readVarInt(), wrapper.readVarInt());
}
else {
throw new IllegalArgumentException("Unknown position type: " + positionTypeName);
switch (positionType) {
case BLOCK:
return new ParticleVibrationData(startingPos, wrapper.readBlockPosition(), wrapper.readVarInt());
case ENTITY:
return new ParticleVibrationData(startingPos, wrapper.readVarInt(), wrapper.readVarInt());
default:
throw new IllegalArgumentException("Illegal position type: " + positionType);
}
}
public static void write(PacketWrapper<?> wrapper, ParticleVibrationData data) {
wrapper.writeBlockPosition(data.getStartingPosition());
wrapper.writeString(data.getType().getName());
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_19_4)) {
wrapper.writeBlockPosition(data.getStartingPosition());
}
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
wrapper.writeVarInt(data.getType().getId(wrapper.getServerVersion().toClientVersion()));
} else {
wrapper.writeIdentifier(data.getType().getName());
}
if (data.getType() == PositionType.BLOCK) {
wrapper.writeBlockPosition(data.getBlockPosition().get());
}
else if (data.getType() == PositionType.ENTITY) {
} else if (data.getType() == PositionType.ENTITY) {
wrapper.writeVarInt(data.getEntityId().get());
}
wrapper.writeVarInt(data.getTicks());
@@ -45,7 +45,8 @@ public class ParticleTypes {
ClientVersion.V_1_18,
ClientVersion.V_1_19,
ClientVersion.V_1_19_4,
ClientVersion.V_1_20);
ClientVersion.V_1_20,
ClientVersion.V_1_20_3);
public static ParticleType define(String key, Function<PacketWrapper<?>, ParticleData> readDataFunction, BiConsumer<PacketWrapper<?>, ParticleData> writeDataFunction) {
TypesBuilderData data = TYPES_BUILDER.defineFromArray(key);
@@ -211,6 +212,14 @@ public class ParticleTypes {
//Added in 1.20
public static final ParticleType CHERRY_LEAVES = define("cherry_leaves");
public static final ParticleType EGG_CRACK = define("egg_crack");
//Added in 1.20.3
public static final ParticleType GUST = define("gust");
public static final ParticleType GUST_EMITTER = define("gust_emitter");
public static final ParticleType WHITE_SMOKE = define("white_smoke");
public static final ParticleType DUST_PLUME = define("dust_plume");
public static final ParticleType GUST_DUST = define("gust_dust");
public static final ParticleType TRIAL_SPAWNER_DETECTION = define("trial_spawner_detection");
static {
TYPES_BUILDER.unloadFileMappings();
}
@@ -84,11 +84,15 @@ public enum ClientVersion {
V_1_19_4(762),
V_1_20(763),
V_1_20_2(764),
/**
* 1.20.3 and 1.20.4 have the same protocol version.
*/
V_1_20_3(765),
//TODO UPDATE Add new protocol version field
LOWER_THAN_SUPPORTED_VERSIONS(V_1_7_10.protocolVersion - 1, true),
//TODO UPDATE Update HIGHER_THAN_SUPPORTED_VERSIONS field
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_20_2.protocolVersion + 1, true),
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_20_3.protocolVersion + 1, true),
UNKNOWN(-1, true);
@@ -167,7 +171,6 @@ public enum ClientVersion {
if (version.protocolVersion > protocolVersion) {
break;
} else if (version.protocolVersion == protocolVersion) {
//Cache for next time
return version;
}
}
@@ -161,8 +161,11 @@ public class WrappedBlockState {
return 10;
} else if (version.isOlderThanOrEquals(ClientVersion.V_1_20)) {
return 11;
} else if (version.isOlderThanOrEquals(ClientVersion.V_1_20_2)) {
return 12;
}
return 12;
// TODO UPDATE increment index (and add previous above)
return 13;
}
private static void loadLegacy() {
@@ -1112,6 +1115,36 @@ public class WrappedBlockState {
checkIsStillValid();
}
public boolean isCracked() {
return (boolean) data.get(StateValue.CRACKED);
}
public void setCracked(boolean cracked) {
checkIfCloneNeeded();
data.put(StateValue.CRACKED, cracked);
checkIsStillValid();
}
public boolean isCrafting() {
return (boolean) data.get(StateValue.CRAFTING);
}
public void setCrafting(boolean crafting) {
checkIfCloneNeeded();
data.put(StateValue.CRAFTING, crafting);
checkIsStillValid();
}
public TrialSpawnerState getTrialSpawnerState() {
return (TrialSpawnerState) data.get(StateValue.TRIAL_SPAWNER_STATE);
}
public void setTrialSpawnerState(TrialSpawnerState trialSpawnerState) {
checkIfCloneNeeded();
data.put(StateValue.TRIAL_SPAWNER_STATE, trialSpawnerState);
checkIsStillValid();
}
// End all block data types
/**
@@ -29,8 +29,9 @@ import java.util.Set;
/**
* This class allows you to use block tags on outdated versions.
* If you are on a version that sends tags to the player, you are suggested to listen to {@link com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTags}
*
* <p>
* Might as well just fucking shade the entire vanilla jar if we are going to copy SO MANY HUNDREDS OF LINES
*
* @author DefineOutside
*/
public class BlockTags {
@@ -95,6 +96,7 @@ public class BlockTags {
public static final BlockTags CANDLES = bind("candles");
public static final BlockTags DIRT = bind("dirt");
public static final BlockTags TERRACOTTA = bind("terracotta");
public static final BlockTags CONCRETE_POWDER = bind("concrete_powder");
public static final BlockTags COMPLETES_FIND_TREE_TUTORIAL = bind("completes_find_tree_tutorial");
public static final BlockTags FLOWER_POTS = bind("flower_pots");
public static final BlockTags ENDERMAN_HOLDABLE = bind("enderman_holdable");
@@ -153,6 +155,7 @@ public class BlockTags {
public static final BlockTags CRYSTAL_SOUND_BLOCKS = bind("crystal_sound_blocks");
public static final BlockTags INSIDE_STEP_SOUND_BLOCKS = bind("inside_step_sound_blocks");
public static final BlockTags COMBINATION_STEP_SOUND_BLOCKS = bind("combination_step_sound_blocks");
public static final BlockTags CAMEL_SAND_STEP_SOUND_BLOCKS = bind("camel_sand_step_sound_blocks");
public static final BlockTags OCCLUDES_VIBRATION_SIGNALS = bind("occludes_vibration_signals");
public static final BlockTags DAMPENS_VIBRATIONS = bind("dampens_vibrations");
public static final BlockTags DRIPSTONE_REPLACEABLE = bind("dripstone_replaceable_blocks");
@@ -190,12 +193,14 @@ public class BlockTags {
public static final BlockTags WOLVES_SPAWNABLE_ON = bind("wolves_spawnable_on");
public static final BlockTags FROGS_SPAWNABLE_ON = bind("frogs_spawnable_on");
public static final BlockTags AZALEA_GROWS_ON = bind("azalea_grows_on");
@Deprecated
public static final BlockTags REPLACEABLE_PLANTS = bind("replaceable_plants");
public static final BlockTags CONVERTABLE_TO_MUD = bind("convertable_to_mud");
public static final BlockTags MANGROVE_LOGS_CAN_GROW_THROUGH = bind("mangrove_logs_can_grow_through");
public static final BlockTags MANGROVE_ROOTS_CAN_GROW_THROUGH = bind("mangrove_roots_can_grow_through");
public static final BlockTags DEAD_BUSH_MAY_PLACE_ON = bind("dead_bush_may_place_on");
public static final BlockTags SNAPS_GOAT_HORN = bind("snaps_goat_horn");
public static final BlockTags REPLACEABLE_BY_TREES = bind("replaceable_by_trees");
public static final BlockTags SNOW_LAYER_CANNOT_SURVIVE_ON = bind("snow_layer_cannot_survive_on");
public static final BlockTags SNOW_LAYER_CAN_SURVIVE_ON = bind("snow_layer_can_survive_on");
public static final BlockTags INVALID_SPAWN_INSIDE = bind("invalid_spawn_inside");
@@ -227,164 +232,164 @@ public class BlockTags {
BlockTags.WOODEN_STAIRS.add(StateTypes.OAK_STAIRS, StateTypes.SPRUCE_STAIRS, StateTypes.BIRCH_STAIRS, StateTypes.JUNGLE_STAIRS, StateTypes.ACACIA_STAIRS, StateTypes.DARK_OAK_STAIRS, StateTypes.CRIMSON_STAIRS, StateTypes.WARPED_STAIRS, StateTypes.MANGROVE_STAIRS, StateTypes.BAMBOO_STAIRS, StateTypes.CHERRY_STAIRS);
BlockTags.WOODEN_SLABS.add(StateTypes.OAK_SLAB, StateTypes.SPRUCE_SLAB, StateTypes.BIRCH_SLAB, StateTypes.JUNGLE_SLAB, StateTypes.ACACIA_SLAB, StateTypes.DARK_OAK_SLAB, StateTypes.CRIMSON_SLAB, StateTypes.WARPED_SLAB, StateTypes.MANGROVE_SLAB, StateTypes.BAMBOO_SLAB, StateTypes.CHERRY_SLAB);
BlockTags.WOODEN_FENCES.add(StateTypes.OAK_FENCE, StateTypes.ACACIA_FENCE, StateTypes.DARK_OAK_FENCE, StateTypes.SPRUCE_FENCE, StateTypes.BIRCH_FENCE, StateTypes.JUNGLE_FENCE, StateTypes.CRIMSON_FENCE, StateTypes.WARPED_FENCE, StateTypes.MANGROVE_FENCE, StateTypes.BAMBOO_FENCE, StateTypes.CHERRY_FENCE);
BlockTags.DOORS.addTag(BlockTags.WOODEN_DOORS).add(StateTypes.IRON_DOOR);
BlockTags.SAPLINGS.add(StateTypes.OAK_SAPLING, StateTypes.SPRUCE_SAPLING, StateTypes.BIRCH_SAPLING, StateTypes.JUNGLE_SAPLING, StateTypes.ACACIA_SAPLING, StateTypes.DARK_OAK_SAPLING, StateTypes.AZALEA, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_SAPLING);
BlockTags.BAMBOO_BLOCKS.add(StateTypes.BAMBOO_BLOCK, StateTypes.STRIPPED_BAMBOO_BLOCK);
BlockTags.DARK_OAK_LOGS.add(StateTypes.DARK_OAK_LOG, StateTypes.DARK_OAK_WOOD, StateTypes.STRIPPED_DARK_OAK_LOG, StateTypes.STRIPPED_DARK_OAK_WOOD);
BlockTags.OAK_LOGS.add(StateTypes.OAK_LOG, StateTypes.OAK_WOOD, StateTypes.STRIPPED_OAK_LOG, StateTypes.STRIPPED_OAK_WOOD);
BlockTags.ACACIA_LOGS.add(StateTypes.ACACIA_LOG, StateTypes.ACACIA_WOOD, StateTypes.STRIPPED_ACACIA_LOG, StateTypes.STRIPPED_ACACIA_WOOD);
BlockTags.CHERRY_LOGS.add(StateTypes.CHERRY_LOG, StateTypes.CHERRY_WOOD, StateTypes.STRIPPED_CHERRY_LOG, StateTypes.STRIPPED_CHERRY_WOOD);
BlockTags.BIRCH_LOGS.add(StateTypes.BIRCH_LOG, StateTypes.BIRCH_WOOD, StateTypes.STRIPPED_BIRCH_LOG, StateTypes.STRIPPED_BIRCH_WOOD);
BlockTags.JUNGLE_LOGS.add(StateTypes.JUNGLE_LOG, StateTypes.JUNGLE_WOOD, StateTypes.STRIPPED_JUNGLE_LOG, StateTypes.STRIPPED_JUNGLE_WOOD);
BlockTags.SPRUCE_LOGS.add(StateTypes.SPRUCE_LOG, StateTypes.SPRUCE_WOOD, StateTypes.STRIPPED_SPRUCE_LOG, StateTypes.STRIPPED_SPRUCE_WOOD);
BlockTags.CRIMSON_STEMS.add(StateTypes.CRIMSON_STEM, StateTypes.STRIPPED_CRIMSON_STEM, StateTypes.CRIMSON_HYPHAE, StateTypes.STRIPPED_CRIMSON_HYPHAE);
BlockTags.WARPED_STEMS.add(StateTypes.WARPED_STEM, StateTypes.STRIPPED_WARPED_STEM, StateTypes.WARPED_HYPHAE, StateTypes.STRIPPED_WARPED_HYPHAE);
BlockTags.MANGROVE_LOGS.add(StateTypes.MANGROVE_LOG, StateTypes.MANGROVE_WOOD, StateTypes.STRIPPED_MANGROVE_LOG, StateTypes.STRIPPED_MANGROVE_WOOD);
BlockTags.LOGS_THAT_BURN.addTag(BlockTags.DARK_OAK_LOGS).addTag(BlockTags.OAK_LOGS).addTag(BlockTags.ACACIA_LOGS).addTag(BlockTags.BIRCH_LOGS).addTag(BlockTags.JUNGLE_LOGS).addTag(BlockTags.SPRUCE_LOGS).addTag(BlockTags.MANGROVE_LOGS).addTag(BlockTags.CHERRY_LOGS);
BlockTags.OVERWORLD_NATURAL_LOGS.add(StateTypes.ACACIA_LOG).add(StateTypes.BIRCH_LOG).add(StateTypes.OAK_LOG).add(StateTypes.JUNGLE_LOG).add(StateTypes.SPRUCE_LOG).add(StateTypes.DARK_OAK_LOG).add(StateTypes.MANGROVE_LOG).add(StateTypes.CHERRY_LOG);
BlockTags.LOGS.addTag(BlockTags.LOGS_THAT_BURN).addTag(BlockTags.CRIMSON_STEMS).addTag(BlockTags.WARPED_STEMS);
BlockTags.ANVIL.add(StateTypes.ANVIL, StateTypes.CHIPPED_ANVIL, StateTypes.DAMAGED_ANVIL);
BlockTags.SMALL_FLOWERS.add(StateTypes.DANDELION, StateTypes.POPPY, StateTypes.BLUE_ORCHID, StateTypes.ALLIUM, StateTypes.AZURE_BLUET, StateTypes.RED_TULIP, StateTypes.ORANGE_TULIP, StateTypes.WHITE_TULIP, StateTypes.PINK_TULIP, StateTypes.OXEYE_DAISY, StateTypes.CORNFLOWER, StateTypes.LILY_OF_THE_VALLEY, StateTypes.WITHER_ROSE, StateTypes.TORCHFLOWER);
BlockTags.DIRT.add(StateTypes.DIRT, StateTypes.GRASS_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT, StateTypes.MYCELIUM, StateTypes.ROOTED_DIRT, StateTypes.MOSS_BLOCK, StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS);
BlockTags.ENDERMAN_HOLDABLE.addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.DIRT).add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.GRAVEL, StateTypes.BROWN_MUSHROOM, StateTypes.RED_MUSHROOM, StateTypes.TNT, StateTypes.CACTUS, StateTypes.CLAY, StateTypes.PUMPKIN, StateTypes.CARVED_PUMPKIN, StateTypes.MELON, StateTypes.CRIMSON_FUNGUS, StateTypes.CRIMSON_NYLIUM, StateTypes.CRIMSON_ROOTS, StateTypes.WARPED_FUNGUS, StateTypes.WARPED_NYLIUM, StateTypes.WARPED_ROOTS);
BlockTags.FLOWER_POTS.add(StateTypes.FLOWER_POT, StateTypes.POTTED_POPPY, StateTypes.POTTED_BLUE_ORCHID, StateTypes.POTTED_ALLIUM, StateTypes.POTTED_AZURE_BLUET, StateTypes.POTTED_RED_TULIP, StateTypes.POTTED_ORANGE_TULIP, StateTypes.POTTED_WHITE_TULIP, StateTypes.POTTED_PINK_TULIP, StateTypes.POTTED_OXEYE_DAISY, StateTypes.POTTED_DANDELION, StateTypes.POTTED_OAK_SAPLING, StateTypes.POTTED_SPRUCE_SAPLING, StateTypes.POTTED_BIRCH_SAPLING, StateTypes.POTTED_JUNGLE_SAPLING, StateTypes.POTTED_ACACIA_SAPLING, StateTypes.POTTED_DARK_OAK_SAPLING, StateTypes.POTTED_RED_MUSHROOM, StateTypes.POTTED_BROWN_MUSHROOM, StateTypes.POTTED_DEAD_BUSH, StateTypes.POTTED_FERN, StateTypes.POTTED_CACTUS, StateTypes.POTTED_CORNFLOWER, StateTypes.POTTED_LILY_OF_THE_VALLEY, StateTypes.POTTED_WITHER_ROSE, StateTypes.POTTED_BAMBOO, StateTypes.POTTED_CRIMSON_FUNGUS, StateTypes.POTTED_WARPED_FUNGUS, StateTypes.POTTED_CRIMSON_ROOTS, StateTypes.POTTED_WARPED_ROOTS, StateTypes.POTTED_AZALEA_BUSH, StateTypes.POTTED_FLOWERING_AZALEA_BUSH, StateTypes.POTTED_MANGROVE_PROPAGULE, StateTypes.POTTED_CHERRY_SAPLING, StateTypes.POTTED_TORCHFLOWER);
BlockTags.BANNERS.add(StateTypes.WHITE_BANNER, StateTypes.ORANGE_BANNER, StateTypes.MAGENTA_BANNER, StateTypes.LIGHT_BLUE_BANNER, StateTypes.YELLOW_BANNER, StateTypes.LIME_BANNER, StateTypes.PINK_BANNER, StateTypes.GRAY_BANNER, StateTypes.LIGHT_GRAY_BANNER, StateTypes.CYAN_BANNER, StateTypes.PURPLE_BANNER, StateTypes.BLUE_BANNER, StateTypes.BROWN_BANNER, StateTypes.GREEN_BANNER, StateTypes.RED_BANNER, StateTypes.BLACK_BANNER, StateTypes.WHITE_WALL_BANNER, StateTypes.ORANGE_WALL_BANNER, StateTypes.MAGENTA_WALL_BANNER, StateTypes.LIGHT_BLUE_WALL_BANNER, StateTypes.YELLOW_WALL_BANNER, StateTypes.LIME_WALL_BANNER, StateTypes.PINK_WALL_BANNER, StateTypes.GRAY_WALL_BANNER, StateTypes.LIGHT_GRAY_WALL_BANNER, StateTypes.CYAN_WALL_BANNER, StateTypes.PURPLE_WALL_BANNER, StateTypes.BLUE_WALL_BANNER, StateTypes.BROWN_WALL_BANNER, StateTypes.GREEN_WALL_BANNER, StateTypes.RED_WALL_BANNER, StateTypes.BLACK_WALL_BANNER);
BlockTags.PRESSURE_PLATES.addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.STONE_PRESSURE_PLATES).add(StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE);
BlockTags.WOODEN_PRESSURE_PLATES.add(StateTypes.OAK_PRESSURE_PLATE, StateTypes.SPRUCE_PRESSURE_PLATE, StateTypes.BIRCH_PRESSURE_PLATE, StateTypes.JUNGLE_PRESSURE_PLATE, StateTypes.ACACIA_PRESSURE_PLATE, StateTypes.DARK_OAK_PRESSURE_PLATE, StateTypes.CRIMSON_PRESSURE_PLATE, StateTypes.WARPED_PRESSURE_PLATE, StateTypes.MANGROVE_PRESSURE_PLATE, StateTypes.BAMBOO_PRESSURE_PLATE, StateTypes.CHERRY_PRESSURE_PLATE);
BlockTags.STONE_PRESSURE_PLATES.add(StateTypes.STONE_PRESSURE_PLATE, StateTypes.POLISHED_BLACKSTONE_PRESSURE_PLATE);
BlockTags.PRESSURE_PLATES.add(StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE).addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.STONE_PRESSURE_PLATES);
BlockTags.WOODEN_TRAPDOORS.add(StateTypes.ACACIA_TRAPDOOR, StateTypes.BIRCH_TRAPDOOR, StateTypes.DARK_OAK_TRAPDOOR, StateTypes.JUNGLE_TRAPDOOR, StateTypes.OAK_TRAPDOOR, StateTypes.SPRUCE_TRAPDOOR, StateTypes.CRIMSON_TRAPDOOR, StateTypes.WARPED_TRAPDOOR, StateTypes.MANGROVE_TRAPDOOR, StateTypes.BAMBOO_TRAPDOOR, StateTypes.CHERRY_TRAPDOOR);
BlockTags.DOORS.addTag(BlockTags.WOODEN_DOORS).add(StateTypes.IRON_DOOR);
BlockTags.SAPLINGS.add(StateTypes.OAK_SAPLING, StateTypes.SPRUCE_SAPLING, StateTypes.BIRCH_SAPLING, StateTypes.JUNGLE_SAPLING, StateTypes.ACACIA_SAPLING, StateTypes.DARK_OAK_SAPLING, StateTypes.AZALEA, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_SAPLING);
BlockTags.LOGS_THAT_BURN.addTag(BlockTags.DARK_OAK_LOGS).addTag(BlockTags.OAK_LOGS).addTag(BlockTags.ACACIA_LOGS).addTag(BlockTags.BIRCH_LOGS).addTag(BlockTags.JUNGLE_LOGS).addTag(BlockTags.SPRUCE_LOGS).addTag(BlockTags.MANGROVE_LOGS).addTag(BlockTags.CHERRY_LOGS);
BlockTags.OVERWORLD_NATURAL_LOGS.add(StateTypes.ACACIA_LOG, StateTypes.BIRCH_LOG, StateTypes.OAK_LOG, StateTypes.JUNGLE_LOG, StateTypes.SPRUCE_LOG, StateTypes.DARK_OAK_LOG, StateTypes.MANGROVE_LOG, StateTypes.CHERRY_LOG);
BlockTags.LOGS.addTag(BlockTags.LOGS_THAT_BURN).addTag(BlockTags.CRIMSON_STEMS).addTag(BlockTags.WARPED_STEMS);
BlockTags.DARK_OAK_LOGS.add(StateTypes.DARK_OAK_LOG, StateTypes.DARK_OAK_WOOD, StateTypes.STRIPPED_DARK_OAK_LOG, StateTypes.STRIPPED_DARK_OAK_WOOD);
BlockTags.OAK_LOGS.add(StateTypes.OAK_LOG, StateTypes.OAK_WOOD, StateTypes.STRIPPED_OAK_LOG, StateTypes.STRIPPED_OAK_WOOD);
BlockTags.BIRCH_LOGS.add(StateTypes.BIRCH_LOG, StateTypes.BIRCH_WOOD, StateTypes.STRIPPED_BIRCH_LOG, StateTypes.STRIPPED_BIRCH_WOOD);
BlockTags.ACACIA_LOGS.add(StateTypes.ACACIA_LOG, StateTypes.ACACIA_WOOD, StateTypes.STRIPPED_ACACIA_LOG, StateTypes.STRIPPED_ACACIA_WOOD);
BlockTags.CHERRY_LOGS.add(StateTypes.CHERRY_LOG, StateTypes.CHERRY_WOOD, StateTypes.STRIPPED_CHERRY_LOG, StateTypes.STRIPPED_CHERRY_WOOD);
BlockTags.JUNGLE_LOGS.add(StateTypes.JUNGLE_LOG, StateTypes.JUNGLE_WOOD, StateTypes.STRIPPED_JUNGLE_LOG, StateTypes.STRIPPED_JUNGLE_WOOD);
BlockTags.SPRUCE_LOGS.add(StateTypes.SPRUCE_LOG, StateTypes.SPRUCE_WOOD, StateTypes.STRIPPED_SPRUCE_LOG, StateTypes.STRIPPED_SPRUCE_WOOD);
BlockTags.MANGROVE_LOGS.add(StateTypes.MANGROVE_LOG, StateTypes.MANGROVE_WOOD, StateTypes.STRIPPED_MANGROVE_LOG, StateTypes.STRIPPED_MANGROVE_WOOD);
BlockTags.CRIMSON_STEMS.add(StateTypes.CRIMSON_STEM, StateTypes.STRIPPED_CRIMSON_STEM, StateTypes.CRIMSON_HYPHAE, StateTypes.STRIPPED_CRIMSON_HYPHAE);
BlockTags.WARPED_STEMS.add(StateTypes.WARPED_STEM, StateTypes.STRIPPED_WARPED_STEM, StateTypes.WARPED_HYPHAE, StateTypes.STRIPPED_WARPED_HYPHAE);
BlockTags.BAMBOO_BLOCKS.add(StateTypes.BAMBOO_BLOCK, StateTypes.STRIPPED_BAMBOO_BLOCK);
BlockTags.WART_BLOCKS.add(StateTypes.NETHER_WART_BLOCK, StateTypes.WARPED_WART_BLOCK);
BlockTags.BANNERS.add(StateTypes.WHITE_BANNER, StateTypes.ORANGE_BANNER, StateTypes.MAGENTA_BANNER, StateTypes.LIGHT_BLUE_BANNER, StateTypes.YELLOW_BANNER, StateTypes.LIME_BANNER, StateTypes.PINK_BANNER, StateTypes.GRAY_BANNER, StateTypes.LIGHT_GRAY_BANNER, StateTypes.CYAN_BANNER, StateTypes.PURPLE_BANNER, StateTypes.BLUE_BANNER, StateTypes.BROWN_BANNER, StateTypes.GREEN_BANNER, StateTypes.RED_BANNER, StateTypes.BLACK_BANNER, StateTypes.WHITE_WALL_BANNER, StateTypes.ORANGE_WALL_BANNER, StateTypes.MAGENTA_WALL_BANNER, StateTypes.LIGHT_BLUE_WALL_BANNER, StateTypes.YELLOW_WALL_BANNER, StateTypes.LIME_WALL_BANNER, StateTypes.PINK_WALL_BANNER, StateTypes.GRAY_WALL_BANNER, StateTypes.LIGHT_GRAY_WALL_BANNER, StateTypes.CYAN_WALL_BANNER, StateTypes.PURPLE_WALL_BANNER, StateTypes.BLUE_WALL_BANNER, StateTypes.BROWN_WALL_BANNER, StateTypes.GREEN_WALL_BANNER, StateTypes.RED_WALL_BANNER, StateTypes.BLACK_WALL_BANNER);
BlockTags.SAND.add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.SUSPICIOUS_SAND, StateTypes.SUSPICIOUS_SAND);
BlockTags.SMELTS_TO_GLASS.add(StateTypes.SAND, StateTypes.RED_SAND);
BlockTags.STAIRS.addTag(BlockTags.WOODEN_STAIRS).add(StateTypes.BAMBOO_MOSAIC_STAIRS, StateTypes.COBBLESTONE_STAIRS, StateTypes.SANDSTONE_STAIRS, StateTypes.NETHER_BRICK_STAIRS, StateTypes.STONE_BRICK_STAIRS, StateTypes.BRICK_STAIRS, StateTypes.PURPUR_STAIRS, StateTypes.QUARTZ_STAIRS, StateTypes.RED_SANDSTONE_STAIRS, StateTypes.PRISMARINE_BRICK_STAIRS, StateTypes.PRISMARINE_STAIRS, StateTypes.DARK_PRISMARINE_STAIRS, StateTypes.POLISHED_GRANITE_STAIRS, StateTypes.SMOOTH_RED_SANDSTONE_STAIRS, StateTypes.MOSSY_STONE_BRICK_STAIRS, StateTypes.POLISHED_DIORITE_STAIRS, StateTypes.MOSSY_COBBLESTONE_STAIRS, StateTypes.END_STONE_BRICK_STAIRS, StateTypes.STONE_STAIRS, StateTypes.SMOOTH_SANDSTONE_STAIRS, StateTypes.SMOOTH_QUARTZ_STAIRS, StateTypes.GRANITE_STAIRS, StateTypes.ANDESITE_STAIRS, StateTypes.RED_NETHER_BRICK_STAIRS, StateTypes.POLISHED_ANDESITE_STAIRS, StateTypes.DIORITE_STAIRS, StateTypes.BLACKSTONE_STAIRS, StateTypes.POLISHED_BLACKSTONE_BRICK_STAIRS, StateTypes.POLISHED_BLACKSTONE_STAIRS, StateTypes.COBBLED_DEEPSLATE_STAIRS, StateTypes.POLISHED_DEEPSLATE_STAIRS, StateTypes.DEEPSLATE_TILE_STAIRS, StateTypes.DEEPSLATE_BRICK_STAIRS, StateTypes.OXIDIZED_CUT_COPPER_STAIRS, StateTypes.WEATHERED_CUT_COPPER_STAIRS, StateTypes.EXPOSED_CUT_COPPER_STAIRS, StateTypes.CUT_COPPER_STAIRS, StateTypes.WAXED_WEATHERED_CUT_COPPER_STAIRS, StateTypes.WAXED_EXPOSED_CUT_COPPER_STAIRS, StateTypes.WAXED_CUT_COPPER_STAIRS, StateTypes.WAXED_OXIDIZED_CUT_COPPER_STAIRS, StateTypes.MUD_BRICK_STAIRS);
BlockTags.SLABS.addTag(BlockTags.WOODEN_SLABS).add(StateTypes.BAMBOO_MOSAIC_SLAB, StateTypes.STONE_SLAB, StateTypes.SMOOTH_STONE_SLAB, StateTypes.STONE_BRICK_SLAB, StateTypes.SANDSTONE_SLAB, StateTypes.PURPUR_SLAB, StateTypes.QUARTZ_SLAB, StateTypes.RED_SANDSTONE_SLAB, StateTypes.BRICK_SLAB, StateTypes.COBBLESTONE_SLAB, StateTypes.NETHER_BRICK_SLAB, StateTypes.PETRIFIED_OAK_SLAB, StateTypes.PRISMARINE_SLAB, StateTypes.PRISMARINE_BRICK_SLAB, StateTypes.DARK_PRISMARINE_SLAB, StateTypes.POLISHED_GRANITE_SLAB, StateTypes.SMOOTH_RED_SANDSTONE_SLAB, StateTypes.MOSSY_STONE_BRICK_SLAB, StateTypes.POLISHED_DIORITE_SLAB, StateTypes.MOSSY_COBBLESTONE_SLAB, StateTypes.END_STONE_BRICK_SLAB, StateTypes.SMOOTH_SANDSTONE_SLAB, StateTypes.SMOOTH_QUARTZ_SLAB, StateTypes.GRANITE_SLAB, StateTypes.ANDESITE_SLAB, StateTypes.RED_NETHER_BRICK_SLAB, StateTypes.POLISHED_ANDESITE_SLAB, StateTypes.DIORITE_SLAB, StateTypes.CUT_SANDSTONE_SLAB, StateTypes.CUT_RED_SANDSTONE_SLAB, StateTypes.BLACKSTONE_SLAB, StateTypes.POLISHED_BLACKSTONE_BRICK_SLAB, StateTypes.POLISHED_BLACKSTONE_SLAB, StateTypes.COBBLED_DEEPSLATE_SLAB, StateTypes.POLISHED_DEEPSLATE_SLAB, StateTypes.DEEPSLATE_TILE_SLAB, StateTypes.DEEPSLATE_BRICK_SLAB, StateTypes.WAXED_WEATHERED_CUT_COPPER_SLAB, StateTypes.WAXED_EXPOSED_CUT_COPPER_SLAB, StateTypes.WAXED_CUT_COPPER_SLAB, StateTypes.OXIDIZED_CUT_COPPER_SLAB, StateTypes.WEATHERED_CUT_COPPER_SLAB, StateTypes.EXPOSED_CUT_COPPER_SLAB, StateTypes.CUT_COPPER_SLAB, StateTypes.WAXED_OXIDIZED_CUT_COPPER_SLAB, StateTypes.MUD_BRICK_SLAB);
BlockTags.WALLS.add(StateTypes.COBBLESTONE_WALL, StateTypes.MOSSY_COBBLESTONE_WALL, StateTypes.BRICK_WALL, StateTypes.PRISMARINE_WALL, StateTypes.RED_SANDSTONE_WALL, StateTypes.MOSSY_STONE_BRICK_WALL, StateTypes.GRANITE_WALL, StateTypes.STONE_BRICK_WALL, StateTypes.NETHER_BRICK_WALL, StateTypes.ANDESITE_WALL, StateTypes.RED_NETHER_BRICK_WALL, StateTypes.SANDSTONE_WALL, StateTypes.END_STONE_BRICK_WALL, StateTypes.DIORITE_WALL, StateTypes.BLACKSTONE_WALL, StateTypes.POLISHED_BLACKSTONE_BRICK_WALL, StateTypes.POLISHED_BLACKSTONE_WALL, StateTypes.COBBLED_DEEPSLATE_WALL, StateTypes.POLISHED_DEEPSLATE_WALL, StateTypes.DEEPSLATE_TILE_WALL, StateTypes.DEEPSLATE_BRICK_WALL, StateTypes.MUD_BRICK_WALL);
BlockTags.CORAL_PLANTS.add(StateTypes.TUBE_CORAL, StateTypes.BRAIN_CORAL, StateTypes.BUBBLE_CORAL, StateTypes.FIRE_CORAL, StateTypes.HORN_CORAL);
BlockTags.CORALS.addTag(BlockTags.CORAL_PLANTS).add(StateTypes.TUBE_CORAL_FAN, StateTypes.BRAIN_CORAL_FAN, StateTypes.BUBBLE_CORAL_FAN, StateTypes.FIRE_CORAL_FAN, StateTypes.HORN_CORAL_FAN);
BlockTags.WALL_CORALS.add(StateTypes.TUBE_CORAL_WALL_FAN, StateTypes.BRAIN_CORAL_WALL_FAN, StateTypes.BUBBLE_CORAL_WALL_FAN, StateTypes.FIRE_CORAL_WALL_FAN, StateTypes.HORN_CORAL_WALL_FAN);
BlockTags.SAND.add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.SUSPICIOUS_SAND);
BlockTags.SMELTS_TO_GLASS.add(StateTypes.SAND, StateTypes.RED_SAND);
BlockTags.ANVIL.add(StateTypes.ANVIL, StateTypes.CHIPPED_ANVIL, StateTypes.DAMAGED_ANVIL);
BlockTags.RAILS.add(StateTypes.RAIL, StateTypes.POWERED_RAIL, StateTypes.DETECTOR_RAIL, StateTypes.ACTIVATOR_RAIL);
BlockTags.CORAL_BLOCKS.add(StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK);
BlockTags.ICE.add(StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BLUE_ICE, StateTypes.FROSTED_ICE);
BlockTags.VALID_SPAWN.add(StateTypes.GRASS_BLOCK, StateTypes.PODZOL);
BlockTags.LEAVES.add(StateTypes.JUNGLE_LEAVES, StateTypes.OAK_LEAVES, StateTypes.SPRUCE_LEAVES, StateTypes.DARK_OAK_LEAVES, StateTypes.ACACIA_LEAVES, StateTypes.BIRCH_LEAVES, StateTypes.AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.MANGROVE_LEAVES, StateTypes.CHERRY_LEAVES);
BlockTags.IMPERMEABLE.add(StateTypes.GLASS, StateTypes.WHITE_STAINED_GLASS, StateTypes.ORANGE_STAINED_GLASS, StateTypes.MAGENTA_STAINED_GLASS, StateTypes.LIGHT_BLUE_STAINED_GLASS, StateTypes.YELLOW_STAINED_GLASS, StateTypes.LIME_STAINED_GLASS, StateTypes.PINK_STAINED_GLASS, StateTypes.GRAY_STAINED_GLASS, StateTypes.LIGHT_GRAY_STAINED_GLASS, StateTypes.CYAN_STAINED_GLASS, StateTypes.PURPLE_STAINED_GLASS, StateTypes.BLUE_STAINED_GLASS, StateTypes.BROWN_STAINED_GLASS, StateTypes.GREEN_STAINED_GLASS, StateTypes.RED_STAINED_GLASS, StateTypes.BLACK_STAINED_GLASS, StateTypes.TINTED_GLASS);
BlockTags.WOODEN_TRAPDOORS.add(StateTypes.ACACIA_TRAPDOOR, StateTypes.BIRCH_TRAPDOOR, StateTypes.DARK_OAK_TRAPDOOR, StateTypes.JUNGLE_TRAPDOOR, StateTypes.OAK_TRAPDOOR, StateTypes.SPRUCE_TRAPDOOR, StateTypes.CRIMSON_TRAPDOOR, StateTypes.WARPED_TRAPDOOR, StateTypes.MANGROVE_TRAPDOOR, StateTypes.BAMBOO_TRAPDOOR, StateTypes.CHERRY_TRAPDOOR);
BlockTags.TRAPDOORS.addTag(BlockTags.WOODEN_TRAPDOORS).add(StateTypes.IRON_TRAPDOOR);
BlockTags.UNDERWATER_BONEMEALS.add(StateTypes.SEAGRASS).addTag(BlockTags.CORALS).addTag(BlockTags.WALL_CORALS);
BlockTags.BAMBOO_PLANTABLE_ON.addTag(BlockTags.SAND).addTag(BlockTags.DIRT).add(StateTypes.BAMBOO, StateTypes.BAMBOO_SAPLING, StateTypes.GRAVEL, StateTypes.SUSPICIOUS_GRAVEL);
BlockTags.STANDING_SIGNS.add(StateTypes.OAK_SIGN, StateTypes.SPRUCE_SIGN, StateTypes.BIRCH_SIGN, StateTypes.ACACIA_SIGN, StateTypes.JUNGLE_SIGN, StateTypes.DARK_OAK_SIGN, StateTypes.CRIMSON_SIGN, StateTypes.WARPED_SIGN, StateTypes.MANGROVE_SIGN, StateTypes.BAMBOO_SIGN, StateTypes.CHERRY_SIGN);
BlockTags.WALL_SIGNS.add(StateTypes.OAK_WALL_SIGN, StateTypes.SPRUCE_WALL_SIGN, StateTypes.BIRCH_WALL_SIGN, StateTypes.ACACIA_WALL_SIGN, StateTypes.JUNGLE_WALL_SIGN, StateTypes.DARK_OAK_WALL_SIGN, StateTypes.CRIMSON_WALL_SIGN, StateTypes.WARPED_WALL_SIGN, StateTypes.MANGROVE_WALL_SIGN, StateTypes.BAMBOO_WALL_SIGN, StateTypes.CHERRY_WALL_SIGN);
BlockTags.SIGNS.addTag(BlockTags.STANDING_SIGNS).addTag(BlockTags.WALL_SIGNS);
BlockTags.CEILING_HANGING_SIGNS.add(StateTypes.OAK_HANGING_SIGN, StateTypes.SPRUCE_HANGING_SIGN, StateTypes.BIRCH_HANGING_SIGN, StateTypes.ACACIA_HANGING_SIGN, StateTypes.JUNGLE_HANGING_SIGN, StateTypes.DARK_OAK_HANGING_SIGN, StateTypes.CRIMSON_HANGING_SIGN, StateTypes.WARPED_HANGING_SIGN, StateTypes.MANGROVE_HANGING_SIGN, StateTypes.BAMBOO_HANGING_SIGN, StateTypes.CHERRY_HANGING_SIGN);
BlockTags.WALL_HANGING_SIGNS.add(StateTypes.OAK_WALL_HANGING_SIGN, StateTypes.SPRUCE_WALL_HANGING_SIGN, StateTypes.BIRCH_WALL_HANGING_SIGN, StateTypes.ACACIA_WALL_HANGING_SIGN, StateTypes.JUNGLE_WALL_HANGING_SIGN, StateTypes.DARK_OAK_WALL_HANGING_SIGN, StateTypes.MANGROVE_WALL_HANGING_SIGN, StateTypes.CRIMSON_WALL_HANGING_SIGN, StateTypes.WARPED_WALL_HANGING_SIGN, StateTypes.BAMBOO_WALL_HANGING_SIGN, StateTypes.CHERRY_WALL_HANGING_SIGN);
BlockTags.ALL_HANGING_SIGNS.addTag(BlockTags.CEILING_HANGING_SIGNS).addTag(BlockTags.WALL_HANGING_SIGNS);
BlockTags.ALL_SIGNS.addTag(BlockTags.SIGNS).addTag(BlockTags.ALL_HANGING_SIGNS);
BlockTags.SMALL_FLOWERS.add(StateTypes.DANDELION, StateTypes.POPPY, StateTypes.BLUE_ORCHID, StateTypes.ALLIUM, StateTypes.AZURE_BLUET, StateTypes.RED_TULIP, StateTypes.ORANGE_TULIP, StateTypes.WHITE_TULIP, StateTypes.PINK_TULIP, StateTypes.OXEYE_DAISY, StateTypes.CORNFLOWER, StateTypes.LILY_OF_THE_VALLEY, StateTypes.WITHER_ROSE, StateTypes.TORCHFLOWER);
BlockTags.BEDS.add(StateTypes.RED_BED, StateTypes.BLACK_BED, StateTypes.BLUE_BED, StateTypes.BROWN_BED, StateTypes.CYAN_BED, StateTypes.GRAY_BED, StateTypes.GREEN_BED, StateTypes.LIGHT_BLUE_BED, StateTypes.LIGHT_GRAY_BED, StateTypes.LIME_BED, StateTypes.MAGENTA_BED, StateTypes.ORANGE_BED, StateTypes.PINK_BED, StateTypes.PURPLE_BED, StateTypes.WHITE_BED, StateTypes.YELLOW_BED);
BlockTags.FENCES.addTag(BlockTags.WOODEN_FENCES).add(StateTypes.NETHER_BRICK_FENCE);
BlockTags.DRAGON_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.OBSIDIAN, StateTypes.CRYING_OBSIDIAN, StateTypes.END_STONE, StateTypes.IRON_BARS, StateTypes.RESPAWN_ANCHOR, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.DRAGON_TRANSPARENT.add(StateTypes.LIGHT).addTag(BlockTags.FIRE);
BlockTags.WITHER_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.LIGHT, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.WITHER_SUMMON_BASE_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.TALL_FLOWERS.add(StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.PEONY, StateTypes.ROSE_BUSH, StateTypes.PITCHER_PLANT);
BlockTags.FLOWERS.addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.TALL_FLOWERS).add(StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE);
BlockTags.BEEHIVES.add(StateTypes.BEE_NEST, StateTypes.BEEHIVE);
BlockTags.CROPS.add(StateTypes.BEETROOTS, StateTypes.CARROTS, StateTypes.POTATOES, StateTypes.WHEAT, StateTypes.MELON_STEM, StateTypes.PUMPKIN_STEM, StateTypes.TORCHFLOWER_CROP, StateTypes.PITCHER_CROP);
BlockTags.BEE_GROWABLES.addTag(BlockTags.CROPS).add(StateTypes.SWEET_BERRY_BUSH).add(StateTypes.CAVE_VINES).add(StateTypes.CAVE_VINES_PLANT);
BlockTags.SHULKER_BOXES.add(StateTypes.SHULKER_BOX, StateTypes.BLACK_SHULKER_BOX, StateTypes.BLUE_SHULKER_BOX, StateTypes.BROWN_SHULKER_BOX, StateTypes.CYAN_SHULKER_BOX, StateTypes.GRAY_SHULKER_BOX, StateTypes.GREEN_SHULKER_BOX, StateTypes.LIGHT_BLUE_SHULKER_BOX, StateTypes.LIGHT_GRAY_SHULKER_BOX, StateTypes.LIME_SHULKER_BOX, StateTypes.MAGENTA_SHULKER_BOX, StateTypes.ORANGE_SHULKER_BOX, StateTypes.PINK_SHULKER_BOX, StateTypes.PURPLE_SHULKER_BOX, StateTypes.RED_SHULKER_BOX, StateTypes.WHITE_SHULKER_BOX, StateTypes.YELLOW_SHULKER_BOX);
BlockTags.PORTALS.add(StateTypes.NETHER_PORTAL, StateTypes.END_PORTAL, StateTypes.END_GATEWAY);
BlockTags.FIRE.add(StateTypes.FIRE, StateTypes.SOUL_FIRE);
BlockTags.NYLIUM.add(StateTypes.CRIMSON_NYLIUM, StateTypes.WARPED_NYLIUM);
BlockTags.WART_BLOCKS.add(StateTypes.NETHER_WART_BLOCK, StateTypes.WARPED_WART_BLOCK);
BlockTags.BEACON_BASE_BLOCKS.add(StateTypes.NETHERITE_BLOCK, StateTypes.EMERALD_BLOCK, StateTypes.DIAMOND_BLOCK, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK);
BlockTags.SOUL_SPEED_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.WALL_POST_OVERRIDE.add(StateTypes.TORCH, StateTypes.SOUL_TORCH, StateTypes.REDSTONE_TORCH, StateTypes.TRIPWIRE).addTag(BlockTags.SIGNS).addTag(BlockTags.BANNERS).addTag(BlockTags.PRESSURE_PLATES);
BlockTags.CLIMBABLE.add(StateTypes.LADDER, StateTypes.VINE, StateTypes.SCAFFOLDING, StateTypes.WEEPING_VINES, StateTypes.WEEPING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.TWISTING_VINES_PLANT, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT);
BlockTags.FALL_DAMAGE_RESETTING.addTag(BlockTags.CLIMBABLE).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.COBWEB);
BlockTags.PIGLIN_REPELLENTS.add(StateTypes.SOUL_FIRE).add(StateTypes.SOUL_TORCH).add(StateTypes.SOUL_LANTERN).add(StateTypes.SOUL_WALL_TORCH).add(StateTypes.SOUL_CAMPFIRE);
BlockTags.HOGLIN_REPELLENTS.add(StateTypes.WARPED_FUNGUS).add(StateTypes.POTTED_WARPED_FUNGUS).add(StateTypes.NETHER_PORTAL).add(StateTypes.RESPAWN_ANCHOR);
BlockTags.FLOWERS.addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.TALL_FLOWERS).add(StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_LEAVES, StateTypes.PINK_PETALS, StateTypes.CHORUS_FLOWER, StateTypes.SPORE_BLOSSOM);
BlockTags.PIGLIN_REPELLENTS.add(StateTypes.SOUL_FIRE, StateTypes.SOUL_TORCH, StateTypes.SOUL_LANTERN, StateTypes.SOUL_WALL_TORCH, StateTypes.SOUL_CAMPFIRE);
BlockTags.GOLD_ORES.add(StateTypes.GOLD_ORE, StateTypes.NETHER_GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE);
BlockTags.IRON_ORES.add(StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE);
BlockTags.DIAMOND_ORES.add(StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE);
BlockTags.REDSTONE_ORES.add(StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE);
BlockTags.LAPIS_ORES.add(StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE);
BlockTags.COAL_ORES.add(StateTypes.COAL_ORE, StateTypes.DEEPSLATE_COAL_ORE);
BlockTags.EMERALD_ORES.add(StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE);
BlockTags.COPPER_ORES.add(StateTypes.COPPER_ORE, StateTypes.DEEPSLATE_COPPER_ORE);
BlockTags.LAPIS_ORES.add(StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE);
BlockTags.CANDLES.add(StateTypes.CANDLE, StateTypes.WHITE_CANDLE, StateTypes.ORANGE_CANDLE, StateTypes.MAGENTA_CANDLE, StateTypes.LIGHT_BLUE_CANDLE, StateTypes.YELLOW_CANDLE, StateTypes.LIME_CANDLE, StateTypes.PINK_CANDLE, StateTypes.GRAY_CANDLE, StateTypes.LIGHT_GRAY_CANDLE, StateTypes.CYAN_CANDLE, StateTypes.PURPLE_CANDLE, StateTypes.BLUE_CANDLE, StateTypes.BROWN_CANDLE, StateTypes.GREEN_CANDLE, StateTypes.RED_CANDLE, StateTypes.BLACK_CANDLE);
BlockTags.DIRT.add(StateTypes.DIRT, StateTypes.GRASS_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT, StateTypes.MYCELIUM, StateTypes.ROOTED_DIRT, StateTypes.MOSS_BLOCK, StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS);
BlockTags.TERRACOTTA.add(StateTypes.TERRACOTTA, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA);
BlockTags.CONCRETE_POWDER.add(StateTypes.WHITE_CONCRETE_POWDER, StateTypes.ORANGE_CONCRETE_POWDER, StateTypes.MAGENTA_CONCRETE_POWDER, StateTypes.LIGHT_BLUE_CONCRETE_POWDER, StateTypes.YELLOW_CONCRETE_POWDER, StateTypes.LIME_CONCRETE_POWDER, StateTypes.PINK_CONCRETE_POWDER, StateTypes.GRAY_CONCRETE_POWDER, StateTypes.LIGHT_GRAY_CONCRETE_POWDER, StateTypes.CYAN_CONCRETE_POWDER, StateTypes.PURPLE_CONCRETE_POWDER, StateTypes.BLUE_CONCRETE_POWDER, StateTypes.BROWN_CONCRETE_POWDER, StateTypes.GREEN_CONCRETE_POWDER, StateTypes.RED_CONCRETE_POWDER, StateTypes.BLACK_CONCRETE_POWDER);
BlockTags.COMPLETES_FIND_TREE_TUTORIAL.addTag(BlockTags.LOGS).addTag(BlockTags.LEAVES).addTag(BlockTags.WART_BLOCKS);
BlockTags.FLOWER_POTS.add(StateTypes.FLOWER_POT, StateTypes.POTTED_POPPY, StateTypes.POTTED_BLUE_ORCHID, StateTypes.POTTED_ALLIUM, StateTypes.POTTED_AZURE_BLUET, StateTypes.POTTED_RED_TULIP, StateTypes.POTTED_ORANGE_TULIP, StateTypes.POTTED_WHITE_TULIP, StateTypes.POTTED_PINK_TULIP, StateTypes.POTTED_OXEYE_DAISY, StateTypes.POTTED_DANDELION, StateTypes.POTTED_OAK_SAPLING, StateTypes.POTTED_SPRUCE_SAPLING, StateTypes.POTTED_BIRCH_SAPLING, StateTypes.POTTED_JUNGLE_SAPLING, StateTypes.POTTED_ACACIA_SAPLING, StateTypes.POTTED_DARK_OAK_SAPLING, StateTypes.POTTED_RED_MUSHROOM, StateTypes.POTTED_BROWN_MUSHROOM, StateTypes.POTTED_DEAD_BUSH, StateTypes.POTTED_FERN, StateTypes.POTTED_CACTUS, StateTypes.POTTED_CORNFLOWER, StateTypes.POTTED_LILY_OF_THE_VALLEY, StateTypes.POTTED_WITHER_ROSE, StateTypes.POTTED_BAMBOO, StateTypes.POTTED_CRIMSON_FUNGUS, StateTypes.POTTED_WARPED_FUNGUS, StateTypes.POTTED_CRIMSON_ROOTS, StateTypes.POTTED_WARPED_ROOTS, StateTypes.POTTED_AZALEA_BUSH, StateTypes.POTTED_FLOWERING_AZALEA_BUSH, StateTypes.POTTED_MANGROVE_PROPAGULE, StateTypes.POTTED_CHERRY_SAPLING, StateTypes.POTTED_TORCHFLOWER);
BlockTags.ENDERMAN_HOLDABLE.addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.DIRT).add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.GRAVEL, StateTypes.BROWN_MUSHROOM, StateTypes.RED_MUSHROOM, StateTypes.TNT, StateTypes.CACTUS, StateTypes.CLAY, StateTypes.PUMPKIN, StateTypes.CARVED_PUMPKIN, StateTypes.MELON, StateTypes.CRIMSON_FUNGUS, StateTypes.CRIMSON_NYLIUM, StateTypes.CRIMSON_ROOTS, StateTypes.WARPED_FUNGUS, StateTypes.WARPED_NYLIUM, StateTypes.WARPED_ROOTS);
BlockTags.ICE.add(StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BLUE_ICE, StateTypes.FROSTED_ICE);
BlockTags.VALID_SPAWN.add(StateTypes.GRASS_BLOCK, StateTypes.PODZOL);
BlockTags.IMPERMEABLE.add(StateTypes.GLASS, StateTypes.WHITE_STAINED_GLASS, StateTypes.ORANGE_STAINED_GLASS, StateTypes.MAGENTA_STAINED_GLASS, StateTypes.LIGHT_BLUE_STAINED_GLASS, StateTypes.YELLOW_STAINED_GLASS, StateTypes.LIME_STAINED_GLASS, StateTypes.PINK_STAINED_GLASS, StateTypes.GRAY_STAINED_GLASS, StateTypes.LIGHT_GRAY_STAINED_GLASS, StateTypes.CYAN_STAINED_GLASS, StateTypes.PURPLE_STAINED_GLASS, StateTypes.BLUE_STAINED_GLASS, StateTypes.BROWN_STAINED_GLASS, StateTypes.GREEN_STAINED_GLASS, StateTypes.RED_STAINED_GLASS, StateTypes.BLACK_STAINED_GLASS, StateTypes.TINTED_GLASS);
BlockTags.UNDERWATER_BONEMEALS.addTag(BlockTags.CORALS).addTag(BlockTags.WALL_CORALS).add(StateTypes.SEAGRASS);
BlockTags.CORAL_BLOCKS.add(StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK);
BlockTags.WALL_CORALS.add(StateTypes.TUBE_CORAL_WALL_FAN, StateTypes.BRAIN_CORAL_WALL_FAN, StateTypes.BUBBLE_CORAL_WALL_FAN, StateTypes.FIRE_CORAL_WALL_FAN, StateTypes.HORN_CORAL_WALL_FAN);
BlockTags.CORAL_PLANTS.add(StateTypes.TUBE_CORAL, StateTypes.BRAIN_CORAL, StateTypes.BUBBLE_CORAL, StateTypes.FIRE_CORAL, StateTypes.HORN_CORAL);
BlockTags.CORALS.addTag(BlockTags.CORAL_PLANTS).add(StateTypes.TUBE_CORAL_FAN, StateTypes.BRAIN_CORAL_FAN, StateTypes.BUBBLE_CORAL_FAN, StateTypes.FIRE_CORAL_FAN, StateTypes.HORN_CORAL_FAN);
BlockTags.BAMBOO_PLANTABLE_ON.addTag(BlockTags.SAND).addTag(BlockTags.DIRT).add(StateTypes.BAMBOO, StateTypes.BAMBOO_SAPLING, StateTypes.GRAVEL, StateTypes.SUSPICIOUS_GRAVEL);
BlockTags.STANDING_SIGNS.add(StateTypes.OAK_SIGN, StateTypes.SPRUCE_SIGN, StateTypes.BIRCH_SIGN, StateTypes.ACACIA_SIGN, StateTypes.JUNGLE_SIGN, StateTypes.DARK_OAK_SIGN, StateTypes.CRIMSON_SIGN, StateTypes.WARPED_SIGN, StateTypes.MANGROVE_SIGN, StateTypes.BAMBOO_SIGN, StateTypes.CHERRY_SIGN);
BlockTags.WALL_SIGNS.add(StateTypes.OAK_WALL_SIGN, StateTypes.SPRUCE_WALL_SIGN, StateTypes.BIRCH_WALL_SIGN, StateTypes.ACACIA_WALL_SIGN, StateTypes.JUNGLE_WALL_SIGN, StateTypes.DARK_OAK_WALL_SIGN, StateTypes.CRIMSON_WALL_SIGN, StateTypes.WARPED_WALL_SIGN, StateTypes.MANGROVE_WALL_SIGN, StateTypes.BAMBOO_WALL_SIGN, StateTypes.CHERRY_WALL_SIGN);
BlockTags.SIGNS.addTag(BlockTags.STANDING_SIGNS).addTag(BlockTags.WALL_SIGNS);
BlockTags.CEILING_HANGING_SIGNS.add(StateTypes.OAK_HANGING_SIGN, StateTypes.SPRUCE_HANGING_SIGN, StateTypes.BIRCH_HANGING_SIGN, StateTypes.ACACIA_HANGING_SIGN, StateTypes.CHERRY_HANGING_SIGN, StateTypes.JUNGLE_HANGING_SIGN, StateTypes.DARK_OAK_HANGING_SIGN, StateTypes.CRIMSON_HANGING_SIGN, StateTypes.WARPED_HANGING_SIGN, StateTypes.MANGROVE_HANGING_SIGN, StateTypes.BAMBOO_HANGING_SIGN);
BlockTags.WALL_HANGING_SIGNS.add(StateTypes.OAK_WALL_HANGING_SIGN, StateTypes.SPRUCE_WALL_HANGING_SIGN, StateTypes.BIRCH_WALL_HANGING_SIGN, StateTypes.ACACIA_WALL_HANGING_SIGN, StateTypes.CHERRY_WALL_HANGING_SIGN, StateTypes.JUNGLE_WALL_HANGING_SIGN, StateTypes.DARK_OAK_WALL_HANGING_SIGN, StateTypes.CRIMSON_WALL_HANGING_SIGN, StateTypes.WARPED_WALL_HANGING_SIGN, StateTypes.MANGROVE_WALL_HANGING_SIGN, StateTypes.BAMBOO_WALL_HANGING_SIGN);
BlockTags.ALL_HANGING_SIGNS.addTag(BlockTags.CEILING_HANGING_SIGNS).addTag(BlockTags.WALL_HANGING_SIGNS);
BlockTags.ALL_SIGNS.addTag(BlockTags.SIGNS).addTag(BlockTags.ALL_HANGING_SIGNS);
BlockTags.DRAGON_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.OBSIDIAN, StateTypes.CRYING_OBSIDIAN, StateTypes.END_STONE, StateTypes.IRON_BARS, StateTypes.RESPAWN_ANCHOR, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.DRAGON_TRANSPARENT.addTag(BlockTags.FIRE).add(StateTypes.LIGHT);
BlockTags.WITHER_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.LIGHT, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.WITHER_SUMMON_BASE_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.BEEHIVES.add(StateTypes.BEE_NEST, StateTypes.BEEHIVE);
BlockTags.CROPS.add(StateTypes.BEETROOTS, StateTypes.CARROTS, StateTypes.POTATOES, StateTypes.WHEAT, StateTypes.MELON_STEM, StateTypes.PUMPKIN_STEM, StateTypes.TORCHFLOWER_CROP, StateTypes.PITCHER_CROP);
BlockTags.BEE_GROWABLES.addTag(BlockTags.CROPS).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT);
BlockTags.PORTALS.add(StateTypes.NETHER_PORTAL, StateTypes.END_PORTAL, StateTypes.END_GATEWAY);
BlockTags.FIRE.add(StateTypes.FIRE, StateTypes.SOUL_FIRE);
BlockTags.NYLIUM.add(StateTypes.CRIMSON_NYLIUM, StateTypes.WARPED_NYLIUM);
BlockTags.BEACON_BASE_BLOCKS.add(StateTypes.NETHERITE_BLOCK, StateTypes.EMERALD_BLOCK, StateTypes.DIAMOND_BLOCK, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK);
BlockTags.SOUL_SPEED_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.WALL_POST_OVERRIDE.addTag(BlockTags.SIGNS).addTag(BlockTags.BANNERS).addTag(BlockTags.PRESSURE_PLATES).add(StateTypes.TORCH, StateTypes.SOUL_TORCH, StateTypes.REDSTONE_TORCH, StateTypes.TRIPWIRE);
BlockTags.CLIMBABLE.add(StateTypes.LADDER, StateTypes.VINE, StateTypes.SCAFFOLDING, StateTypes.WEEPING_VINES, StateTypes.WEEPING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.TWISTING_VINES_PLANT, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT);
BlockTags.FALL_DAMAGE_RESETTING.addTag(BlockTags.CLIMBABLE).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.COBWEB);
BlockTags.SHULKER_BOXES.add(StateTypes.SHULKER_BOX, StateTypes.BLACK_SHULKER_BOX, StateTypes.BLUE_SHULKER_BOX, StateTypes.BROWN_SHULKER_BOX, StateTypes.CYAN_SHULKER_BOX, StateTypes.GRAY_SHULKER_BOX, StateTypes.GREEN_SHULKER_BOX, StateTypes.LIGHT_BLUE_SHULKER_BOX, StateTypes.LIGHT_GRAY_SHULKER_BOX, StateTypes.LIME_SHULKER_BOX, StateTypes.MAGENTA_SHULKER_BOX, StateTypes.ORANGE_SHULKER_BOX, StateTypes.PINK_SHULKER_BOX, StateTypes.PURPLE_SHULKER_BOX, StateTypes.RED_SHULKER_BOX, StateTypes.WHITE_SHULKER_BOX, StateTypes.YELLOW_SHULKER_BOX);
BlockTags.HOGLIN_REPELLENTS.add(StateTypes.WARPED_FUNGUS, StateTypes.POTTED_WARPED_FUNGUS, StateTypes.NETHER_PORTAL, StateTypes.RESPAWN_ANCHOR);
BlockTags.SOUL_FIRE_BASE_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.STRIDER_WARM_BLOCKS.add(StateTypes.LAVA);
BlockTags.CAMPFIRES.add(StateTypes.CAMPFIRE, StateTypes.SOUL_CAMPFIRE);
BlockTags.GUARDED_BY_PIGLINS.add(StateTypes.GOLD_BLOCK, StateTypes.BARREL, StateTypes.CHEST, StateTypes.ENDER_CHEST, StateTypes.GILDED_BLACKSTONE, StateTypes.TRAPPED_CHEST, StateTypes.RAW_GOLD_BLOCK).addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.GOLD_ORES);
BlockTags.GUARDED_BY_PIGLINS.addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.GOLD_ORES).add(StateTypes.GOLD_BLOCK, StateTypes.BARREL, StateTypes.CHEST, StateTypes.ENDER_CHEST, StateTypes.GILDED_BLACKSTONE, StateTypes.TRAPPED_CHEST, StateTypes.RAW_GOLD_BLOCK);
BlockTags.PREVENT_MOB_SPAWNING_INSIDE.addTag(BlockTags.RAILS);
BlockTags.FENCE_GATES.add(StateTypes.ACACIA_FENCE_GATE, StateTypes.BIRCH_FENCE_GATE, StateTypes.DARK_OAK_FENCE_GATE, StateTypes.JUNGLE_FENCE_GATE, StateTypes.OAK_FENCE_GATE, StateTypes.SPRUCE_FENCE_GATE, StateTypes.CRIMSON_FENCE_GATE, StateTypes.WARPED_FENCE_GATE, StateTypes.MANGROVE_FENCE_GATE, StateTypes.BAMBOO_FENCE_GATE, StateTypes.CHERRY_FENCE_GATE);
BlockTags.UNSTABLE_BOTTOM_CENTER.addTag(BlockTags.FENCE_GATES);
BlockTags.MUSHROOM_GROW_BLOCK.add(StateTypes.MYCELIUM).add(StateTypes.PODZOL).add(StateTypes.CRIMSON_NYLIUM).add(StateTypes.WARPED_NYLIUM);
BlockTags.MUSHROOM_GROW_BLOCK.add(StateTypes.MYCELIUM, StateTypes.PODZOL, StateTypes.CRIMSON_NYLIUM, StateTypes.WARPED_NYLIUM);
BlockTags.INFINIBURN_OVERWORLD.add(StateTypes.NETHERRACK, StateTypes.MAGMA_BLOCK);
BlockTags.INFINIBURN_NETHER.addTag(BlockTags.INFINIBURN_OVERWORLD);
BlockTags.INFINIBURN_END.addTag(BlockTags.INFINIBURN_OVERWORLD).add(StateTypes.BEDROCK);
BlockTags.STONE_ORE_REPLACEABLES.add(StateTypes.STONE).add(StateTypes.GRANITE).add(StateTypes.DIORITE).add(StateTypes.ANDESITE);
BlockTags.DEEPSLATE_ORE_REPLACEABLES.add(StateTypes.DEEPSLATE).add(StateTypes.TUFF);
BlockTags.BASE_STONE_OVERWORLD.add(StateTypes.STONE).add(StateTypes.GRANITE).add(StateTypes.DIORITE).add(StateTypes.ANDESITE).add(StateTypes.TUFF).add(StateTypes.DEEPSLATE);
BlockTags.BASE_STONE_NETHER.add(StateTypes.NETHERRACK).add(StateTypes.BASALT).add(StateTypes.BLACKSTONE);
BlockTags.BASE_STONE_OVERWORLD.add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.DIORITE, StateTypes.ANDESITE, StateTypes.TUFF, StateTypes.DEEPSLATE);
BlockTags.STONE_ORE_REPLACEABLES.add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.DIORITE, StateTypes.ANDESITE);
BlockTags.DEEPSLATE_ORE_REPLACEABLES.add(StateTypes.DEEPSLATE, StateTypes.TUFF);
BlockTags.BASE_STONE_NETHER.add(StateTypes.NETHERRACK, StateTypes.BASALT, StateTypes.BLACKSTONE);
BlockTags.OVERWORLD_CARVER_REPLACEABLES.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.SAND).addTag(BlockTags.TERRACOTTA).addTag(BlockTags.IRON_ORES).addTag(BlockTags.COPPER_ORES).add(StateTypes.WATER, StateTypes.GRAVEL, StateTypes.SUSPICIOUS_GRAVEL, StateTypes.SANDSTONE, StateTypes.RED_SANDSTONE, StateTypes.CALCITE, StateTypes.SNOW, StateTypes.PACKED_ICE, StateTypes.RAW_IRON_BLOCK, StateTypes.RAW_COPPER_BLOCK);
BlockTags.NETHER_CARVER_REPLACEABLES.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.BASE_STONE_NETHER).addTag(BlockTags.DIRT).addTag(BlockTags.NYLIUM).addTag(BlockTags.WART_BLOCKS).add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.CANDLES.add(StateTypes.CANDLE, StateTypes.WHITE_CANDLE, StateTypes.ORANGE_CANDLE, StateTypes.MAGENTA_CANDLE, StateTypes.LIGHT_BLUE_CANDLE, StateTypes.YELLOW_CANDLE, StateTypes.LIME_CANDLE, StateTypes.PINK_CANDLE, StateTypes.GRAY_CANDLE, StateTypes.LIGHT_GRAY_CANDLE, StateTypes.CYAN_CANDLE, StateTypes.PURPLE_CANDLE, StateTypes.BLUE_CANDLE, StateTypes.BROWN_CANDLE, StateTypes.GREEN_CANDLE, StateTypes.RED_CANDLE, StateTypes.BLACK_CANDLE);
BlockTags.CANDLE_CAKES.add(StateTypes.CANDLE_CAKE, StateTypes.WHITE_CANDLE_CAKE, StateTypes.ORANGE_CANDLE_CAKE, StateTypes.MAGENTA_CANDLE_CAKE, StateTypes.LIGHT_BLUE_CANDLE_CAKE, StateTypes.YELLOW_CANDLE_CAKE, StateTypes.LIME_CANDLE_CAKE, StateTypes.PINK_CANDLE_CAKE, StateTypes.GRAY_CANDLE_CAKE, StateTypes.LIGHT_GRAY_CANDLE_CAKE, StateTypes.CYAN_CANDLE_CAKE, StateTypes.PURPLE_CANDLE_CAKE, StateTypes.BLUE_CANDLE_CAKE, StateTypes.BROWN_CANDLE_CAKE, StateTypes.GREEN_CANDLE_CAKE, StateTypes.RED_CANDLE_CAKE, StateTypes.BLACK_CANDLE_CAKE);
BlockTags.CRYSTAL_SOUND_BLOCKS.add(StateTypes.AMETHYST_BLOCK, StateTypes.BUDDING_AMETHYST);
BlockTags.CAULDRONS.add(StateTypes.CAULDRON, StateTypes.WATER_CAULDRON, StateTypes.LAVA_CAULDRON, StateTypes.POWDER_SNOW_CAULDRON);
BlockTags.CRYSTAL_SOUND_BLOCKS.add(StateTypes.AMETHYST_BLOCK, StateTypes.BUDDING_AMETHYST);
BlockTags.INSIDE_STEP_SOUND_BLOCKS.add(StateTypes.POWDER_SNOW, StateTypes.SCULK_VEIN, StateTypes.GLOW_LICHEN, StateTypes.LILY_PAD, StateTypes.SMALL_AMETHYST_BUD, StateTypes.PINK_PETALS);
BlockTags.COMBINATION_STEP_SOUND_BLOCKS.addTag(BlockTags.WOOL_CARPETS).add(StateTypes.MOSS_CARPET, StateTypes.SNOW, StateTypes.NETHER_SPROUTS, StateTypes.WARPED_ROOTS, StateTypes.CRIMSON_ROOTS);
BlockTags.DRIPSTONE_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD);
BlockTags.CAVE_VINES.add(StateTypes.CAVE_VINES_PLANT).add(StateTypes.CAVE_VINES);
BlockTags.MOSS_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.CAVE_VINES).addTag(BlockTags.DIRT);
BlockTags.LUSH_GROUND_REPLACEABLE.addTag(BlockTags.MOSS_REPLACEABLE).add(StateTypes.CLAY).add(StateTypes.GRAVEL).add(StateTypes.SAND);
BlockTags.AZALEA_ROOT_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).add(StateTypes.RED_SAND).add(StateTypes.CLAY).add(StateTypes.GRAVEL).add(StateTypes.SAND).add(StateTypes.SNOW_BLOCK).add(StateTypes.POWDER_SNOW);
BlockTags.SMALL_DRIPLEAF_PLACEABLE.add(StateTypes.CLAY).add(StateTypes.MOSS_BLOCK);
BlockTags.BIG_DRIPLEAF_PLACEABLE.addTag(BlockTags.SMALL_DRIPLEAF_PLACEABLE).addTag(BlockTags.DIRT).add(StateTypes.FARMLAND);
BlockTags.CAMEL_SAND_STEP_SOUND_BLOCKS.addTag(BlockTags.SAND).addTag(BlockTags.CONCRETE_POWDER);
BlockTags.OCCLUDES_VIBRATION_SIGNALS.addTag(BlockTags.WOOL);
BlockTags.DAMPENS_VIBRATIONS.addTag(BlockTags.WOOL).addTag(BlockTags.WOOL_CARPETS);
BlockTags.DRIPSTONE_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD);
BlockTags.CAVE_VINES.add(StateTypes.CAVE_VINES_PLANT, StateTypes.CAVE_VINES);
BlockTags.MOSS_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.CAVE_VINES).addTag(BlockTags.DIRT);
BlockTags.LUSH_GROUND_REPLACEABLE.addTag(BlockTags.MOSS_REPLACEABLE).add(StateTypes.CLAY, StateTypes.GRAVEL, StateTypes.SAND);
BlockTags.AZALEA_ROOT_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).add(StateTypes.RED_SAND, StateTypes.CLAY, StateTypes.GRAVEL, StateTypes.SAND, StateTypes.SNOW_BLOCK, StateTypes.POWDER_SNOW);
BlockTags.SMALL_DRIPLEAF_PLACEABLE.add(StateTypes.CLAY, StateTypes.MOSS_BLOCK);
BlockTags.BIG_DRIPLEAF_PLACEABLE.addTag(BlockTags.SMALL_DRIPLEAF_PLACEABLE).addTag(BlockTags.DIRT).add(StateTypes.FARMLAND);
BlockTags.SNOW.add(StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.POWDER_SNOW);
BlockTags.MINEABLE_WITH_AXE.add(StateTypes.NOTE_BLOCK, StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.AZALEA, StateTypes.BAMBOO, StateTypes.BARREL, StateTypes.BEE_NEST, StateTypes.BEEHIVE, StateTypes.BEETROOTS, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.BIG_DRIPLEAF, StateTypes.BOOKSHELF, StateTypes.BROWN_MUSHROOM_BLOCK, StateTypes.BROWN_MUSHROOM, StateTypes.CAMPFIRE, StateTypes.CARROTS, StateTypes.CARTOGRAPHY_TABLE, StateTypes.CARVED_PUMPKIN, StateTypes.CAVE_VINES_PLANT, StateTypes.CAVE_VINES, StateTypes.CHEST, StateTypes.CHORUS_FLOWER, StateTypes.CHORUS_PLANT, StateTypes.COCOA, StateTypes.COMPOSTER, StateTypes.CRAFTING_TABLE, StateTypes.CRIMSON_FUNGUS, StateTypes.DAYLIGHT_DETECTOR, StateTypes.DEAD_BUSH, StateTypes.FERN, StateTypes.FLETCHING_TABLE, StateTypes.GLOW_LICHEN, StateTypes.GRASS, StateTypes.HANGING_ROOTS, StateTypes.JACK_O_LANTERN, StateTypes.JUKEBOX, StateTypes.LADDER, StateTypes.LARGE_FERN, StateTypes.LECTERN, StateTypes.LILY_PAD, StateTypes.LOOM, StateTypes.MELON_STEM, StateTypes.MELON, StateTypes.MUSHROOM_STEM, StateTypes.NETHER_WART, StateTypes.POTATOES, StateTypes.PUMPKIN_STEM, StateTypes.PUMPKIN, StateTypes.RED_MUSHROOM_BLOCK, StateTypes.RED_MUSHROOM, StateTypes.SCAFFOLDING, StateTypes.SMALL_DRIPLEAF, StateTypes.SMITHING_TABLE, StateTypes.SOUL_CAMPFIRE, StateTypes.SPORE_BLOSSOM, StateTypes.SUGAR_CANE, StateTypes.SWEET_BERRY_BUSH, StateTypes.TALL_GRASS, StateTypes.TRAPPED_CHEST, StateTypes.TWISTING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.VINE, StateTypes.WARPED_FUNGUS, StateTypes.WEEPING_VINES_PLANT, StateTypes.WEEPING_VINES, StateTypes.WHEAT).addTag(BlockTags.BANNERS).addTag(BlockTags.FENCE_GATES).addTag(BlockTags.LOGS).addTag(BlockTags.PLANKS).addTag(BlockTags.SAPLINGS).addTag(BlockTags.SIGNS).addTag(BlockTags.WOODEN_BUTTONS).addTag(BlockTags.WOODEN_DOORS).addTag(BlockTags.WOODEN_FENCES).addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.WOODEN_SLABS).addTag(BlockTags.WOODEN_STAIRS).addTag(BlockTags.WOODEN_TRAPDOORS).add(StateTypes.MANGROVE_ROOTS).addTag(ALL_HANGING_SIGNS).add(StateTypes.BAMBOO_MOSAIC, StateTypes.BAMBOO_MOSAIC_SLAB, StateTypes.BAMBOO_MOSAIC_STAIRS).addTag(BAMBOO_BLOCKS).add(StateTypes.CHISELED_BOOKSHELF);
BlockTags.MINEABLE_WITH_HOE.add(StateTypes.NETHER_WART_BLOCK, StateTypes.WARPED_WART_BLOCK, StateTypes.HAY_BLOCK, StateTypes.DRIED_KELP_BLOCK, StateTypes.TARGET, StateTypes.SHROOMLIGHT, StateTypes.SPONGE, StateTypes.WET_SPONGE, StateTypes.JUNGLE_LEAVES, StateTypes.OAK_LEAVES, StateTypes.SPRUCE_LEAVES, StateTypes.DARK_OAK_LEAVES, StateTypes.ACACIA_LEAVES, StateTypes.BIRCH_LEAVES, StateTypes.AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.MANGROVE_LEAVES, StateTypes.SCULK_SENSOR, StateTypes.MOSS_BLOCK, StateTypes.MOSS_CARPET, StateTypes.SCULK, StateTypes.SCULK_CATALYST, StateTypes.SCULK_VEIN, StateTypes.SCULK_SHRIEKER, StateTypes.PINK_PETALS, StateTypes.CHERRY_LEAVES);
BlockTags.MINEABLE_WITH_PICKAXE.add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.POLISHED_GRANITE, StateTypes.DIORITE, StateTypes.POLISHED_DIORITE, StateTypes.ANDESITE, StateTypes.POLISHED_ANDESITE, StateTypes.COBBLESTONE, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.COAL_ORE, StateTypes.DEEPSLATE_COAL_ORE, StateTypes.NETHER_GOLD_ORE, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.LAPIS_BLOCK, StateTypes.DISPENSER, StateTypes.SANDSTONE, StateTypes.CHISELED_SANDSTONE, StateTypes.CUT_SANDSTONE, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK, StateTypes.BRICKS, StateTypes.MOSSY_COBBLESTONE, StateTypes.OBSIDIAN, StateTypes.SPAWNER, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.DIAMOND_BLOCK, StateTypes.FURNACE, StateTypes.COBBLESTONE_STAIRS, StateTypes.STONE_PRESSURE_PLATE, StateTypes.IRON_DOOR, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE, StateTypes.NETHERRACK, StateTypes.BASALT, StateTypes.POLISHED_BASALT, StateTypes.STONE_BRICKS, StateTypes.MOSSY_STONE_BRICKS, StateTypes.CRACKED_STONE_BRICKS, StateTypes.CHISELED_STONE_BRICKS, StateTypes.IRON_BARS, StateTypes.CHAIN, StateTypes.BRICK_STAIRS, StateTypes.STONE_BRICK_STAIRS, StateTypes.NETHER_BRICKS, StateTypes.NETHER_BRICK_FENCE, StateTypes.NETHER_BRICK_STAIRS, StateTypes.ENCHANTING_TABLE, StateTypes.BREWING_STAND, StateTypes.END_STONE, StateTypes.SANDSTONE_STAIRS, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.ENDER_CHEST, StateTypes.EMERALD_BLOCK, StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE, StateTypes.REDSTONE_BLOCK, StateTypes.NETHER_QUARTZ_ORE, StateTypes.HOPPER, StateTypes.QUARTZ_BLOCK, StateTypes.CHISELED_QUARTZ_BLOCK, StateTypes.QUARTZ_PILLAR, StateTypes.QUARTZ_STAIRS, StateTypes.DROPPER, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA, StateTypes.IRON_TRAPDOOR, StateTypes.PRISMARINE, StateTypes.PRISMARINE_BRICKS, StateTypes.DARK_PRISMARINE, StateTypes.PRISMARINE_STAIRS, StateTypes.PRISMARINE_BRICK_STAIRS, StateTypes.DARK_PRISMARINE_STAIRS, StateTypes.PRISMARINE_SLAB, StateTypes.PRISMARINE_BRICK_SLAB, StateTypes.DARK_PRISMARINE_SLAB, StateTypes.TERRACOTTA, StateTypes.COAL_BLOCK, StateTypes.RED_SANDSTONE, StateTypes.CHISELED_RED_SANDSTONE, StateTypes.CUT_RED_SANDSTONE, StateTypes.RED_SANDSTONE_STAIRS, StateTypes.STONE_SLAB, StateTypes.SMOOTH_STONE_SLAB, StateTypes.SANDSTONE_SLAB, StateTypes.CUT_SANDSTONE_SLAB, StateTypes.PETRIFIED_OAK_SLAB, StateTypes.COBBLESTONE_SLAB, StateTypes.BRICK_SLAB, StateTypes.STONE_BRICK_SLAB, StateTypes.NETHER_BRICK_SLAB, StateTypes.QUARTZ_SLAB, StateTypes.RED_SANDSTONE_SLAB, StateTypes.CUT_RED_SANDSTONE_SLAB, StateTypes.PURPUR_SLAB, StateTypes.SMOOTH_STONE, StateTypes.SMOOTH_SANDSTONE, StateTypes.SMOOTH_QUARTZ, StateTypes.SMOOTH_RED_SANDSTONE, StateTypes.PURPUR_BLOCK, StateTypes.PURPUR_PILLAR, StateTypes.PURPUR_STAIRS, StateTypes.END_STONE_BRICKS, StateTypes.MAGMA_BLOCK, StateTypes.RED_NETHER_BRICKS, StateTypes.BONE_BLOCK, StateTypes.OBSERVER, StateTypes.WHITE_GLAZED_TERRACOTTA, StateTypes.ORANGE_GLAZED_TERRACOTTA, StateTypes.MAGENTA_GLAZED_TERRACOTTA, StateTypes.LIGHT_BLUE_GLAZED_TERRACOTTA, StateTypes.YELLOW_GLAZED_TERRACOTTA, StateTypes.LIME_GLAZED_TERRACOTTA, StateTypes.PINK_GLAZED_TERRACOTTA, StateTypes.GRAY_GLAZED_TERRACOTTA, StateTypes.LIGHT_GRAY_GLAZED_TERRACOTTA, StateTypes.CYAN_GLAZED_TERRACOTTA, StateTypes.PURPLE_GLAZED_TERRACOTTA, StateTypes.BLUE_GLAZED_TERRACOTTA, StateTypes.BROWN_GLAZED_TERRACOTTA, StateTypes.GREEN_GLAZED_TERRACOTTA, StateTypes.RED_GLAZED_TERRACOTTA, StateTypes.BLACK_GLAZED_TERRACOTTA, StateTypes.WHITE_CONCRETE, StateTypes.ORANGE_CONCRETE, StateTypes.MAGENTA_CONCRETE, StateTypes.LIGHT_BLUE_CONCRETE, StateTypes.YELLOW_CONCRETE, StateTypes.LIME_CONCRETE, StateTypes.PINK_CONCRETE, StateTypes.GRAY_CONCRETE, StateTypes.LIGHT_GRAY_CONCRETE, StateTypes.CYAN_CONCRETE, StateTypes.PURPLE_CONCRETE, StateTypes.BLUE_CONCRETE, StateTypes.BROWN_CONCRETE, StateTypes.GREEN_CONCRETE, StateTypes.RED_CONCRETE, StateTypes.BLACK_CONCRETE, StateTypes.DEAD_TUBE_CORAL_BLOCK, StateTypes.DEAD_BRAIN_CORAL_BLOCK, StateTypes.DEAD_BUBBLE_CORAL_BLOCK, StateTypes.DEAD_FIRE_CORAL_BLOCK, StateTypes.DEAD_HORN_CORAL_BLOCK, StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK, StateTypes.DEAD_TUBE_CORAL, StateTypes.DEAD_BRAIN_CORAL, StateTypes.DEAD_BUBBLE_CORAL, StateTypes.DEAD_FIRE_CORAL, StateTypes.DEAD_HORN_CORAL, StateTypes.DEADLine truncated
BlockTags.MINEABLE_WITH_SHOVEL.add(StateTypes.CLAY, StateTypes.DIRT, StateTypes.COARSE_DIRT, StateTypes.PODZOL, StateTypes.FARMLAND, StateTypes.GRASS_BLOCK, StateTypes.GRAVEL, StateTypes.MYCELIUM, StateTypes.SAND, StateTypes.RED_SAND, StateTypes.SNOW_BLOCK, StateTypes.SNOW, StateTypes.SOUL_SAND, StateTypes.DIRT_PATH, StateTypes.WHITE_CONCRETE_POWDER, StateTypes.ORANGE_CONCRETE_POWDER, StateTypes.MAGENTA_CONCRETE_POWDER, StateTypes.LIGHT_BLUE_CONCRETE_POWDER, StateTypes.YELLOW_CONCRETE_POWDER, StateTypes.LIME_CONCRETE_POWDER, StateTypes.PINK_CONCRETE_POWDER, StateTypes.GRAY_CONCRETE_POWDER, StateTypes.LIGHT_GRAY_CONCRETE_POWDER, StateTypes.CYAN_CONCRETE_POWDER, StateTypes.PURPLE_CONCRETE_POWDER, StateTypes.BLUE_CONCRETE_POWDER, StateTypes.BROWN_CONCRETE_POWDER, StateTypes.GREEN_CONCRETE_POWDER, StateTypes.RED_CONCRETE_POWDER, StateTypes.BLACK_CONCRETE_POWDER, StateTypes.SOUL_SOIL, StateTypes.ROOTED_DIRT, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.MUD, StateTypes.SUSPICIOUS_SAND, StateTypes.SUSPICIOUS_GRAVEL);
BlockTags.SWORD_EFFICIENT.addTag(BlockTags.LEAVES).addTag(BlockTags.SAPLINGS).addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.CROPS).add(StateTypes.GRASS, StateTypes.FERN, StateTypes.DEAD_BUSH, StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.ROSE_BUSH, StateTypes.PEONY, StateTypes.TALL_GRASS, StateTypes.LARGE_FERN, StateTypes.HANGING_ROOTS, StateTypes.PITCHER_PLANT, StateTypes.BROWN_MUSHROOM, StateTypes.RED_MUSHROOM, StateTypes.SUGAR_CANE, StateTypes.PUMPKIN, StateTypes.CARVED_PUMPKIN, StateTypes.JACK_O_LANTERN, StateTypes.MELON, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.ATTACHED_MELON_STEM, StateTypes.LILY_PAD, StateTypes.COCOA, StateTypes.PITCHER_CROP, StateTypes.SWEET_BERRY_BUSH, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT, StateTypes.SPORE_BLOSSOM, StateTypes.MOSS_CARPET, StateTypes.PINK_PETALS, StateTypes.BIG_DRIPLEAF, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.SMALL_DRIPLEAF, StateTypes.NETHER_WART, StateTypes.WARPED_FUNGUS, StateTypes.WARPED_ROOTS, StateTypes.NETHER_SPROUTS, StateTypes.CRIMSON_FUNGUS, StateTypes.WEEPING_VINES, StateTypes.WEEPING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.TWISTING_VINES_PLANT, StateTypes.CRIMSON_ROOTS, StateTypes.CHORUS_PLANT, StateTypes.CHORUS_FLOWER);
BlockTags.MINEABLE_WITH_AXE.addTag(BlockTags.BANNERS).addTag(BlockTags.FENCE_GATES).addTag(BlockTags.LOGS).addTag(BlockTags.PLANKS).addTag(BlockTags.SAPLINGS).addTag(BlockTags.SIGNS).addTag(BlockTags.WOODEN_BUTTONS).addTag(BlockTags.WOODEN_DOORS).addTag(BlockTags.WOODEN_FENCES).addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.WOODEN_SLABS).addTag(BlockTags.WOODEN_STAIRS).addTag(BlockTags.WOODEN_TRAPDOORS).addTag(BlockTags.ALL_HANGING_SIGNS).addTag(BlockTags.BAMBOO_BLOCKS).add(StateTypes.NOTE_BLOCK, StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.AZALEA, StateTypes.BAMBOO, StateTypes.BARREL, StateTypes.BEE_NEST, StateTypes.BEEHIVE, StateTypes.BEETROOTS, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.BIG_DRIPLEAF, StateTypes.BOOKSHELF, StateTypes.BROWN_MUSHROOM_BLOCK, StateTypes.BROWN_MUSHROOM, StateTypes.CAMPFIRE, StateTypes.CARROTS, StateTypes.CARTOGRAPHY_TABLE, StateTypes.CARVED_PUMPKIN, StateTypes.CAVE_VINES_PLANT, StateTypes.CAVE_VINES, StateTypes.CHEST, StateTypes.CHORUS_FLOWER, StateTypes.CHORUS_PLANT, StateTypes.COCOA, StateTypes.COMPOSTER, StateTypes.CRAFTING_TABLE, StateTypes.CRIMSON_FUNGUS, StateTypes.DAYLIGHT_DETECTOR, StateTypes.DEAD_BUSH, StateTypes.FERN, StateTypes.FLETCHING_TABLE, StateTypes.GLOW_LICHEN, StateTypes.SHORT_GRASS, StateTypes.HANGING_ROOTS, StateTypes.JACK_O_LANTERN, StateTypes.JUKEBOX, StateTypes.LADDER, StateTypes.LARGE_FERN, StateTypes.LECTERN, StateTypes.LILY_PAD, StateTypes.LOOM, StateTypes.MELON_STEM, StateTypes.MELON, StateTypes.MUSHROOM_STEM, StateTypes.NETHER_WART, StateTypes.POTATOES, StateTypes.PUMPKIN_STEM, StateTypes.PUMPKIN, StateTypes.RED_MUSHROOM_BLOCK, StateTypes.RED_MUSHROOM, StateTypes.SCAFFOLDING, StateTypes.SMALL_DRIPLEAF, StateTypes.SMITHING_TABLE, StateTypes.SOUL_CAMPFIRE, StateTypes.SPORE_BLOSSOM, StateTypes.SUGAR_CANE, StateTypes.SWEET_BERRY_BUSH, StateTypes.TALL_GRASS, StateTypes.TRAPPED_CHEST, StateTypes.TWISTING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.VINE, StateTypes.WARPED_FUNGUS, StateTypes.WEEPING_VINES_PLANT, StateTypes.WEEPING_VINES, StateTypes.WHEAT, StateTypes.MANGROVE_ROOTS, StateTypes.BAMBOO_MOSAIC, StateTypes.BAMBOO_MOSAIC_SLAB, StateTypes.BAMBOO_MOSAIC_STAIRS, StateTypes.CHISELED_BOOKSHELF);
BlockTags.MINEABLE_WITH_HOE.add(StateTypes.NETHER_WART_BLOCK, StateTypes.WARPED_WART_BLOCK, StateTypes.HAY_BLOCK, StateTypes.DRIED_KELP_BLOCK, StateTypes.TARGET, StateTypes.SHROOMLIGHT, StateTypes.SPONGE, StateTypes.WET_SPONGE, StateTypes.JUNGLE_LEAVES, StateTypes.OAK_LEAVES, StateTypes.SPRUCE_LEAVES, StateTypes.DARK_OAK_LEAVES, StateTypes.ACACIA_LEAVES, StateTypes.BIRCH_LEAVES, StateTypes.AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.MANGROVE_LEAVES, StateTypes.SCULK_SENSOR, StateTypes.CALIBRATED_SCULK_SENSOR, StateTypes.MOSS_BLOCK, StateTypes.MOSS_CARPET, StateTypes.SCULK, StateTypes.SCULK_CATALYST, StateTypes.SCULK_VEIN, StateTypes.SCULK_SHRIEKER, StateTypes.PINK_PETALS, StateTypes.CHERRY_LEAVES);
BlockTags.MINEABLE_WITH_PICKAXE.addTag(BlockTags.STONE_BUTTONS).addTag(BlockTags.WALLS).addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.ANVIL).addTag(BlockTags.CAULDRONS).addTag(BlockTags.RAILS).add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.POLISHED_GRANITE, StateTypes.DIORITE, StateTypes.POLISHED_DIORITE, StateTypes.ANDESITE, StateTypes.POLISHED_ANDESITE, StateTypes.COBBLESTONE, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.COAL_ORE, StateTypes.DEEPSLATE_COAL_ORE, StateTypes.NETHER_GOLD_ORE, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.LAPIS_BLOCK, StateTypes.DISPENSER, StateTypes.SANDSTONE, StateTypes.CHISELED_SANDSTONE, StateTypes.CUT_SANDSTONE, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK, StateTypes.BRICKS, StateTypes.MOSSY_COBBLESTONE, StateTypes.OBSIDIAN, StateTypes.SPAWNER, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.DIAMOND_BLOCK, StateTypes.FURNACE, StateTypes.COBBLESTONE_STAIRS, StateTypes.STONE_PRESSURE_PLATE, StateTypes.IRON_DOOR, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE, StateTypes.NETHERRACK, StateTypes.BASALT, StateTypes.POLISHED_BASALT, StateTypes.STONE_BRICKS, StateTypes.MOSSY_STONE_BRICKS, StateTypes.CRACKED_STONE_BRICKS, StateTypes.CHISELED_STONE_BRICKS, StateTypes.IRON_BARS, StateTypes.CHAIN, StateTypes.BRICK_STAIRS, StateTypes.STONE_BRICK_STAIRS, StateTypes.NETHER_BRICKS, StateTypes.NETHER_BRICK_FENCE, StateTypes.NETHER_BRICK_STAIRS, StateTypes.ENCHANTING_TABLE, StateTypes.BREWING_STAND, StateTypes.END_STONE, StateTypes.SANDSTONE_STAIRS, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.ENDER_CHEST, StateTypes.EMERALD_BLOCK, StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE, StateTypes.REDSTONE_BLOCK, StateTypes.NETHER_QUARTZ_ORE, StateTypes.HOPPER, StateTypes.QUARTZ_BLOCK, StateTypes.CHISELED_QUARTZ_BLOCK, StateTypes.QUARTZ_PILLAR, StateTypes.QUARTZ_STAIRS, StateTypes.DROPPER, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA, StateTypes.IRON_TRAPDOOR, StateTypes.PRISMARINE, StateTypes.PRISMARINE_BRICKS, StateTypes.DARK_PRISMARINE, StateTypes.PRISMARINE_STAIRS, StateTypes.PRISMARINE_BRICK_STAIRS, StateTypes.DARK_PRISMARINE_STAIRS, StateTypes.PRISMARINE_SLAB, StateTypes.PRISMARINE_BRICK_SLAB, StateTypes.DARK_PRISMARINE_SLAB, StateTypes.TERRACOTTA, StateTypes.COAL_BLOCK, StateTypes.RED_SANDSTONE, StateTypes.CHISELED_RED_SANDSTONE, StateTypes.CUT_RED_SANDSTONE, StateTypes.RED_SANDSTONE_STAIRS, StateTypes.STONE_SLAB, StateTypes.SMOOTH_STONE_SLAB, StateTypes.SANDSTONE_SLAB, StateTypes.CUT_SANDSTONE_SLAB, StateTypes.PETRIFIED_OAK_SLAB, StateTypes.COBBLESTONE_SLAB, StateTypes.BRICK_SLAB, StateTypes.STONE_BRICK_SLAB, StateTypes.NETHER_BRICK_SLAB, StateTypes.QUARTZ_SLAB, StateTypes.RED_SANDSTONE_SLAB, StateTypes.CUT_RED_SANDSTONE_SLAB, StateTypes.PURPUR_SLAB, StateTypes.SMOOTH_STONE, StateTypes.SMOOTH_SANDSTONE, StateTypes.SMOOTH_QUARTZ, StateTypes.SMOOTH_RED_SANDSTONE, StateTypes.PURPUR_BLOCK, StateTypes.PURPUR_PILLAR, StateTypes.PURPUR_STAIRS, StateTypes.END_STONE_BRICKS, StateTypes.MAGMA_BLOCK, StateTypes.RED_NETHER_BRICKS, StateTypes.BONE_BLOCK, StateTypes.OBSERVER, StateTypes.WHITE_GLAZED_TERRACOTTA, StateTypes.ORANGE_GLAZED_TERRACOTTA, StateTypes.MAGENTA_GLAZED_TERRACOTTA, StateTypes.LIGHT_BLUE_GLAZED_TERRACOTTA, StateTypes.YELLOW_GLAZED_TERRACOTTA, StateTypes.LIME_GLAZED_TERRACOTTA, StateTypes.PINK_GLAZED_TERRACOTTA, StateTypes.GRAY_GLAZED_TERRACOTTA, StateTypes.LIGHT_GRAY_GLAZED_TERRACOTTA, StateTypes.CYAN_GLAZED_TERRACOTTA, StateTypes.PURPLE_GLAZED_TERRACOTTA, StateTypes.BLUE_GLAZED_TERRACOTTA, StateTypes.BROWN_GLAZED_TERRACOTTA, StateTypes.GREEN_GLAZED_TERRACOTTA, StateTypes.RED_GLAZED_TERRACOTTA, StateTypes.BLACK_GLAZED_TERRACOTTA, StateTypes.WHITE_CONCRETE, StateTypes.ORANGE_CONCRETE, StateTypes.MAGENTA_CONCRETE, StateTypes.LIGHT_BLUE_CONCRETE, StateTypes.YELLOW_CONCRETE, StateTypes.LIME_CONCRETE, StateTypes.PINK_CONCRETE, StateTypes.GRAY_CONCRETE, StateTypes.LIGHT_GRAY_CONCRETE, StateTypes.CYAN_CONCRETE, StateTypes.PURPLE_CONCRETE, StateTypes.BLUE_CONCRETE, StateTypes.BROWN_CONCRETE, StateTypes.GREEN_CONCRETE, StateTypes.RED_CONCRETE, StateTypes.BLACK_CONCRETE, StateTypes.DEAD_TUBE_CORAL_BLOCK, StateTypes.DEAD_BRAIN_CORAL_BLOCK, StateTypes.DEAD_BUBBLE_CORAL_BLOCK, StateTypes.DEAD_FIRE_CORAL_BLOCK, StateTypes.DEAD_HORN_CORAL_BLOCK, StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLine truncated
BlockTags.MINEABLE_WITH_SHOVEL.addTag(BlockTags.CONCRETE_POWDER).add(StateTypes.CLAY, StateTypes.DIRT, StateTypes.COARSE_DIRT, StateTypes.PODZOL, StateTypes.FARMLAND, StateTypes.GRASS_BLOCK, StateTypes.GRAVEL, StateTypes.MYCELIUM, StateTypes.SAND, StateTypes.RED_SAND, StateTypes.SNOW_BLOCK, StateTypes.SNOW, StateTypes.SOUL_SAND, StateTypes.DIRT_PATH, StateTypes.SOUL_SOIL, StateTypes.ROOTED_DIRT, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.MUD, StateTypes.SUSPICIOUS_SAND, StateTypes.SUSPICIOUS_GRAVEL);
BlockTags.SWORD_EFFICIENT.addTag(BlockTags.LEAVES).addTag(BlockTags.SAPLINGS).addTag(BlockTags.SMALL_FLOWERS).addTag(BlockTags.CROPS).add(StateTypes.SHORT_GRASS, StateTypes.FERN, StateTypes.DEAD_BUSH, StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.ROSE_BUSH, StateTypes.PEONY, StateTypes.TALL_GRASS, StateTypes.LARGE_FERN, StateTypes.HANGING_ROOTS, StateTypes.PITCHER_PLANT, StateTypes.BROWN_MUSHROOM, StateTypes.RED_MUSHROOM, StateTypes.SUGAR_CANE, StateTypes.PUMPKIN, StateTypes.CARVED_PUMPKIN, StateTypes.JACK_O_LANTERN, StateTypes.MELON, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.ATTACHED_MELON_STEM, StateTypes.LILY_PAD, StateTypes.COCOA, StateTypes.PITCHER_CROP, StateTypes.SWEET_BERRY_BUSH, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT, StateTypes.SPORE_BLOSSOM, StateTypes.MOSS_CARPET, StateTypes.PINK_PETALS, StateTypes.BIG_DRIPLEAF, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.SMALL_DRIPLEAF, StateTypes.NETHER_WART, StateTypes.WARPED_FUNGUS, StateTypes.WARPED_ROOTS, StateTypes.NETHER_SPROUTS, StateTypes.CRIMSON_FUNGUS, StateTypes.WEEPING_VINES, StateTypes.WEEPING_VINES_PLANT, StateTypes.TWISTING_VINES, StateTypes.TWISTING_VINES_PLANT, StateTypes.CRIMSON_ROOTS, StateTypes.CHORUS_PLANT, StateTypes.CHORUS_FLOWER);
BlockTags.NEEDS_DIAMOND_TOOL.add(StateTypes.OBSIDIAN, StateTypes.CRYING_OBSIDIAN, StateTypes.NETHERITE_BLOCK, StateTypes.RESPAWN_ANCHOR, StateTypes.ANCIENT_DEBRIS);
BlockTags.NEEDS_IRON_TOOL.add(StateTypes.DIAMOND_BLOCK, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.EMERALD_BLOCK, StateTypes.GOLD_BLOCK, StateTypes.RAW_GOLD_BLOCK, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE);
BlockTags.NEEDS_STONE_TOOL.add(StateTypes.IRON_BLOCK, StateTypes.RAW_IRON_BLOCK, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.LAPIS_BLOCK, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.COPPER_BLOCK, StateTypes.RAW_COPPER_BLOCK, StateTypes.COPPER_ORE, StateTypes.DEEPSLATE_COPPER_ORE, StateTypes.CUT_COPPER_SLAB, StateTypes.CUT_COPPER_STAIRS, StateTypes.CUT_COPPER, StateTypes.WEATHERED_COPPER, StateTypes.WEATHERED_CUT_COPPER_SLAB, StateTypes.WEATHERED_CUT_COPPER_STAIRS, StateTypes.WEATHERED_CUT_COPPER, StateTypes.OXIDIZED_COPPER, StateTypes.OXIDIZED_CUT_COPPER_SLAB, StateTypes.OXIDIZED_CUT_COPPER_STAIRS, StateTypes.OXIDIZED_CUT_COPPER, StateTypes.EXPOSED_COPPER, StateTypes.EXPOSED_CUT_COPPER_SLAB, StateTypes.EXPOSED_CUT_COPPER_STAIRS, StateTypes.EXPOSED_CUT_COPPER, StateTypes.WAXED_COPPER_BLOCK, StateTypes.WAXED_CUT_COPPER_SLAB, StateTypes.WAXED_CUT_COPPER_STAIRS, StateTypes.WAXED_CUT_COPPER, StateTypes.WAXED_WEATHERED_COPPER, StateTypes.WAXED_WEATHERED_CUT_COPPER_SLAB, StateTypes.WAXED_WEATHERED_CUT_COPPER_STAIRS, StateTypes.WAXED_WEATHERED_CUT_COPPER, StateTypes.WAXED_EXPOSED_COPPER, StateTypes.WAXED_EXPOSED_CUT_COPPER_SLAB, StateTypes.WAXED_EXPOSED_CUT_COPPER_STAIRS, StateTypes.WAXED_EXPOSED_CUT_COPPER, StateTypes.WAXED_OXIDIZED_COPPER, StateTypes.WAXED_OXIDIZED_CUT_COPPER_SLAB, StateTypes.WAXED_OXIDIZED_CUT_COPPER_STAIRS, StateTypes.WAXED_OXIDIZED_CUT_COPPER, StateTypes.LIGHTNING_ROD);
BlockTags.FEATURES_CANNOT_REPLACE.add(StateTypes.BEDROCK, StateTypes.SPAWNER, StateTypes.CHEST, StateTypes.END_PORTAL_FRAME, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.LAVA_POOL_STONE_CANNOT_REPLACE.addTag(BlockTags.FEATURES_CANNOT_REPLACE).addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS);
BlockTags.GEODE_INVALID_BLOCKS.add(StateTypes.BEDROCK, StateTypes.WATER, StateTypes.LAVA, StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BLUE_ICE);
BlockTags.FROG_PREFER_JUMP_TO.add(StateTypes.LILY_PAD, StateTypes.BIG_DRIPLEAF);
BlockTags.SCULK_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).addTag(BlockTags.NYLIUM).addTag(BlockTags.BASE_STONE_NETHER).add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.GRAVEL, StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL, StateTypes.CALCITE, StateTypes.SMOOTH_BASALT, StateTypes.CLAY, StateTypes.DRIPSTONE_BLOCK, StateTypes.END_STONE, StateTypes.RED_SANDSTONE, StateTypes.SANDSTONE);
BlockTags.SCULK_REPLACEABLE_WORLD_GEN.addTag(BlockTags.SCULK_REPLACEABLE).add(StateTypes.DEEPSLATE_BRICKS, StateTypes.DEEPSLATE_TILES, StateTypes.COBBLED_DEEPSLATE, StateTypes.CRACKED_DEEPSLATE_BRICKS, StateTypes.CRACKED_DEEPSLATE_TILES, StateTypes.POLISHED_DEEPSLATE);
BlockTags.ANCIENT_CITY_REPLACEABLE.add(StateTypes.DEEPSLATE, StateTypes.DEEPSLATE_BRICKS, StateTypes.DEEPSLATE_TILES, StateTypes.DEEPSLATE_BRICK_SLAB, StateTypes.DEEPSLATE_TILE_SLAB, StateTypes.DEEPSLATE_BRICK_STAIRS, StateTypes.DEEPSLATE_TILE_WALL, StateTypes.DEEPSLATE_BRICK_WALL, StateTypes.COBBLED_DEEPSLATE, StateTypes.CRACKED_DEEPSLATE_BRICKS, StateTypes.CRACKED_DEEPSLATE_TILES, StateTypes.GRAY_WOOL);
BlockTags.VIBRATION_RESONATORS.add(StateTypes.AMETHYST_BLOCK);
BlockTags.ANIMALS_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK);
BlockTags.AXOLOTLS_SPAWNABLE_ON.add(StateTypes.CLAY);
BlockTags.GOATS_SPAWNABLE_ON.addTag(BlockTags.ANIMALS_SPAWNABLE_ON).add(StateTypes.STONE, StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.PACKED_ICE, StateTypes.GRAVEL);
BlockTags.MOOSHROOMS_SPAWNABLE_ON.add(StateTypes.MYCELIUM);
BlockTags.PARROTS_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK, StateTypes.AIR).addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS);
BlockTags.PARROTS_SPAWNABLE_ON.addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS).add(StateTypes.GRASS_BLOCK, StateTypes.AIR);
BlockTags.POLAR_BEARS_SPAWNABLE_ON_ALTERNATE.add(StateTypes.ICE);
BlockTags.RABBITS_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK, StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.SAND);
BlockTags.FOXES_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK, StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT);
BlockTags.WOLVES_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK, StateTypes.SNOW, StateTypes.SNOW_BLOCK);
BlockTags.FROGS_SPAWNABLE_ON.add(StateTypes.GRASS_BLOCK, StateTypes.MUD, StateTypes.MANGROVE_ROOTS, StateTypes.MUDDY_MANGROVE_ROOTS);
BlockTags.TERRACOTTA.add(StateTypes.TERRACOTTA, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA);
BlockTags.AZALEA_GROWS_ON.addTag(BlockTags.DIRT).addTag(BlockTags.SAND).addTag(BlockTags.TERRACOTTA).add(StateTypes.SNOW_BLOCK).add(StateTypes.POWDER_SNOW);
BlockTags.REPLACEABLE_PLANTS.add(StateTypes.GRASS, StateTypes.FERN, StateTypes.DEAD_BUSH, StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.ROSE_BUSH, StateTypes.PEONY, StateTypes.TALL_GRASS, StateTypes.LARGE_FERN, StateTypes.HANGING_ROOTS, StateTypes.PITCHER_PLANT);
BlockTags.FROG_PREFER_JUMP_TO.add(StateTypes.LILY_PAD, StateTypes.BIG_DRIPLEAF);
BlockTags.SCULK_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).addTag(BlockTags.NYLIUM).addTag(BlockTags.BASE_STONE_NETHER).addTag(BlockTags.SAND).add(StateTypes.GRAVEL).add(StateTypes.SOUL_SAND).add(StateTypes.SOUL_SOIL).add(StateTypes.CALCITE).add(StateTypes.SMOOTH_BASALT).add(StateTypes.CLAY).add(StateTypes.DRIPSTONE_BLOCK).add(StateTypes.END_STONE).add(StateTypes.RED_SANDSTONE).add(StateTypes.SANDSTONE);
BlockTags.SCULK_REPLACEABLE_WORLD_GEN.addTag(BlockTags.SCULK_REPLACEABLE).add(StateTypes.DEEPSLATE_BRICKS).add(StateTypes.DEEPSLATE_TILES).add(StateTypes.COBBLED_DEEPSLATE).add(StateTypes.CRACKED_DEEPSLATE_BRICKS).add(StateTypes.CRACKED_DEEPSLATE_TILES).add(StateTypes.POLISHED_DEEPSLATE);
BlockTags.VIBRATION_RESONATORS.add(StateTypes.AMETHYST_BLOCK);
BlockTags.AZALEA_GROWS_ON.addTag(BlockTags.DIRT).addTag(BlockTags.SAND).addTag(BlockTags.TERRACOTTA).add(StateTypes.SNOW_BLOCK, StateTypes.POWDER_SNOW);
BlockTags.CONVERTABLE_TO_MUD.add(StateTypes.DIRT, StateTypes.COARSE_DIRT, StateTypes.ROOTED_DIRT);
BlockTags.ANCIENT_CITY_REPLACEABLE.add(StateTypes.DEEPSLATE).add(StateTypes.DEEPSLATE_BRICKS).add(StateTypes.DEEPSLATE_TILES).add(StateTypes.DEEPSLATE_BRICK_SLAB).add(StateTypes.DEEPSLATE_TILE_SLAB).add(StateTypes.DEEPSLATE_BRICK_STAIRS).add(StateTypes.DEEPSLATE_TILE_WALL).add(StateTypes.DEEPSLATE_BRICK_WALL).add(StateTypes.COBBLED_DEEPSLATE).add(StateTypes.CRACKED_DEEPSLATE_BRICKS).add(StateTypes.CRACKED_DEEPSLATE_TILES).add(StateTypes.GRAY_WOOL);
BlockTags.MANGROVE_LOGS_CAN_GROW_THROUGH.add(StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.MANGROVE_ROOTS, StateTypes.MANGROVE_LEAVES, StateTypes.MANGROVE_LOG, StateTypes.MANGROVE_PROPAGULE, StateTypes.MOSS_CARPET, StateTypes.VINE);
BlockTags.MANGROVE_ROOTS_CAN_GROW_THROUGH.add(StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.MANGROVE_ROOTS, StateTypes.MOSS_CARPET, StateTypes.VINE, StateTypes.MANGROVE_PROPAGULE, StateTypes.SNOW);
BlockTags.DEAD_BUSH_MAY_PLACE_ON.addTag(BlockTags.SAND).addTag(BlockTags.TERRACOTTA).addTag(BlockTags.DIRT);
BlockTags.SNOW_LAYER_CANNOT_SURVIVE_ON.add(StateTypes.ICE).add(StateTypes.PACKED_ICE).add(StateTypes.BARRIER);
BlockTags.SNOW_LAYER_CAN_SURVIVE_ON.add(StateTypes.HONEY_BLOCK).add(StateTypes.SOUL_SAND).add(StateTypes.MUD);
BlockTags.COMPLETES_FIND_TREE_TUTORIAL.addTag(BlockTags.LOGS).addTag(BlockTags.LEAVES).addTag(BlockTags.WART_BLOCKS);
BlockTags.SNAPS_GOAT_HORN.addTag(BlockTags.OVERWORLD_NATURAL_LOGS).add(StateTypes.STONE).add(StateTypes.PACKED_ICE).add(StateTypes.IRON_ORE).add(StateTypes.COAL_ORE).add(StateTypes.COPPER_ORE).add(StateTypes.EMERALD_ORE);
BlockTags.SNAPS_GOAT_HORN.addTag(BlockTags.OVERWORLD_NATURAL_LOGS).add(StateTypes.STONE, StateTypes.PACKED_ICE, StateTypes.IRON_ORE, StateTypes.COAL_ORE, StateTypes.COPPER_ORE, StateTypes.EMERALD_ORE);
BlockTags.REPLACEABLE_BY_TREES.addTag(BlockTags.LEAVES).add(StateTypes.SHORT_GRASS, StateTypes.FERN, StateTypes.DEAD_BUSH, StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.ROSE_BUSH, StateTypes.PEONY, StateTypes.TALL_GRASS, StateTypes.LARGE_FERN, StateTypes.HANGING_ROOTS, StateTypes.PITCHER_PLANT, StateTypes.WATER, StateTypes.SEAGRASS, StateTypes.TALL_SEAGRASS, StateTypes.WARPED_ROOTS, StateTypes.NETHER_SPROUTS, StateTypes.CRIMSON_ROOTS);
BlockTags.SNOW_LAYER_CANNOT_SURVIVE_ON.add(StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BARRIER);
BlockTags.SNOW_LAYER_CAN_SURVIVE_ON.add(StateTypes.HONEY_BLOCK, StateTypes.SOUL_SAND, StateTypes.MUD);
BlockTags.INVALID_SPAWN_INSIDE.add(StateTypes.END_PORTAL, StateTypes.END_GATEWAY);
BlockTags.TRAIL_RUINS_REPLACEABLE.add(StateTypes.GRAVEL);
BlockTags.SNIFFER_DIGGABLE_BLOCK.add(StateTypes.DIRT, StateTypes.GRASS_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT, StateTypes.ROOTED_DIRT, StateTypes.MOSS_BLOCK, StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS);
BlockTags.SNIFFER_EGG_HATCH_BOOST.add(StateTypes.MOSS_BLOCK);
for (StateType value : StateTypes.values()) {
if (value.isReplaceable()) BlockTags.REPLACEABLE.add(value);
}
BlockTags.TRAIL_RUINS_REPLACEABLE.add(StateTypes.GRAVEL);
BlockTags.REPLACEABLE.add(StateTypes.AIR, StateTypes.WATER, StateTypes.LAVA, StateTypes.SHORT_GRASS, StateTypes.FERN, StateTypes.DEAD_BUSH, StateTypes.SEAGRASS, StateTypes.TALL_SEAGRASS, StateTypes.FIRE, StateTypes.SOUL_FIRE, StateTypes.SNOW, StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.LIGHT, StateTypes.TALL_GRASS, StateTypes.LARGE_FERN, StateTypes.STRUCTURE_VOID, StateTypes.VOID_AIR, StateTypes.CAVE_AIR, StateTypes.BUBBLE_COLUMN, StateTypes.WARPED_ROOTS, StateTypes.NETHER_SPROUTS, StateTypes.CRIMSON_ROOTS, StateTypes.HANGING_ROOTS);
BlockTags.ENCHANTMENT_POWER_PROVIDER.add(StateTypes.BOOKSHELF);
BlockTags.ENCHANTMENT_POWER_TRANSMITTER.addTag(BlockTags.REPLACEABLE);
BlockTags.MAINTAINS_FARMLAND.add(StateTypes.PUMPKIN_STEM, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.MELON_STEM, StateTypes.ATTACHED_MELON_STEM, StateTypes.BEETROOTS, StateTypes.CARROTS, StateTypes.POTATOES, StateTypes.TORCHFLOWER_CROP, StateTypes.TORCHFLOWER, StateTypes.PITCHER_CROP, StateTypes.WHEAT);
@@ -144,40 +144,43 @@ public class ItemTags {
copy(BlockTags.WOODEN_FENCES, ItemTags.WOODEN_FENCES);
copy(BlockTags.FENCE_GATES, ItemTags.FENCE_GATES);
copy(BlockTags.WOODEN_PRESSURE_PLATES, ItemTags.WOODEN_PRESSURE_PLATES);
copy(BlockTags.WOODEN_TRAPDOORS, ItemTags.WOODEN_TRAPDOORS);
copy(BlockTags.DOORS, ItemTags.DOORS);
copy(BlockTags.SAPLINGS, ItemTags.SAPLINGS);
copy(BlockTags.BAMBOO_BLOCKS, ItemTags.BAMBOO_BLOCKS);
copy(BlockTags.OAK_LOGS, ItemTags.OAK_LOGS);
copy(BlockTags.DARK_OAK_LOGS, ItemTags.DARK_OAK_LOGS);
copy(BlockTags.BIRCH_LOGS, ItemTags.BIRCH_LOGS);
copy(BlockTags.ACACIA_LOGS, ItemTags.ACACIA_LOGS);
copy(BlockTags.SPRUCE_LOGS, ItemTags.SPRUCE_LOGS);
copy(BlockTags.MANGROVE_LOGS, ItemTags.MANGROVE_LOGS);
copy(BlockTags.JUNGLE_LOGS, ItemTags.JUNGLE_LOGS);
copy(BlockTags.CHERRY_LOGS, ItemTags.CHERRY_LOGS);
copy(BlockTags.CRIMSON_STEMS, ItemTags.CRIMSON_STEMS);
copy(BlockTags.WARPED_STEMS, ItemTags.WARPED_STEMS);
copy(BlockTags.WART_BLOCKS, ItemTags.WART_BLOCKS);
copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
copy(BlockTags.LOGS, ItemTags.LOGS);
copy(BlockTags.DARK_OAK_LOGS, ItemTags.DARK_OAK_LOGS);
copy(BlockTags.OAK_LOGS, ItemTags.OAK_LOGS);
copy(BlockTags.BIRCH_LOGS, ItemTags.BIRCH_LOGS);
copy(BlockTags.ACACIA_LOGS, ItemTags.ACACIA_LOGS);
copy(BlockTags.CHERRY_LOGS, ItemTags.CHERRY_LOGS);
copy(BlockTags.JUNGLE_LOGS, ItemTags.JUNGLE_LOGS);
copy(BlockTags.SPRUCE_LOGS, ItemTags.SPRUCE_LOGS);
copy(BlockTags.MANGROVE_LOGS, ItemTags.MANGROVE_LOGS);
copy(BlockTags.CRIMSON_STEMS, ItemTags.CRIMSON_STEMS);
copy(BlockTags.WARPED_STEMS, ItemTags.WARPED_STEMS);
copy(BlockTags.BAMBOO_BLOCKS, ItemTags.BAMBOO_BLOCKS);
copy(BlockTags.WART_BLOCKS, ItemTags.WART_BLOCKS);
ItemTags.BANNERS.add(ItemTypes.WHITE_BANNER, ItemTypes.ORANGE_BANNER, ItemTypes.MAGENTA_BANNER, ItemTypes.LIGHT_BLUE_BANNER, ItemTypes.YELLOW_BANNER, ItemTypes.LIME_BANNER, ItemTypes.PINK_BANNER, ItemTypes.GRAY_BANNER, ItemTypes.LIGHT_GRAY_BANNER, ItemTypes.CYAN_BANNER, ItemTypes.PURPLE_BANNER, ItemTypes.BLUE_BANNER, ItemTypes.BROWN_BANNER, ItemTypes.GREEN_BANNER, ItemTypes.RED_BANNER, ItemTypes.BLACK_BANNER);
copy(BlockTags.SAND, ItemTags.SAND);
copy(BlockTags.SMELTS_TO_GLASS, ItemTags.SMELTS_TO_GLASS);
copy(BlockTags.STAIRS, ItemTags.STAIRS);
copy(BlockTags.SLABS, ItemTags.SLABS);
copy(BlockTags.WALLS, ItemTags.WALLS);
copy(BlockTags.STAIRS, ItemTags.STAIRS);
copy(BlockTags.ANVIL, ItemTags.ANVIL);
copy(BlockTags.RAILS, ItemTags.RAILS);
copy(BlockTags.LEAVES, ItemTags.LEAVES);
copy(BlockTags.WOODEN_TRAPDOORS, ItemTags.WOODEN_TRAPDOORS);
copy(BlockTags.TRAPDOORS, ItemTags.TRAPDOORS);
copy(BlockTags.SMALL_FLOWERS, ItemTags.SMALL_FLOWERS);
copy(BlockTags.BEDS, ItemTags.BEDS);
copy(BlockTags.FENCES, ItemTags.FENCES);
copy(BlockTags.TALL_FLOWERS, ItemTags.TALL_FLOWERS);
copy(BlockTags.FLOWERS, ItemTags.FLOWERS);
copy(BlockTags.SOUL_FIRE_BASE_BLOCKS, ItemTags.SOUL_FIRE_BASE_BLOCKS);
copy(BlockTags.CANDLES, ItemTags.CANDLES);
copy(BlockTags.DAMPENS_VIBRATIONS, ItemTags.DAMPENS_VIBRATIONS);
ItemTags.PIGLIN_REPELLENTS.add(ItemTypes.SOUL_TORCH, ItemTypes.SOUL_LANTERN, ItemTypes.SOUL_CAMPFIRE);
ItemTags.PIGLIN_LOVED.addTag(ItemTags.GOLD_ORES).add(ItemTypes.GOLD_BLOCK, ItemTypes.GILDED_BLACKSTONE, ItemTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, ItemTypes.GOLD_INGOT, ItemTypes.BELL, ItemTypes.CLOCK, ItemTypes.GOLDEN_CARROT, ItemTypes.GLISTERING_MELON_SLICE, ItemTypes.GOLDEN_APPLE, ItemTypes.ENCHANTED_GOLDEN_APPLE, ItemTypes.GOLDEN_HELMET, ItemTypes.GOLDEN_CHESTPLATE, ItemTypes.GOLDEN_LEGGINGS, ItemTypes.GOLDEN_BOOTS, ItemTypes.GOLDEN_HORSE_ARMOR, ItemTypes.GOLDEN_SWORD, ItemTypes.GOLDEN_PICKAXE, ItemTypes.GOLDEN_SHOVEL, ItemTypes.GOLDEN_AXE, ItemTypes.GOLDEN_HOE, ItemTypes.RAW_GOLD, ItemTypes.RAW_GOLD_BLOCK);
ItemTags.IGNORED_BY_PIGLIN_BABIES.add(ItemTypes.LEATHER);
ItemTags.PIGLIN_FOOD.add(ItemTypes.PORKCHOP, ItemTypes.COOKED_PORKCHOP);
ItemTags.FOX_FOOD.add(ItemTypes.SWEET_BERRIES, ItemTypes.GLOW_BERRIES);
copy(BlockTags.GOLD_ORES, ItemTags.GOLD_ORES);
copy(BlockTags.IRON_ORES, ItemTags.IRON_ORES);
copy(BlockTags.DIAMOND_ORES, ItemTags.DIAMOND_ORES);
@@ -186,49 +189,46 @@ public class ItemTags {
copy(BlockTags.COAL_ORES, ItemTags.COAL_ORES);
copy(BlockTags.EMERALD_ORES, ItemTags.EMERALD_ORES);
copy(BlockTags.COPPER_ORES, ItemTags.COPPER_ORES);
ItemTags.NON_FLAMMABLE_WOOD.add(ItemTypes.WARPED_STEM, ItemTypes.STRIPPED_WARPED_STEM, ItemTypes.WARPED_HYPHAE, ItemTypes.STRIPPED_WARPED_HYPHAE, ItemTypes.CRIMSON_STEM, ItemTypes.STRIPPED_CRIMSON_STEM, ItemTypes.CRIMSON_HYPHAE, ItemTypes.STRIPPED_CRIMSON_HYPHAE, ItemTypes.CRIMSON_PLANKS, ItemTypes.WARPED_PLANKS, ItemTypes.CRIMSON_SLAB, ItemTypes.WARPED_SLAB, ItemTypes.CRIMSON_PRESSURE_PLATE, ItemTypes.WARPED_PRESSURE_PLATE, ItemTypes.CRIMSON_FENCE, ItemTypes.WARPED_FENCE, ItemTypes.CRIMSON_TRAPDOOR, ItemTypes.WARPED_TRAPDOOR, ItemTypes.CRIMSON_FENCE_GATE, ItemTypes.WARPED_FENCE_GATE, ItemTypes.CRIMSON_STAIRS, ItemTypes.WARPED_STAIRS, ItemTypes.CRIMSON_BUTTON, ItemTypes.WARPED_BUTTON, ItemTypes.CRIMSON_DOOR, ItemTypes.WARPED_DOOR, ItemTypes.CRIMSON_SIGN, ItemTypes.WARPED_SIGN, ItemTypes.WARPED_HANGING_SIGN, ItemTypes.CRIMSON_HANGING_SIGN);
copy(BlockTags.SOUL_FIRE_BASE_BLOCKS, ItemTags.SOUL_FIRE_BASE_BLOCKS);
copy(BlockTags.CANDLES, ItemTags.CANDLES);
copy(BlockTags.DIRT, ItemTags.DIRT);
copy(BlockTags.TERRACOTTA, ItemTags.TERRACOTTA);
copy(BlockTags.COMPLETES_FIND_TREE_TUTORIAL, ItemTags.COMPLETES_FIND_TREE_TUTORIAL);
ItemTags.BANNERS.add(ItemTypes.WHITE_BANNER, ItemTypes.ORANGE_BANNER, ItemTypes.MAGENTA_BANNER, ItemTypes.LIGHT_BLUE_BANNER, ItemTypes.YELLOW_BANNER, ItemTypes.LIME_BANNER, ItemTypes.PINK_BANNER, ItemTypes.GRAY_BANNER, ItemTypes.LIGHT_GRAY_BANNER, ItemTypes.CYAN_BANNER, ItemTypes.PURPLE_BANNER, ItemTypes.BLUE_BANNER, ItemTypes.BROWN_BANNER, ItemTypes.GREEN_BANNER, ItemTypes.RED_BANNER, ItemTypes.BLACK_BANNER);
ItemTags.BOATS.add(ItemTypes.OAK_BOAT, ItemTypes.SPRUCE_BOAT, ItemTypes.BIRCH_BOAT, ItemTypes.JUNGLE_BOAT, ItemTypes.ACACIA_BOAT, ItemTypes.DARK_OAK_BOAT, ItemTypes.MANGROVE_BOAT, ItemTypes.BAMBOO_RAFT, ItemTypes.CHERRY_BOAT).addTag(ItemTags.CHEST_BOATS);
ItemTags.BOATS.addTag(ItemTags.CHEST_BOATS).add(ItemTypes.OAK_BOAT, ItemTypes.SPRUCE_BOAT, ItemTypes.BIRCH_BOAT, ItemTypes.JUNGLE_BOAT, ItemTypes.ACACIA_BOAT, ItemTypes.DARK_OAK_BOAT, ItemTypes.MANGROVE_BOAT, ItemTypes.BAMBOO_RAFT, ItemTypes.CHERRY_BOAT);
ItemTags.CHEST_BOATS.add(ItemTypes.OAK_CHEST_BOAT, ItemTypes.SPRUCE_CHEST_BOAT, ItemTypes.BIRCH_CHEST_BOAT, ItemTypes.JUNGLE_CHEST_BOAT, ItemTypes.ACACIA_CHEST_BOAT, ItemTypes.DARK_OAK_CHEST_BOAT, ItemTypes.MANGROVE_CHEST_BOAT, ItemTypes.BAMBOO_CHEST_RAFT, ItemTypes.CHERRY_CHEST_BOAT);
ItemTags.FISHES.add(ItemTypes.COD, ItemTypes.COOKED_COD, ItemTypes.SALMON, ItemTypes.COOKED_SALMON, ItemTypes.PUFFERFISH, ItemTypes.TROPICAL_FISH);
copy(BlockTags.STANDING_SIGNS, ItemTags.SIGNS);
copy(BlockTags.CEILING_HANGING_SIGNS, ItemTags.HANGING_SIGNS);
ItemTags.CREEPER_DROP_MUSIC_DISCS.add(ItemTypes.MUSIC_DISC_13, ItemTypes.MUSIC_DISC_CAT, ItemTypes.MUSIC_DISC_BLOCKS, ItemTypes.MUSIC_DISC_CHIRP, ItemTypes.MUSIC_DISC_FAR, ItemTypes.MUSIC_DISC_MALL, ItemTypes.MUSIC_DISC_MELLOHI, ItemTypes.MUSIC_DISC_STAL, ItemTypes.MUSIC_DISC_STRAD, ItemTypes.MUSIC_DISC_WARD, ItemTypes.MUSIC_DISC_11, ItemTypes.MUSIC_DISC_WAIT);
ItemTags.MUSIC_DISCS.addTag(ItemTags.CREEPER_DROP_MUSIC_DISCS).add(ItemTypes.MUSIC_DISC_PIGSTEP, ItemTypes.MUSIC_DISC_OTHERSIDE, ItemTypes.MUSIC_DISC_5, ItemTypes.MUSIC_DISC_RELIC);
ItemTags.CREEPER_DROP_MUSIC_DISCS.add(ItemTypes.MUSIC_DISC_13, ItemTypes.MUSIC_DISC_CAT, ItemTypes.MUSIC_DISC_BLOCKS, ItemTypes.MUSIC_DISC_CHIRP, ItemTypes.MUSIC_DISC_FAR, ItemTypes.MUSIC_DISC_MALL, ItemTypes.MUSIC_DISC_MELLOHI, ItemTypes.MUSIC_DISC_STAL, ItemTypes.MUSIC_DISC_STRAD, ItemTypes.MUSIC_DISC_WARD, ItemTypes.MUSIC_DISC_11, ItemTypes.MUSIC_DISC_WAIT);
ItemTags.COALS.add(ItemTypes.COAL, ItemTypes.CHARCOAL);
ItemTags.ARROWS.add(ItemTypes.ARROW, ItemTypes.TIPPED_ARROW, ItemTypes.SPECTRAL_ARROW);
ItemTags.LECTERN_BOOKS.add(ItemTypes.WRITTEN_BOOK, ItemTypes.WRITABLE_BOOK);
ItemTags.BOOKSHELF_BOOKS.add(ItemTypes.BOOK, ItemTypes.WRITTEN_BOOK, ItemTypes.ENCHANTED_BOOK, ItemTypes.WRITABLE_BOOK, ItemTypes.KNOWLEDGE_BOOK);
ItemTags.BEACON_PAYMENT_ITEMS.add(ItemTypes.NETHERITE_INGOT, ItemTypes.EMERALD, ItemTypes.DIAMOND, ItemTypes.GOLD_INGOT, ItemTypes.IRON_INGOT);
ItemTags.PIGLIN_REPELLENTS.add(ItemTypes.SOUL_TORCH, ItemTypes.SOUL_LANTERN, ItemTypes.SOUL_CAMPFIRE);
ItemTags.PIGLIN_LOVED.addTag(ItemTags.GOLD_ORES).add(ItemTypes.GOLD_BLOCK, ItemTypes.GILDED_BLACKSTONE, ItemTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, ItemTypes.GOLD_INGOT, ItemTypes.BELL, ItemTypes.CLOCK, ItemTypes.GOLDEN_CARROT, ItemTypes.GLISTERING_MELON_SLICE, ItemTypes.GOLDEN_APPLE, ItemTypes.ENCHANTED_GOLDEN_APPLE, ItemTypes.GOLDEN_HELMET, ItemTypes.GOLDEN_CHESTPLATE, ItemTypes.GOLDEN_LEGGINGS, ItemTypes.GOLDEN_BOOTS, ItemTypes.GOLDEN_HORSE_ARMOR, ItemTypes.GOLDEN_SWORD, ItemTypes.GOLDEN_PICKAXE, ItemTypes.GOLDEN_SHOVEL, ItemTypes.GOLDEN_AXE, ItemTypes.GOLDEN_HOE, ItemTypes.RAW_GOLD, ItemTypes.RAW_GOLD_BLOCK);
ItemTags.IGNORED_BY_PIGLIN_BABIES.add(ItemTypes.LEATHER);
ItemTags.PIGLIN_FOOD.add(ItemTypes.PORKCHOP, ItemTypes.COOKED_PORKCHOP);
ItemTags.FOX_FOOD.add(ItemTypes.SWEET_BERRIES, ItemTypes.GLOW_BERRIES);
ItemTags.NON_FLAMMABLE_WOOD.add(ItemTypes.WARPED_STEM, ItemTypes.STRIPPED_WARPED_STEM, ItemTypes.WARPED_HYPHAE, ItemTypes.STRIPPED_WARPED_HYPHAE, ItemTypes.CRIMSON_STEM, ItemTypes.STRIPPED_CRIMSON_STEM, ItemTypes.CRIMSON_HYPHAE, ItemTypes.STRIPPED_CRIMSON_HYPHAE, ItemTypes.CRIMSON_PLANKS, ItemTypes.WARPED_PLANKS, ItemTypes.CRIMSON_SLAB, ItemTypes.WARPED_SLAB, ItemTypes.CRIMSON_PRESSURE_PLATE, ItemTypes.WARPED_PRESSURE_PLATE, ItemTypes.CRIMSON_FENCE, ItemTypes.WARPED_FENCE, ItemTypes.CRIMSON_TRAPDOOR, ItemTypes.WARPED_TRAPDOOR, ItemTypes.CRIMSON_FENCE_GATE, ItemTypes.WARPED_FENCE_GATE, ItemTypes.CRIMSON_STAIRS, ItemTypes.WARPED_STAIRS, ItemTypes.CRIMSON_BUTTON, ItemTypes.WARPED_BUTTON, ItemTypes.CRIMSON_DOOR, ItemTypes.WARPED_DOOR, ItemTypes.CRIMSON_SIGN, ItemTypes.WARPED_SIGN, ItemTypes.WARPED_HANGING_SIGN, ItemTypes.CRIMSON_HANGING_SIGN);
ItemTags.STONE_TOOL_MATERIALS.add(ItemTypes.COBBLESTONE, ItemTypes.BLACKSTONE, ItemTypes.COBBLED_DEEPSLATE);
ItemTags.STONE_CRAFTING_MATERIALS.add(ItemTypes.COBBLESTONE, ItemTypes.BLACKSTONE, ItemTypes.COBBLED_DEEPSLATE);
ItemTags.FREEZE_IMMUNE_WEARABLES.add(ItemTypes.LEATHER_BOOTS, ItemTypes.LEATHER_LEGGINGS, ItemTypes.LEATHER_CHESTPLATE, ItemTypes.LEATHER_HELMET, ItemTypes.LEATHER_HORSE_ARMOR);
ItemTags.AXOLOTL_TEMPT_ITEMS.add(ItemTypes.TROPICAL_FISH_BUCKET);
copy(BlockTags.DAMPENS_VIBRATIONS, ItemTags.DAMPENS_VIBRATIONS);
ItemTags.CLUSTER_MAX_HARVESTABLES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.IRON_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.WOODEN_PICKAXE);
ItemTags.COMPASSES.add(ItemTypes.COMPASS, ItemTypes.RECOVERY_COMPASS);
copy(BlockTags.CEILING_HANGING_SIGNS, ItemTags.HANGING_SIGNS);
ItemTags.CREEPER_IGNITERS.add(ItemTypes.FLINT_AND_STEEL, ItemTypes.FIRE_CHARGE);
ItemTags.SWORDS.add(ItemTypes.DIAMOND_SWORD, ItemTypes.STONE_SWORD, ItemTypes.GOLDEN_SWORD, ItemTypes.NETHERITE_SWORD, ItemTypes.WOODEN_SWORD, ItemTypes.IRON_SWORD);
ItemTags.AXES.add(ItemTypes.DIAMOND_AXE, ItemTypes.STONE_AXE, ItemTypes.GOLDEN_AXE, ItemTypes.NETHERITE_AXE, ItemTypes.WOODEN_AXE, ItemTypes.IRON_AXE);
ItemTags.PICKAXES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.IRON_PICKAXE);
ItemTags.SHOVELS.add(ItemTypes.DIAMOND_SHOVEL, ItemTypes.STONE_SHOVEL, ItemTypes.GOLDEN_SHOVEL, ItemTypes.NETHERITE_SHOVEL, ItemTypes.WOODEN_SHOVEL, ItemTypes.IRON_SHOVEL);
ItemTags.HOES.add(ItemTypes.DIAMOND_HOE, ItemTypes.STONE_HOE, ItemTypes.GOLDEN_HOE, ItemTypes.NETHERITE_HOE, ItemTypes.WOODEN_HOE, ItemTypes.IRON_HOE);
ItemTags.TOOLS.addTag(ItemTags.SWORDS).addTag(ItemTags.AXES).addTag(ItemTags.PICKAXES).addTag(ItemTags.SHOVELS).addTag(ItemTags.HOES).add(ItemTypes.TRIDENT);
ItemTags.BREAKS_DECORATED_POTS.addTag(ItemTags.TOOLS);
ItemTags.DECORATED_POT_SHERDS.add(ItemTypes.ANGLER_POTTERY_SHERD, ItemTypes.ARCHER_POTTERY_SHERD, ItemTypes.ARMS_UP_POTTERY_SHERD, ItemTypes.BLADE_POTTERY_SHERD, ItemTypes.BREWER_POTTERY_SHERD, ItemTypes.BURN_POTTERY_SHERD, ItemTypes.DANGER_POTTERY_SHERD, ItemTypes.EXPLORER_POTTERY_SHERD, ItemTypes.FRIEND_POTTERY_SHERD, ItemTypes.HEART_POTTERY_SHERD, ItemTypes.HEARTBREAK_POTTERY_SHERD, ItemTypes.HOWL_POTTERY_SHERD, ItemTypes.MINER_POTTERY_SHERD, ItemTypes.MOURNER_POTTERY_SHERD, ItemTypes.PLENTY_POTTERY_SHERD, ItemTypes.PRIZE_POTTERY_SHERD, ItemTypes.SHEAF_POTTERY_SHERD, ItemTypes.SHELTER_POTTERY_SHERD, ItemTypes.SKULL_POTTERY_SHERD, ItemTypes.SNORT_POTTERY_SHERD);
ItemTags.DECORATED_POT_INGREDIENTS.add(ItemTypes.BRICK).addTag(ItemTags.DECORATED_POT_SHERDS);
ItemTags.NOTEBLOCK_TOP_INSTRUMENTS.add(ItemTypes.ZOMBIE_HEAD, ItemTypes.SKELETON_SKULL, ItemTypes.CREEPER_HEAD, ItemTypes.DRAGON_HEAD, ItemTypes.WITHER_SKELETON_SKULL, ItemTypes.PIGLIN_HEAD, ItemTypes.PLAYER_HEAD);
ItemTags.TRIMMABLE_ARMOR.add(ItemTypes.NETHERITE_HELMET, ItemTypes.NETHERITE_CHESTPLATE, ItemTypes.NETHERITE_LEGGINGS, ItemTypes.NETHERITE_BOOTS, ItemTypes.DIAMOND_HELMET, ItemTypes.DIAMOND_CHESTPLATE, ItemTypes.DIAMOND_LEGGINGS, ItemTypes.DIAMOND_BOOTS, ItemTypes.GOLDEN_HELMET, ItemTypes.GOLDEN_CHESTPLATE, ItemTypes.GOLDEN_LEGGINGS, ItemTypes.GOLDEN_BOOTS, ItemTypes.IRON_HELMET, ItemTypes.IRON_CHESTPLATE, ItemTypes.IRON_LEGGINGS, ItemTypes.IRON_BOOTS, ItemTypes.CHAINMAIL_HELMET, ItemTypes.CHAINMAIL_CHESTPLATE, ItemTypes.CHAINMAIL_LEGGINGS, ItemTypes.CHAINMAIL_BOOTS, ItemTypes.LEATHER_HELMET, ItemTypes.LEATHER_CHESTPLATE, ItemTypes.LEATHER_LEGGINGS, ItemTypes.LEATHER_BOOTS, ItemTypes.TURTLE_HELMET);
ItemTags.TRIM_MATERIALS.add(ItemTypes.IRON_INGOT, ItemTypes.COPPER_INGOT, ItemTypes.GOLD_INGOT, ItemTypes.LAPIS_LAZULI, ItemTypes.EMERALD, ItemTypes.DIAMOND, ItemTypes.NETHERITE_INGOT, ItemTypes.REDSTONE, ItemTypes.QUARTZ, ItemTypes.AMETHYST_SHARD);
ItemTags.TRIM_TEMPLATES.add(ItemTypes.WARD_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.COAST_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.EYE_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.WILD_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.RIB_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.VEX_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, ItemTypes.HOST_ARMOR_TRIM_SMITHING_TEMPLATE);
ItemTags.BOOKSHELF_BOOKS.add(ItemTypes.BOOK, ItemTypes.WRITTEN_BOOK, ItemTypes.ENCHANTED_BOOK, ItemTypes.WRITABLE_BOOK, ItemTypes.KNOWLEDGE_BOOK);
ItemTags.NOTEBLOCK_TOP_INSTRUMENTS.add(ItemTypes.ZOMBIE_HEAD, ItemTypes.SKELETON_SKULL, ItemTypes.CREEPER_HEAD, ItemTypes.DRAGON_HEAD, ItemTypes.WITHER_SKELETON_SKULL, ItemTypes.PIGLIN_HEAD, ItemTypes.PLAYER_HEAD);
ItemTags.SNIFFER_FOOD.add(ItemTypes.TORCHFLOWER_SEEDS);
ItemTags.DECORATED_POT_SHERDS.add(ItemTypes.ANGLER_POTTERY_SHERD, ItemTypes.ARCHER_POTTERY_SHERD, ItemTypes.ARMS_UP_POTTERY_SHERD, ItemTypes.BLADE_POTTERY_SHERD, ItemTypes.BREWER_POTTERY_SHERD, ItemTypes.BURN_POTTERY_SHERD, ItemTypes.DANGER_POTTERY_SHERD, ItemTypes.EXPLORER_POTTERY_SHERD, ItemTypes.FRIEND_POTTERY_SHERD, ItemTypes.HEART_POTTERY_SHERD, ItemTypes.HEARTBREAK_POTTERY_SHERD, ItemTypes.HOWL_POTTERY_SHERD, ItemTypes.MINER_POTTERY_SHERD, ItemTypes.MOURNER_POTTERY_SHERD, ItemTypes.PLENTY_POTTERY_SHERD, ItemTypes.PRIZE_POTTERY_SHERD, ItemTypes.SHEAF_POTTERY_SHERD, ItemTypes.SHELTER_POTTERY_SHERD, ItemTypes.SKULL_POTTERY_SHERD, ItemTypes.SNORT_POTTERY_SHERD);
ItemTags.DECORATED_POT_INGREDIENTS.addTag(ItemTags.DECORATED_POT_SHERDS).add(ItemTypes.BRICK);
ItemTags.SWORDS.add(ItemTypes.DIAMOND_SWORD, ItemTypes.STONE_SWORD, ItemTypes.GOLDEN_SWORD, ItemTypes.NETHERITE_SWORD, ItemTypes.WOODEN_SWORD, ItemTypes.IRON_SWORD);
ItemTags.AXES.add(ItemTypes.DIAMOND_AXE, ItemTypes.STONE_AXE, ItemTypes.GOLDEN_AXE, ItemTypes.NETHERITE_AXE, ItemTypes.WOODEN_AXE, ItemTypes.IRON_AXE);
ItemTags.HOES.add(ItemTypes.DIAMOND_HOE, ItemTypes.STONE_HOE, ItemTypes.GOLDEN_HOE, ItemTypes.NETHERITE_HOE, ItemTypes.WOODEN_HOE, ItemTypes.IRON_HOE);
ItemTags.PICKAXES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.IRON_PICKAXE);
ItemTags.SHOVELS.add(ItemTypes.DIAMOND_SHOVEL, ItemTypes.STONE_SHOVEL, ItemTypes.GOLDEN_SHOVEL, ItemTypes.NETHERITE_SHOVEL, ItemTypes.WOODEN_SHOVEL, ItemTypes.IRON_SHOVEL);
ItemTags.TOOLS.addTag(ItemTags.SWORDS).addTag(ItemTags.AXES).addTag(ItemTags.PICKAXES).addTag(ItemTags.SHOVELS).addTag(ItemTags.HOES).add(ItemTypes.TRIDENT);
ItemTags.BREAKS_DECORATED_POTS.addTag(ItemTags.TOOLS);
ItemTags.VILLAGER_PLANTABLE_SEEDS.add(ItemTypes.WHEAT_SEEDS, ItemTypes.POTATO, ItemTypes.CARROT, ItemTypes.BEETROOT_SEEDS, ItemTypes.TORCHFLOWER_SEEDS, ItemTypes.PITCHER_POD);
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.world.states.enums;
public enum TrialSpawnerState {
INACTIVE,
WAITING_FOR_PLAYERS,
ACTIVE,
WAITING_FOR_REWARD_EJECTION,
EJECTING_REWARD,
COOLDOWN,
}
@@ -202,7 +202,15 @@ public class StateTypes {
public static StateType CHISELED_SANDSTONE = StateTypes.builder().name("CHISELED_SANDSTONE").blastResistance(0.8f).hardness(0.8f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType CUT_SANDSTONE = StateTypes.builder().name("CUT_SANDSTONE").blastResistance(0.8f).hardness(0.8f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType COBWEB = StateTypes.builder().name("COBWEB").blastResistance(4.0f).hardness(4.0f).isBlocking(false).requiresCorrectTool(true).isSolid(false).setMaterial(MaterialType.WEB).build();
public static StateType GRASS = StateTypes.builder().name("GRASS").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.REPLACEABLE_PLANT).build();
public static StateType SHORT_GRASS = StateTypes.builder().name("SHORT_GRASS").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.REPLACEABLE_PLANT).build();
/**
* This is short grass.
* @deprecated Please use SHORT_GRASS instead of GRASS, this is now deprecated.
* */
@Deprecated
public static StateType GRASS = SHORT_GRASS;
public static StateType FERN = StateTypes.builder().name("FERN").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.REPLACEABLE_PLANT).build();
public static StateType AZALEA = StateTypes.builder().name("AZALEA").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.PLANT).build();
public static StateType FLOWERING_AZALEA = StateTypes.builder().name("FLOWERING_AZALEA").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.PLANT).build();
@@ -1043,6 +1051,63 @@ public class StateTypes {
.blastResistance(1.5f).hardness(1.5f).isBlocking(true).requiresCorrectTool(false)
.isSolid(true).setMaterial(MaterialType.SCULK).build();
//1.20.3 added types
public static StateType TUFF_SLAB = StateTypes.builder().name("TUFF_SLAB").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_STAIRS = StateTypes.builder().name("TUFF_STAIRS").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_WALL = StateTypes.builder().name("TUFF_WALL").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType POLISHED_TUFF = StateTypes.builder().name("POLISHED_TUFF").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType POLISHED_TUFF_SLAB = StateTypes.builder().name("POLISHED_TUFF_SLAB").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType POLISHED_TUFF_STAIRS = StateTypes.builder().name("POLISHED_TUFF_STAIRS").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType POLISHED_TUFF_WALL = StateTypes.builder().name("POLISHED_TUFF_WALL").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType CHISELED_TUFF = StateTypes.builder().name("CHISELED_TUFF").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_BRICKS = StateTypes.builder().name("TUFF_BRICKS").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_BRICK_SLAB = StateTypes.builder().name("TUFF_BRICK_SLAB").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_BRICK_STAIRS = StateTypes.builder().name("TUFF_BRICK_STAIRS").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TUFF_BRICK_WALL = StateTypes.builder().name("TUFF_BRICK_WALL").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType CHISELED_TUFF_BRICKS = StateTypes.builder().name("CHISELED_TUFF_BRICKS").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType OXIDIZED_CHISELED_COPPER = StateTypes.builder().name("OXIDIZED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WEATHERED_CHISELED_COPPER = StateTypes.builder().name("WEATHERED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType EXPOSED_CHISELED_COPPER = StateTypes.builder().name("EXPOSED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType CHISELED_COPPER = StateTypes.builder().name("CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_OXIDIZED_CHISELED_COPPER = StateTypes.builder().name("WAXED_OXIDIZED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_WEATHERED_CHISELED_COPPER = StateTypes.builder().name("WAXED_WEATHERED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_EXPOSED_CHISELED_COPPER = StateTypes.builder().name("WAXED_EXPOSED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_CHISELED_COPPER = StateTypes.builder().name("WAXED_CHISELED_COPPER").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType COPPER_DOOR = StateTypes.builder().name("COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType EXPOSED_COPPER_DOOR = StateTypes.builder().name("EXPOSED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType OXIDIZED_COPPER_DOOR = StateTypes.builder().name("OXIDIZED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WEATHERED_COPPER_DOOR = StateTypes.builder().name("WEATHERED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_COPPER_DOOR = StateTypes.builder().name("WAXED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_EXPOSED_COPPER_DOOR = StateTypes.builder().name("WAXED_EXPOSED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_OXIDIZED_COPPER_DOOR = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_WEATHERED_COPPER_DOOR = StateTypes.builder().name("WAXED_WEATHERED_COPPER_DOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType COPPER_TRAPDOOR = StateTypes.builder().name("COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType EXPOSED_COPPER_TRAPDOOR = StateTypes.builder().name("EXPOSED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType OXIDIZED_COPPER_TRAPDOOR = StateTypes.builder().name("OXIDIZED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WEATHERED_COPPER_TRAPDOOR = StateTypes.builder().name("WEATHERED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_COPPER_TRAPDOOR = StateTypes.builder().name("WAXED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_EXPOSED_COPPER_TRAPDOOR = StateTypes.builder().name("WAXED_EXPOSED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_OXIDIZED_COPPER_TRAPDOOR = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_WEATHERED_COPPER_TRAPDOOR = StateTypes.builder().name("WAXED_WEATHERED_COPPER_TRAPDOOR").blastResistance(3.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType COPPER_GRATE = StateTypes.builder().name("COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType EXPOSED_COPPER_GRATE = StateTypes.builder().name("EXPOSED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WEATHERED_COPPER_GRATE = StateTypes.builder().name("WEATHERED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType OXIDIZED_COPPER_GRATE = StateTypes.builder().name("OXIDIZED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_COPPER_GRATE = StateTypes.builder().name("WAXED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_EXPOSED_COPPER_GRATE = StateTypes.builder().name("WAXED_EXPOSED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_WEATHERED_COPPER_GRATE = StateTypes.builder().name("WAXED_WEATHERED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_OXIDIZED_COPPER_GRATE = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_GRATE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType COPPER_BULB = StateTypes.builder().name("COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType EXPOSED_COPPER_BULB = StateTypes.builder().name("EXPOSED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WEATHERED_COPPER_BULB = StateTypes.builder().name("WEATHERED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType OXIDIZED_COPPER_BULB = StateTypes.builder().name("OXIDIZED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_COPPER_BULB = StateTypes.builder().name("WAXED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_EXPOSED_COPPER_BULB = StateTypes.builder().name("WAXED_EXPOSED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_WEATHERED_COPPER_BULB = StateTypes.builder().name("WAXED_WEATHERED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType WAXED_OXIDIZED_COPPER_BULB = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_BULB").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType CRAFTER = StateTypes.builder().name("CRAFTER").blastResistance(3.5f).hardness(1.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.STONE).build();
public static StateType TRIAL_SPAWNER = StateTypes.builder().name("TRIAL_SPAWNER").blastResistance(50.0f).hardness(50.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
public static Builder builder() {
return new Builder();
}
@@ -1110,10 +1175,11 @@ public class StateTypes {
this.isShapeExceedsCube = b;
return this;
}
public StateType build() {
StateType type = new StateType(name, blastResistance, hardness, isSolid, isBlocking, isAir, requiresCorrectTool, isShapeExceedsCube, materialType);
BY_NAME.put(name, type);
return type;
}
}
}
}
@@ -105,7 +105,9 @@ public enum StateValue {
VERTICAL_DIRECTION("vertical_direction", VerticalDirection::valueOf),
WATERLOGGED("waterlogged", Boolean::parseBoolean),
WEST("west", West::valueOf),
CRACKED("cracked", Boolean::parseBoolean);
CRACKED("cracked", Boolean::parseBoolean),
CRAFTING("crafting", Boolean::parseBoolean),
TRIAL_SPAWNER_STATE("trial_spawner_state", TrialSpawnerState::valueOf);
private final String name;
private final Function<String, Object> parser;
@@ -56,11 +56,15 @@ public class AdventureSerializer {
}
public static Component fromLegacyFormat(String legacyMessage) {
return getLegacyGsonSerializer().deserialize(legacyMessage);
return getLegacyGsonSerializer().deserializeOrNull(legacyMessage);
}
public static String toLegacyFormat(Component component) {
return getLegacyGsonSerializer().serializeOrNull(component);
}
public static Component parseComponent(String json) {
return getGsonSerializer().deserialize(json);
return getGsonSerializer().deserializeOrNull(json);
}
public static Component parseJsonTree(JsonElement json) {
@@ -68,11 +72,11 @@ public class AdventureSerializer {
}
public static String toJson(Component component) {
return getGsonSerializer().serialize(component);
return getGsonSerializer().serializeOrNull(component);
}
public static JsonElement toJsonTree(Component component) {
return getGsonSerializer().serializeToTree(component);
}
}
}
@@ -25,9 +25,17 @@ import com.github.retrooper.packetevents.event.ProtocolPacketEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.manager.server.VersionComparison;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.netty.buffer.ByteBufOutputStream;
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.chat.*;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.ChatTypes;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.MessageSignature;
import com.github.retrooper.packetevents.protocol.chat.Node;
import com.github.retrooper.packetevents.protocol.chat.Parsers;
import com.github.retrooper.packetevents.protocol.chat.RemoteChatSession;
import com.github.retrooper.packetevents.protocol.chat.SignedCommandArgument;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMaskType;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1;
@@ -39,6 +47,7 @@ import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.codec.NBTCodec;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
@@ -53,6 +62,7 @@ import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.StringUtil;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.util.adventure.AdventureNBTSerialization;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.crypto.MinecraftEncryptionUtil;
import com.github.retrooper.packetevents.util.crypto.SaltSignature;
@@ -63,10 +73,19 @@ import org.jetbrains.annotations.ApiStatus.Experimental;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.time.Instant;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.EnumSet;
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;
import java.util.function.IntFunction;
@@ -185,8 +204,7 @@ public class PacketWrapper<T extends PacketWrapper> {
serverVersion = user.getClientVersion().toServerVersion();
int id = packetTypeData.getPacketType().getId(user.getClientVersion());
writeVarInt(id);
}
else {
} else {
writeVarInt(packetTypeData.getNativePacketId());
}
write();
@@ -240,8 +258,9 @@ public class PacketWrapper<T extends PacketWrapper> {
/**
* Gets the Packet ID for the current platform version
* @deprecated Use {@link #getNativePacketId()}
*
* @return Packet ID
* @deprecated Use {@link #getNativePacketId()}
*/
@Deprecated
public int getPacketId() {
@@ -250,6 +269,7 @@ public class PacketWrapper<T extends PacketWrapper> {
/**
* Sets the Packet ID for the current platform version
*
* @deprecated Use {@link #setNativePacketId(int)}
*/
@Deprecated
@@ -424,10 +444,18 @@ public class PacketWrapper<T extends PacketWrapper> {
}
public NBTCompound readNBT() {
return (NBTCompound) this.readDirectNBT();
}
public NBT readDirectNBT() {
return NBTCodec.readNBTFromBuffer(buffer, serverVersion);
}
public void writeNBT(NBTCompound nbt) {
this.writeDirectNBT((NBT) nbt);
}
public void writeDirectNBT(NBT nbt) {
NBTCodec.writeNBTToBuffer(buffer, serverVersion, nbt);
}
@@ -453,8 +481,10 @@ public class PacketWrapper<T extends PacketWrapper> {
}
}
@Deprecated
public String readComponentJSON() {
return readString(getMaxMessageLength());
// needs to be converted to nbt as of 1.20.3
return AdventureSerializer.asVanilla(this.readComponent());
}
public void writeString(String s) {
@@ -478,16 +508,49 @@ public class PacketWrapper<T extends PacketWrapper> {
}
}
@Deprecated
public void writeComponentJSON(String json) {
writeString(json, getMaxMessageLength());
// needs to be converted to nbt as of 1.20.3
this.writeComponent(AdventureSerializer.parseComponent(json));
}
public Component readComponent() {
return AdventureSerializer.parseComponent(readComponentJSON());
return this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)
? this.readComponentAsNBT() : this.readComponentAsJSON();
}
public Component readComponentAsNBT() {
try {
return AdventureNBTSerialization.readComponent(this.buffer);
} catch (IOException exception) {
throw new IllegalStateException(exception);
}
}
public Component readComponentAsJSON() {
String jsonString = this.readString(this.getMaxMessageLength());
return AdventureSerializer.parseComponent(jsonString);
}
public void writeComponent(Component component) {
writeComponentJSON(AdventureSerializer.toJson(component));
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeComponentAsNBT(component);
} else {
this.writeComponentAsJSON(component);
}
}
public void writeComponentAsNBT(Component component) {
try {
AdventureNBTSerialization.writeComponent(new ByteBufOutputStream(this.buffer), component);
} catch (IOException exception) {
throw new IllegalStateException(exception);
}
}
public void writeComponentAsJSON(Component component) {
String jsonString = AdventureSerializer.toJson(component);
this.writeString(jsonString, this.getMaxMessageLength());
}
public ResourceLocation readIdentifier(int maxLen) {
@@ -775,11 +838,11 @@ public class PacketWrapper<T extends PacketWrapper> {
}
public void writeEntityMetadata(EntityMetadataProvider metadata) {
writeEntityMetadata(metadata.entityData());
writeEntityMetadata(metadata.entityData(serverVersion.toClientVersion()));
}
public Dimension readDimension() {
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_19)) {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_19)) {
Dimension dimension = new Dimension(new NBTCompound());
dimension.setDimensionName(readIdentifier().toString());
return dimension;
@@ -789,8 +852,8 @@ public class PacketWrapper<T extends PacketWrapper> {
}
public void writeDimension(Dimension dimension) {
boolean v1_19 = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_19);
boolean v1_16_2 = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_16_2);
boolean v1_19 = serverVersion.isNewerThanOrEquals(ServerVersion.V_1_19);
boolean v1_16_2 = serverVersion.isNewerThanOrEquals(ServerVersion.V_1_16_2);
if (v1_19 || !v1_16_2) {
writeString(dimension.getDimensionName(), 32767);
} else {
@@ -19,11 +19,16 @@
package com.github.retrooper.packetevents.wrapper.configuration.client;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.security.Provider;
import java.util.UUID;
public class WrapperConfigClientResourcePackStatus extends PacketWrapper<WrapperConfigClientResourcePackStatus> {
private UUID packId;
private Result result;
public WrapperConfigClientResourcePackStatus(PacketReceiveEvent event) {
@@ -31,25 +36,45 @@ public class WrapperConfigClientResourcePackStatus extends PacketWrapper<Wrapper
}
public WrapperConfigClientResourcePackStatus(Result result) {
this(UUID.randomUUID(), result);
}
public WrapperConfigClientResourcePackStatus(UUID packId, Result result) {
super(PacketType.Configuration.Client.RESOURCE_PACK_STATUS);
this.packId = packId;
this.result = result;
}
@Override
public void read() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.packId = this.readUUID();
}
this.result = Result.VALUES[this.readVarInt()];
}
@Override
public void write() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeUUID(this.packId);
}
this.writeVarInt(this.result.ordinal());
}
@Override
public void copy(WrapperConfigClientResourcePackStatus wrapper) {
this.packId = wrapper.packId;
this.result = wrapper.result;
}
public UUID getPackId() {
return this.packId;
}
public void setPackId(UUID packId) {
this.packId = packId;
}
public Result getResult() {
return this.result;
}
@@ -59,10 +84,15 @@ public class WrapperConfigClientResourcePackStatus extends PacketWrapper<Wrapper
}
public enum Result {
SUCCESSFULLY_LOADED,
DECLINED,
FAILED_DOWNLOAD,
ACCEPTED;
ACCEPTED,
DOWNLOADED,
INVALID_URL,
FAILED_RELOAD,
DISCARDED;
public static final Result[] VALUES = values();
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.configuration.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class WrapperConfigServerResourcePackRemove extends PacketWrapper<WrapperConfigServerResourcePackRemove> {
private @Nullable UUID packId;
public WrapperConfigServerResourcePackRemove(PacketSendEvent event) {
super(event);
}
public WrapperConfigServerResourcePackRemove(@Nullable UUID packId) {
super(PacketType.Configuration.Server.RESOURCE_PACK_REMOVE);
this.packId = packId;
}
@Override
public void read() {
this.packId = this.readOptional(PacketWrapper::readUUID);
}
@Override
public void write() {
this.writeOptional(this.packId, PacketWrapper::writeUUID);
}
@Override
public void copy(WrapperConfigServerResourcePackRemove wrapper) {
this.packId = wrapper.packId;
}
public @Nullable UUID getPackId() {
return this.packId;
}
public void setPackId(@Nullable UUID packId) {
this.packId = packId;
}
}
@@ -19,15 +19,19 @@
package com.github.retrooper.packetevents.wrapper.configuration.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class WrapperConfigServerResourcePackSend extends PacketWrapper<WrapperConfigServerResourcePackSend> {
public static final int MAX_HASH_LENGTH = 40;
private UUID packId;
private String url;
private String hash;
private boolean required;
@@ -38,12 +42,17 @@ public class WrapperConfigServerResourcePackSend extends PacketWrapper<WrapperCo
}
public WrapperConfigServerResourcePackSend(String url, String hash, boolean required, @Nullable Component prompt) {
this(UUID.randomUUID(), url, hash, required, prompt);
}
public WrapperConfigServerResourcePackSend(UUID packId, String url, String hash, boolean required, @Nullable Component prompt) {
super(PacketType.Configuration.Server.RESOURCE_PACK_SEND);
if (hash.length() > MAX_HASH_LENGTH) {
throw new IllegalArgumentException("Hash is too long (max 40, was " + hash.length() + ")");
throw new IllegalArgumentException("Hash is too long (max " + MAX_HASH_LENGTH + ", was " + hash.length() + ")");
}
this.packId = packId;
this.url = url;
this.hash = hash;
this.required = required;
@@ -52,6 +61,10 @@ public class WrapperConfigServerResourcePackSend extends PacketWrapper<WrapperCo
@Override
public void read() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.packId = this.readUUID();
}
this.url = this.readString();
this.hash = this.readString(MAX_HASH_LENGTH);
this.required = this.readBoolean();
@@ -62,6 +75,10 @@ public class WrapperConfigServerResourcePackSend extends PacketWrapper<WrapperCo
@Override
public void write() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeUUID(this.packId);
}
this.writeString(this.url);
this.writeString(this.hash, MAX_HASH_LENGTH);
this.writeBoolean(this.required);
@@ -75,12 +92,21 @@ public class WrapperConfigServerResourcePackSend extends PacketWrapper<WrapperCo
@Override
public void copy(WrapperConfigServerResourcePackSend wrapper) {
this.packId = wrapper.packId;
this.url = wrapper.url;
this.hash = wrapper.hash;
this.required = wrapper.required;
this.prompt = wrapper.prompt;
}
public UUID getPackId() {
return this.packId;
}
public void setPackId(UUID packId) {
this.packId = packId;
}
public String getUrl() {
return this.url;
}
@@ -41,12 +41,12 @@ public class WrapperLoginServerDisconnect extends PacketWrapper<WrapperLoginServ
@Override
public void read() {
this.reason = readComponent();
this.reason = this.readComponentAsJSON();
}
@Override
public void write() {
writeComponent(reason);
this.writeComponentAsJSON(this.reason);
}
@Override
@@ -23,7 +23,11 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.UUID;
public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPlayClientResourcePackStatus> {
private UUID packId;
private String hash;
private Result result;
@@ -32,7 +36,12 @@ public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPl
}
public WrapperPlayClientResourcePackStatus(Result result) {
this(UUID.randomUUID(), result);
}
public WrapperPlayClientResourcePackStatus(UUID packId, Result result) {
super(PacketType.Play.Client.RESOURCE_PACK_STATUS);
this.packId = packId;
this.result = result;
}
@@ -45,6 +54,10 @@ public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPl
@Override
public void read() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.packId = this.readUUID();
}
if (serverVersion.isOlderThan(ServerVersion.V_1_10)) {
//For now ignore hash, maybe make optional
this.hash = readString(40);
@@ -57,6 +70,10 @@ public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPl
@Override
public void write() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeUUID(this.packId);
}
if (serverVersion.isOlderThan(ServerVersion.V_1_10)) {
writeString(hash, 40);
}
@@ -65,10 +82,19 @@ public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPl
@Override
public void copy(WrapperPlayClientResourcePackStatus wrapper) {
this.packId = wrapper.packId;
this.hash = wrapper.hash;
this.result = wrapper.result;
}
public UUID getPackId() {
return this.packId;
}
public void setPackId(UUID packId) {
this.packId = packId;
}
public Result getResult() {
return result;
}
@@ -86,10 +112,15 @@ public class WrapperPlayClientResourcePackStatus extends PacketWrapper<WrapperPl
}
public enum Result {
SUCCESSFULLY_LOADED,
DECLINED,
FAILED_DOWNLOAD,
ACCEPTED;
ACCEPTED,
DOWNLOADED,
INVALID_URL,
FAILED_RELOAD,
DISCARDED;
public static final Result[] VALUES = values();
}
@@ -0,0 +1,86 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.client;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayClientSlotStateChange extends PacketWrapper<WrapperPlayClientSlotStateChange> {
private int slot;
private int windowId;
private boolean state;
public WrapperPlayClientSlotStateChange(PacketReceiveEvent event) {
super(event);
}
public WrapperPlayClientSlotStateChange(int slot, int windowId, boolean state) {
super(PacketType.Play.Client.SLOT_STATE_CHANGE);
this.slot = slot;
this.windowId = windowId;
this.state = state;
}
@Override
public void read() {
this.slot = this.readVarInt();
this.windowId = this.readVarInt();
this.state = this.readBoolean();
}
@Override
public void write() {
this.writeVarInt(this.slot);
this.writeVarInt(this.windowId);
this.writeBoolean(this.state);
}
@Override
public void copy(WrapperPlayClientSlotStateChange wrapper) {
this.slot = wrapper.slot;
this.windowId = wrapper.windowId;
this.state = wrapper.state;
}
public int getSlot() {
return this.slot;
}
public void setSlot(int slot) {
this.slot = slot;
}
public int getWindowId() {
return this.windowId;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
public boolean isState() {
return this.state;
}
public void setState(boolean state) {
this.state = state;
}
}
@@ -37,6 +37,8 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
private ResourceLocation pool; // target pool
private String finalState; // turns into
private @Nullable JointType jointType;
private int selectionPriority; // Added in 1.20.3
private int placementPriority; // Added in 1.20.3
public WrapperPlayClientUpdateJigsawBlock(PacketReceiveEvent event) {
super(event);
@@ -48,6 +50,11 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
public WrapperPlayClientUpdateJigsawBlock(Vector3i position, ResourceLocation name, @Nullable ResourceLocation target,
ResourceLocation pool, String finalState, @Nullable JointType jointType) {
this(position,name,target,pool,finalState,jointType,0,0);
}
public WrapperPlayClientUpdateJigsawBlock(Vector3i position, ResourceLocation name, @Nullable ResourceLocation target,
ResourceLocation pool, String finalState, @Nullable JointType jointType,
int selectionPriority, int placementPriority) {
super(PacketType.Play.Client.UPDATE_JIGSAW_BLOCK);
this.position = position;
this.name = name;
@@ -55,6 +62,8 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
this.pool = pool;
this.finalState = finalState;
this.jointType = jointType;
this.selectionPriority = selectionPriority;
this.placementPriority = placementPriority;
}
@Override
@@ -69,6 +78,10 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
if (this.v1_16()) {
this.jointType = JointType.byName(readString()).orElse(JointType.ALIGNED);
}
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.selectionPriority = this.readVarInt();
this.placementPriority = this.readVarInt();
}
}
@Override
@@ -83,6 +96,10 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
if (this.v1_16()) {
writeString(this.jointType.getSerializedName());
}
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeVarInt(this.selectionPriority);
this.writeVarInt(this.placementPriority);
}
}
@Override
@@ -93,6 +110,8 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
this.pool = wrapper.pool;
this.finalState = wrapper.finalState;
this.jointType = wrapper.jointType;
this.selectionPriority = wrapper.selectionPriority;
this.placementPriority = wrapper.placementPriority;
}
private boolean v1_16() {
@@ -146,4 +165,20 @@ public class WrapperPlayClientUpdateJigsawBlock extends PacketWrapper<WrapperPla
public void setJointType(@Nullable JointType jointType) {
this.jointType = jointType;
}
public int getSelectionPriority() {
return this.selectionPriority;
}
public void setSelectionPriority(int selectionPriority) {
this.selectionPriority = selectionPriority;
}
public int getPlacementPriority() {
return this.placementPriority;
}
public void setPlacementPriority(int placementPriority) {
this.placementPriority = placementPriority;
}
}
@@ -88,7 +88,9 @@ public class WrapperPlayServerChangeGameState extends PacketWrapper<WrapperPlayS
THUNDER_LEVEL_CHANGE,
PLAY_PUFFER_FISH_STING_SOUND,
PLAY_ELDER_GUARDIAN_MOB_APPEARANCE,
ENABLE_RESPAWN_SCREEN;
ENABLE_RESPAWN_SCREEN,
LIMITED_CRAFTING,
START_LOADING_CHUNKS;
private static final Reason[] VALUES = values();
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
@@ -42,7 +43,7 @@ public class WrapperPlayServerEntityMetadata extends PacketWrapper<WrapperPlaySe
}
public WrapperPlayServerEntityMetadata(int entityID, EntityMetadataProvider metadata) {
this(entityID, metadata.entityData());
this(entityID, metadata.entityData(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
}
@Override
@@ -84,6 +85,6 @@ public class WrapperPlayServerEntityMetadata extends PacketWrapper<WrapperPlaySe
}
public void setEntityMetadata(EntityMetadataProvider metadata) {
this.entityMetadata = metadata.entityData();
this.entityMetadata = metadata.entityData(serverVersion.toClientVersion());
}
}
@@ -21,10 +21,16 @@ package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.particle.Particle;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleData;
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -36,16 +42,36 @@ public class WrapperPlayServerExplosion extends PacketWrapper<WrapperPlayServerE
private List<Vector3i> records;
private Vector3f playerMotion;
private Particle smallExplosionParticles;
private Particle largeExplosionParticles;
private BlockInteraction blockInteraction;
private ResourceLocation explosionSoundKey;
private @Nullable Float explosionSoundRange;
public WrapperPlayServerExplosion(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerExplosion(Vector3d position, float strength, List<Vector3i> records, Vector3f playerMotion) {
this(position, strength, records, playerMotion, new Particle(ParticleTypes.EXPLOSION),
new Particle(ParticleTypes.EXPLOSION_EMITTER), BlockInteraction.DESTROY_BLOCKS,
new ResourceLocation("minecraft:entity.generic.explode"), null);
}
public WrapperPlayServerExplosion(Vector3d position, float strength, List<Vector3i> records, Vector3f playerMotion,
Particle smallExplosionParticles, Particle largeExplosionParticles,
BlockInteraction blockInteraction, ResourceLocation explosionSoundKey,
@Nullable Float explosionSoundRange) {
super(PacketType.Play.Server.EXPLOSION);
this.position = position;
this.strength = strength;
this.records = records;
this.playerMotion = playerMotion;
this.smallExplosionParticles = smallExplosionParticles;
this.largeExplosionParticles = largeExplosionParticles;
this.blockInteraction = blockInteraction;
this.explosionSoundKey = explosionSoundKey;
this.explosionSoundRange = explosionSoundRange;
}
@Override
@@ -72,6 +98,21 @@ public class WrapperPlayServerExplosion extends PacketWrapper<WrapperPlayServerE
float motY = readFloat();
float motZ = readFloat();
playerMotion = new Vector3f(motX, motY, motZ);
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.blockInteraction = BlockInteraction.values()[this.readVarInt()];
ParticleType smallPartType = ParticleTypes.getById(this.serverVersion.toClientVersion(), this.readVarInt());
ParticleData smallPartData = smallPartType.readDataFunction().apply(this);
this.smallExplosionParticles = new Particle(smallPartType, smallPartData);
ParticleType largePartType = ParticleTypes.getById(this.serverVersion.toClientVersion(), this.readVarInt());
ParticleData largePartData = largePartType.readDataFunction().apply(this);
this.largeExplosionParticles = new Particle(largePartType, largePartData);
this.explosionSoundKey = this.readIdentifier();
this.explosionSoundRange = this.readOptional(PacketWrapper::readFloat);
}
}
@Override
@@ -104,6 +145,19 @@ public class WrapperPlayServerExplosion extends PacketWrapper<WrapperPlayServerE
writeFloat(playerMotion.x);
writeFloat(playerMotion.y);
writeFloat(playerMotion.z);
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeVarInt(this.blockInteraction.ordinal());
this.writeVarInt(this.smallExplosionParticles.getType().getId(this.serverVersion.toClientVersion()));
this.smallExplosionParticles.getType().writeDataFunction().accept(this, this.smallExplosionParticles.getData());
this.writeVarInt(this.largeExplosionParticles.getType().getId(this.serverVersion.toClientVersion()));
this.largeExplosionParticles.getType().writeDataFunction().accept(this, this.largeExplosionParticles.getData());
this.writeIdentifier(this.explosionSoundKey);
this.writeOptional(this.explosionSoundRange, PacketWrapper::writeFloat);
}
}
@Override
@@ -112,6 +166,11 @@ public class WrapperPlayServerExplosion extends PacketWrapper<WrapperPlayServerE
strength = wrapper.strength;
records = wrapper.records;
playerMotion = wrapper.playerMotion;
smallExplosionParticles = wrapper.smallExplosionParticles;
largeExplosionParticles = wrapper.largeExplosionParticles;
blockInteraction = wrapper.blockInteraction;
explosionSoundKey = wrapper.explosionSoundKey;
explosionSoundRange = wrapper.explosionSoundRange;
}
private Vector3i toFloor(Vector3d position) {
@@ -161,4 +220,51 @@ public class WrapperPlayServerExplosion extends PacketWrapper<WrapperPlayServerE
public void setPlayerMotion(Vector3f playerMotion) {
this.playerMotion = playerMotion;
}
public Particle getSmallExplosionParticles() {
return this.smallExplosionParticles;
}
public void setSmallExplosionParticles(Particle smallExplosionParticles) {
this.smallExplosionParticles = smallExplosionParticles;
}
public Particle getLargeExplosionParticles() {
return this.largeExplosionParticles;
}
public void setLargeExplosionParticles(Particle largeExplosionParticles) {
this.largeExplosionParticles = largeExplosionParticles;
}
public BlockInteraction getBlockInteraction() {
return this.blockInteraction;
}
public void setBlockInteraction(BlockInteraction blockInteraction) {
this.blockInteraction = blockInteraction;
}
public ResourceLocation getExplosionSoundKey() {
return this.explosionSoundKey;
}
public void setExplosionSoundKey(ResourceLocation explosionSoundKey) {
this.explosionSoundKey = explosionSoundKey;
}
public @Nullable Float getExplosionSoundRange() {
return this.explosionSoundRange;
}
public void setExplosionSoundRange(@Nullable Float explosionSoundRange) {
this.explosionSoundRange = explosionSoundRange;
}
public enum BlockInteraction {
KEEP_BLOCKS,
DESTROY_BLOCKS,
DECAY_DESTROYED_BLOCKS,
TRIGGER_BLOCKS,
}
}
@@ -35,8 +35,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
private int legacySlots; // 1.13-
private int horseId; // 1.13-
private String title;
private Component titleAsComponent = null;
private Component title;
private boolean useProvidedWindowTitle; // 1.7 only
@@ -49,7 +48,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
super(PacketType.Play.Server.OPEN_WINDOW);
this.containerId = containerId;
this.type = type;
this.title = AdventureSerializer.toJson(title);
this.title = title;
}
// 1.8 through 1.13
@@ -59,7 +58,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
this.legacyType = legacyType;
this.legacySlots = legacySlots;
this.horseId = horseId;
this.title = AdventureSerializer.toJson(title);
this.title = title;
}
// 1.7
@@ -67,7 +66,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
super(PacketType.Play.Server.OPEN_WINDOW);
this.containerId = containerId;
this.type = type;
this.title = AdventureSerializer.toJson(title);
this.title = title;
this.legacySlots = legacySlots;
this.useProvidedWindowTitle = useProvidedWindowTitle;
this.horseId = horseId;
@@ -84,7 +83,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
// 1.7 has a very different packet format
if (serverVersion.isOlderThanOrEquals(ServerVersion.V_1_7_10)) {
this.type = readUnsignedByte();
this.title = readString(32);
this.title = AdventureSerializer.fromLegacyFormat(readString(32));
this.legacySlots = readUnsignedByte();
this.useProvidedWindowTitle = readBoolean();
@@ -97,10 +96,10 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
// Known to be 1.8 or above
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_14)) {
this.type = readVarInt();
this.title = readComponentJSON();
this.title = readComponent();
} else {
this.legacyType = readString();
this.title = readComponentJSON();
this.title = readComponent();
this.legacySlots = readUnsignedByte();
// This is only sent for horses
if (legacyType.equals("EntityHorse")) {
@@ -120,7 +119,7 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
// 1.7 has a very different packet format
if (serverVersion.isOlderThanOrEquals(ServerVersion.V_1_7_10)) {
writeByte(this.type);
writeString(this.title);
writeString(AdventureSerializer.toLegacyFormat(this.title));
writeByte(this.legacySlots);
writeBoolean(this.useProvidedWindowTitle);
@@ -133,18 +132,10 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
// Known to be 1.8 or above
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_14)) {
writeVarInt(this.type);
if (this.titleAsComponent != null) {
writeComponent(this.titleAsComponent);
} else {
writeString(this.title);
}
writeComponent(this.title);
} else {
writeString(this.legacyType);
if (this.titleAsComponent != null) {
writeComponent(this.titleAsComponent);
} else {
writeString(this.title);
}
writeComponent(this.title);
writeByte(this.legacySlots);
// This is only sent for horses
if (legacyType.equals("EntityHorse")) {
@@ -161,7 +152,6 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
this.legacySlots = wrapper.legacySlots;
this.horseId = wrapper.horseId;
this.title = wrapper.title;
this.titleAsComponent = wrapper.titleAsComponent;
this.useProvidedWindowTitle = wrapper.useProvidedWindowTitle;
}
@@ -206,12 +196,11 @@ public class WrapperPlayServerOpenWindow extends PacketWrapper<WrapperPlayServer
}
public Component getTitle() {
if (titleAsComponent != null) return titleAsComponent;
return titleAsComponent = AdventureSerializer.parseComponent(title);
return this.title;
}
public void setTitle(Component title) {
titleAsComponent = title;
this.title = title;
}
public boolean isUseProvidedWindowTitle() {
@@ -25,85 +25,99 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
public class WrapperPlayServerPlayerListHeaderAndFooter extends PacketWrapper<WrapperPlayServerPlayerListHeaderAndFooter> {
@Deprecated
public static boolean HANDLE_JSON = true;
private String headerJson;
private String footerJson;
private Component headerComponent;
private Component footerComponent;
private Component header;
private Component footer;
public WrapperPlayServerPlayerListHeaderAndFooter(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerPlayerListHeaderAndFooter(Component headerComponent, Component footerComponent) {
super(PacketType.Play.Server.PLAYER_LIST_HEADER_AND_FOOTER);
this.headerComponent = headerComponent;
this.footerComponent = footerComponent;
@Deprecated
public WrapperPlayServerPlayerListHeaderAndFooter(String headerJson, String footerJson) {
this(AdventureSerializer.parseComponent(headerJson), AdventureSerializer.parseComponent(footerJson));
}
public WrapperPlayServerPlayerListHeaderAndFooter(String headerJson, String footerJson) {
public WrapperPlayServerPlayerListHeaderAndFooter(Component header, Component footer) {
super(PacketType.Play.Server.PLAYER_LIST_HEADER_AND_FOOTER);
this.headerJson = headerJson;
this.footerJson = footerJson;
this.header = header;
this.footer = footer;
}
@Override
public void read() {
headerJson = readComponentJSON();
footerJson = readComponentJSON();
if (HANDLE_JSON) {
headerComponent = AdventureSerializer.parseComponent(headerJson);
footerComponent = AdventureSerializer.parseComponent(footerJson);
}
this.header = this.readComponent();
this.footer = this.readComponent();
}
@Override
public void write() {
if (HANDLE_JSON && headerComponent != null && footerComponent != null) {
headerJson = AdventureSerializer.toJson(headerComponent);
footerJson = AdventureSerializer.toJson(footerComponent);
}
writeComponentJSON(headerJson);
writeComponentJSON(footerJson);
this.writeComponent(this.header);
this.writeComponent(this.footer);
}
@Override
public void copy(WrapperPlayServerPlayerListHeaderAndFooter wrapper) {
headerJson = wrapper.headerJson;
footerJson = wrapper.footerJson;
headerComponent = wrapper.headerComponent;
footerComponent = wrapper.footerComponent;
this.header = wrapper.header;
this.footer = wrapper.footer;
}
public Component getHeader() {
return this.header;
}
public void setHeader(Component header) {
this.header = header;
}
public Component getFooter() {
return this.footer;
}
public void setFooter(Component footer) {
this.footer = footer;
}
@Deprecated
public String getHeaderJson() {
return headerJson;
return AdventureSerializer.toJson(this.getHeader());
}
@Deprecated
public void setHeaderJson(String headerJson) {
this.headerJson = headerJson;
this.setHeader(AdventureSerializer.parseComponent(headerJson));
}
@Deprecated
public String getFooterJson() {
return footerJson;
return AdventureSerializer.toJson(this.getFooter());
}
@Deprecated
public void setFooterJson(String footerJson) {
this.footerJson = footerJson;
this.setFooter(AdventureSerializer.parseComponent(footerJson));
}
@Deprecated
public Component getHeaderComponent() {
return headerComponent;
return this.getHeader();
}
@Deprecated
public void setHeaderComponent(Component headerComponent) {
this.headerComponent = headerComponent;
this.setHeader(headerComponent);
}
@Deprecated
public Component getFooterComponent() {
return footerComponent;
return this.getFooter();
}
@Deprecated
public void setFooterComponent(Component footerComponent) {
this.footerComponent = footerComponent;
this.setFooter(footerComponent);
}
}
@@ -0,0 +1,83 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public class WrapperPlayServerResetScore extends PacketWrapper<WrapperPlayServerResetScore> {
private String targetName;
private @Nullable String objective;
public WrapperPlayServerResetScore(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerResetScore(String targetName, @Nullable String objective) {
super(PacketType.Play.Server.RESET_SCORE);
this.targetName = targetName;
this.objective = objective;
}
@Override
public void read() {
this.targetName = this.readString();
this.objective = this.readOptional(PacketWrapper::readString);
}
@Override
public void write() {
this.writeString(this.targetName);
this.writeOptional(this.objective, PacketWrapper::writeString);
}
@Override
public void copy(WrapperPlayServerResetScore wrapper) {
this.targetName = wrapper.targetName;
this.objective = wrapper.objective;
}
/**
* Scoreboard name of the target score holder.
* This can be an entity, player, or nothing at all.
*/
public String getTargetName() {
return this.targetName;
}
/**
* Scoreboard name of the target score holder.
* This can be an entity, player, or nothing at all.
*/
public void setTargetName(String targetName) {
this.targetName = targetName;
}
public @Nullable String getObjective() {
return this.objective;
}
public void setObjective(@Nullable String objective) {
this.objective = objective;
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class WrapperPlayServerResourcePackRemove extends PacketWrapper<WrapperPlayServerResourcePackRemove> {
private @Nullable UUID packId;
public WrapperPlayServerResourcePackRemove(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerResourcePackRemove(@Nullable UUID packId) {
super(PacketType.Play.Server.RESOURCE_PACK_REMOVE);
this.packId = packId;
}
@Override
public void read() {
this.packId = this.readOptional(PacketWrapper::readUUID);
}
@Override
public void write() {
this.writeOptional(this.packId, PacketWrapper::writeUUID);
}
@Override
public void copy(WrapperPlayServerResourcePackRemove wrapper) {
this.packId = wrapper.packId;
}
public @Nullable UUID getPackId() {
return this.packId;
}
public void setPackId(@Nullable UUID packId) {
this.packId = packId;
}
}
@@ -25,8 +25,13 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlayServerResourcePackSend> {
public static final int MAX_HASH_LENGTH = 40;
private UUID packId;
private String url;
private String hash;
private boolean required;
@@ -37,19 +42,29 @@ public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlay
}
public WrapperPlayServerResourcePackSend(String url, String hash, boolean required, @Nullable Component prompt) {
this(UUID.randomUUID(), url, hash, required, prompt);
}
public WrapperPlayServerResourcePackSend(UUID packId, String url, String hash, boolean required, @Nullable Component prompt) {
super(PacketType.Play.Server.RESOURCE_PACK_SEND);
if (hash.length() > MAX_HASH_LENGTH) {
throw new IllegalArgumentException("Hash is too long (max 40, was " + hash.length() + ")");
} else {
this.url = url;
this.hash = hash;
this.required = required;
this.prompt = prompt;
throw new IllegalArgumentException("Hash is too long (max " + MAX_HASH_LENGTH + ", was " + hash.length() + ")");
}
this.packId = packId;
this.url = url;
this.hash = hash;
this.required = required;
this.prompt = prompt;
}
@Override
public void read() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.packId = this.readUUID();
}
url = readString();
hash = readString(MAX_HASH_LENGTH);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_16)) {
@@ -63,6 +78,10 @@ public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlay
@Override
public void write() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeUUID(this.packId);
}
writeString(url);
writeString(hash, MAX_HASH_LENGTH);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_16)) {
@@ -76,24 +95,45 @@ public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlay
@Override
public void copy(WrapperPlayServerResourcePackSend wrapper) {
packId = wrapper.packId;
url = wrapper.url;
hash = wrapper.hash;
required = wrapper.required;
prompt = wrapper.prompt;
}
public UUID getPackId() {
return this.packId;
}
public void setPackId(UUID packId) {
this.packId = packId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public Component getPrompt() {
return prompt;
}
@@ -25,59 +25,55 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
public class WrapperPlayServerSetTitleSubtitle extends PacketWrapper<WrapperPlayServerSetTitleSubtitle> {
@Deprecated
public static boolean HANDLE_JSON = true;
private String subtitleJson;
private Component subtitle;
public WrapperPlayServerSetTitleSubtitle(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerSetTitleSubtitle(String subtitleJson) {
this(AdventureSerializer.parseComponent(subtitleJson));
}
public WrapperPlayServerSetTitleSubtitle(Component subtitle) {
super(PacketType.Play.Server.SET_TITLE_SUBTITLE);
this.subtitle = subtitle;
}
public WrapperPlayServerSetTitleSubtitle(String subtitleJson) {
super(PacketType.Play.Server.SET_TITLE_SUBTITLE);
this.subtitleJson = subtitleJson;
}
@Override
public void read() {
subtitleJson = readComponentJSON();
if (HANDLE_JSON) {
subtitle = AdventureSerializer.parseComponent(subtitleJson);
}
this.subtitle = this.readComponent();
}
@Override
public void write() {
if (HANDLE_JSON && subtitle != null) {
subtitleJson = AdventureSerializer.toJson(subtitle);
}
writeComponentJSON(subtitleJson);
this.writeComponent(this.subtitle);
}
@Override
public void copy(WrapperPlayServerSetTitleSubtitle wrapper) {
subtitleJson = wrapper.subtitleJson;
subtitle = wrapper.subtitle;
this.subtitle = wrapper.subtitle;
}
public Component getSubtitle() {
return subtitle;
return this.subtitle;
}
public void setSubtitle(Component subtitle) {
this.subtitle = subtitle;
}
@Deprecated
public String getSubtitleJson() {
return subtitleJson;
return AdventureSerializer.toJson(this.getSubtitle());
}
@Deprecated
public void setSubtitleJson(String subtitleJson) {
this.subtitleJson = subtitleJson;
this.setSubtitle(AdventureSerializer.parseComponent(subtitleJson));
}
}
@@ -25,44 +25,38 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
public class WrapperPlayServerSetTitleText extends PacketWrapper<WrapperPlayServerSetTitleText> {
@Deprecated
public static boolean HANDLE_JSON = true;
private String titleJson;
private Component title;
public WrapperPlayServerSetTitleText(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerSetTitleText(String titleJson) {
this(AdventureSerializer.parseComponent(titleJson));
}
public WrapperPlayServerSetTitleText(Component title) {
super(PacketType.Play.Server.SET_TITLE_TEXT);
this.title = title;
}
public WrapperPlayServerSetTitleText(String titleJson) {
super(PacketType.Play.Server.SET_TITLE_TEXT);
this.titleJson = titleJson;
}
@Override
public void read() {
titleJson = readComponentJSON();
if (HANDLE_JSON) {
title = AdventureSerializer.parseComponent(titleJson);
}
this.title = this.readComponent();
}
@Override
public void write() {
if (HANDLE_JSON && title != null) {
titleJson = AdventureSerializer.toJson(title);
}
writeComponentJSON(titleJson);
this.writeComponent(this.title);
}
@Override
public void copy(WrapperPlayServerSetTitleText wrapper) {
titleJson = wrapper.titleJson;
title = wrapper.title;
this.title = wrapper.title;
}
public Component getTitle() {
@@ -73,11 +67,13 @@ public class WrapperPlayServerSetTitleText extends PacketWrapper<WrapperPlayServ
this.title = title;
}
@Deprecated
public String getTitleJson() {
return titleJson;
return AdventureSerializer.toJson(this.getTitle());
}
@Deprecated
public void setTitleJson(String titleJson) {
this.titleJson = titleJson;
this.setTitle(AdventureSerializer.parseComponent(titleJson));
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
@@ -66,7 +67,7 @@ public class WrapperPlayServerSpawnLivingEntity extends PacketWrapper<WrapperPla
}
public WrapperPlayServerSpawnLivingEntity(int entityID, UUID entityUUID, EntityType entityType, Vector3d position, float yaw, float pitch, float headPitch, Vector3d velocity, EntityMetadataProvider metadata) {
this(entityID, entityUUID, entityType, position, yaw, pitch, headPitch, velocity, metadata.entityData());
this(entityID, entityUUID, entityType, position, yaw, pitch, headPitch, velocity, metadata.entityData(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
}
public WrapperPlayServerSpawnLivingEntity(int entityId, UUID entityUUID,
@@ -82,7 +83,7 @@ public class WrapperPlayServerSpawnLivingEntity extends PacketWrapper<WrapperPla
Vector3d velocity,
EntityMetadataProvider metadata) {
this(entityId, entityUUID, entityType, location.getPosition(), location.getYaw(), location.getPitch(),
headPitch, velocity, metadata.entityData());
headPitch, velocity, metadata.entityData(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
}
@Override
@@ -235,6 +236,6 @@ public class WrapperPlayServerSpawnLivingEntity extends PacketWrapper<WrapperPla
}
public void setEntityMetadata(EntityMetadataProvider metadata) {
this.entityMetadata = metadata.entityData();
this.entityMetadata = metadata.entityData(serverVersion.toClientVersion());
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
@@ -29,6 +30,7 @@ import com.github.retrooper.packetevents.protocol.world.Location;
import com.github.retrooper.packetevents.util.MathUtil;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.Arrays;
@@ -52,7 +54,7 @@ public class WrapperPlayServerSpawnPlayer extends PacketWrapper<WrapperPlayServe
}
public WrapperPlayServerSpawnPlayer(int entityId, UUID uuid, Location location, EntityMetadataProvider metadata) {
this(entityId, uuid, location.getPosition(), location.getYaw(), location.getPitch(), metadata.entityData());
this(entityId, uuid, location.getPosition(), location.getYaw(), location.getPitch(), metadata.entityData(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
}
public WrapperPlayServerSpawnPlayer(int entityId, UUID uuid, Location location, List<EntityData> entityMetadata) {
@@ -75,7 +77,7 @@ public class WrapperPlayServerSpawnPlayer extends PacketWrapper<WrapperPlayServe
}
public WrapperPlayServerSpawnPlayer(int entityID, UUID uuid, Vector3d position, float yaw, float pitch, EntityMetadataProvider metadata) {
this(entityID, uuid, position, yaw, pitch, metadata.entityData());
this(entityID, uuid, position, yaw, pitch, metadata.entityData(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
}
@Override
@@ -187,7 +189,7 @@ public class WrapperPlayServerSpawnPlayer extends PacketWrapper<WrapperPlayServe
@Deprecated
public void setEntityMetadata(EntityMetadataProvider metadata) {
this.entityMetadata = metadata.entityData();
this.entityMetadata = metadata.entityData(serverVersion.toClientVersion());
}
@Deprecated
@@ -36,12 +36,14 @@ import org.jetbrains.annotations.Nullable;
* For example, join messages, quit messages, etc...
*/
public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPlayServerSystemChatMessage> {
@Deprecated
public static boolean HANDLE_JSON = true;
private @Nullable ChatType type;
//Overlay is a replacement for the chat type field. If overlay is true, the message will appear above your hot bar.
//If not, it will appear in the normal chat.
private boolean overlay;
private String messageJson;
private Component message;
public WrapperPlayServerSystemChatMessage(PacketSendEvent event) {
@@ -61,7 +63,7 @@ public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPla
@Deprecated
public WrapperPlayServerSystemChatMessage(@NotNull ChatType type, String messageJson) {
super(PacketType.Play.Server.SYSTEM_CHAT_MESSAGE);
this.messageJson = messageJson;
this.message = AdventureSerializer.parseComponent(messageJson);
this.type = type;
if (type == ChatTypes.GAME_INFO) {
this.overlay = true;
@@ -78,18 +80,14 @@ public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPla
@Deprecated
public WrapperPlayServerSystemChatMessage(boolean overlay, String messageJson) {
super(PacketType.Play.Server.SYSTEM_CHAT_MESSAGE);
this.messageJson = messageJson;
this.message = AdventureSerializer.parseComponent(messageJson);
this.overlay = overlay;
this.type = overlay ? ChatTypes.GAME_INFO : ChatTypes.SYSTEM;
}
@Override
public void read() {
this.messageJson = readComponentJSON();
// Parse JSON message
if (HANDLE_JSON) {
message = AdventureSerializer.parseComponent(this.messageJson);
}
this.message = this.readComponent();
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_19_1)) {
overlay = readBoolean();
} else {
@@ -99,10 +97,7 @@ public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPla
@Override
public void write() {
if (HANDLE_JSON && message != null) {
messageJson = AdventureSerializer.toJson(message);
}
writeComponentJSON(messageJson);
this.writeComponent(this.message);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_19_1)) {
writeBoolean(overlay);
} else {
@@ -122,7 +117,6 @@ public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPla
public void copy(WrapperPlayServerSystemChatMessage wrapper) {
this.type = wrapper.type;
this.overlay = wrapper.overlay;
this.messageJson = wrapper.messageJson;
this.message = wrapper.message;
}
@@ -136,12 +130,14 @@ public class WrapperPlayServerSystemChatMessage extends PacketWrapper<WrapperPla
this.type = type;
}
@Deprecated
public String getMessageJson() {
return messageJson;
return AdventureSerializer.toJson(this.getMessage());
}
@Deprecated
public void setMessageJson(String messageJson) {
this.messageJson = messageJson;
this.setMessage(AdventureSerializer.parseComponent(messageJson));
}
public Component getMessage() {
@@ -21,7 +21,6 @@ package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
@@ -68,14 +67,7 @@ public class WrapperPlayServerTabComplete extends PacketWrapper<WrapperPlayServe
commandMatches = new ArrayList<>(matchLength);
for (int i = 0; i < matchLength; i++) {
String text = readString();
Component tooltip;
boolean hasTooltip = readBoolean();
if (hasTooltip) {
String tooltipJson = readComponentJSON();
tooltip = AdventureSerializer.parseComponent(tooltipJson);
} else {
tooltip = null;
}
Component tooltip = readOptional(PacketWrapper::readComponent);
CommandMatch commandMatch = new CommandMatch(text, tooltip);
commandMatches.add(commandMatch);
}
@@ -84,7 +76,7 @@ public class WrapperPlayServerTabComplete extends PacketWrapper<WrapperPlayServe
commandMatches = new ArrayList<>(matchLength);
for (int i = 0; i < matchLength; i++) {
String text = readString();
CommandMatch commandMatch = new CommandMatch(text, (Component) null);
CommandMatch commandMatch = new CommandMatch(text, null);
commandMatches.add(commandMatch);
}
}
@@ -103,8 +95,7 @@ public class WrapperPlayServerTabComplete extends PacketWrapper<WrapperPlayServe
boolean hasTooltip = match.getTooltip().isPresent();
writeBoolean(hasTooltip);
if (hasTooltip) {
String tooltipJson = AdventureSerializer.toJson(match.getTooltip().get());
writeComponentJSON(tooltipJson);
writeComponent(match.getTooltip().get());
}
}
} else {
@@ -0,0 +1,79 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayServerTickingState extends PacketWrapper<WrapperPlayServerTickingState> {
private float tickRate;
private boolean frozen;
public WrapperPlayServerTickingState(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerTickingState(float tickRate, boolean frozen) {
super(PacketType.Play.Server.TICKING_STATE);
this.tickRate = tickRate;
this.frozen = frozen;
}
@Override
public void read() {
this.tickRate = this.readFloat();
this.frozen = this.readBoolean();
}
@Override
public void write() {
this.writeFloat(this.tickRate);
this.writeBoolean(this.frozen);
}
@Override
public void copy(WrapperPlayServerTickingState wrapper) {
this.tickRate = wrapper.tickRate;
this.frozen = wrapper.frozen;
}
/**
* The tick rate is measured in ticks per second.
*/
public float getTickRate() {
return this.tickRate;
}
/**
* The tick rate is measured in ticks per second.
*/
public void setTickRate(float tickRate) {
this.tickRate = tickRate;
}
public boolean isFrozen() {
return this.frozen;
}
public void setFrozen(boolean frozen) {
this.frozen = frozen;
}
}
@@ -0,0 +1,60 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayServerTickingStep extends PacketWrapper<WrapperPlayServerTickingStep> {
private int tickSteps;
public WrapperPlayServerTickingStep(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerTickingStep(int tickSteps) {
super(PacketType.Play.Server.TICKING_STEP);
this.tickSteps = tickSteps;
}
@Override
public void read() {
this.tickSteps = this.readVarInt();
}
@Override
public void write() {
this.writeVarInt(this.tickSteps);
}
@Override
public void copy(WrapperPlayServerTickingStep wrapper) {
this.tickSteps = wrapper.tickSteps;
}
public int getTickSteps() {
return this.tickSteps;
}
public void setTickSteps(int tickSteps) {
this.tickSteps = tickSteps;
}
}
@@ -18,7 +18,6 @@
package com.github.retrooper.packetevents.wrapper.play.server;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
@@ -30,20 +29,17 @@ import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle> {
@Deprecated
public static boolean HANDLE_JSON = true;
private TitleAction action;
@Nullable
private Component title;
@Nullable
private String titleJson;
@Nullable
private Component subtitle;
@Nullable
private String subtitleJson;
@Nullable
private Component actionBar;
@Nullable
private String actionBarJson;
private int fadeInTicks;
private int stayTicks;
@@ -65,16 +61,11 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
this.fadeOutTicks = fadeOutTicks;
}
@Deprecated
public WrapperPlayServerTitle(TitleAction action, @Nullable String titleJson, @Nullable String subtitleJson,
@Nullable String actionBarJson, int fadeInTicks, int stayTicks, int fadeOutTicks) {
super(PacketType.Play.Server.TITLE);
this.action = action;
this.titleJson = titleJson;
this.subtitleJson = subtitleJson;
this.actionBarJson = actionBarJson;
this.fadeInTicks = fadeInTicks;
this.stayTicks = stayTicks;
this.fadeOutTicks = fadeOutTicks;
this(action, AdventureSerializer.parseComponent(titleJson), AdventureSerializer.parseComponent(subtitleJson),
AdventureSerializer.parseComponent(actionBarJson), fadeInTicks, stayTicks, fadeOutTicks);
}
@Override
@@ -88,22 +79,13 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
}
switch (Objects.requireNonNull(action)) {
case SET_TITLE:
titleJson = readComponentJSON();
if (HANDLE_JSON) {
title = AdventureSerializer.parseComponent(titleJson);
}
title = readComponent();
break;
case SET_SUBTITLE:
subtitleJson = readComponentJSON();
if (HANDLE_JSON) {
subtitle = AdventureSerializer.parseComponent(subtitleJson);
}
subtitle = readComponent();
break;
case SET_ACTION_BAR:
actionBarJson = readComponentJSON();
if (HANDLE_JSON) {
actionBar = AdventureSerializer.parseComponent(actionBarJson);
}
actionBar = readComponent();
break;
case SET_TIMES_AND_DISPLAY:
fadeInTicks = readInt();
@@ -117,11 +99,8 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
public void copy(WrapperPlayServerTitle wrapper) {
action = wrapper.action;
title = wrapper.title;
titleJson = wrapper.titleJson;
subtitle = wrapper.subtitle;
subtitleJson = wrapper.subtitleJson;
actionBar = wrapper.actionBar;
actionBarJson = wrapper.actionBarJson;
fadeInTicks = wrapper.fadeInTicks;
stayTicks = wrapper.stayTicks;
fadeOutTicks = wrapper.fadeOutTicks;
@@ -134,22 +113,13 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
writeVarInt(id);
switch (action) {
case SET_TITLE:
if (HANDLE_JSON && title != null) {
titleJson = AdventureSerializer.toJson(title);
}
writeComponentJSON(titleJson);
writeComponent(title);
break;
case SET_SUBTITLE:
if (HANDLE_JSON && subtitle != null) {
subtitleJson = AdventureSerializer.toJson(subtitle);
}
writeComponentJSON(subtitleJson);
writeComponent(subtitle);
break;
case SET_ACTION_BAR:
if (HANDLE_JSON && actionBar != null) {
actionBarJson = AdventureSerializer.toJson(actionBar);
}
writeComponentJSON(actionBarJson);
writeComponent(actionBar);
break;
case SET_TIMES_AND_DISPLAY:
writeInt(fadeInTicks);
@@ -175,12 +145,14 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
this.title = title;
}
@Deprecated
public @Nullable String getTitleJson() {
return titleJson;
return AdventureSerializer.toJson(this.getTitle());
}
@Deprecated
public void setTitleJson(@Nullable String titleJson) {
this.titleJson = titleJson;
this.setTitle(AdventureSerializer.parseComponent(titleJson));
}
public @Nullable Component getSubtitle() {
@@ -191,12 +163,14 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
this.subtitle = subtitle;
}
@Deprecated
public @Nullable String getSubtitleJson() {
return subtitleJson;
return AdventureSerializer.toJson(this.getSubtitle());
}
@Deprecated
public void setSubtitleJson(@Nullable String subtitleJson) {
this.subtitleJson = subtitleJson;
this.setSubtitle(AdventureSerializer.parseComponent(subtitleJson));
}
public @Nullable Component getActionBar() {
@@ -207,12 +181,14 @@ public class WrapperPlayServerTitle extends PacketWrapper<WrapperPlayServerTitle
this.actionBar = actionBar;
}
@Deprecated
public @Nullable String getActionBarJson() {
return actionBarJson;
return AdventureSerializer.toJson(this.getActionBar());
}
@Deprecated
public void setActionBarJson(@Nullable String actionBarJson) {
this.actionBarJson = actionBarJson;
this.setActionBar(AdventureSerializer.parseComponent(actionBarJson));
}
public int getFadeInTicks() {
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,132 @@
{
"V_1_20_3": {
"allay": 0,
"area_effect_cloud": 1,
"armor_stand": 2,
"arrow": 3,
"axolotl": 4,
"bat": 5,
"bee": 6,
"blaze": 7,
"block_display": 8,
"boat": 9,
"breeze": 10,
"camel": 11,
"cat": 12,
"cave_spider": 13,
"chest_boat": 14,
"chest_minecart": 15,
"chicken": 16,
"cod": 17,
"command_block_minecart": 18,
"cow": 19,
"creeper": 20,
"dolphin": 21,
"donkey": 22,
"dragon_fireball": 23,
"drowned": 24,
"egg": 25,
"elder_guardian": 26,
"end_crystal": 27,
"ender_dragon": 28,
"ender_pearl": 29,
"enderman": 30,
"endermite": 31,
"evoker": 32,
"evoker_fangs": 33,
"experience_bottle": 34,
"experience_orb": 35,
"eye_of_ender": 36,
"falling_block": 37,
"firework_rocket": 38,
"fox": 39,
"frog": 40,
"furnace_minecart": 41,
"ghast": 42,
"giant": 43,
"glow_item_frame": 44,
"glow_squid": 45,
"goat": 46,
"guardian": 47,
"hoglin": 48,
"hopper_minecart": 49,
"horse": 50,
"husk": 51,
"illusioner": 52,
"interaction": 53,
"iron_golem": 54,
"item": 55,
"item_display": 56,
"item_frame": 57,
"fireball": 58,
"leash_knot": 59,
"lightning_bolt": 60,
"llama": 61,
"llama_spit": 62,
"magma_cube": 63,
"marker": 64,
"minecart": 65,
"mooshroom": 66,
"mule": 67,
"ocelot": 68,
"painting": 69,
"panda": 70,
"parrot": 71,
"phantom": 72,
"pig": 73,
"piglin": 74,
"piglin_brute": 75,
"pillager": 76,
"polar_bear": 77,
"potion": 78,
"pufferfish": 79,
"rabbit": 80,
"ravager": 81,
"salmon": 82,
"sheep": 83,
"shulker": 84,
"shulker_bullet": 85,
"silverfish": 86,
"skeleton": 87,
"skeleton_horse": 88,
"slime": 89,
"small_fireball": 90,
"sniffer": 91,
"snow_golem": 92,
"snowball": 93,
"spawner_minecart": 94,
"spectral_arrow": 95,
"spider": 96,
"squid": 97,
"stray": 98,
"strider": 99,
"tadpole": 100,
"text_display": 101,
"tnt": 102,
"tnt_minecart": 103,
"trader_llama": 104,
"trident": 105,
"tropical_fish": 106,
"turtle": 107,
"vex": 108,
"villager": 109,
"vindicator": 110,
"wandering_trader": 111,
"warden": 112,
"wind_charge": 113,
"witch": 114,
"wither": 115,
"wither_skeleton": 116,
"wither_skull": 117,
"wolf": 118,
"zoglin": 119,
"zombie": 120,
"zombie_horse": 121,
"zombie_villager": 122,
"zombified_piglin": 123,
"player": 124,
"fishing_bobber": 125
},
"V_1_19_4": {
"allay": 0,
"area_effect_cloud": 1,
@@ -1230,4 +1358,4 @@
"villager": 120,
"end_crystal": 200
}
}
}
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,107 @@
{
"V_1_20_3": [
"ambient_entity_effect",
"angry_villager",
"block",
"block_marker",
"bubble",
"cloud",
"crit",
"damage_indicator",
"dragon_breath",
"dripping_lava",
"falling_lava",
"landing_lava",
"dripping_water",
"falling_water",
"dust",
"dust_color_transition",
"effect",
"elder_guardian",
"enchanted_hit",
"enchant",
"end_rod",
"entity_effect",
"explosion_emitter",
"explosion",
"gust",
"gust_emitter",
"sonic_boom",
"falling_dust",
"firework",
"fishing",
"flame",
"cherry_leaves",
"sculk_soul",
"sculk_charge",
"sculk_charge_pop",
"soul_fire_flame",
"soul",
"flash",
"happy_villager",
"composter",
"heart",
"instant_effect",
"item",
"vibration",
"item_slime",
"item_snowball",
"large_smoke",
"lava",
"mycelium",
"note",
"poof",
"portal",
"rain",
"smoke",
"white_smoke",
"sneeze",
"spit",
"squid_ink",
"sweep_attack",
"totem_of_undying",
"underwater",
"splash",
"witch",
"bubble_pop",
"current_down",
"bubble_column_up",
"nautilus",
"dolphin",
"campfire_cosy_smoke",
"campfire_signal_smoke",
"dripping_honey",
"falling_honey",
"landing_honey",
"falling_nectar",
"falling_spore_blossom",
"ash",
"crimson_spore",
"warped_spore",
"spore_blossom_air",
"dripping_obsidian_tear",
"falling_obsidian_tear",
"landing_obsidian_tear",
"reverse_portal",
"white_ash",
"small_flame",
"snowflake",
"dripping_dripstone_lava",
"falling_dripstone_lava",
"dripping_dripstone_water",
"falling_dripstone_water",
"glow_squid_ink",
"glow",
"wax_on",
"wax_off",
"electric_spark",
"scrape",
"shriek",
"egg_crack",
"dust_plume",
"gust_dust",
"trial_spawner_detection"
],
"V_1_20": [
"ambient_entity_effect",
"angry_villager",
@@ -897,4 +1000,4 @@
"totem_of_undying",
"split"
]
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ subprojects {
group = 'com.github.retrooper'
description = project.name
version = '2.1.0'//TODO UPDATE - ADD "-SNAPSHOT" if we are dealing with snapshot versions
version = '2.2.0'//TODO UPDATE - ADD "-SNAPSHOT" if we are dealing with snapshot versions
project.ext.nettyVersion = '4.1.72.Final'
project.ext.adventureVersion = '4.14.0'
project.ext.adventureDependencies=["net.kyori:adventure-api:${adventureVersion}",
@@ -0,0 +1,758 @@
package io.github.retrooper.packetevents.bstats;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
//This file was taken from bStats https://github.com/Bastian/bStats-Metrics
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class Metrics {
static {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'n', 'g', 'e', 'e', 'c', 'o', 'r', 'd'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
// The version of this bStats class
public static final int B_STATS_VERSION = 1;
// The url to which the data is sent
private static final String URL = "https://bStats.org/submitData/bungeecord";
// The plugin
private final Plugin plugin;
// The plugin id
private final int pluginId;
// Is bStats enabled on this server?
private boolean enabled;
// The uuid of the server
private String serverUUID;
// Should failed requests be logged?
private boolean logFailedRequests = false;
// Should the sent data be logged?
private static boolean logSentData;
// Should the response text be logged?
private static boolean logResponseStatusText;
// A list with all known metrics class objects including this one
private static final List<Object> knownMetricsInstances = new ArrayList<>();
// A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>();
/**
* Class constructor.
*
* @param plugin The plugin which stats should be submitted.
* @param pluginId The id of the plugin.
* It can be found at <a href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
*/
public Metrics(Plugin plugin, int pluginId) {
this.plugin = plugin;
this.pluginId = pluginId;
try {
loadConfig();
} catch (IOException e) {
// Failed to load configuration
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
return;
}
// We are not allowed to send data about this server :(
if (!enabled) {
return;
}
Class<?> usedMetricsClass = getFirstBStatsClass();
if (usedMetricsClass == null) {
// Failed to get first metrics class
return;
}
if (usedMetricsClass == getClass()) {
// We are the first! :)
linkMetrics(this);
startSubmitting();
} else {
// We aren't the first so we link to the first metrics class
try {
usedMetricsClass.getMethod("linkMetrics", Object.class).invoke(null, this);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Failed to link to first metrics class " + usedMetricsClass.getName() + "!", e);
}
}
}
}
/**
* Checks if bStats is enabled.
*
* @return Whether bStats is enabled or not.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
plugin.getLogger().log(Level.WARNING, "Chart cannot be null");
}
charts.add(chart);
}
/**
* Links an other metrics class with this class.
* This method is called using Reflection.
*
* @param metrics An object of the metrics class to link.
*/
public static void linkMetrics(Object metrics) {
knownMetricsInstances.add(metrics);
}
/**
* Gets the plugin specific data.
* This method is called using Reflection.
*
* @return The plugin specific data.
*/
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
String pluginName = plugin.getDescription().getName();
String pluginVersion = plugin.getDescription().getVersion();
data.addProperty("pluginName", pluginName);
data.addProperty("id", pluginId);
data.addProperty("pluginVersion", pluginVersion);
JsonArray customCharts = new JsonArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JsonObject chart = customChart.getRequestJsonObject(plugin.getLogger(), logFailedRequests);
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.add("customCharts", customCharts);
return data;
}
private void startSubmitting() {
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
plugin.getProxy().getScheduler().schedule(plugin, this::submitData, initialDelay, TimeUnit.MILLISECONDS);
plugin.getProxy().getScheduler().schedule(
plugin, this::submitData, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
/**
* Gets the server specific data.
*
* @return The server specific data.
*/
private JsonObject getServerData() {
// Minecraft specific data
int playerAmount = Math.min(plugin.getProxy().getOnlineCount(), 500);
int onlineMode = plugin.getProxy().getConfig().isOnlineMode() ? 1 : 0;
String bungeecordVersion = plugin.getProxy().getVersion();
int managedServers = plugin.getProxy().getServers().size();
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JsonObject data = new JsonObject();
data.addProperty("serverUUID", serverUUID);
data.addProperty("playerAmount", playerAmount);
data.addProperty("managedServers", managedServers);
data.addProperty("onlineMode", onlineMode);
data.addProperty("bungeecordVersion", bungeecordVersion);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", coreCount);
return data;
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JsonObject data = getServerData();
final JsonArray pluginData = new JsonArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Object metrics : knownMetricsInstances) {
try {
Object plugin = metrics.getClass().getMethod("getPluginData").invoke(metrics);
if (plugin instanceof JsonObject) {
pluginData.add((JsonObject) plugin);
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
}
data.add("plugins", pluginData);
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats!", e);
}
}
}
/**
* Loads the bStats configuration.
*
* @throws IOException If something did not work :(
*/
private void loadConfig() throws IOException {
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
bStatsFolder.mkdirs();
File configFile = new File(bStatsFolder, "config.yml");
if (!configFile.exists()) {
writeFile(configFile,
"#bStats collects some data for plugin authors like how many servers are using their plugins.",
"#To honor their work, you should not disable it.",
"#This has nearly no effect on the server performance!",
"#Check out https://bStats.org/ to learn more :)",
"enabled: true",
"serverUuid: \"" + UUID.randomUUID() + "\"",
"logFailedRequests: false",
"logSentData: false",
"logResponseStatusText: false");
}
Configuration configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
// Load configuration
enabled = configuration.getBoolean("enabled", true);
serverUUID = configuration.getString("serverUuid");
logFailedRequests = configuration.getBoolean("logFailedRequests", false);
logSentData = configuration.getBoolean("logSentData", false);
logResponseStatusText = configuration.getBoolean("logResponseStatusText", false);
}
/**
* Gets the first bStat Metrics class.
*
* @return The first bStats metrics class.
*/
private Class<?> getFirstBStatsClass() {
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
bStatsFolder.mkdirs();
File tempFile = new File(bStatsFolder, "temp.txt");
try {
String className = readFile(tempFile);
if (className != null) {
try {
// Let's check if a class with the given name exists.
return Class.forName(className);
} catch (ClassNotFoundException ignored) { }
}
writeFile(tempFile, getClass().getName());
return getClass();
} catch (IOException e) {
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Failed to get first bStats class!", e);
}
return null;
}
}
/**
* Reads the first line of the file.
*
* @param file The file to read. Cannot be null.
* @return The first line of the file or {@code null} if the file does not exist or is empty.
* @throws IOException If something did not work :(
*/
private String readFile(File file) throws IOException {
if (!file.exists()) {
return null;
}
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
return bufferedReader.readLine();
}
}
/**
* Writes a String to a file. It also adds a note for the user,
*
* @param file The file to write to. Cannot be null.
* @param lines The lines to write.
* @throws IOException If something did not work :(
*/
private void writeFile(File file, String... lines) throws IOException {
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
for (String line : lines) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
}
}
/**
* Sends the data to the bStats server.
*
* @param plugin Any plugin. It's just used to get a logger instance.
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null");
}
if (logSentData) {
plugin.getLogger().info("Sending data to bStats: " + data);
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
// Add headers
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
plugin.getLogger().info("Sent data to bStats and received response: " + builder);
}
}
/**
* Gzips the given String.
*
* @param str The string to gzip.
* @return The gzipped String.
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
/**
* Represents a custom chart.
*/
public static abstract class CustomChart {
// The id of the chart
private final String chartId;
/**
* Class constructor.
*
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JsonObject getRequestJsonObject(Logger logger, boolean logFailedRequests) {
JsonObject chart = new JsonObject();
chart.addProperty("chartId", chartId);
try {
JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.add("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JsonObject getChartData() throws Exception;
}
/**
* Represents a custom simple pie.
*/
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
/**
* Represents a custom advanced pie.
*/
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom drilldown pie.
*/
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObject value = new JsonObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.add(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom single line chart.
*/
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
/**
* Represents a custom multi line chart.
*/
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom simple bar chart.
*/
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JsonArray categoryValues = new JsonArray();
categoryValues.add(new JsonPrimitive(entry.getValue()));
values.add(entry.getKey(), categoryValues);
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom advanced bar chart.
*/
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JsonArray categoryValues = new JsonArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(new JsonPrimitive(categoryValue));
}
values.add(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
}
@@ -35,7 +35,7 @@ import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
import com.github.retrooper.packetevents.util.LogManager;
import io.github.retrooper.packetevents.PacketEventsPlugin;
import io.github.retrooper.packetevents.bstats.Metrics;
import io.github.retrooper.packetevents.impl.netty.NettyManagerImpl;
import io.github.retrooper.packetevents.impl.netty.manager.player.PlayerManagerAbstract;
import io.github.retrooper.packetevents.impl.netty.manager.protocol.ProtocolManagerAbstract;
@@ -205,7 +205,11 @@ public class BungeePacketEventsBuilder {
}
if (settings.isbStatsEnabled()) {
// TODO: Cross-platform metrics?
Metrics metrics = new Metrics(plugin, 11327);
//Just to have an idea of which versions of packetevents people use
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
return getVersion().toString();
}));
}
PacketType.Play.Client.load();
+1 -1
View File
@@ -1,4 +1,4 @@
name: packetevents
version: 2.0.0
version: 2.2.0 #//TODO UPDATE
main: io.github.retrooper.packetevents.PacketEventsPlugin
author: retrooper
@@ -84,13 +84,13 @@ public class SpigotPacketEventsBuilder {
private final NettyManager nettyManager = new NettyManagerImpl();
private final SpigotChannelInjector injector = new SpigotChannelInjector();
private final LogManager logManager = new BukkitLogManager();
private final AtomicBoolean loaded = new AtomicBoolean(false);
private final AtomicBoolean initialized = new AtomicBoolean(false);
private boolean loaded;
private boolean initialized;
private boolean lateBind = false;
@Override
public void load() {
if (!loaded.getAndSet(true)) {
if (!loaded) {
//Resolve server version and cache
String id = plugin.getName().toLowerCase();
PacketEvents.IDENTIFIER = "pe-" + id;
@@ -117,6 +117,8 @@ public class SpigotPacketEventsBuilder {
injector.inject();
}
loaded = true;
//Register internal packet listener (should be the first listener)
//This listener doesn't do any modifications to the packets, just reads data
getEventManager().registerListener(new InternalBukkitPacketListener());
@@ -125,21 +127,21 @@ public class SpigotPacketEventsBuilder {
@Override
public boolean isLoaded() {
return loaded.get();
return loaded;
}
@Override
public void init() {
//Load if we haven't loaded already
load();
if (!initialized.getAndSet(true)) {
if (!initialized) {
if (settings.shouldCheckForUpdates()) {
getUpdateChecker().handleUpdateCheck();
}
if (settings.isbStatsEnabled()) {
Metrics metrics = new Metrics((JavaPlugin) plugin, 11327);
//Just to have an idea what versions of packetevents people use
//Just to have an idea of which versions of packetevents people use
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
return getVersion().toString();
}));
@@ -161,6 +163,8 @@ public class SpigotPacketEventsBuilder {
if (!"true".equalsIgnoreCase(System.getenv("PE_IGNORE_INCOMPATIBILITY"))) {
checkCompatibility();
}
initialized = true;
}
}
@@ -200,12 +204,12 @@ public class SpigotPacketEventsBuilder {
@Override
public boolean isInitialized() {
return initialized.get();
return initialized;
}
@Override
public void terminate() {
if (initialized.getAndSet(false)) {
if (initialized) {
//Uninject the injector if needed(depends on the injector implementation)
injector.uninject();
for (User user : ProtocolManager.USERS.values()) {
@@ -213,6 +217,7 @@ public class SpigotPacketEventsBuilder {
}
//Unregister all listeners. Because if we attempt to reload, we will end up with duplicate listeners.
getEventManager().unregisterAllListeners();
initialized = false;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: packetevents
version: 2.0.0
version: 2.2.0 #//TODO UPDATE
api-version: 1.13
main: io.github.retrooper.packetevents.PacketEventsPlugin
author: retrooper
@@ -29,26 +29,28 @@ import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.proxy.ProxyServer;
import io.github.retrooper.packetevents.bstats.Metrics;
import io.github.retrooper.packetevents.velocity.factory.VelocityPacketEventsBuilder;
import java.util.logging.Logger;
@Plugin(id = "packetevents", name = "PacketEvents", version = "2.0.2")
@Plugin(id = "packetevents", name = "PacketEvents", version = "2.2.0") //TODO UPDATE
public class PacketEventsPlugin {
private final ProxyServer server;
private final Logger logger;
private final PluginContainer pluginContainer;
public final Metrics.Factory metricsFactory;
@Inject
public PacketEventsPlugin(
final ProxyServer server,
final Logger logger,
final PluginContainer pluginContainer
) {
public PacketEventsPlugin(final ProxyServer server,
final Logger logger,
final PluginContainer pluginContainer, final Metrics.Factory metricsFactory) {
this.server = server;
this.logger = logger;
this.pluginContainer = pluginContainer;
this.metricsFactory = metricsFactory;
logger.info("Plugin started");
}
@Subscribe
@@ -59,7 +61,7 @@ public class PacketEventsPlugin {
PacketEvents.getAPI().getSettings().reEncodeByDefault(false);
// It should only be enabled in a development environment, not globally
// PacketEvents.getAPI().getSettings().debug(true);
PacketEvents.getAPI().getEventManager().registerListener(new PacketListenerAbstract() {
PacketListenerAbstract listener = new PacketListenerAbstract() {
@Override
public void onPacketReceive(PacketReceiveEvent event) {
//System.out.println("Incoming: " + event.getPacketType().getName());
@@ -84,7 +86,8 @@ public class PacketEventsPlugin {
System.out.println("After processing: " + msg.getMessage());
}*/
}
});
};
//PacketEvents.getAPI().getEventManager().registerListener(listener);
PacketEvents.getAPI().init();
}
@@ -0,0 +1,727 @@
package io.github.retrooper.packetevents.bstats;
import com.google.inject.Inject;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import org.slf4j.Logger;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;
//This file was taken from bStats https://github.com/Bastian/bStats-Metrics
//and has been modified to fit our needs (compactness by fitting it into one file)
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
public class Metrics {
/**
* A factory to create new Metrics classes.
*/
public static class Factory {
private final ProxyServer server;
private final Logger logger;
private final Path dataDirectory;
// The constructor is not meant to be called by the user.
// The instance is created using Dependency Injection
@Inject
private Factory(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
this.server = server;
this.logger = logger;
this.dataDirectory = dataDirectory;
}
/**
* Creates a new Metrics class.
*
* @param serviceId The id of the service.
* It can be found at <a href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
* <p>Not to be confused with Velocity's {@link PluginDescription#getId()} method!
* @return A Metrics instance that can be used to register custom charts.
* <p>The return value can be ignored, when you do not want to register custom charts.
*/
public Metrics make(Object plugin, int serviceId) {
return new Metrics(plugin, server, logger, dataDirectory, serviceId);
}
}
private final PluginContainer pluginContainer;
private final ProxyServer server;
private final MetricsBase metricsBase;
private final Logger logger;
private final Path dataDirectory;
private String serverUUID;
private boolean enabled;
private boolean logErrors;
private boolean logSentData;
private boolean logResponseStatusText;
private Metrics(Object plugin, ProxyServer server, Logger logger, Path dataDirectory, int serviceId) {
pluginContainer = server.getPluginManager().fromInstance(plugin)
.orElseThrow(() -> new IllegalArgumentException("The provided instance is not a plugin"));
this.server = server;
this.logger = logger;
this.dataDirectory = dataDirectory;
try {
setupConfig(true);
} catch (IOException e) {
logger.error("Failed to create bStats config", e);
}
metricsBase = new MetricsBase(
"velocity",
serverUUID,
serviceId,
enabled,
this::appendPlatformData,
this::appendServiceData,
task -> server.getScheduler().buildTask(plugin, task).schedule(),
() -> true,
logger::warn,
logger::info,
logErrors,
logSentData,
logResponseStatusText
);
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
metricsBase.addCustomChart(chart);
}
private void appendPlatformData(JsonObjectBuilder builder) {
builder.appendField("playerAmount", server.getPlayerCount());
builder.appendField("managedServers", server.getAllServers().size());
builder.appendField("onlineMode", server.getConfiguration().isOnlineMode() ? 1 : 0);
builder.appendField("velocityVersionVersion", server.getVersion().getVersion());
builder.appendField("velocityVersionName", server.getVersion().getName());
builder.appendField("velocityVersionVendor", server.getVersion().getVendor());
builder.appendField("javaVersion", System.getProperty("java.version"));
builder.appendField("osName", System.getProperty("os.name"));
builder.appendField("osArch", System.getProperty("os.arch"));
builder.appendField("osVersion", System.getProperty("os.version"));
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
}
private void appendServiceData(JsonObjectBuilder builder) {
builder.appendField("pluginVersion", pluginContainer.getDescription().getVersion().orElse("unknown"));
}
/**
* Setups the bStats configuration.
*
* @param recreateWhenMalformed Whether the method should recreate the config file when it's malformed.
*/
public void setupConfig(boolean recreateWhenMalformed) throws IOException {
File configFolder = dataDirectory.getParent().resolve("bStats").toFile();
configFolder.mkdirs();
File configFile = new File(configFolder, "config.txt");
if (!configFile.exists()) {
writeConfig(configFile);
}
List<String> lines = readFile(configFile);
if (lines == null) {
throw new AssertionError("Content of newly created file is null");
}
enabled = getConfigValue("enabled", lines).map("true"::equals).orElse(true);
serverUUID = getConfigValue("server-uuid", lines).orElse(null);
logErrors = getConfigValue("log-errors", lines).map("true"::equals).orElse(false);
logSentData = getConfigValue("log-sent-data", lines).map("true"::equals).orElse(false);
logResponseStatusText = getConfigValue("log-response-status-text", lines).map("true"::equals).orElse(false);
if (serverUUID == null) {
if (recreateWhenMalformed) {
logger.info("Found malformed bStats config file. Re-creating it...");
configFile.delete();
setupConfig(false);
} else {
throw new AssertionError("Failed to re-create malformed bStats config file");
}
}
}
/**
* Creates a simple bStats configuration.
*
* @param file The config file.
*/
private void writeConfig(File file) throws IOException {
List<String> configContent = new ArrayList<>();
configContent.add("# bStats collects some basic information for plugin authors, like how many people use");
configContent.add("# their plugin and their total player count. It's recommend to keep bStats enabled, but");
configContent.add("# if you're not comfortable with this, you can turn this setting off. There is no");
configContent.add("# performance penalty associated with having metrics enabled, and data sent to bStats");
configContent.add("# can't identify your server.");
configContent.add("enabled=true");
configContent.add("server-uuid=" + UUID.randomUUID().toString());
configContent.add("log-errors=false");
configContent.add("log-sent-data=false");
configContent.add("log-response-status-text=false");
writeFile(file, configContent);
}
/**
* Gets a config setting from the given list of lines of the file.
*
* @param key The key for the setting.
* @param lines The lines of the file.
* @return The value of the setting.
*/
private Optional<String> getConfigValue(String key, List<String> lines) {
return lines.stream()
.filter(line -> line.startsWith(key + "="))
.map(line -> line.replaceFirst(Pattern.quote(key + "="), ""))
.findFirst();
}
/**
* Reads the text content of the given file.
*
* @param file The file to read.
* @return The lines of the given file.
*/
private List<String> readFile(File file) throws IOException {
if (!file.exists()) {
return null;
}
try (
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader)
) {
return bufferedReader.lines().collect(Collectors.toList());
}
}
/**
* Writes the given lines to the given file.
*
* @param file The file to write to.
* @param lines The lines to write.
*/
private void writeFile(File file, List<String> lines) throws IOException {
if (!file.exists()) {
file.createNewFile();
}
try (
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)
) {
for (String line : lines) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
}
}
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder()
.appendField("value", value)
.build();
}
}
public static class JsonObjectBuilder {
private StringBuilder builder = new StringBuilder();
private boolean hasAtLeastOneField = false;
public JsonObjectBuilder() {
builder.append("{");
}
/**
* Appends a null field to the JSON.
*
* @param key The key of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendNull(String key) {
appendFieldUnescaped(key, "null");
return this;
}
/**
* Appends a string field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String value) {
if (value == null) {
throw new IllegalArgumentException("JSON value must not be null");
}
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
return this;
}
/**
* Appends an integer field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int value) {
appendFieldUnescaped(key, String.valueOf(value));
return this;
}
/**
* Appends an object to the JSON.
*
* @param key The key of the field.
* @param object The object.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject object) {
if (object == null) {
throw new IllegalArgumentException("JSON object must not be null");
}
appendFieldUnescaped(key, object.toString());
return this;
}
/**
* Appends a string array to the JSON.
*
* @param key The key of the field.
* @param values The string array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues = Arrays.stream(values)
.map(value -> "\"" + escape(value) + "\"")
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an integer array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues = Arrays.stream(values)
.mapToObj(String::valueOf)
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an object array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues = Arrays.stream(values)
.map(JsonObject::toString)
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends a field to the object.
*
* @param key The key of the field.
* @param escapedValue The escaped value of the field.
*/
private void appendFieldUnescaped(String key, String escapedValue) {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
if (key == null) {
throw new IllegalArgumentException("JSON key must not be null");
}
if (hasAtLeastOneField) {
builder.append(",");
}
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
hasAtLeastOneField = true;
}
/**
* Builds the JSON string and invalidates this builder.
*
* @return The built JSON string.
*/
public JsonObject build() {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
JsonObject object = new JsonObject(builder.append("}").toString());
builder = null;
return object;
}
/**
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
*
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
*
* @param value The value to escape.
* @return The escaped value.
*/
private static String escape(String value) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '"') {
builder.append("\\\"");
} else if (c == '\\') {
builder.append("\\\\");
} else if (c <= '\u000F') {
builder.append("\\u000").append(Integer.toHexString(c));
} else if (c <= '\u001F') {
builder.append("\\u00").append(Integer.toHexString(c));
} else {
builder.append(c);
}
}
return builder.toString();
}
/**
* A super simple representation of a JSON object.
*
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and
* not allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String, JsonObject)}.
*/
public static class JsonObject {
private final String value;
private JsonObject(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
public static abstract class CustomChart {
private final String chartId;
protected CustomChart(String chartId) {
if (chartId == null) {
throw new IllegalArgumentException("chartId must not be null");
}
this.chartId = chartId;
}
public JsonObjectBuilder.JsonObject getRequestJsonObject(BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
JsonObjectBuilder builder = new JsonObjectBuilder();
builder.appendField("chartId", chartId);
try {
JsonObjectBuilder.JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
builder.appendField("data", data);
} catch (Throwable t) {
if (logErrors) {
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return builder.build();
}
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
}
public static class MetricsBase {
/**
* The version of the Metrics class.
*/
public static final String METRICS_VERSION = "2.1.1-SNAPSHOT";
private static final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
private final String platform;
private final String serverUuid;
private final int serviceId;
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
private final Consumer<Runnable> submitTaskConsumer;
private final Supplier<Boolean> checkServiceEnabledSupplier;
private final BiConsumer<String, Throwable> errorLogger;
private final Consumer<String> infoLogger;
private final boolean logErrors;
private final boolean logSentData;
private final boolean logResponseStatusText;
private final Set<CustomChart> customCharts = new HashSet<>();
private final boolean enabled;
/**
* Creates a new MetricsBase class instance.
*
* @param platform The platform of the service.
* @param serviceId The id of the service.
* @param serverUuid The server uuid.
* @param enabled Whether or not data sending is enabled.
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and appends all
* platform-specific data.
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and appends all
* service-specific data.
* @param submitTaskConsumer A consumer that takes a runnable with the submit task.
* This can be used to delegate the data collection to a another thread to prevent
* errors caused by concurrency. Can be {@code null}.
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
* @param errorLogger A consumer that accepts log message and an error.
* @param infoLogger A consumer that accepts info log messages.
* @param logErrors Whether or not errors should be logged.
* @param logSentData Whether or not the sent data should be logged.
* @param logResponseStatusText Whether or not the response status text should be logged.
*/
public MetricsBase(
String platform,
String serverUuid,
int serviceId,
boolean enabled,
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
Consumer<Runnable> submitTaskConsumer,
Supplier<Boolean> checkServiceEnabledSupplier,
BiConsumer<String, Throwable> errorLogger,
Consumer<String> infoLogger,
boolean logErrors,
boolean logSentData,
boolean logResponseStatusText
) {
this.platform = platform;
this.serverUuid = serverUuid;
this.serviceId = serviceId;
this.enabled = enabled;
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
this.appendServiceDataConsumer = appendServiceDataConsumer;
this.submitTaskConsumer = submitTaskConsumer;
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
this.errorLogger = errorLogger;
this.infoLogger = infoLogger;
this.logErrors = logErrors;
this.logSentData = logSentData;
this.logResponseStatusText = logResponseStatusText;
checkRelocation();
if (enabled) {
startSubmitting();
}
}
public void addCustomChart(CustomChart chart) {
this.customCharts.add(chart);
}
private void startSubmitting() {
final Runnable submitTask = () -> {
if (!enabled || !checkServiceEnabledSupplier.get()) { // Submitting data or service is disabled
scheduler.shutdown();
return;
}
if (submitTaskConsumer != null) {
submitTaskConsumer.accept(this::submitData);
} else {
this.submitData();
}
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
scheduler.scheduleAtFixedRate(submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
private void submitData() {
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
appendPlatformDataConsumer.accept(baseJsonBuilder);
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
appendServiceDataConsumer.accept(serviceJsonBuilder);
JsonObjectBuilder.JsonObject[] chartData = customCharts.stream()
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
.filter(Objects::nonNull)
.toArray(JsonObjectBuilder.JsonObject[]::new);
serviceJsonBuilder.appendField("id", serviceId);
serviceJsonBuilder.appendField("customCharts", chartData);
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
baseJsonBuilder.appendField("serverUUID", serverUuid);
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
scheduler.execute(() -> {
try {
// Send the data
sendData(data);
} catch (Exception e) {
// Something went wrong! :(
if (logErrors) {
errorLogger.accept("Could not submit bStats metrics data", e);
}
}
});
}
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
if (logSentData) {
infoLogger.accept("Sent bStats metrics data: " + data.toString());
}
String url = String.format(REPORT_URL, platform);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
infoLogger.accept("Sent data to bStats and received response: " + builder);
}
}
/**
* Checks that the class was properly relocated.
*/
private void checkRelocation() {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure no one just copy & pastes the example and uses the wrong package names
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage) || MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
/**
* Gzips the given string.
*
* @param str The string to gzip.
* @return The gzipped string.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
}
}
@@ -20,6 +20,8 @@ package io.github.retrooper.packetevents.velocity.factory;
import java.util.logging.Level;
import io.github.retrooper.packetevents.PacketEventsPlugin;
import io.github.retrooper.packetevents.bstats.Metrics;
import org.jetbrains.annotations.Nullable;
import com.github.retrooper.packetevents.PacketEvents;
@@ -169,7 +171,14 @@ public class VelocityPacketEventsBuilder {
}
if (settings.isbStatsEnabled()) {
// TODO: Velocity bstats
PacketEventsPlugin instance = (PacketEventsPlugin) plugin.getInstance().orElse(null);
if (instance != null) {
Metrics metrics = instance.metricsFactory.make(plugin, 11327);
//Just to have an idea of which versions of packetevents people use
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
return getVersion().toString();
}));
}
}
PacketType.Play.Client.load();