Compare commits

...
121 Commits
Author SHA1 Message Date
retrooper 5bb90aa0de Update PacketEvents version to 2.2.1 2024-02-11 22:20:55 +01:00
retrooper 9b1e92b555 Increase DEPTH_LIMIT of components to 512 2024-02-11 22:10:39 +01:00
retrooper 104615edb5 Increase AdventureNBTSerialization#DEPTH_LIMIT to 13 2024-02-11 21:54:43 +01:00
retrooper 9f54ca6843 Fixing metrics on velocity module 2024-02-11 21:52:50 +01:00
retrooper 46919017e1 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-02-11 21:27:19 +01:00
retrooper 0a1ce38c7e Fix null player instance in event after reload. 2024-02-11 21:26:51 +01:00
retrooper f60d5230c3 Merge pull request #668 from honkling/2.0
Request signatures from Mojang API
2024-02-11 21:19:18 +01:00
retrooper 8034f5dc89 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-02-11 21:14:19 +01:00
retrooper 265ade55d0 Credit to vytskalt: Limit objective display name to 32 characters (new commit created due to PR conflicts) 2024-02-11 21:13:53 +01:00
retrooper cffcbaf596 Merge pull request #655 from BlueTree242/2.0
Assume protocols higher or lower than the supported versions as closest protocol versions
2024-02-11 21:08:18 +01:00
retrooper 4dc90a2920 Deprecate ClientVersion#LOWER_THAN_SUPPORTED_VERSIONS
and ClientVersion#HIGHER_THAN_SUPPORTED_VERSIONS
2024-02-11 21:07:22 +01:00
Abhigya b5f6a7f6b8 Merge pull request #676 from AbhigyaKrishna/2.0
Fixed adventure version detection
2024-02-09 00:26:11 +05:30
AbhigyaKrishna f916addda3 Fixed adventure version detection 2024-02-09 00:22:47 +05:30
retrooper d275fb8d8b Merge pull request #669 from booky10/fix/breeze-poses
Add missing entity poses for 1.20.4
2024-02-08 00:15:41 +01:00
retrooper 3ce8971215 Little comment on EntityPoses for clarity when looked at in the future 2024-02-08 00:15:25 +01:00
retrooper 5866e4ede1 Merge pull request #674 from gabber235/2.0
Added WrapperPlayServerSetActionBarText
2024-02-08 00:06:22 +01:00
retrooper a47040e18a Spacing change 2024-02-08 00:06:03 +01:00
retrooper 631b41d9d0 Some changes to WrapperPlayServerActionBar
Unfortunately we need to name it WrapperPlayServerActionBar, so that it aligns with the packet type enum constant. I like that you tried to use wiki.vg/Protocol naming, but packetevents needs to be consistent in its naming.
2024-02-08 00:05:28 +01:00
Gabber235 8b9cf0c283 Add Set Action Bar Text Wrapper 2024-02-07 18:52:21 +01:00
retrooper e7afd771f8 Merge pull request #672 from AbhigyaKrishna/2.0
Updated AdventureSerializer for adventure 4.15.0
2024-02-06 22:01:34 +01:00
AbhigyaKrishna 98446b5afc Changed improper variable name 2024-02-07 01:25:25 +05:30
AbhigyaKrishna 0fbfca81a1 Updated AdventureSerializer for adventure 4.15.0 2024-02-06 23:54:38 +05:30
booky10 33f1eab93b Add missing entity poses for 1.20.4 2024-02-03 17:44:12 +01:00
retrooper 38fcccd7c9 Merge pull request #651 from cheaterSK/2.0
Fix packet encoding on Velocity
2024-02-02 21:57:43 +01:00
honkling 053768ccfa Request signatures from Mojang API 2024-02-01 21:10:59 -06:00
AoElite d11a0406cb Merge pull request #661 from joshuaprince/vibration-particle-entity-height
Read and write entity eye height in Vibration particle wrapper
2024-02-01 15:13:52 -05:00
AoElite 5966ca1355 Merge pull request #660 from booky10/fix/scoreboard-packets
Fix scoreboard objective packet
2024-02-01 15:13:12 -05:00
AoElite 72944a00c0 add max durability to netherite armor itemtypes 2024-02-01 14:55:53 -05:00
retrooper 671c935134 Merge pull request #665 from booky10/fix/adventure-v4.15
Fix gson component serialization for adventure v4.15
2024-01-23 23:12:23 +01:00
booky10 c931974779 Fix gson component serialization for adventure v4.15 2024-01-23 19:52:18 +01:00
Joshua Prince 5e6d0bffde Read and write entity eye height in Vibration particle wrapper
Fixes https://github.com/joshuaprince/CoordinateOffset/issues/9

Vibration particle data for vibrations emitted by entities contains
an "entity eye height" field. The ParticleVibrationData wrapper for
WrapperPlayServerParticle did not read or write this field, so any
usage of this wrapper would corrupt the packet and cause players to
be kicked when they moved near an entity that can receive vibrations
(i.e. Wardens).

Tested on 1.19.4 and 1.20.4. This field has been present and unchanged
since 1.19's changes to the Vibration particle (which is also the
first fully-released version to add Wardens):
https://wiki.vg/index.php?title=Data_types&oldid=17608#Particle
2024-01-22 23:19:28 -08:00
retrooper c08719acc7 Merge pull request #663 from booky10/fix/villager-levels
Fix VillagerLevel being invalid
2024-01-22 18:22:07 +01:00
booky10 e76b00c880 Fix VillagerLevel being invalid 2024-01-22 13:38:38 +01:00
cheaterSK b30d56ed0b Merge branch 'retrooper:2.0' into 2.0 2024-01-20 22:43:44 +01:00
booky10 211b85a51b Add missing constructor parameter for ScoreFormat in WrapperPlayServerScoreboardObjective 2024-01-20 19:02:31 +01:00
booky10 f895ff0e0a Fix missing version check for scoreboard objective 2024-01-20 19:01:27 +01:00
AoElite 6f0f6eaa24 Merge pull request #601 from mpc19/2.0
Updater updates
2024-01-18 22:24:32 -05:00
AoElite d6ee3b356e Merge pull request #657 from joshuaprince/sign-editor
Properly read isFrontText in sign edit wrappers
2024-01-18 22:20:22 -05:00
Joshua Prince 7b800a9015 Properly read isFrontText in sign edit wrappers
Fixes https://github.com/retrooper/packetevents/issues/656

WrapperPlayServerOpenSignEditor and WrapperPlayClientUpdateSign
break editing the back of signs by simply calling the wrapper. The
initializers for these isFrontText fields to "true" ran AFTER the
wrappers' superclass constructor, which means that the initializers
would overwrite the value set by the "read" method.
2024-01-16 23:48:56 -08:00
BlueTree242 ba0feb31f0 Assume protocol versions below lowest supported versions 1.7.2, and above highest supported version to be 1.20.4 2024-01-15 09:56:29 +02:00
AoElite 36b73752f7 Merge pull request #649 from SamB440/fix/pack-send-prompt
Fix WrapperPlayServerResourcePackSend in 1.16
2024-01-14 15:23:22 -05:00
cheaterSK 6f0586ce23 Fix memory leak 2024-01-13 15:28:46 +01:00
cheaterSK 59159d47a0 Fix packet encoding on Velocity 2024-01-13 13:36:35 +01:00
retrooper 23c0fc9bff PacketWrapper#prepareForSend including proxy parameter created. 2024-01-12 23:05:12 +01:00
retrooper c34690197d Merge pull request #647 from Tofaa2/2.0
Implement misc missing protocol objects into packet events
2024-01-12 22:47:51 +01:00
TofaaandJulian c98425cb99 Update api/src/main/java/com/github/retrooper/packetevents/protocol/entity/villager/VillagerData.java
Co-authored-by: Julian <53055251+NoJokeFNA@users.noreply.github.com>
2024-01-11 13:03:09 +03:00
TofaaandJulian 55f4280ccb Update api/src/main/java/com/github/retrooper/packetevents/protocol/entity/villager/VillagerData.java
Co-authored-by: Julian <53055251+NoJokeFNA@users.noreply.github.com>
2024-01-11 13:01:36 +03:00
TofaaandJulian b9299dfa96 Update api/src/main/java/com/github/retrooper/packetevents/protocol/entity/villager/level/VillagerLevel.java
Co-authored-by: Julian <53055251+NoJokeFNA@users.noreply.github.com>
2024-01-11 13:01:23 +03:00
TofaaandJulian b1fb30163c Update api/src/main/java/com/github/retrooper/packetevents/protocol/world/Rotation.java
Co-authored-by: Julian <53055251+NoJokeFNA@users.noreply.github.com>
2024-01-11 13:01:18 +03:00
Tofaa 50b8776aa9 fix retrooper nitpick 2024-01-11 13:01:48 +03:00
Tofaa d47b450307 Add copyright headers 2024-01-09 05:32:58 +03:00
SamB440 1f41447a02 Fix WrapperPlayServerResourcePackSend in 1.16 2024-01-07 14:40:30 +00:00
Tofaa a306ac26b9 add constructors to support the Color api 2024-01-06 03:24:32 +03:00
Tofaa df6a334a00 implement color api 2024-01-06 03:20:32 +03:00
Tofaa c43ea28f59 Create Rotation.java 2024-01-06 03:19:45 +03:00
Tofaa 596f1b57ce add villager level api 2024-01-06 03:15:44 +03:00
retrooper 386238aae8 Fix Vector3i#subtract 2024-01-05 12:00:31 +01:00
retrooper e7dcb4c96e Merge pull request #643 from booky10/fix/scoreboard-wrappers
Fix scoreboard wrappers for 1.20.3/1.20.4
2024-01-04 12:09:32 +01:00
retrooper 6049e37d87 Minor change to ScoreFormatType 2024-01-04 12:09:07 +01:00
booky10 a41e747da7 Fix objective name and score owner character limitation
Was removed by mojang in 1.18
2024-01-03 22:47:14 +01:00
booky10 c4c61dff3c Fix issues noticed while testing 2024-01-03 22:35:12 +01:00
booky10 84b85c8f00 Fix WrapperPlayServerScoreboardObjective and WrapperPlayServerUpdateScore on 1.20.3/1.20.4 2024-01-03 21:32:02 +01:00
AoElite f9b3786c16 fix exception if lvl nbt is missing from enchanted items 2024-01-03 13:46:14 -05:00
retrooper d2350ad383 Update README.md 2024-01-01 11:52:02 +01:00
MWHunter f6c554da02 fix reflection after paper update 2023-12-31 09:57:39 -06:00
AoElite 7ff8c40402 add equals & hashcode to statetype 2023-12-27 17:48:05 -05:00
retrooper df6d7fa741 Fix npc's not spawning on modern versions 2023-12-26 10:16:49 +01:00
retrooper 3a5aa401f0 Merge pull request #634 from SamB440/fix/test-ci
v2: Fix tests for actions, bump gradle wrapper
2023-12-22 18:08:30 +01:00
SamB440 9c5263bf20 v2: Fix tests for actions, bump gradle wrapper 2023-12-22 15:00:13 +00:00
retrooper 838426e1bf Merge pull request #633 from retrooper/revert-629-fix/test-ci
Revert "Fix tests for actions, bump gradle wrapper"
2023-12-21 18:49:21 +01:00
retrooper d486863a64 Revert "Fix tests for actions, bump gradle wrapper" 2023-12-21 18:48:08 +01:00
retrooper cd98e8488b Merge pull request #629 from SamB440/fix/test-ci
Fix tests for actions, bump gradle wrapper
2023-12-21 18:44:34 +01:00
retrooper a7c6f88a11 Merge pull request #630 from SamB440/feat/better-tests
Fix ItemTags, improve testing
2023-12-21 18:44:10 +01:00
retrooper c15b88e77f Merge pull request #632 from booky10/fix/bits-overflow-global-palette
Fix bits overflowing when using global palette with bit storage
2023-12-21 18:42:59 +01:00
booky10 1a2d39d68f Fix bits overflowing when using global palette with bit storage 2023-12-21 01:53:11 +01:00
SamB440 fe8ca640cc Test ItemTags like BlockTags, add dummy API instance in tests, fix REPLACEABLE_PLANTS 2023-12-20 14:34:29 +00:00
SamB440 e8bdd02838 Gradle 8.5 2023-12-19 18:26:20 +00:00
SamB440 b962876dfd Use build task instead of shadowJar to support tests 2023-12-19 18:21:34 +00:00
retrooper f0135204e3 Merge pull request #626 from SamB440/fix/twenty-three-tags-2
Ensure order of block tags is correct
2023-12-15 22:35:08 +01:00
SamB440 5bedb44e11 Ensure order of block tags is correct 2023-12-15 21:24:46 +00:00
retrooper 4e3ada1bd8 Merge pull request #625 from SamB440/fix/twenty-three-tags
Fix 1.20.3/4 experimental block and item tags
2023-12-15 21:55:41 +01:00
SamB440 38d68418dc Fix 1.20.3/4 experimental block and item tags 2023-12-14 14:49:35 +00:00
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
mpc19 aaf00bf167 Updater Update | Part 2 2023-08-05 12:25:28 +01:00
mpc19 d72c8df72c Updating the Updater
- Reduced amount of times it checks for update
- Remove error trace logs from console to prevent spam if it can't connect to github (firewalls, offline, etc)
- Removed random bracket in a message while making another follow the standard format used in previous messages.
- Replace some system print methods with LogManager methods
2023-08-04 23:37:16 +01:00
112 changed files with 34117 additions and 670 deletions

No files matched your search

+3 -3
View File
@@ -13,16 +13,16 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up JDK 8
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '17'
distribution: 'adopt'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Gradle
run: chmod +x gradlew && ./gradlew shadowJar
run: chmod +x gradlew && ./gradlew build
- name: Upload build artifacts api
uses: actions/upload-artifact@v3
+3
View File
@@ -13,6 +13,9 @@ our [Discord Server](https://discord.me/packetevents) for help.
### Setup
[How to Setup PacketEvents](https://github.com/retrooper/packetevents/wiki/Depending-on-pre%E2%80%90built-PacketEvents)
### Examples / How to use PacketEvents
[Example repository](https://github.com/retrooper/packetevents-example)
### Sponsorships
[![](https://www.ej-technologies.com/images/product_banners/jprofiler_small.png)](https://www.ej-technologies.com/products/jprofiler/overview.html)
+20
View File
@@ -1,3 +1,23 @@
// papermc repo + disableAutoTargetJvm needed for mockbukkit
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
java {
disableAutoTargetJvm()
}
dependencies {
compileOnly(adventureDependencies)
testImplementation(adventureDependencies)
testImplementation(project(":netty-common"))
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.9.0")
testImplementation("org.slf4j:slf4j-simple:2.0.7")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
}
test {
useJUnitPlatform()
}
@@ -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, 1);
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() {
@@ -0,0 +1,73 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.color;
import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
public final class Color implements RGBLike {
private static final int BIT_MASK = 0xFF;
private final int red, green, blue;
public Color(@Range(from = 0L, to = 255L) int red, @Range(from = 0L, to = 255L) int green, @Range(from = 0L, to = 255L) int blue) {
this.red = red;
this.green = green;
this.blue = blue;
}
public Color(int rgb) {
this((rgb >> 16) & BIT_MASK, (rgb >> 8) & BIT_MASK, rgb & BIT_MASK);
}
public @NotNull Color withRed(@Range(from = 0L, to = 255L) int red) {
return new Color(red, green, blue);
}
public @NotNull Color withGreen(@Range(from = 0L, to = 255L) int green) {
return new Color(red, green, blue);
}
public @NotNull Color withBlue(@Range(from = 0L, to = 255L) int blue) {
return new Color(red, green, blue);
}
public int asRGB() {
int rgb = red;
rgb = (rgb << 8) + green;
return (rgb << 8) + blue;
}
@Override
public @Range(from = 0L, to = 255L) int red() {
return red;
}
@Override
public @Range(from = 0L, to = 255L) int green() {
return green;
}
@Override
public @Range(from = 0L, to = 255L) int blue() {
return blue;
}
}
@@ -0,0 +1,103 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.color;
import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull;
public enum DyeColor implements RGBLike {
WHITE(new Color(0xf9fffe), new Color(0xffffff), new Color(0xf0f0f0), 8),
ORANGE(new Color(0xf9801d), new Color(0xff681f), new Color(0xeb8844), 15),
MAGENTA(new Color(0xc74ebd), new Color(0xff00ff), new Color(0xc354cd), 16),
LIGHT_BLUE(new Color(0x3ab3da), new Color(0x9ac0cd), new Color(0x6689d3), 17),
YELLOW(new Color(0xfed83d), new Color(0xffff00), new Color(0xdecf2a), 18),
LIME(new Color(0x80c71f), new Color(0xbfff00), new Color(0x41cd34), 19),
PINK(new Color(0xf38baa), new Color(0xff69b4), new Color(0xd88198), 20),
GRAY(new Color(0x474f52), new Color(0x808080), new Color(0x434343), 21),
LIGHT_GRAY(new Color(0x9d9d97), new Color(0xd3d3d3), new Color(0xababab), 22),
CYAN(new Color(0x169c9c), new Color(0xffff), new Color(0x287697), 23),
PURPLE(new Color(0x8932b8), new Color(0xa020f0), new Color(0x7b2fbe), 24),
BLUE(new Color(0x3c44aa), new Color(0xff), new Color(0x253192), 25),
BROWN(new Color(0x835432), new Color(0x8b4513), new Color(0x51301a), 26),
GREEN(new Color(0x5e7c16), new Color(0xff00), new Color(0x3b511a), 27),
RED(new Color(0xb02e26), new Color(0xff0000), new Color(0xb3312c), 28),
BLACK(new Color(0x1d1d21), new Color(0x0), new Color(0x1e1b1b), 29);
private final Color textureDiffuseColor;
private final Color textColor;
private final Color fireworkColor;
private final int mapColorId;
DyeColor(@NotNull Color textureDiffuseColor, @NotNull Color textColor,
@NotNull Color fireworkColor, int mapColorId) {
this.textureDiffuseColor = textureDiffuseColor;
this.textColor = textColor;
this.fireworkColor = fireworkColor;
this.mapColorId = mapColorId;
}
public @NotNull Color color() {
return this.textureDiffuseColor;
}
public @NotNull Color textColor() {
return this.textColor;
}
public @NotNull Color fireworkColor() {
return this.fireworkColor;
}
@Override
public int red() {
return this.textureDiffuseColor.red();
}
@Override
public int green() {
return this.textureDiffuseColor.green();
}
@Override
public int blue() {
return this.textureDiffuseColor.blue();
}
public int mapColorId() {
return this.mapColorId;
}
}
@@ -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());
}
}
@@ -35,7 +35,11 @@ public enum EntityPose {
ROARING,
SNIFFING,
EMERGING,
DIGGING;
DIGGING,
//Added in 1.20.4
SLIDING,
SHOOTING,
INHALING;
public int getId(ClientVersion version) {
if (this == DYING && version.isOlderThan(ClientVersion.V_1_17)) {
@@ -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);
}
@@ -18,16 +18,23 @@
package com.github.retrooper.packetevents.protocol.entity.villager;
import com.github.retrooper.packetevents.protocol.entity.villager.level.VillagerLevel;
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfession;
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions;
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerType;
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
import org.jetbrains.annotations.Nullable;
public class VillagerData {
private VillagerType type;
private VillagerProfession profession;
private int level;
public VillagerData(VillagerType type, VillagerProfession profession, VillagerLevel level) {
this(type, profession, level.getId());
}
public VillagerData(VillagerType type, VillagerProfession profession, int level) {
this.type = type;
this.profession = profession;
@@ -55,10 +62,18 @@ public class VillagerData {
}
public int getLevel() {
return level;
return this.level;
}
public @Nullable VillagerLevel getVillagerLevel() {
return VillagerLevel.getById(this.level);
}
public void setLevel(int level) {
this.level = level;
}
public void setLevel(VillagerLevel level) {
this.level = level.getId();
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.entity.villager.level;
import org.jetbrains.annotations.Nullable;
public enum VillagerLevel {
NOVICE,
APPRENTICE,
JOURNEYMAN,
EXPERT,
MASTER;
private static final VillagerLevel[] VALUES = values();
public static @Nullable VillagerLevel getById(int id) {
if (id >= 1 && id <= VALUES.length) {
return VALUES[id - 1];
}
return null;
}
public int getId() {
return this.ordinal() + 1;
}
}
@@ -50,7 +50,6 @@ public class VillagerProfessions {
return VILLAGER_PROFESSION_ID_MAP.get((byte)id);
}
public static VillagerProfession getByName(String name) {
return VILLAGER_PROFESSION_MAP.get(name);
}
@@ -192,7 +192,9 @@ public class ItemStack {
for (NBTCompound base : nbt.getCompoundListTagOrNull(tagName).getTags()) {
EnchantmentType type = getEnchantmentTypeFromTag(base, version);
if (enchantment == type) {
return base.getTagOfTypeOrNull("lvl", NBTShort.class).getAsInt();
NBTShort nbtShort = base.getTagOfTypeOrNull("lvl", NBTShort.class);
if (nbtShort == null) return 0; // this might need to be set to 1
return nbtShort.getAsInt();
}
}
}
@@ -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();
@@ -122,7 +130,7 @@ public class ItemTypes {
public static final ItemType STRIPPED_OAK_LOG = builder("stripped_oak_log").setMaxAmount(64).setAttributes(ItemAttribute.FUEL).setPlacedType(StateTypes.STRIPPED_OAK_LOG).build();
public static final ItemType LIGHT_GRAY_CONCRETE_POWDER = builder("light_gray_concrete_powder").setMaxAmount(64).setPlacedType(StateTypes.LIGHT_GRAY_CONCRETE_POWDER).build();
public static final ItemType COOKED_PORKCHOP = builder("cooked_porkchop").setMaxAmount(64).setAttributes(ItemAttribute.EDIBLE).build();
public static final ItemType NETHERITE_HELMET = builder("netherite_helmet").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).build();
public static final ItemType NETHERITE_HELMET = builder("netherite_helmet").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).setMaxDurability(407).build();
public static final ItemType BLACK_CANDLE = builder("black_candle").setMaxAmount(64).setPlacedType(StateTypes.BLACK_CANDLE).build();
public static final ItemType CYAN_CONCRETE_POWDER = builder("cyan_concrete_powder").setMaxAmount(64).setPlacedType(StateTypes.CYAN_CONCRETE_POWDER).build();
public static final ItemType SADDLE = builder("saddle").setMaxAmount(1).build();
@@ -565,7 +573,7 @@ public class ItemTypes {
public static final ItemType GREEN_GLAZED_TERRACOTTA = builder("green_glazed_terracotta").setMaxAmount(64).setPlacedType(StateTypes.GREEN_GLAZED_TERRACOTTA).build();
public static final ItemType SCUTE = builder("scute").setMaxAmount(64).build();
public static final ItemType GOLDEN_CHESTPLATE = builder("golden_chestplate").setMaxAmount(1).setMaxDurability(112).build();
public static final ItemType NETHERITE_LEGGINGS = builder("netherite_leggings").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).build();
public static final ItemType NETHERITE_LEGGINGS = builder("netherite_leggings").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).setMaxDurability(555).build();
public static final ItemType GOLDEN_SHOVEL = builder("golden_shovel").setMaxAmount(1).setAttributes(ItemAttribute.SHOVEL, ItemAttribute.GOLD_TIER).setMaxDurability(32).build();
public static final ItemType SPRUCE_STAIRS = builder("spruce_stairs").setMaxAmount(64).setAttributes(ItemAttribute.FUEL).setPlacedType(StateTypes.SPRUCE_STAIRS).build();
public static final ItemType BIRCH_PLANKS = builder("birch_planks").setMaxAmount(64).setAttributes(ItemAttribute.FUEL).setPlacedType(StateTypes.BIRCH_PLANKS).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();
@@ -776,7 +788,7 @@ public class ItemTypes {
public static final ItemType MOOSHROOM_SPAWN_EGG = builder("mooshroom_spawn_egg").setMaxAmount(64).build();
public static final ItemType MAP = builder("map").setMaxAmount(64).build();
public static final ItemType DARK_OAK_SIGN = builder("dark_oak_sign").setMaxAmount(16).setAttributes(ItemAttribute.FUEL).setPlacedType(StateTypes.DARK_OAK_SIGN).build();
public static final ItemType NETHERITE_BOOTS = builder("netherite_boots").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).build();
public static final ItemType NETHERITE_BOOTS = builder("netherite_boots").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).setMaxDurability(481).build();
public static final ItemType BREAD = builder("bread").setMaxAmount(64).setAttributes(ItemAttribute.EDIBLE).build();
public static final ItemType DEEPSLATE_TILE_SLAB = builder("deepslate_tile_slab").setMaxAmount(64).setPlacedType(StateTypes.DEEPSLATE_TILE_SLAB).build();
public static final ItemType POLISHED_BLACKSTONE_BUTTON = builder("polished_blackstone_button").setMaxAmount(64).setPlacedType(StateTypes.POLISHED_BLACKSTONE_BUTTON).build();
@@ -859,7 +871,7 @@ public class ItemTypes {
public static final ItemType YELLOW_DYE = builder("yellow_dye").setMaxAmount(64).build();
public static final ItemType CYAN_STAINED_GLASS = builder("cyan_stained_glass").setMaxAmount(64).setPlacedType(StateTypes.CYAN_STAINED_GLASS).build();
public static final ItemType BRICKS = builder("bricks").setMaxAmount(64).setPlacedType(StateTypes.BRICKS).build();
public static final ItemType NETHERITE_CHESTPLATE = builder("netherite_chestplate").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).build();
public static final ItemType NETHERITE_CHESTPLATE = builder("netherite_chestplate").setMaxAmount(1).setAttributes(ItemAttribute.FIRE_RESISTANT).setMaxDurability(592).build();
public static final ItemType ORANGE_BED = builder("orange_bed").setMaxAmount(1).setPlacedType(StateTypes.ORANGE_BED).build();
public static final ItemType PETRIFIED_OAK_SLAB = builder("petrified_oak_slab").setMaxAmount(64).setPlacedType(StateTypes.PETRIFIED_OAK_SLAB).build();
public static final ItemType SALMON_SPAWN_EGG = builder("salmon_spawn_egg").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) {
@@ -20,6 +20,7 @@ package com.github.retrooper.packetevents.protocol.npc;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.player.*;
import com.github.retrooper.packetevents.protocol.world.Location;
@@ -86,10 +87,17 @@ public class NPC {
PacketEvents.getAPI().getProtocolManager().sendPacket(channel, playerInfo);
//TODO Later if we want entity metadata, its not supported on newer server versions though(confirm if its mandatory on older versions)
WrapperPlayServerSpawnPlayer spawnPlayer = new WrapperPlayServerSpawnPlayer(getId(),
getProfile().getUUID(),
getLocation());
PacketEvents.getAPI().getProtocolManager().sendPacket(channel, spawnPlayer);
PacketWrapper<?> spawnPacket;
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_20_2)) {
spawnPacket = new WrapperPlayServerSpawnEntity(getId(), getProfile().getUUID(), EntityTypes.PLAYER, getLocation(), getLocation().getYaw(), 0, null);
}
else {
spawnPacket = new WrapperPlayServerSpawnPlayer(getId(),
getProfile().getUUID(),
getLocation());
}
PacketEvents.getAPI().getProtocolManager().sendPacket(channel, spawnPacket);
//Create team
if (getNameColor() != null || getPrefixName() != 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,7 @@
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
@@ -51,6 +52,10 @@ public class ParticleDustColorTransitionData extends ParticleData {
this(scale, startRGB.getX(), startRGB.getY(), startRGB.getZ(), endRGB.getX(), endRGB.getY(), endRGB.getZ());
}
public ParticleDustColorTransitionData(float scale, Color start, Color end) {
this(scale, start.red(), start.green(), start.blue(), end.red(), end.green(), end.blue());
}
public float getScale() {
return scale;
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
@@ -41,6 +42,10 @@ public class ParticleDustData extends ParticleData {
this(scale, rgb.getX(), rgb.getY(), rgb.getZ());
}
public ParticleDustData(float scale, Color color) {
this(scale, color.red(), color.green(), color.blue());
}
public float getRed() {
return red;
}
@@ -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,33 +29,58 @@ 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;
private @Nullable Float entityEyeHeight; // Added in 1.19
private int ticks;
public ParticleVibrationData(Vector3i startingPosition, @Nullable Vector3i blockPosition, int ticks) {
@@ -67,6 +96,16 @@ public class ParticleVibrationData extends ParticleData {
this.type = PositionType.ENTITY;
this.blockPosition = null;
this.entityId = entityId;
this.entityEyeHeight = null;
this.ticks = ticks;
}
public ParticleVibrationData(Vector3i startingPosition, int entityId, float entityEyeHeight, int ticks) {
this.startingPosition = startingPosition;
this.type = PositionType.ENTITY;
this.blockPosition = null;
this.entityId = entityId;
this.entityEyeHeight = entityEyeHeight;
this.ticks = ticks;
}
@@ -98,6 +137,14 @@ public class ParticleVibrationData extends ParticleData {
this.entityId = entityId;
}
public Optional<Float> getEntityEyeHeight() {
return Optional.ofNullable(entityEyeHeight);
}
public void setEntityEyeHeight(@Nullable Float entityEyeHeight) {
this.entityEyeHeight = entityEyeHeight;
}
public int getTicks() {
return ticks;
}
@@ -107,29 +154,53 @@ 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:
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_19)) {
return new ParticleVibrationData(startingPos, wrapper.readVarInt(),
wrapper.readFloat(), wrapper.readVarInt());
} else {
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());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_19)) {
wrapper.writeFloat(data.getEntityEyeHeight().orElse(0f));
}
}
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,17 @@ 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
@Deprecated
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),
@Deprecated
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_20_3.protocolVersion + 1, true),
UNKNOWN(-1, true);
@@ -159,15 +165,14 @@ public enum ClientVersion {
@NotNull
public static ClientVersion getById(int protocolVersion) {
if (protocolVersion < LOWEST_SUPPORTED_PROTOCOL_VERSION) {
return LOWER_THAN_SUPPORTED_VERSIONS;
return V_1_7_10;
} else if (protocolVersion > HIGHEST_SUPPORTED_PROTOCOL_VERSION) {
return HIGHER_THAN_SUPPORTED_VERSIONS;
return V_1_20_3;
} else {
for (ClientVersion version : VALUES) {
if (version.protocolVersion > protocolVersion) {
break;
} else if (version.protocolVersion == protocolVersion) {
//Cache for next time
return version;
}
}
@@ -0,0 +1,39 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import net.kyori.adventure.text.Component;
public final class BlankScoreFormat implements ScoreFormat {
public static final BlankScoreFormat INSTANCE = new BlankScoreFormat();
private BlankScoreFormat() {
}
@Override
public Component format(int score) {
return Component.empty();
}
@Override
public ScoreFormatType getType() {
return ScoreFormatTypes.BLANK;
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import net.kyori.adventure.text.Component;
public final class FixedScoreFormat implements ScoreFormat {
private final Component value;
public FixedScoreFormat(Component value) {
this.value = value;
}
@Override
public ScoreFormatType getType() {
return ScoreFormatTypes.FIXED;
}
@Override
public Component format(int score) {
return this.value;
}
public Component getValue() {
return this.value;
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.NonExtendable
public interface ScoreFormat {
static BlankScoreFormat blankScore() {
return BlankScoreFormat.INSTANCE;
}
static StyledScoreFormat styledScore(Style style) {
return new StyledScoreFormat(style);
}
static FixedScoreFormat fixedScore(Component value) {
return new FixedScoreFormat(value);
}
Component format(int score);
ScoreFormatType getType();
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import com.github.retrooper.packetevents.protocol.mapper.StaticMappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface ScoreFormatType extends StaticMappedEntity {
ScoreFormat read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, ScoreFormat format);
}
@@ -0,0 +1,106 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
public final class ScoreFormatTypes {
private static final Map<String, ScoreFormatType> SCORE_FORMAT_TYPE_MAP = new HashMap<>();
private static final Map<Byte, ScoreFormatType> SCORE_FORMAT_TYPE_ID_MAP = new HashMap<>();
public static final ScoreFormatType BLANK = define(0, "blank", BlankScoreFormat.class,
wrapper -> ScoreFormat.blankScore(),
(wrapper, format) -> { /**/ });
public static final ScoreFormatType STYLED = define(1, "styled", StyledScoreFormat.class,
wrapper -> ScoreFormat.styledScore(wrapper.readStyle()),
(wrapper, format) -> wrapper.writeStyle(format.getStyle()));
public static final ScoreFormatType FIXED = define(2, "fixed", FixedScoreFormat.class,
wrapper -> ScoreFormat.fixedScore(wrapper.readComponent()),
(wrapper, format) -> wrapper.writeComponent(format.getValue()));
private ScoreFormatTypes() {
}
public static ScoreFormat read(PacketWrapper<?> wrapper) {
int formatTypeId = wrapper.readVarInt();
ScoreFormatType formatType = getById(wrapper.getServerVersion().toClientVersion(), formatTypeId);
if (formatType == null) {
throw new NullPointerException("Can't resolve format type " + formatTypeId);
}
return formatType.read(wrapper);
}
public static void write(PacketWrapper<?> wrapper, ScoreFormat format) {
int formatTypeId = format.getType().getId(wrapper.getServerVersion().toClientVersion());
wrapper.writeVarInt(formatTypeId);
format.getType().write(wrapper, format);
}
public static <T extends ScoreFormat> ScoreFormatType define(int id, String name,
Class<T> formatClass,
Function<PacketWrapper<?>, T> reader,
BiConsumer<PacketWrapper<?>, T> writer) {
ResourceLocation location = new ResourceLocation(name);
ScoreFormatType type = new ScoreFormatType() {
@Override
public ScoreFormat read(PacketWrapper<?> wrapper) {
return reader.apply(wrapper);
}
@Override
public void write(PacketWrapper<?> wrapper, ScoreFormat format) {
writer.accept(wrapper, formatClass.cast(format));
}
@Override
public ResourceLocation getName() {
return location;
}
@Override
public int getId() {
return id;
}
};
SCORE_FORMAT_TYPE_MAP.put(location.toString(), type);
SCORE_FORMAT_TYPE_ID_MAP.put((byte) id, type);
return type;
}
public static @Nullable ScoreFormatType getById(ClientVersion version, int id) {
return SCORE_FORMAT_TYPE_ID_MAP.get((byte) id);
}
public static @Nullable ScoreFormatType getByName(String name) {
return getByName(new ResourceLocation(name));
}
public static @Nullable ScoreFormatType getByName(ResourceLocation name) {
return SCORE_FORMAT_TYPE_MAP.get(name.toString());
}
}
@@ -0,0 +1,48 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.score;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
public final class StyledScoreFormat implements ScoreFormat {
private final Style style;
public StyledScoreFormat(Style style) {
this.style = style;
}
@Override
public Component format(int score) {
return Component.text()
.content(Integer.toString(score))
.style(this.style)
.build();
}
@Override
public ScoreFormatType getType() {
return ScoreFormatTypes.STYLED;
}
public Style getStyle() {
return this.style;
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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;
public enum Rotation {
/**
* No rotation
*/
NONE,
/**
* Rotated clockwise by 45 degrees
*/
CLOCKWISE_45,
/**
* Rotated clockwise by 90 degrees
*/
CLOCKWISE,
/**
* Rotated clockwise by 135 degrees
*/
CLOCKWISE_135,
/**
* Flipped upside-down, a 180-degree rotation
*/
FLIPPED,
/**
* Flipped upside-down + 45-degree rotation
*/
FLIPPED_45,
/**
* Rotated counter-clockwise by 90 degrees
*/
COUNTER_CLOCKWISE,
/**
* Rotated counter-clockwise by 45 degrees
*/
COUNTER_CLOCKWISE_45;
}
@@ -27,7 +27,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DataPalette {
public static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 14;
// this is the amount of bits required to store the biggest state id number
public static final int GLOBAL_PALETTE_BITS_PER_ENTRY = 15;
public @NotNull Palette palette;
public BaseStorage storage;
@@ -187,4 +189,4 @@ public class DataPalette {
private static int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
}
}
@@ -107,6 +107,10 @@ public class BitStorage extends BaseStorage {
@Override
public int get(int index) {
if (index < 0 || index > this.size - 1L) {
throw new IllegalStateException("Illegal index: " + index + " < 0 || " + index + " > " + this.size + " - 1");
}
int cellIndex = cellIndex(index);
int bitIndex = bitIndex(index, cellIndex);
return (int) (this.data[cellIndex] >> bitIndex & this.maxValue);
@@ -114,6 +118,13 @@ public class BitStorage extends BaseStorage {
@Override
public void set(int index, int value) {
if (index < 0 || index > this.size - 1L) {
throw new IllegalStateException("Illegal index: " + index + " < 0 || " + index + " > " + this.size + " - 1");
}
if (value < 0 || value > this.maxValue) {
throw new IllegalStateException("Illegal value: " + value + " < 0 || " + value + " > " + this.maxValue);
}
int cellIndex = cellIndex(index);
int bitIndex = bitIndex(index, cellIndex);
this.data[cellIndex] = this.data[cellIndex] & ~(this.maxValue << bitIndex) | ((long) value & this.maxValue) << bitIndex;
@@ -79,7 +79,7 @@ public class WrappedBlockState {
this.data.put(value, value.getParser().apply(split[1].toUpperCase(Locale.ROOT)));
} catch (Exception e) {
e.printStackTrace();
System.out.println("Failed to parse block state: " + s);
PacketEvents.getAPI().getLogManager().warn("Failed to parse block state: " + s);
}
}
}
@@ -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");
@@ -223,168 +228,169 @@ public class BlockTags {
BlockTags.STONE_BUTTONS.add(StateTypes.STONE_BUTTON, StateTypes.POLISHED_BLACKSTONE_BUTTON);
BlockTags.BUTTONS.addTag(BlockTags.WOODEN_BUTTONS).addTag(BlockTags.STONE_BUTTONS);
BlockTags.WOOL_CARPETS.add(StateTypes.WHITE_CARPET, StateTypes.ORANGE_CARPET, StateTypes.MAGENTA_CARPET, StateTypes.LIGHT_BLUE_CARPET, StateTypes.YELLOW_CARPET, StateTypes.LIME_CARPET, StateTypes.PINK_CARPET, StateTypes.GRAY_CARPET, StateTypes.LIGHT_GRAY_CARPET, StateTypes.CYAN_CARPET, StateTypes.PURPLE_CARPET, StateTypes.BLUE_CARPET, StateTypes.BROWN_CARPET, StateTypes.GREEN_CARPET, StateTypes.RED_CARPET, StateTypes.BLACK_CARPET);
BlockTags.WOODEN_DOORS.add(StateTypes.OAK_DOOR, StateTypes.SPRUCE_DOOR, StateTypes.BIRCH_DOOR, StateTypes.JUNGLE_DOOR, StateTypes.ACACIA_DOOR, StateTypes.DARK_OAK_DOOR, StateTypes.CRIMSON_DOOR, StateTypes.WARPED_DOOR, StateTypes.MANGROVE_DOOR, StateTypes.BAMBOO_DOOR, StateTypes.CHERRY_DOOR);
BlockTags.WOODEN_DOORS.add(StateTypes.OAK_DOOR, StateTypes.SPRUCE_DOOR, StateTypes.BIRCH_DOOR, StateTypes.JUNGLE_DOOR, StateTypes.ACACIA_DOOR, StateTypes.DARK_OAK_DOOR, StateTypes.CRIMSON_DOOR, StateTypes.WARPED_DOOR, StateTypes.MANGROVE_DOOR, StateTypes.BAMBOO_DOOR, StateTypes.CHERRY_DOOR, StateTypes.COPPER_DOOR, StateTypes.EXPOSED_COPPER_DOOR, StateTypes.WEATHERED_COPPER_DOOR, StateTypes.OXIDIZED_COPPER_DOOR, StateTypes.WAXED_COPPER_DOOR, StateTypes.WAXED_EXPOSED_COPPER_DOOR, StateTypes.WAXED_WEATHERED_COPPER_DOOR, StateTypes.WAXED_OXIDIZED_COPPER_DOOR);
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.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.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.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.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_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.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.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.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.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, StateTypes.TUFF_STAIRS, StateTypes.POLISHED_TUFF_STAIRS, StateTypes.TUFF_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, StateTypes.TUFF_SLAB, StateTypes.POLISHED_TUFF_SLAB, StateTypes.TUFF_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, StateTypes.TUFF_WALL, StateTypes.POLISHED_TUFF_WALL, StateTypes.TUFF_BRICK_WALL);
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.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.TRAPDOORS.addTag(BlockTags.WOODEN_TRAPDOORS).add(StateTypes.IRON_TRAPDOOR, StateTypes.COPPER_TRAPDOOR, StateTypes.EXPOSED_COPPER_TRAPDOOR, StateTypes.WEATHERED_COPPER_TRAPDOOR, StateTypes.OXIDIZED_COPPER_TRAPDOOR, StateTypes.WAXED_COPPER_TRAPDOOR, StateTypes.WAXED_EXPOSED_COPPER_TRAPDOOR, StateTypes.WAXED_WEATHERED_COPPER_TRAPDOOR, StateTypes.WAXED_OXIDIZED_COPPER_TRAPDOOR);
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.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.UNDERWATER_BONEMEALS.addTag(BlockTags.CORALS).addTag(BlockTags.WALL_CORALS).add(StateTypes.SEAGRASS);
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.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.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.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.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.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, StateTypes.CRAFTER, StateTypes.CHISELED_COPPER, StateTypes.EXPOSED_CHISELED_COPPER, StateTypes.WEATHERED_CHISELED_COPPER, StateTypes.OXIDIZED_CHISELED_COPPER, StateTypes.WAXED_CHISELED_COPPER, StateTypes.WAXED_EXPOSED_CHISELED_COPPER, StateTypes.WAXED_WEATHERED_CHISELED_COPPER, StateTypes.WAXED_OXIDIZED_CHISELED_COPPER, StateTypes.COPPER_GRATE, StateTypes.EXPOSED_COPPER_GRATE, StateTypes.WEATHERED_COPPER_GRATE, StateTypes.OXIDIZED_COPPER_GRATE, StateTypes.WAXED_COPPER_GRATE, StateTypes.WAXED_EXPOSED_COPPER_GRATE, StateTypes.WAXED_WEATHERED_COPPER_GRATE, StateTypes.WAXED_OXIDIZED_COPPER_GRATE, StateTypes.COPPER_BULB, StateTypes.EXPOSED_COPPER_BULB, StateTypes.WEATHERED_COPPER_BULB, StateTypes.OXIDIZED_COPPER_BULB, StateTypes.WAXED_COPPER_BULB, StateTypes.WAXED_EXPOSED_COPPER_BULB, StateTypes.WAXED_WEATHERED_COPPER_BULB, StateTypes.WAXED_OXIDIZED_COPPER_BULB, StateTypes.COPPER_TRAPDOOR, StateTypes.EXPOSED_COPPER_TRAPDOOR, StateTypes.WEATHERED_COPPER_TRAPDOOR, StateTypes.OXIDIZED_COPPER_TRAPDOOR, StateTypes.WAXED_COPPER_TRAPDOOR, StateTypes.WAXED_EXPOSED_COPPER_TRAPDOOR, StateTypes.WAXED_WEATHERED_COPPER_TRAPDOOR, StateTypes.WAXED_OXIDIZED_COPPER_TRAPDOOR);
BlockTags.FEATURES_CANNOT_REPLACE.add(StateTypes.BEDROCK, StateTypes.SPAWNER, StateTypes.CHEST, StateTypes.END_PORTAL_FRAME, StateTypes.REINFORCED_DEEPSLATE, StateTypes.TRIAL_SPAWNER);
BlockTags.LAVA_POOL_STONE_CANNOT_REPLACE.addTag(BlockTags.FEATURES_CANNOT_REPLACE).addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS).addTag(BlockTags.FEATURES_CANNOT_REPLACE);
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.REPLACEABLE_PLANTS.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);
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);
@@ -411,6 +417,9 @@ public class BlockTags {
}
private BlockTags addTag(BlockTags tags) {
if (tags.states.isEmpty()) {
throw new IllegalArgumentException("Tag " + tags.name + " is empty when adding to " + this.name + ", you (packetevents updater) probably messed up the block tags order!!");
}
this.states.addAll(tags.states);
return this;
}
@@ -136,48 +136,41 @@ public class ItemTags {
copy(BlockTags.STONE_BRICKS, ItemTags.STONE_BRICKS);
copy(BlockTags.WOODEN_BUTTONS, ItemTags.WOODEN_BUTTONS);
copy(BlockTags.STONE_BUTTONS, ItemTags.STONE_BUTTONS);
copy(BlockTags.BUTTONS, ItemTags.BUTTONS);
copy(BlockTags.WOOL_CARPETS, ItemTags.WOOL_CARPETS);
copy(BlockTags.WOODEN_DOORS, ItemTags.WOODEN_DOORS);
ItemTags.WOODEN_DOORS.add(ItemTypes.OAK_DOOR, ItemTypes.SPRUCE_DOOR, ItemTypes.BIRCH_DOOR, ItemTypes.JUNGLE_DOOR, ItemTypes.ACACIA_DOOR, ItemTypes.DARK_OAK_DOOR, ItemTypes.CRIMSON_DOOR, ItemTypes.WARPED_DOOR, ItemTypes.MANGROVE_DOOR, ItemTypes.BAMBOO_DOOR, ItemTypes.CHERRY_DOOR);
copy(BlockTags.WOODEN_STAIRS, ItemTags.WOODEN_STAIRS);
copy(BlockTags.WOODEN_SLABS, ItemTags.WOODEN_SLABS);
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.DOORS, ItemTags.DOORS);
copy(BlockTags.WOODEN_TRAPDOORS, ItemTags.WOODEN_TRAPDOORS);
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.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.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.BAMBOO_BLOCKS, ItemTags.BAMBOO_BLOCKS);
copy(BlockTags.WART_BLOCKS, ItemTags.WART_BLOCKS);
copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
copy(BlockTags.LOGS, ItemTags.LOGS);
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.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.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,50 +179,57 @@ 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.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.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);
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.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.VILLAGER_PLANTABLE_SEEDS.add(ItemTypes.WHEAT_SEEDS, ItemTypes.POTATO, ItemTypes.CARROT, ItemTypes.BEETROOT_SEEDS, ItemTypes.TORCHFLOWER_SEEDS, ItemTypes.PITCHER_POD);
copy(BlockTags.BUTTONS, ItemTags.BUTTONS);
ItemTags.DOORS.addTag(ItemTags.WOODEN_DOORS).add(ItemTypes.IRON_DOOR);
copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
copy(BlockTags.STAIRS, ItemTags.STAIRS);
copy(BlockTags.SLABS, ItemTags.SLABS);
ItemTags.TRAPDOORS.addTag(ItemTags.WOODEN_TRAPDOORS).add(ItemTypes.IRON_TRAPDOOR);
copy(BlockTags.FENCES, ItemTags.FENCES);
copy(BlockTags.FLOWERS, ItemTags.FLOWERS);
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.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.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);
copy(BlockTags.DAMPENS_VIBRATIONS, ItemTags.DAMPENS_VIBRATIONS);
ItemTags.DECORATED_POT_INGREDIENTS.addTag(ItemTags.DECORATED_POT_SHERDS).add(ItemTypes.BRICK);
ItemTags.TOOLS.addTag(ItemTags.SWORDS).addTag(ItemTags.AXES).addTag(ItemTags.PICKAXES).addTag(ItemTags.SHOVELS).addTag(ItemTags.HOES).add(ItemTypes.TRIDENT);
copy(BlockTags.LOGS, ItemTags.LOGS);
ItemTags.BREAKS_DECORATED_POTS.addTag(ItemTags.TOOLS);
copy(BlockTags.COMPLETES_FIND_TREE_TUTORIAL, ItemTags.COMPLETES_FIND_TREE_TUTORIAL);
}
String name;
@@ -257,6 +257,9 @@ public class ItemTags {
}
private ItemTags addTag(ItemTags tags) {
if (tags.states.isEmpty()) {
throw new IllegalArgumentException("Tag " + tags.name + " is empty when adding to " + this.name + ", you (packetevents updater) probably messed up the item tags order!!");
}
this.states.addAll(tags.states);
return this;
}
@@ -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,
}
@@ -23,6 +23,8 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.MaterialType;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import java.util.Objects;
public class StateType {
private final String name;
private final float blastResistance;
@@ -112,4 +114,25 @@ public class StateType {
public String toString() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StateType stateType = (StateType) o;
return Float.compare(blastResistance, stateType.blastResistance) == 0
&& Float.compare(hardness, stateType.hardness) == 0
&& isSolid == stateType.isSolid
&& isBlocking == stateType.isBlocking
&& isAir == stateType.isAir
&& requiresCorrectTool == stateType.requiresCorrectTool
&& exceedsCube == stateType.exceedsCube
&& Objects.equals(name, stateType.name)
&& materialType == stateType.materialType;
}
@Override
public int hashCode() {
return Objects.hash(name, blastResistance, hardness, isSolid, isBlocking, isAir, requiresCorrectTool, exceedsCube, materialType);
}
}
@@ -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;
@@ -39,7 +39,7 @@ public class MojangAPIUtil {
String uuidStr = UUIDUtil.toStringWithoutDashes(uuid);
try {
List<TextureProperty> textureProperties = new ArrayList<>();
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidStr);
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidStr + "?unsigned=false");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
//Bad request, this UUID is not valid
@@ -202,7 +202,7 @@ public class Vector3i {
}
public Vector3i subtract(int x, int y, int z) {
return new Vector3i(this.x + x, this.y + y, this.z + z);
return new Vector3i(this.x - x, this.y - y, this.z - z);
}
public Vector3i subtract(Vector3i other) {
@@ -1,5 +1,7 @@
package com.github.retrooper.packetevents.util.adventure;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.util.reflection.Reflection;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
@@ -9,15 +11,20 @@ import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.json.JSONOptions;
import net.kyori.adventure.util.Index;
import net.kyori.option.OptionState;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.function.Function;
public class AdventureReflectionUtil {
static boolean IS_LEGACY_ADVENTURE;
static boolean IS_4_15_0_OR_NEWER = false;
static TypeAdapter<Key> KEY_SERIALIZER_INSTANCE;
static Function<Gson, Object> COMPONENT_SERIALIZER_CREATE;
static TypeAdapter<ClickEvent.Action> CLICK_EVENT_ACTION_SERIALIZER_INSTANCE;
@@ -28,8 +35,11 @@ public class AdventureReflectionUtil {
static TypeAdapter<TextColor> TEXT_COLOR_SERIALIZER_DOWNSAMPLE_COLOR_INSTANCE;
static TypeAdapter<TextDecoration> TEXT_DECORATION_SERIALIZER_INSTANCE;
static TypeAdapter<BlockNBTComponent.Pos> BLOCK_NBT_POS_SERIALIZER_INSTANCE;
static TypeAdapter<UUID> UUID_SERIALIZER_INSTANCE;
static Function<Gson, Object> TRANSLATION_ARGUMENT_SERIALIZER_CREATE;
static {
IS_LEGACY_ADVENTURE = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.SerializerFactory") == null;
Class<?> KEY_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.KeySerializer");
Field KEY_SERIALIZER_INSTANCE_FIELD = Reflection.getField(KEY_SERIALIZER, "INSTANCE");
KEY_SERIALIZER_INSTANCE = (TypeAdapter<Key>) getSafe(KEY_SERIALIZER_INSTANCE_FIELD);
@@ -38,7 +48,7 @@ public class AdventureReflectionUtil {
Class<?> SHOW_ITEM_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.ShowItemSerializer");
Class<?> SHOW_ENTITY_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.ShowEntitySerializer");
if (GsonComponentSerializerExtended.LEGACY_ADVENTURE) {
if (IS_LEGACY_ADVENTURE) {
Constructor<?> COMPONENT_SERIALIZER_CONSTRUCTOR = Reflection.getConstructor(COMPONENT_SERIALIZER, 0);
COMPONENT_SERIALIZER_CREATE = gson -> invokeSafe(COMPONENT_SERIALIZER_CONSTRUCTOR);
@@ -55,8 +65,21 @@ public class AdventureReflectionUtil {
Constructor<?> SHOW_ENTITY_SERIALIZER_CONSTRUCTOR = Reflection.getConstructor(SHOW_ENTITY_SERIALIZER, 0);
SHOW_ENTITY_SERIALIZER_CREATE = gson -> invokeSafe(SHOW_ENTITY_SERIALIZER_CONSTRUCTOR);
} else {
Method COMPONENT_SERIALIZER_CREATE_METHOD = Reflection.getMethod(COMPONENT_SERIALIZER, "create", Gson.class);
COMPONENT_SERIALIZER_CREATE = gson -> invokeSafe(COMPONENT_SERIALIZER_CREATE_METHOD, gson);
IS_4_15_0_OR_NEWER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.TranslationArgumentSerializer") != null;
final Object optionState;
if (IS_4_15_0_OR_NEWER) {
// adventure >= v4.15; add option state for serializer construction
optionState = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_16)
? JSONOptions.byDataVersion() : JSONOptions.byDataVersion().at(2525);
Method COMPONENT_SERIALIZER_CREATE_METHOD = Reflection.getMethod(COMPONENT_SERIALIZER, "create", OptionState.class, Gson.class);
COMPONENT_SERIALIZER_CREATE = gson -> invokeSafe(COMPONENT_SERIALIZER_CREATE_METHOD, optionState, gson);
} else {
// adventure < 4.15; no option states available
optionState = null;
Method COMPONENT_SERIALIZER_CREATE_METHOD = Reflection.getMethod(COMPONENT_SERIALIZER, "create", Gson.class);
COMPONENT_SERIALIZER_CREATE = gson -> invokeSafe(COMPONENT_SERIALIZER_CREATE_METHOD, gson);
}
Class<?> CLICK_EVENT_ACTION_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.ClickEventActionSerializer");
Field CLICK_EVENT_ACTION_SERIALIZER_INSTANCE_FIELD = Reflection.getField(CLICK_EVENT_ACTION_SERIALIZER, "INSTANCE");
@@ -75,6 +98,16 @@ public class AdventureReflectionUtil {
Method SHOW_ENTITY_SERIALIZER_CREATE_METHOD = Reflection.getMethod(SHOW_ENTITY_SERIALIZER, "create", Gson.class);
SHOW_ENTITY_SERIALIZER_CREATE = gson -> invokeSafe(SHOW_ENTITY_SERIALIZER_CREATE_METHOD, gson);
if (IS_4_15_0_OR_NEWER) {
Class<?> UUID_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.UUIDSerializer");
Method UUID_SERIALIZER_CREATE = Reflection.getMethod(UUID_SERIALIZER, "uuidSerializer", OptionState.class);
UUID_SERIALIZER_INSTANCE = (TypeAdapter<UUID>) invokeSafe(UUID_SERIALIZER_CREATE, optionState);
Class<?> TRANSLATION_ARGUMENT_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.TranslationArgumentSerializer");
Method TRANSLATION_ARGUMENT_SERIALIZER_CREATE_METHOD = Reflection.getMethod(TRANSLATION_ARGUMENT_SERIALIZER, "create", Gson.class);
TRANSLATION_ARGUMENT_SERIALIZER_CREATE = gson -> invokeSafe(TRANSLATION_ARGUMENT_SERIALIZER_CREATE_METHOD, gson);
}
}
Class<?> TEXT_COLOR_SERIALIZER = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.TextColorSerializer");
@@ -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);
}
}
}
@@ -18,7 +18,6 @@
package com.github.retrooper.packetevents.util.adventure;
import com.github.retrooper.packetevents.util.reflection.Reflection;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
@@ -42,13 +41,11 @@ import java.util.function.UnaryOperator;
*/
public class GsonComponentSerializerExtended implements GsonComponentSerializer {
static boolean LEGACY_ADVENTURE = Reflection.getClassByNameWithoutException("net.kyori.adventure.text.serializer.gson.SerializerFactory") == null;
private final Gson serializer;
private final UnaryOperator<GsonBuilder> populator;
public GsonComponentSerializerExtended(final boolean downsampleColor, final boolean emitLegacyHover) {
if (LEGACY_ADVENTURE) {
if (AdventureReflectionUtil.IS_LEGACY_ADVENTURE) {
this.populator = builder -> {
builder.registerTypeHierarchyAdapter(Key.class, AdventureReflectionUtil.KEY_SERIALIZER_INSTANCE);
builder.registerTypeHierarchyAdapter(Component.class, AdventureReflectionUtil.COMPONENT_SERIALIZER_CREATE.apply(null));
@@ -69,7 +66,7 @@ public class GsonComponentSerializerExtended implements GsonComponentSerializer
return builder;
};
}
this.serializer = this.populator.apply(new GsonBuilder()).create();
this.serializer = this.populator.apply(new GsonBuilder().disableHtmlEscaping()).create();
}
@Override
@@ -25,12 +25,15 @@ import com.google.gson.reflect.TypeToken;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.BlockNBTComponent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslationArgument;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import java.util.UUID;
public class SerializerFactory implements TypeAdapterFactory {
private final boolean downsampleColors;
@@ -67,9 +70,15 @@ public class SerializerFactory implements TypeAdapterFactory {
return (TypeAdapter<T>) AdventureReflectionUtil.TEXT_DECORATION_SERIALIZER_INSTANCE;
} else if (BlockNBTComponent.Pos.class.isAssignableFrom(rawType)) {
return (TypeAdapter<T>) AdventureReflectionUtil.BLOCK_NBT_POS_SERIALIZER_INSTANCE;
} else {
return null;
} else if (AdventureReflectionUtil.IS_4_15_0_OR_NEWER) {
if (UUID.class.isAssignableFrom(rawType)) {
return (TypeAdapter<T>) AdventureReflectionUtil.UUID_SERIALIZER_INSTANCE;
} else if (TranslationArgument.class.isAssignableFrom(rawType)) {
return (TypeAdapter<T>) AdventureReflectionUtil.TRANSLATION_ARGUMENT_SERIALIZER_CREATE.apply(gson);
}
}
return null;
}
}
@@ -242,7 +242,7 @@ public class StyleSerializerExtended extends TypeAdapter<Style> {
if (this.emitLegacyHover) {
out.name(HOVER_EVENT_VALUE);
this.serializeLegacyHoverEvent(hoverEvent, out);
} else {
} else if (!action.toString().equals("show_achievement")) { // Using string because the variable for SHOW_ACHIEVEMENT is not available in version before 4.14.0
out.name(HOVER_EVENT_CONTENTS);
if (action == HoverEvent.Action.SHOW_ITEM) {
this.gson.toJson(hoverEvent.value(), HoverEvent.ShowItem.class, out);
@@ -271,6 +271,9 @@ public class StyleSerializerExtended extends TypeAdapter<Style> {
if (hoverEvent.action() == HoverEvent.Action.SHOW_TEXT) { // serialization is the same
this.gson.toJson(hoverEvent.value(), Component.class, out);
return;
} else if (hoverEvent.action().toString().equals("show_achievement")) {
this.gson.toJson(hoverEvent.value(), String.class, out);
return;
}
// Patch for hover event serialization
@@ -61,17 +61,17 @@ public class UpdateChecker {
try {
newVersion = new PEVersion(checkLatestReleasedVersion());
} catch (Exception ex) {
ex.printStackTrace();
newVersion = null;
PacketEvents.getAPI().getLogManager().warn("Failed to check for updates. " + (ex.getCause() != null ? ex.getCause().getClass().getName()+ ": " + ex.getCause().getMessage() : ex.getMessage()));
return UpdateCheckerStatus.FAILED;
}
if (newVersion != null && localVersion.isOlderThan(newVersion)) {
if (localVersion.isOlderThan(newVersion)) {
PacketEvents.getAPI().getLogManager().warn("There is an update available for packetevents! Your build: ("
+ ColorUtil.toString(NamedTextColor.YELLOW) + localVersion
+ ColorUtil.toString(NamedTextColor.WHITE) + ") | Latest released build: ("
+ ColorUtil.toString(NamedTextColor.GREEN) + newVersion
+ ColorUtil.toString(NamedTextColor.WHITE) + ")");
return UpdateCheckerStatus.OUTDATED;
} else if (newVersion != null && localVersion.isNewerThan(newVersion)) {
} else if (localVersion.isNewerThan(newVersion)) {
PacketEvents.getAPI().getLogManager().info("You are on a dev or pre released build of packetevents. Your build: ("
+ ColorUtil.toString(NamedTextColor.AQUA) + localVersion
+ ColorUtil.toString(NamedTextColor.WHITE) + ") | Latest released build: ("
@@ -79,27 +79,24 @@ public class UpdateChecker {
+ ColorUtil.toString(NamedTextColor.WHITE) + ")");
return UpdateCheckerStatus.PRE_RELEASE;
} else if (localVersion.equals(newVersion)) {
PacketEvents.getAPI().getLogManager().info("You are on the latest released version of packetevents. ("
PacketEvents.getAPI().getLogManager().info("You are on the latest released version of packetevents. Your build: ("
+ ColorUtil.toString(NamedTextColor.GREEN) + newVersion + ColorUtil.toString(NamedTextColor.WHITE) + ")");
return UpdateCheckerStatus.UP_TO_DATE;
} else {
PacketEvents.getAPI().getLogManager().warn("Something went wrong while checking for an update. Your build: (" + localVersion + ")");
PacketEvents.getAPI().getLogManager().warn("Failed to check for updates. Your build: (" + localVersion + ")");
return UpdateCheckerStatus.FAILED;
}
}
public void handleUpdateCheck() {
Thread thread = new Thread(() -> {
PacketEvents.getAPI().getLogManager().info("Checking for an update, please wait...");
PacketEvents.getAPI().getLogManager().info("Checking for updates, please wait...");
UpdateChecker.UpdateCheckerStatus status = checkForUpdate();
int waitTimeInSeconds = 5;
int maxRetryCount = 5;
int maxRetryCount = 3;
int retries = 0;
while (retries < maxRetryCount) {
if (status != UpdateChecker.UpdateCheckerStatus.FAILED) {
break;
}
PacketEvents.getAPI().getLogManager().warn("[Checking for an update again in " + waitTimeInSeconds + " seconds...");
while (retries < maxRetryCount && status == UpdateChecker.UpdateCheckerStatus.FAILED) {
PacketEvents.getAPI().getLogManager().warn("Checking for updates again in " + waitTimeInSeconds + " seconds...");
try {
Thread.sleep(waitTimeInSeconds * 1000L);
} catch (InterruptedException e) {
@@ -111,7 +108,7 @@ public class UpdateChecker {
status = checkForUpdate();
if (retries == (maxRetryCount - 1)) {
PacketEvents.getAPI().getLogManager().warn("packetevents failed to check for an update. No longer retrying.");
PacketEvents.getAPI().getLogManager().severe("Failed to check for updates after " + maxRetryCount + " times.");
break;
}
@@ -27,7 +27,14 @@ import com.github.retrooper.packetevents.manager.server.VersionComparison;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
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 +46,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,20 +61,31 @@ 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;
import com.github.retrooper.packetevents.util.crypto.SignatureData;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
import org.jetbrains.annotations.ApiStatus;
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;
@@ -166,7 +185,7 @@ public class PacketWrapper<T extends PacketWrapper> {
}
@ApiStatus.Internal
public final void prepareForSend(Object channel, boolean outgoing) {
public final void prepareForSend(Object channel, boolean outgoing, boolean proxy) {
// Null means the packet was manually created and wasn't sent by the server itself
// A reference count of 0 means that the packet was freed (it was already sent)
if (buffer == null || ByteBufHelper.refCnt(buffer) == 0) {
@@ -174,7 +193,7 @@ public class PacketWrapper<T extends PacketWrapper> {
}
//On proxies, we must rewrite the packet ID in a format compatible for the targeted client version
if (PacketEvents.getAPI().getInjector().isProxy()) {
if (proxy) {
User user = PacketEvents.getAPI().getProtocolManager().getUser(channel);
if (packetTypeData.getPacketType() == null) {
//Get the packet type with the local version packet type mappings.
@@ -185,13 +204,17 @@ 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();
}
@ApiStatus.Internal
public final void prepareForSend(Object channel, boolean outgoing) {
prepareForSend(channel, outgoing, PacketEvents.getAPI().getInjector().isProxy());
}
public void read() {
}
@@ -240,8 +263,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 +274,7 @@ public class PacketWrapper<T extends PacketWrapper> {
/**
* Sets the Packet ID for the current platform version
*
* @deprecated Use {@link #setNativePacketId(int)}
*/
@Deprecated
@@ -424,10 +449,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 +486,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 +513,65 @@ 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(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 Style readStyle() {
try {
return AdventureNBTSerialization.readStyle(this.buffer);
} catch (IOException exception) {
throw new IllegalStateException(exception);
}
}
public void writeStyle(Style style) {
try {
AdventureNBTSerialization.writeStyle(this.buffer, style);
} catch (IOException exception) {
throw new IllegalStateException(exception);
}
}
public ResourceLocation readIdentifier(int maxLen) {
@@ -775,11 +859,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 +873,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;
}
}
@@ -30,7 +30,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayClientUpdateSign extends PacketWrapper<WrapperPlayClientUpdateSign> {
private Vector3i blockPosition;
private String[] textLines;
private boolean isFrontText = true;
private boolean isFrontText;
public WrapperPlayClientUpdateSign(PacketReceiveEvent event) {
super(event);
@@ -55,6 +55,8 @@ public class WrapperPlayClientUpdateSign extends PacketWrapper<WrapperPlayClient
}
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20)) {
isFrontText = readBoolean();
} else {
isFrontText = true;
}
textLines = new String[4];
for (int i = 0; i < 4; i++) {
@@ -0,0 +1,61 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
public class WrapperPlayServerActionBar extends PacketWrapper<WrapperPlayServerActionBar> {
private Component actionBarText;
public WrapperPlayServerActionBar(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerActionBar(Component actionBarText) {
super(PacketType.Play.Server.ACTION_BAR);
this.actionBarText = actionBarText;
}
@Override
public void read() {
this.actionBarText = this.readComponent();
}
@Override
public void write() {
this.writeComponent(this.actionBarText);
}
@Override
public void copy(WrapperPlayServerActionBar wrapper) {
this.actionBarText = wrapper.actionBarText;
}
public Component getActionBarText() {
return actionBarText;
}
public void setActionBarText(Component actionBarText) {
this.actionBarText = actionBarText;
}
}
@@ -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();
@@ -44,7 +44,11 @@ public class WrapperPlayServerDisplayScoreboard extends PacketWrapper<WrapperPla
} else {
position = readByte();
}
scoreName = readString(16);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
scoreName = readString();
} else {
scoreName = readString(16);
}
}
@Override
@@ -54,7 +58,11 @@ public class WrapperPlayServerDisplayScoreboard extends PacketWrapper<WrapperPla
} else {
writeByte(position);
}
writeString(scoreName, 16);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
writeString(scoreName); // length limit removed
} else {
writeString(scoreName, 16);
}
}
@Override
@@ -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,
}
}
@@ -26,7 +26,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayServerOpenSignEditor extends PacketWrapper<WrapperPlayServerOpenSignEditor> {
private Vector3i position;
private boolean isFrontText = true;
private boolean isFrontText;
public WrapperPlayServerOpenSignEditor(PacketSendEvent event) {
super(event);
@@ -50,6 +50,8 @@ public class WrapperPlayServerOpenSignEditor extends PacketWrapper<WrapperPlaySe
}
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20)) {
isFrontText = readBoolean();
} else {
isFrontText = true;
}
}
@@ -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,22 +42,32 @@ 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)) {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17)) {
required = readBoolean();
boolean hasPrompt = readBoolean();
if (hasPrompt) {
@@ -63,9 +78,13 @@ 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)) {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17)) {
writeBoolean(required);
writeBoolean(prompt != null);
if (prompt != null) {
@@ -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;
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
* Copyright (C) 2024 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
@@ -21,36 +21,55 @@ 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.score.ScoreFormat;
import com.github.retrooper.packetevents.protocol.score.ScoreFormatTypes;
import com.github.retrooper.packetevents.util.LegacyFormat;
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.Nullable;
public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperPlayServerScoreboardObjective> {
private String name;
private ObjectiveMode mode;
private Component displayName;
private @Nullable RenderType renderType;
private @Nullable ScoreFormat scoreFormat;
public WrapperPlayServerScoreboardObjective(PacketSendEvent event) {
super(event);
}
public WrapperPlayServerScoreboardObjective(String name, ObjectiveMode mode, Component displayName, @Nullable RenderType renderType) {
public WrapperPlayServerScoreboardObjective(String name, ObjectiveMode mode, Component displayName,
@Nullable RenderType renderType) {
this(name, mode, displayName, renderType, null);
}
public WrapperPlayServerScoreboardObjective(String name, ObjectiveMode mode, Component displayName,
@Nullable RenderType renderType, @Nullable ScoreFormat scoreFormat) {
super(PacketType.Play.Server.SCOREBOARD_OBJECTIVE);
this.name = name;
this.mode = mode;
this.displayName = displayName;
this.renderType = renderType;
this.scoreFormat = scoreFormat;
}
@Override
public void read() {
name = readString();
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
name = readString();
} else {
name = readString(16);
}
mode = ObjectiveMode.getById(readByte());
if (mode != ObjectiveMode.CREATE && mode != ObjectiveMode.UPDATE) {
displayName = Component.empty();
renderType = RenderType.INTEGER;
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
scoreFormat = null;
}
} else {
if (serverVersion.isOlderThan(ServerVersion.V_1_13)) {
displayName = AdventureSerializer.fromLegacyFormat(readString(32));
@@ -58,17 +77,24 @@ public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperP
} else {
displayName = readComponent();
renderType = RenderType.getById(readVarInt());
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
scoreFormat = readOptional(ScoreFormatTypes::read);
}
}
}
}
@Override
public void write() {
writeString(name);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
writeString(name);
} else {
writeString(name, 16);
}
writeByte((byte) mode.ordinal());
if (this.mode == ObjectiveMode.CREATE || this.mode == ObjectiveMode.UPDATE) {
if (serverVersion.isOlderThan(ServerVersion.V_1_13)) {
writeString(AdventureSerializer.asVanilla(displayName));
writeString(LegacyFormat.trimLegacyFormat(AdventureSerializer.asVanilla(displayName), 32));
if (renderType != null) {
writeString(renderType.name().toLowerCase());
} else {
@@ -81,6 +107,9 @@ public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperP
} else {
writeVarInt(RenderType.INTEGER.ordinal());
}
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
writeOptional(scoreFormat, ScoreFormatTypes::write);
}
}
}
}
@@ -91,6 +120,7 @@ public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperP
mode = wrapper.mode;
displayName = wrapper.displayName;
renderType = wrapper.renderType;
scoreFormat = wrapper.scoreFormat;
}
public String getName() {
@@ -125,6 +155,14 @@ public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperP
this.renderType = renderType;
}
public @Nullable ScoreFormat getScoreFormat() {
return this.scoreFormat;
}
public void setScoreFormat(@Nullable ScoreFormat scoreFormat) {
this.scoreFormat = scoreFormat;
}
public enum ObjectiveMode {
CREATE,
REMOVE,
@@ -168,4 +206,4 @@ public class WrapperPlayServerScoreboardObjective extends PacketWrapper<WrapperP
return VALUES[id];
}
}
}
}
@@ -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));
}
}
@@ -23,9 +23,11 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
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.Nullable;
import java.util.Optional;
import java.util.UUID;
@@ -60,6 +62,19 @@ public class WrapperPlayServerSpawnEntity extends PacketWrapper<WrapperPlayServe
this.velocity = velocity;
}
public WrapperPlayServerSpawnEntity(int entityID, @Nullable UUID uuid, EntityType entityType, Location location, float headYaw, int data, @Nullable Vector3d velocity) {
super(PacketType.Play.Server.SPAWN_ENTITY);
this.entityID = entityID;
this.uuid = Optional.ofNullable(uuid);
this.entityType = entityType;
this.position = location.getPosition();
this.pitch = location.getPitch();
this.yaw = location.getYaw();
this.headYaw = headYaw;
this.data = data;
this.velocity = Optional.ofNullable(velocity);
}
@Override
public void read() {
entityID = readVarInt();
@@ -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() {
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
* Copyright (C) 2024 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
@@ -21,22 +21,22 @@ 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.score.ScoreFormat;
import com.github.retrooper.packetevents.protocol.score.ScoreFormatTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServerUpdateScore> {
private String entityName;
private Action action;
private String objectiveName;
private Optional<Integer> value;
public enum Action {
CREATE_OR_UPDATE_ITEM,
REMOVE_ITEM;
public static final Action[] VALUES = values();
}
private @Nullable Component entityDisplayName;
private @Nullable ScoreFormat scoreFormat;
public WrapperPlayServerUpdateScore(PacketSendEvent event) {
super(event);
@@ -50,9 +50,26 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
this.value = value;
}
public WrapperPlayServerUpdateScore(String entityName, Action action, String objectiveName, int value,
@Nullable Component entityDisplayName, @Nullable ScoreFormat scoreFormat) {
super(PacketType.Play.Server.UPDATE_SCORE);
this.entityName = entityName;
this.action = action;
this.objectiveName = objectiveName;
this.value = Optional.of(value);
this.entityDisplayName = entityDisplayName;
this.scoreFormat = scoreFormat;
}
@Override
public void read() {
if (serverVersion == ServerVersion.V_1_7_10) {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.entityName = this.readString();
this.objectiveName = this.readString();
this.value = Optional.of(this.readVarInt());
this.entityDisplayName = this.readOptional(PacketWrapper::readComponent);
this.scoreFormat = this.readOptional(ScoreFormatTypes::read);
} else if (this.serverVersion == ServerVersion.V_1_7_10) {
entityName = readString(16);
action = Action.VALUES[readByte()];
if (action != Action.REMOVE_ITEM) {
@@ -63,9 +80,17 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
value = Optional.empty();
}
} else {
entityName = readString(40);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
entityName = readString();
} else {
entityName = readString(40);
}
action = Action.VALUES[readByte()];
objectiveName = readString(16);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
objectiveName = readString();
} else {
objectiveName = readString(16);
}
if (action != Action.REMOVE_ITEM) {
value = Optional.of(readVarInt());
} else {
@@ -77,7 +102,13 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
@Override
public void write() {
if (serverVersion == ServerVersion.V_1_7_10) {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
this.writeString(this.entityName);
this.writeString(this.objectiveName);
this.writeVarInt(this.value.orElse(0));
this.writeOptional(this.entityDisplayName, PacketWrapper::writeComponent);
this.writeOptional(this.scoreFormat, ScoreFormatTypes::write);
} else if (this.serverVersion == ServerVersion.V_1_7_10) {
writeString(entityName, 16);
writeByte(action.ordinal());
if (action != Action.REMOVE_ITEM) {
@@ -88,9 +119,17 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
value = Optional.empty();
}
} else {
writeString(entityName, 40);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
writeString(entityName);
} else {
writeString(entityName, 40);
}
writeByte(action.ordinal());
writeString(objectiveName, 16);
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_18)) {
writeString(objectiveName);
} else {
writeString(objectiveName, 16);
}
if (action != Action.REMOVE_ITEM) {
writeVarInt(value.orElse(-1));
}
@@ -104,6 +143,8 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
action = wrapper.action;
objectiveName = wrapper.objectiveName;
value = wrapper.value;
entityDisplayName = wrapper.entityDisplayName;
scoreFormat = wrapper.scoreFormat;
}
public String getEntityName() {
@@ -130,11 +171,41 @@ public class WrapperPlayServerUpdateScore extends PacketWrapper<WrapperPlayServe
this.objectiveName = objectiveName;
}
/**
* Always present for >=1.20.3
*/
public Optional<Integer> getValue() {
return value;
}
/**
* Always present for >=1.20.3
*/
public void setValue(Optional<Integer> value) {
this.value = value;
}
public @Nullable Component getEntityDisplayName() {
return this.entityDisplayName;
}
public void setEntityDisplayName(@Nullable Component entityDisplayName) {
this.entityDisplayName = entityDisplayName;
}
public @Nullable ScoreFormat getScoreFormat() {
return this.scoreFormat;
}
public void setScoreFormat(@Nullable ScoreFormat scoreFormat) {
this.scoreFormat = scoreFormat;
}
public enum Action {
CREATE_OR_UPDATE_ITEM,
REMOVE_ITEM;
public static final Action[] VALUES = values();
}
}
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"
]
}
}
@@ -0,0 +1,44 @@
package com.github.retrooper.packetevents.test;
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.ItemTags;
import com.github.retrooper.packetevents.test.base.BaseDummyAPITest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class EnsureCorrectTagsTest extends BaseDummyAPITest {
// These make sure the order of our tags are correct, or there's some other weird error on initialization
// The order is wrong if we try to add a tag to another tag but the former has nothing in it
@Test
@DisplayName("Test block tags order")
public void testBlockTagsOrder() {
assertDoesNotThrow(BlockTags.DRIPSTONE_REPLACEABLE::getName); // init the class
}
@Test
@DisplayName("Test item tags order")
public void testItemTagsOrder() {
assertDoesNotThrow(ItemTags.ACACIA_LOGS::getName); // init the class
}
// This makes sure we don't add a tag and forget to add stuff to it
@Test
@DisplayName("Ensure tags are not empty")
public void testTagsAreNotEmpty() throws ReflectiveOperationException {
for (Field field : ItemTags.class.getFields()) {
final ItemTags tags = (ItemTags) field.get(ItemTags.class);
assertFalse(tags.getStates().isEmpty(), "Item tag " + tags.getName() + " has nothing inside it! Did you forget to add types to it?");
}
for (Field field : BlockTags.class.getFields()) {
final BlockTags tags = (BlockTags) field.get(BlockTags.class);
assertFalse(tags.getStates().isEmpty(), "Block tag " + tags.getName() + " has nothing inside it! Did you forget to add types to it?");
}
}
}
@@ -0,0 +1,30 @@
package com.github.retrooper.packetevents.test.base;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.MockPlugin;
import be.seeseemelk.mockbukkit.ServerMock;
import com.github.retrooper.packetevents.PacketEvents;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.slf4j.Logger;
public abstract class BaseDummyAPITest {
public static final Logger LOGGER = TestPacketEventsBuilder.LOGGER;
private ServerMock server;
private MockPlugin plugin;
@BeforeEach
public void setup() {
server = MockBukkit.mock();
plugin = MockBukkit.createMockPlugin("packetevents");
PacketEvents.setAPI(TestPacketEventsBuilder.build(plugin));
}
@AfterEach
public void teardown() {
MockBukkit.unmock();
PacketEvents.setAPI(null);
}
}
@@ -0,0 +1,174 @@
package com.github.retrooper.packetevents.test.base;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.injector.ChannelInjector;
import com.github.retrooper.packetevents.manager.player.PlayerManager;
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
import com.github.retrooper.packetevents.manager.server.ServerManager;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.netty.NettyManager;
import com.github.retrooper.packetevents.protocol.ProtocolVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
import com.github.retrooper.packetevents.util.LogManager;
import io.github.retrooper.packetevents.impl.netty.NettyManagerImpl;
import io.github.retrooper.packetevents.impl.netty.manager.protocol.ProtocolManagerAbstract;
import io.github.retrooper.packetevents.impl.netty.manager.server.ServerManagerAbstract;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.logging.Level;
public class TestPacketEventsBuilder {
public static final Logger LOGGER = LoggerFactory.getLogger("packetevents");
private static PacketEventsAPI<Plugin> API_INSTANCE;
public static void clearBuildCache() {
API_INSTANCE = null;
}
public static PacketEventsAPI<Plugin> build(Plugin plugin) {
if (API_INSTANCE == null) {
API_INSTANCE = buildNoCache(plugin);
}
return API_INSTANCE;
}
public static PacketEventsAPI<Plugin> build(Plugin plugin, PacketEventsSettings settings) {
if (API_INSTANCE == null) {
API_INSTANCE = buildNoCache(plugin, settings);
}
return API_INSTANCE;
}
public static PacketEventsAPI<Plugin> buildNoCache(Plugin plugin) {
return buildNoCache(plugin, new PacketEventsSettings());
}
public static PacketEventsAPI<Plugin> buildNoCache(Plugin plugin, PacketEventsSettings inSettings) {
return new PacketEventsAPI<Plugin>() {
private final PacketEventsSettings settings = inSettings;
private final ProtocolManager protocolManager = new ProtocolManagerAbstract() {
@Override
public ProtocolVersion getPlatformVersion() {
return ProtocolVersion.UNKNOWN;
}
};
private final ServerManager serverManager = new ServerManagerAbstract() {
@Override
public ServerVersion getVersion() {
return ServerVersion.getLatest();
}
};
private final NettyManager nettyManager = new NettyManagerImpl();
private final LogManager logManager = new LogManager() {
@Override
protected void log(Level level, @Nullable NamedTextColor color, String message) {
if (level == Level.SEVERE) {
LOGGER.error(message);
} else if (level == Level.WARNING) {
LOGGER.warn(message);
} else {
LOGGER.info(message);
}
}
};
private boolean loaded;
private boolean initialized;
@Override
public void load() {
if (!loaded) {
//Resolve server version and cache
String id = plugin.getName().toLowerCase();
PacketEvents.IDENTIFIER = "pe-" + id;
PacketEvents.ENCODER_NAME = "pe-encoder-" + id;
PacketEvents.DECODER_NAME = "pe-decoder-" + id;
PacketEvents.CONNECTION_HANDLER_NAME = "pe-connection-handler-" + id;
PacketEvents.SERVER_CHANNEL_HANDLER_NAME = "pe-connection-initializer-" + id;
PacketEvents.TIMEOUT_HANDLER_NAME = "pe-timeout-handler-" + id;
if (!PacketType.isPrepared()) {
PacketType.prepare();
}
loaded = true;
}
}
@Override
public boolean isLoaded() {
return loaded;
}
@Override
public void init() {
//Load if we haven't loaded already
load();
if (!initialized) {
initialized = true;
}
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void terminate() {
if (initialized) {
initialized = false;
}
}
@Override
public Plugin getPlugin() {
return plugin;
}
@Override
public ProtocolManager getProtocolManager() {
return protocolManager;
}
@Override
public ServerManager getServerManager() {
return serverManager;
}
@Override
public PlayerManager getPlayerManager() {
return null;
}
@Override
public PacketEventsSettings getSettings() {
return settings;
}
@Override
public NettyManager getNettyManager() {
return nettyManager;
}
@Override
public ChannelInjector getInjector() {
return null;
}
@Override
public LogManager getLogManager() {
return logManager;
}
};
}
}
+8 -6
View File
@@ -2,15 +2,14 @@ plugins {
id 'java'
id 'java-library'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '7.1.0' apply(false)
id 'com.github.johnrengelman.shadow' version '8.1.1' apply(false)
}
wrapper {
gradleVersion = "7.3.1"
gradleVersion = "8.5"
distributionType = Wrapper.DistributionType.ALL
}
subprojects {
apply plugin: 'java'
apply plugin: 'java-library'
@@ -19,15 +18,15 @@ 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.1'//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.adventureVersion = '4.15.0'
project.ext.adventureDependencies=["net.kyori:adventure-api:${adventureVersion}",
"net.kyori:adventure-text-serializer-gson:${adventureVersion}",
"net.kyori:adventure-text-serializer-legacy:${adventureVersion}",
"net.kyori:adventure-nbt:${adventureVersion}"]
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_1_8
repositories {
@@ -55,6 +54,9 @@ subprojects {
withType(JavaCompile) {
options.encoding = 'UTF-8'
// Set the release flag. This configures what version bytecode the compiler will emit, as well as what JDK APIs are usable.
// See https://openjdk.java.net/jeps/247 for more information.
options.release.set(8)
}
jar.configure {
@@ -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;
@@ -129,7 +129,7 @@ public class BungeePacketEventsBuilder {
}
if (user == null) {
System.out.println("User null???");
PacketEvents.getAPI().getLogManager().warn("User is null?");
user = new User(channel, ConnectionState.PLAY, null, new UserProfile(p.getUniqueId(), p.getName()));
synchronized (channel) {
@@ -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.1 #//TODO UPDATE
main: io.github.retrooper.packetevents.PacketEventsPlugin
author: retrooper
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff. Show more