Compare commits

...
84 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
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
65 changed files with 1878 additions and 586 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()
}
@@ -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, 2, 0);
private static final PEVersion VERSION = new PEVersion(2, 2, 1);
public EventManager getEventManager() {
return EVENT_MANAGER;
@@ -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;
}
}
@@ -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)) {
@@ -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();
}
}
}
@@ -130,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();
@@ -573,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();
@@ -788,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();
@@ -871,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();
@@ -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
@@ -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;
}
@@ -80,6 +80,7 @@ public class ParticleVibrationData extends ParticleData {
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) {
@@ -95,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;
}
@@ -126,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;
}
@@ -153,7 +172,12 @@ public class ParticleVibrationData extends ParticleData {
case BLOCK:
return new ParticleVibrationData(startingPos, wrapper.readBlockPosition(), wrapper.readVarInt());
case ENTITY:
return new ParticleVibrationData(startingPos, wrapper.readVarInt(), wrapper.readVarInt());
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);
}
@@ -174,6 +198,9 @@ public class ParticleVibrationData extends ParticleData {
wrapper.writeBlockPosition(data.getBlockPosition().get());
} 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());
}
@@ -90,8 +90,10 @@ public enum ClientVersion {
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
@Deprecated
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_20_3.protocolVersion + 1, true),
UNKNOWN(-1, true);
@@ -163,9 +165,9 @@ 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) {
@@ -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);
}
}
}
@@ -228,19 +228,16 @@ 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.PRESSURE_PLATES.addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.STONE_PRESSURE_PLATES).add(StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE);
BlockTags.WOODEN_PRESSURE_PLATES.add(StateTypes.OAK_PRESSURE_PLATE, StateTypes.SPRUCE_PRESSURE_PLATE, StateTypes.BIRCH_PRESSURE_PLATE, StateTypes.JUNGLE_PRESSURE_PLATE, StateTypes.ACACIA_PRESSURE_PLATE, StateTypes.DARK_OAK_PRESSURE_PLATE, StateTypes.CRIMSON_PRESSURE_PLATE, StateTypes.WARPED_PRESSURE_PLATE, StateTypes.MANGROVE_PRESSURE_PLATE, StateTypes.BAMBOO_PRESSURE_PLATE, StateTypes.CHERRY_PRESSURE_PLATE);
BlockTags.STONE_PRESSURE_PLATES.add(StateTypes.STONE_PRESSURE_PLATE, StateTypes.POLISHED_BLACKSTONE_PRESSURE_PLATE);
BlockTags.PRESSURE_PLATES.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.DOORS.addTag(BlockTags.WOODEN_DOORS).add(StateTypes.IRON_DOOR);
BlockTags.SAPLINGS.add(StateTypes.OAK_SAPLING, StateTypes.SPRUCE_SAPLING, StateTypes.BIRCH_SAPLING, StateTypes.JUNGLE_SAPLING, StateTypes.ACACIA_SAPLING, StateTypes.DARK_OAK_SAPLING, StateTypes.AZALEA, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_SAPLING);
BlockTags.LOGS_THAT_BURN.addTag(BlockTags.DARK_OAK_LOGS).addTag(BlockTags.OAK_LOGS).addTag(BlockTags.ACACIA_LOGS).addTag(BlockTags.BIRCH_LOGS).addTag(BlockTags.JUNGLE_LOGS).addTag(BlockTags.SPRUCE_LOGS).addTag(BlockTags.MANGROVE_LOGS).addTag(BlockTags.CHERRY_LOGS);
BlockTags.OVERWORLD_NATURAL_LOGS.add(StateTypes.ACACIA_LOG, StateTypes.BIRCH_LOG, StateTypes.OAK_LOG, StateTypes.JUNGLE_LOG, StateTypes.SPRUCE_LOG, StateTypes.DARK_OAK_LOG, StateTypes.MANGROVE_LOG, StateTypes.CHERRY_LOG);
BlockTags.LOGS.addTag(BlockTags.LOGS_THAT_BURN).addTag(BlockTags.CRIMSON_STEMS).addTag(BlockTags.WARPED_STEMS);
BlockTags.DARK_OAK_LOGS.add(StateTypes.DARK_OAK_LOG, StateTypes.DARK_OAK_WOOD, StateTypes.STRIPPED_DARK_OAK_LOG, StateTypes.STRIPPED_DARK_OAK_WOOD);
BlockTags.OAK_LOGS.add(StateTypes.OAK_LOG, StateTypes.OAK_WOOD, StateTypes.STRIPPED_OAK_LOG, StateTypes.STRIPPED_OAK_WOOD);
BlockTags.BIRCH_LOGS.add(StateTypes.BIRCH_LOG, StateTypes.BIRCH_WOOD, StateTypes.STRIPPED_BIRCH_LOG, StateTypes.STRIPPED_BIRCH_WOOD);
@@ -251,18 +248,21 @@ public class BlockTags {
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);
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.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);
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);
@@ -287,11 +287,11 @@ public class BlockTags {
BlockTags.ICE.add(StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BLUE_ICE, StateTypes.FROSTED_ICE);
BlockTags.VALID_SPAWN.add(StateTypes.GRASS_BLOCK, StateTypes.PODZOL);
BlockTags.IMPERMEABLE.add(StateTypes.GLASS, StateTypes.WHITE_STAINED_GLASS, StateTypes.ORANGE_STAINED_GLASS, StateTypes.MAGENTA_STAINED_GLASS, StateTypes.LIGHT_BLUE_STAINED_GLASS, StateTypes.YELLOW_STAINED_GLASS, StateTypes.LIME_STAINED_GLASS, StateTypes.PINK_STAINED_GLASS, StateTypes.GRAY_STAINED_GLASS, StateTypes.LIGHT_GRAY_STAINED_GLASS, StateTypes.CYAN_STAINED_GLASS, StateTypes.PURPLE_STAINED_GLASS, StateTypes.BLUE_STAINED_GLASS, StateTypes.BROWN_STAINED_GLASS, StateTypes.GREEN_STAINED_GLASS, StateTypes.RED_STAINED_GLASS, StateTypes.BLACK_STAINED_GLASS, StateTypes.TINTED_GLASS);
BlockTags.UNDERWATER_BONEMEALS.addTag(BlockTags.CORALS).addTag(BlockTags.WALL_CORALS).add(StateTypes.SEAGRASS);
BlockTags.CORAL_BLOCKS.add(StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK);
BlockTags.WALL_CORALS.add(StateTypes.TUBE_CORAL_WALL_FAN, StateTypes.BRAIN_CORAL_WALL_FAN, StateTypes.BUBBLE_CORAL_WALL_FAN, StateTypes.FIRE_CORAL_WALL_FAN, StateTypes.HORN_CORAL_WALL_FAN);
BlockTags.CORAL_PLANTS.add(StateTypes.TUBE_CORAL, StateTypes.BRAIN_CORAL, StateTypes.BUBBLE_CORAL, StateTypes.FIRE_CORAL, StateTypes.HORN_CORAL);
BlockTags.CORALS.addTag(BlockTags.CORAL_PLANTS).add(StateTypes.TUBE_CORAL_FAN, StateTypes.BRAIN_CORAL_FAN, StateTypes.BUBBLE_CORAL_FAN, StateTypes.FIRE_CORAL_FAN, StateTypes.HORN_CORAL_FAN);
BlockTags.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);
@@ -300,15 +300,15 @@ public class BlockTags {
BlockTags.WALL_HANGING_SIGNS.add(StateTypes.OAK_WALL_HANGING_SIGN, StateTypes.SPRUCE_WALL_HANGING_SIGN, StateTypes.BIRCH_WALL_HANGING_SIGN, StateTypes.ACACIA_WALL_HANGING_SIGN, StateTypes.CHERRY_WALL_HANGING_SIGN, StateTypes.JUNGLE_WALL_HANGING_SIGN, StateTypes.DARK_OAK_WALL_HANGING_SIGN, StateTypes.CRIMSON_WALL_HANGING_SIGN, StateTypes.WARPED_WALL_HANGING_SIGN, StateTypes.MANGROVE_WALL_HANGING_SIGN, StateTypes.BAMBOO_WALL_HANGING_SIGN);
BlockTags.ALL_HANGING_SIGNS.addTag(BlockTags.CEILING_HANGING_SIGNS).addTag(BlockTags.WALL_HANGING_SIGNS);
BlockTags.ALL_SIGNS.addTag(BlockTags.SIGNS).addTag(BlockTags.ALL_HANGING_SIGNS);
BlockTags.DRAGON_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.OBSIDIAN, StateTypes.CRYING_OBSIDIAN, StateTypes.END_STONE, StateTypes.IRON_BARS, StateTypes.RESPAWN_ANCHOR, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.DRAGON_TRANSPARENT.addTag(BlockTags.FIRE).add(StateTypes.LIGHT);
BlockTags.WITHER_IMMUNE.add(StateTypes.BARRIER, StateTypes.BEDROCK, StateTypes.END_PORTAL, StateTypes.END_PORTAL_FRAME, StateTypes.END_GATEWAY, StateTypes.COMMAND_BLOCK, StateTypes.REPEATING_COMMAND_BLOCK, StateTypes.CHAIN_COMMAND_BLOCK, StateTypes.STRUCTURE_BLOCK, StateTypes.JIGSAW, StateTypes.MOVING_PISTON, StateTypes.LIGHT, StateTypes.REINFORCED_DEEPSLATE);
BlockTags.WITHER_SUMMON_BASE_BLOCKS.add(StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL);
BlockTags.BEEHIVES.add(StateTypes.BEE_NEST, StateTypes.BEEHIVE);
BlockTags.CROPS.add(StateTypes.BEETROOTS, StateTypes.CARROTS, StateTypes.POTATOES, StateTypes.WHEAT, StateTypes.MELON_STEM, StateTypes.PUMPKIN_STEM, StateTypes.TORCHFLOWER_CROP, StateTypes.PITCHER_CROP);
BlockTags.BEE_GROWABLES.addTag(BlockTags.CROPS).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT);
BlockTags.PORTALS.add(StateTypes.NETHER_PORTAL, StateTypes.END_PORTAL, StateTypes.END_GATEWAY);
BlockTags.FIRE.add(StateTypes.FIRE, StateTypes.SOUL_FIRE);
BlockTags.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);
@@ -352,14 +352,14 @@ public class BlockTags {
BlockTags.SNOW.add(StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.POWDER_SNOW);
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_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);
@@ -377,6 +377,7 @@ public class BlockTags {
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.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.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);
@@ -416,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,19 +136,15 @@ 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.WOODEN_TRAPDOORS, ItemTags.WOODEN_TRAPDOORS);
copy(BlockTags.DOORS, ItemTags.DOORS);
copy(BlockTags.SAPLINGS, ItemTags.SAPLINGS);
copy(BlockTags.LOGS_THAT_BURN, ItemTags.LOGS_THAT_BURN);
copy(BlockTags.LOGS, ItemTags.LOGS);
copy(BlockTags.DARK_OAK_LOGS, ItemTags.DARK_OAK_LOGS);
copy(BlockTags.OAK_LOGS, ItemTags.OAK_LOGS);
copy(BlockTags.BIRCH_LOGS, ItemTags.BIRCH_LOGS);
@@ -164,20 +160,14 @@ public class ItemTags {
ItemTags.BANNERS.add(ItemTypes.WHITE_BANNER, ItemTypes.ORANGE_BANNER, ItemTypes.MAGENTA_BANNER, ItemTypes.LIGHT_BLUE_BANNER, ItemTypes.YELLOW_BANNER, ItemTypes.LIME_BANNER, ItemTypes.PINK_BANNER, ItemTypes.GRAY_BANNER, ItemTypes.LIGHT_GRAY_BANNER, ItemTypes.CYAN_BANNER, ItemTypes.PURPLE_BANNER, ItemTypes.BLUE_BANNER, ItemTypes.BROWN_BANNER, ItemTypes.GREEN_BANNER, ItemTypes.RED_BANNER, ItemTypes.BLACK_BANNER);
copy(BlockTags.SAND, ItemTags.SAND);
copy(BlockTags.SMELTS_TO_GLASS, ItemTags.SMELTS_TO_GLASS);
copy(BlockTags.STAIRS, ItemTags.STAIRS);
copy(BlockTags.SLABS, ItemTags.SLABS);
copy(BlockTags.WALLS, ItemTags.WALLS);
copy(BlockTags.ANVIL, ItemTags.ANVIL);
copy(BlockTags.RAILS, ItemTags.RAILS);
copy(BlockTags.LEAVES, ItemTags.LEAVES);
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);
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);
@@ -194,12 +184,9 @@ public class ItemTags {
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.BOATS.addTag(ItemTags.CHEST_BOATS).add(ItemTypes.OAK_BOAT, ItemTypes.SPRUCE_BOAT, ItemTypes.BIRCH_BOAT, ItemTypes.JUNGLE_BOAT, ItemTypes.ACACIA_BOAT, ItemTypes.DARK_OAK_BOAT, ItemTypes.MANGROVE_BOAT, ItemTypes.BAMBOO_RAFT, ItemTypes.CHERRY_BOAT);
ItemTags.CHEST_BOATS.add(ItemTypes.OAK_CHEST_BOAT, ItemTypes.SPRUCE_CHEST_BOAT, ItemTypes.BIRCH_CHEST_BOAT, ItemTypes.JUNGLE_CHEST_BOAT, ItemTypes.ACACIA_CHEST_BOAT, ItemTypes.DARK_OAK_CHEST_BOAT, ItemTypes.MANGROVE_CHEST_BOAT, ItemTypes.BAMBOO_CHEST_RAFT, ItemTypes.CHERRY_CHEST_BOAT);
ItemTags.FISHES.add(ItemTypes.COD, ItemTypes.COOKED_COD, ItemTypes.SALMON, ItemTypes.COOKED_SALMON, ItemTypes.PUFFERFISH, ItemTypes.TROPICAL_FISH);
copy(BlockTags.STANDING_SIGNS, ItemTags.SIGNS);
ItemTags.MUSIC_DISCS.addTag(ItemTags.CREEPER_DROP_MUSIC_DISCS).add(ItemTypes.MUSIC_DISC_PIGSTEP, ItemTypes.MUSIC_DISC_OTHERSIDE, ItemTypes.MUSIC_DISC_5, ItemTypes.MUSIC_DISC_RELIC);
ItemTags.CREEPER_DROP_MUSIC_DISCS.add(ItemTypes.MUSIC_DISC_13, ItemTypes.MUSIC_DISC_CAT, ItemTypes.MUSIC_DISC_BLOCKS, ItemTypes.MUSIC_DISC_CHIRP, ItemTypes.MUSIC_DISC_FAR, ItemTypes.MUSIC_DISC_MALL, ItemTypes.MUSIC_DISC_MELLOHI, ItemTypes.MUSIC_DISC_STAL, ItemTypes.MUSIC_DISC_STRAD, ItemTypes.MUSIC_DISC_WARD, ItemTypes.MUSIC_DISC_11, ItemTypes.MUSIC_DISC_WAIT);
ItemTags.COALS.add(ItemTypes.COAL, ItemTypes.CHARCOAL);
ItemTags.ARROWS.add(ItemTypes.ARROW, ItemTypes.TIPPED_ARROW, ItemTypes.SPECTRAL_ARROW);
@@ -210,7 +197,6 @@ public class ItemTags {
ItemTags.STONE_CRAFTING_MATERIALS.add(ItemTypes.COBBLESTONE, ItemTypes.BLACKSTONE, ItemTypes.COBBLED_DEEPSLATE);
ItemTags.FREEZE_IMMUNE_WEARABLES.add(ItemTypes.LEATHER_BOOTS, ItemTypes.LEATHER_LEGGINGS, ItemTypes.LEATHER_CHESTPLATE, ItemTypes.LEATHER_HELMET, ItemTypes.LEATHER_HORSE_ARMOR);
ItemTags.AXOLOTL_TEMPT_ITEMS.add(ItemTypes.TROPICAL_FISH_BUCKET);
copy(BlockTags.DAMPENS_VIBRATIONS, ItemTags.DAMPENS_VIBRATIONS);
ItemTags.CLUSTER_MAX_HARVESTABLES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.IRON_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.WOODEN_PICKAXE);
ItemTags.COMPASSES.add(ItemTypes.COMPASS, ItemTypes.RECOVERY_COMPASS);
copy(BlockTags.CEILING_HANGING_SIGNS, ItemTags.HANGING_SIGNS);
@@ -221,15 +207,29 @@ public class ItemTags {
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.SNIFFER_FOOD.add(ItemTypes.TORCHFLOWER_SEEDS);
ItemTags.DECORATED_POT_SHERDS.add(ItemTypes.ANGLER_POTTERY_SHERD, ItemTypes.ARCHER_POTTERY_SHERD, ItemTypes.ARMS_UP_POTTERY_SHERD, ItemTypes.BLADE_POTTERY_SHERD, ItemTypes.BREWER_POTTERY_SHERD, ItemTypes.BURN_POTTERY_SHERD, ItemTypes.DANGER_POTTERY_SHERD, ItemTypes.EXPLORER_POTTERY_SHERD, ItemTypes.FRIEND_POTTERY_SHERD, ItemTypes.HEART_POTTERY_SHERD, ItemTypes.HEARTBREAK_POTTERY_SHERD, ItemTypes.HOWL_POTTERY_SHERD, ItemTypes.MINER_POTTERY_SHERD, ItemTypes.MOURNER_POTTERY_SHERD, ItemTypes.PLENTY_POTTERY_SHERD, ItemTypes.PRIZE_POTTERY_SHERD, ItemTypes.SHEAF_POTTERY_SHERD, ItemTypes.SHELTER_POTTERY_SHERD, ItemTypes.SKULL_POTTERY_SHERD, ItemTypes.SNORT_POTTERY_SHERD);
ItemTags.DECORATED_POT_INGREDIENTS.addTag(ItemTags.DECORATED_POT_SHERDS).add(ItemTypes.BRICK);
ItemTags.SWORDS.add(ItemTypes.DIAMOND_SWORD, ItemTypes.STONE_SWORD, ItemTypes.GOLDEN_SWORD, ItemTypes.NETHERITE_SWORD, ItemTypes.WOODEN_SWORD, ItemTypes.IRON_SWORD);
ItemTags.AXES.add(ItemTypes.DIAMOND_AXE, ItemTypes.STONE_AXE, ItemTypes.GOLDEN_AXE, ItemTypes.NETHERITE_AXE, ItemTypes.WOODEN_AXE, ItemTypes.IRON_AXE);
ItemTags.HOES.add(ItemTypes.DIAMOND_HOE, ItemTypes.STONE_HOE, ItemTypes.GOLDEN_HOE, ItemTypes.NETHERITE_HOE, ItemTypes.WOODEN_HOE, ItemTypes.IRON_HOE);
ItemTags.PICKAXES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.IRON_PICKAXE);
ItemTags.SHOVELS.add(ItemTypes.DIAMOND_SHOVEL, ItemTypes.STONE_SHOVEL, ItemTypes.GOLDEN_SHOVEL, ItemTypes.NETHERITE_SHOVEL, ItemTypes.WOODEN_SHOVEL, ItemTypes.IRON_SHOVEL);
ItemTags.TOOLS.addTag(ItemTags.SWORDS).addTag(ItemTags.AXES).addTag(ItemTags.PICKAXES).addTag(ItemTags.SHOVELS).addTag(ItemTags.HOES).add(ItemTypes.TRIDENT);
ItemTags.BREAKS_DECORATED_POTS.addTag(ItemTags.TOOLS);
ItemTags.VILLAGER_PLANTABLE_SEEDS.add(ItemTypes.WHEAT_SEEDS, ItemTypes.POTATO, ItemTypes.CARROT, ItemTypes.BEETROOT_SEEDS, ItemTypes.TORCHFLOWER_SEEDS, ItemTypes.PITCHER_POD);
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;
}
@@ -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);
}
}
@@ -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,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 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
@@ -19,6 +19,7 @@
package com.github.retrooper.packetevents.util.adventure;
import com.github.retrooper.packetevents.netty.buffer.ByteBufInputStream;
import com.github.retrooper.packetevents.netty.buffer.ByteBufOutputStream;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.BlockNBTComponent;
@@ -35,8 +36,10 @@ import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.format.TextDecoration.State;
import net.kyori.adventure.text.serializer.json.JSONComponentConstants;
import java.io.DataInput;
@@ -56,6 +59,7 @@ import static net.kyori.adventure.text.Component.score;
import static net.kyori.adventure.text.Component.storageNBT;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
import static net.kyori.adventure.text.event.ClickEvent.clickEvent;
import static net.kyori.adventure.text.event.HoverEvent.ShowEntity.showEntity;
import static net.kyori.adventure.text.event.HoverEvent.ShowItem.showItem;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.CLICK_EVENT;
@@ -88,7 +92,7 @@ import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TR
public final class AdventureNBTSerialization {
private static final TagType[] NBT_TYPES = TagType.values();
private static final int DEPTH_LIMIT = 12;
private static final int DEPTH_LIMIT = 512;
// more constants
// decorations
@@ -148,6 +152,445 @@ public final class AdventureNBTSerialization {
}
}
public static Style readStyle(Object byteBuf) throws IOException {
return readStyle(new ByteBufInputStream(byteBuf));
}
public static Style readStyle(DataInput input) throws IOException {
TagType type = resolveNbtType(input.readByte());
return readStyle(input, type);
}
private static Style readStyle(DataInput input, TagType rootType) throws IOException {
return readStyle(input, rootType, 0);
}
private static Style readStyle(DataInput input, TagType rootType, int depth) throws IOException {
if (depth > DEPTH_LIMIT) {
throw new RuntimeException("Depth limit reached while decoding style: " + depth + " > " + DEPTH_LIMIT);
}
if (rootType != TagType.COMPOUND) {
throw new RuntimeException("Unsupported nbt tag type for style: " + rootType);
}
Style.Builder style = null;
// read until end
TagType type;
while ((type = resolveNbtType(input.readByte())) != TagType.END) {
String key = input.readUTF();
if (style == null) {
style = Style.style();
}
readStyle(style, key, type, input, depth);
}
return style == null ? Style.empty() : style.build();
}
@SuppressWarnings({"PatternValidation", "unchecked"}) // Key and HoverEvent
private static void readStyle(Style.Builder style, String key, TagType type,
DataInput input, int depth) throws IOException {
switch (key) {
case FONT:
requireType(type, TagType.STRING);
style.font(key(input.readUTF()));
break;
case COLOR:
requireType(type, TagType.STRING);
style.color(parseColor(input.readUTF()));
break;
case BOLD:
requireType(type, TagType.BYTE);
style.decoration(TextDecoration.BOLD, State.byBoolean(input.readBoolean()));
break;
case ITALIC:
requireType(type, TagType.BYTE);
style.decoration(TextDecoration.ITALIC, State.byBoolean(input.readBoolean()));
break;
case UNDERLINED:
requireType(type, TagType.BYTE);
style.decoration(TextDecoration.UNDERLINED, State.byBoolean(input.readBoolean()));
break;
case STRIKETHROUGH:
requireType(type, TagType.BYTE);
style.decoration(TextDecoration.STRIKETHROUGH, State.byBoolean(input.readBoolean()));
break;
case OBFUSCATED:
requireType(type, TagType.BYTE);
style.decoration(TextDecoration.OBFUSCATED, State.byBoolean(input.readBoolean()));
break;
case INSERTION:
requireType(type, TagType.STRING);
style.insertion(input.readUTF());
break;
case CLICK_EVENT:
requireType(type, TagType.COMPOUND);
ClickEvent.Action clickEventAction = null;
String clickEventValue = null;
TagType clickType;
while ((clickType = resolveNbtType(input.readByte())) != TagType.END) {
String clickKey = input.readUTF();
switch (clickKey) {
case CLICK_EVENT_ACTION:
requireType(clickType, TagType.STRING);
requireState(clickEventAction == null);
String actionId = input.readUTF();
switch (actionId) {
case OPEN_URL:
clickEventAction = ClickEvent.Action.OPEN_URL;
break;
case RUN_COMMAND:
clickEventAction = ClickEvent.Action.RUN_COMMAND;
break;
case SUGGEST_COMMAND:
clickEventAction = ClickEvent.Action.SUGGEST_COMMAND;
break;
case CHANGE_PAGE:
clickEventAction = ClickEvent.Action.CHANGE_PAGE;
break;
case COPY_TO_CLIPBOARD:
clickEventAction = ClickEvent.Action.COPY_TO_CLIPBOARD;
break;
default:
throw new IllegalStateException("Illegal click event action read: '" + actionId + "'");
}
break;
case CLICK_EVENT_VALUE:
requireType(clickType, TagType.STRING);
requireState(clickEventValue == null);
clickEventValue = input.readUTF();
break;
default:
throw new IllegalStateException("Illegal click event nbt key read: '" + clickKey + "'");
}
}
requireState(clickEventAction != null && clickEventValue != null);
style.clickEvent(clickEvent(clickEventAction, clickEventValue));
break;
case HOVER_EVENT:
requireType(type, TagType.COMPOUND);
HoverEvent.Action<?> hoverEventAction = null;
Object hoverEventContents = null;
TagType hoverType;
while ((hoverType = resolveNbtType(input.readByte())) != TagType.END) {
String hoverKey = input.readUTF();
switch (hoverKey) {
case HOVER_EVENT_ACTION:
requireType(hoverType, TagType.STRING);
requireState(hoverEventAction == null);
String actionId = input.readUTF();
switch (actionId) {
case SHOW_TEXT:
hoverEventAction = HoverEvent.Action.SHOW_TEXT;
break;
case SHOW_ITEM:
hoverEventAction = HoverEvent.Action.SHOW_ITEM;
break;
case SHOW_ENTITY:
hoverEventAction = HoverEvent.Action.SHOW_ENTITY;
break;
default:
throw new IllegalStateException("Illegal hover event action read: '" + actionId + "'");
}
break;
case HOVER_EVENT_CONTENTS:
requireState(hoverEventContents == null);
requireState(hoverEventAction != null);
switch (hoverEventAction.toString()) {
case SHOW_TEXT:
requireComponentType(hoverType);
hoverEventContents = readComponent(input, hoverType, depth + 1);
break;
case SHOW_ITEM:
if (hoverType == TagType.STRING) {
String itemId = input.readUTF();
hoverEventContents = showItem(key(itemId), 1);
} else {
requireType(hoverType, TagType.COMPOUND);
String itemId = null;
int count = 1;
String tag = null;
TagType itemType;
while ((itemType = resolveNbtType(input.readByte())) != TagType.END) {
String itemKey = input.readUTF();
switch (itemKey) {
case ITEM_ID:
requireType(itemType, TagType.STRING);
requireState(itemId == null);
itemId = input.readUTF();
break;
case ITEM_COUNT:
requireType(itemType, TagType.INT);
count = input.readInt();
break;
case ITEM_TAG:
requireType(itemType, TagType.STRING);
tag = input.readUTF();
break;
}
}
requireState(itemId != null);
hoverEventContents = showItem(key(itemId), count,
tag == null ? null : binaryTagHolder(tag));
}
break;
case SHOW_ENTITY:
requireType(hoverType, TagType.COMPOUND);
String entityType = null;
UUID entityId = null;
Component entityName = null;
TagType itemType;
while ((itemType = resolveNbtType(input.readByte())) != TagType.END) {
String itemKey = input.readUTF();
switch (itemKey) {
case ENTITY_TYPE:
requireType(itemType, TagType.STRING);
requireState(entityType == null);
entityType = input.readUTF();
break;
case ENTITY_ID:
requireType(itemType, TagType.INT_ARRAY);
requireState(entityId == null);
entityId = readUniqueId(input);
break;
case ENTITY_NAME:
requireComponentType(itemType);
requireState(entityName == null);
entityName = readComponent(input, itemType, depth + 1);
break;
}
}
requireState(entityType != null && entityId != null);
hoverEventContents = showEntity(key(entityType), entityId, entityName);
break;
}
break;
default:
throw new IllegalStateException("Illegal hover event nbt key read: '" + hoverKey + "'");
}
}
requireState(hoverEventContents != null);
// this is not unchecked, as it will 100% never fail - validated while reading
HoverEvent.Action<? super Object> unsafeAction = (HoverEvent.Action<? super Object>) hoverEventAction;
style.hoverEvent(HoverEvent.hoverEvent(unsafeAction, hoverEventContents));
break;
default:
throw new IllegalStateException("Illegal component nbt key read: '" + key + "'");
}
}
public static void writeStyle(Object byteBuf, Style style) throws IOException {
writeStyle(new ByteBufOutputStream(byteBuf), style);
}
public static void writeStyle(DataOutput output, Style style) throws IOException {
TagType tagType = TagType.COMPOUND;
output.writeByte(tagType.getId());
writeStyle(output, style, tagType);
output.writeByte(TagType.END.getId()); // ends style tag
}
private static void writeStyle(DataOutput output, Style style, TagType rootType) throws IOException {
if (rootType != TagType.COMPOUND) {
throw new UnsupportedEncodingException();
}
if (style.isEmpty()) {
return;
}
// font
Key font = style.font();
if (font != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(FONT);
output.writeUTF(font.asString());
}
// color
TextColor color = style.color();
if (color != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(COLOR);
output.writeUTF(stringifyColor(color));
}
// bold
State bold = style.decoration(TextDecoration.BOLD);
if (bold != State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(BOLD);
output.writeBoolean(bold == State.TRUE);
}
// italic
State italic = style.decoration(TextDecoration.ITALIC);
if (italic != State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(ITALIC);
output.writeBoolean(italic == State.TRUE);
}
// underlined
State underlined = style.decoration(TextDecoration.UNDERLINED);
if (underlined != State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(UNDERLINED);
output.writeBoolean(underlined == State.TRUE);
}
// strikethrough
State strikethrough = style.decoration(TextDecoration.STRIKETHROUGH);
if (strikethrough != State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(STRIKETHROUGH);
output.writeBoolean(strikethrough == State.TRUE);
}
// obfuscated
State obfuscated = style.decoration(TextDecoration.OBFUSCATED);
if (obfuscated != State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(OBFUSCATED);
output.writeBoolean(obfuscated == State.TRUE);
}
// insertion
String insertion = style.insertion();
if (insertion != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(INSERTION);
output.writeUTF(insertion);
}
// click event
ClickEvent clickEvent = style.clickEvent();
if (clickEvent != null) {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(CLICK_EVENT);
// click event action
ClickEvent.Action action = clickEvent.action();
output.writeByte(TagType.STRING.getId());
output.writeUTF(CLICK_EVENT_ACTION);
output.writeUTF(action.toString());
// click event value
String value = clickEvent.value();
output.writeByte(TagType.STRING.getId());
output.writeUTF(CLICK_EVENT_VALUE);
output.writeUTF(value);
output.writeByte(TagType.END.getId()); // ends compound
}
// hover event
HoverEvent<?> hoverEvent = style.hoverEvent();
if (hoverEvent != null) {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT);
// hover event action
HoverEvent.Action<?> action = hoverEvent.action();
output.writeByte(TagType.STRING.getId());
output.writeUTF(HOVER_EVENT_ACTION);
output.writeUTF(action.toString());
// hover event contents
switch (action.toString()) {
case SHOW_TEXT:
Component text = (Component) hoverEvent.value();
TagType textTagType = getComponentTagType(text);
output.writeByte(textTagType.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
writeComponent(output, text, textTagType);
break;
case SHOW_ITEM:
HoverEvent.ShowItem item = (HoverEvent.ShowItem) hoverEvent.value();
Key itemId = item.item();
int count = item.count();
BinaryTagHolder nbt = item.nbt();
if (count == 1 && nbt == null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
output.writeUTF(itemId.asString());
} else {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
// item id
output.writeByte(TagType.STRING.getId());
output.writeUTF(ITEM_ID);
output.writeUTF(itemId.asString());
// item count
if (count != 1) {
output.writeByte(TagType.INT.getId());
output.writeUTF(ITEM_COUNT);
output.writeInt(count);
}
// item nbt
if (nbt != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(ITEM_TAG);
output.writeUTF(nbt.string());
}
output.writeByte(TagType.END.getId()); // ends compound
}
break;
case SHOW_ENTITY:
HoverEvent.ShowEntity entity = (HoverEvent.ShowEntity) hoverEvent.value();
Key entityType = entity.type();
UUID entityId = entity.id();
Component entityName = entity.name();
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
// entity type
output.writeByte(TagType.STRING.getId());
output.writeUTF(ENTITY_TYPE);
output.writeUTF(entityType.asString());
// entity uuid
output.writeByte(TagType.INT_ARRAY.getId());
output.writeUTF(ENTITY_ID);
writeUniqueId(output, entityId);
// entity name
if (entityName != null) {
TagType nameTagType = getComponentTagType(entityName);
output.writeByte(nameTagType.getId());
output.writeUTF(ENTITY_NAME);
writeComponent(output, entityName, nameTagType);
}
output.writeByte(TagType.END.getId()); // ends compound
break;
}
output.writeByte(TagType.END.getId()); // ends compound
}
}
public static Component readComponent(Object byteBuf) throws IOException {
return readComponent(new ByteBufInputStream(byteBuf));
}
@@ -161,7 +604,7 @@ public final class AdventureNBTSerialization {
return readComponent(input, rootType, 0);
}
@SuppressWarnings({"PatternValidation", "unchecked"}) // Key and HoverEvent
@SuppressWarnings({"PatternValidation"}) // Key
private static Component readComponent(DataInput input, TagType rootType, int depth) throws IOException {
if (depth > DEPTH_LIMIT) {
throw new RuntimeException("Depth limit reached while decoding component: " + depth + " > " + DEPTH_LIMIT);
@@ -191,19 +634,7 @@ public final class AdventureNBTSerialization {
String nbtStorage = null;
Component separator = null;
// style
String font = null;
String color = null;
TextDecoration.State obfuscated = TextDecoration.State.NOT_SET;
TextDecoration.State bold = TextDecoration.State.NOT_SET;
TextDecoration.State strikethrough = TextDecoration.State.NOT_SET;
TextDecoration.State underlined = TextDecoration.State.NOT_SET;
TextDecoration.State italic = TextDecoration.State.NOT_SET;
String insertion = null;
ClickEvent.Action clickEventAction = null;
String clickEventValue = null;
HoverEvent.Action<?> hoverEventAction = null;
Object hoverEventContents = null;
Style.Builder style = null;
// read until end
TagType type;
@@ -301,204 +732,12 @@ public final class AdventureNBTSerialization {
requireState(separator == null);
separator = readComponent(input, type, depth + 1);
break;
case FONT:
requireType(type, TagType.STRING);
requireState(font == null);
font = input.readUTF();
break;
case COLOR:
requireType(type, TagType.STRING);
requireState(color == null);
color = input.readUTF();
break;
case BOLD:
requireType(type, TagType.BYTE);
requireState(bold == TextDecoration.State.NOT_SET);
bold = TextDecoration.State.byBoolean(input.readBoolean());
break;
case ITALIC:
requireType(type, TagType.BYTE);
requireState(italic == TextDecoration.State.NOT_SET);
italic = TextDecoration.State.byBoolean(input.readBoolean());
break;
case UNDERLINED:
requireType(type, TagType.BYTE);
requireState(underlined == TextDecoration.State.NOT_SET);
underlined = TextDecoration.State.byBoolean(input.readBoolean());
break;
case STRIKETHROUGH:
requireType(type, TagType.BYTE);
requireState(strikethrough == TextDecoration.State.NOT_SET);
strikethrough = TextDecoration.State.byBoolean(input.readBoolean());
break;
case OBFUSCATED:
requireType(type, TagType.BYTE);
requireState(obfuscated == TextDecoration.State.NOT_SET);
obfuscated = TextDecoration.State.byBoolean(input.readBoolean());
break;
case INSERTION:
requireType(type, TagType.STRING);
requireState(insertion == null);
insertion = input.readUTF();
break;
case CLICK_EVENT:
requireType(type, TagType.COMPOUND);
requireState(clickEventAction == null && clickEventValue == null);
TagType clickType;
while ((clickType = resolveNbtType(input.readByte())) != TagType.END) {
String clickKey = input.readUTF();
switch (clickKey) {
case CLICK_EVENT_ACTION:
requireType(clickType, TagType.STRING);
requireState(clickEventAction == null);
String actionId = input.readUTF();
switch (actionId) {
case OPEN_URL:
clickEventAction = ClickEvent.Action.OPEN_URL;
break;
case RUN_COMMAND:
clickEventAction = ClickEvent.Action.RUN_COMMAND;
break;
case SUGGEST_COMMAND:
clickEventAction = ClickEvent.Action.SUGGEST_COMMAND;
break;
case CHANGE_PAGE:
clickEventAction = ClickEvent.Action.CHANGE_PAGE;
break;
case COPY_TO_CLIPBOARD:
clickEventAction = ClickEvent.Action.COPY_TO_CLIPBOARD;
break;
default:
throw new IllegalStateException("Illegal click event action read: '" + actionId + "'");
}
break;
case CLICK_EVENT_VALUE:
requireType(clickType, TagType.STRING);
requireState(clickEventValue == null);
clickEventValue = input.readUTF();
break;
default:
throw new IllegalStateException("Illegal click event nbt key read: '" + clickKey + "'");
}
}
requireState(clickEventAction != null && clickEventValue != null);
break;
case HOVER_EVENT:
requireType(type, TagType.COMPOUND);
requireState(hoverEventAction == null);
TagType hoverType;
while ((hoverType = resolveNbtType(input.readByte())) != TagType.END) {
String hoverKey = input.readUTF();
switch (hoverKey) {
case HOVER_EVENT_ACTION:
requireType(hoverType, TagType.STRING);
requireState(hoverEventAction == null);
String actionId = input.readUTF();
switch (actionId) {
case SHOW_TEXT:
hoverEventAction = HoverEvent.Action.SHOW_TEXT;
break;
case SHOW_ITEM:
hoverEventAction = HoverEvent.Action.SHOW_ITEM;
break;
case SHOW_ENTITY:
hoverEventAction = HoverEvent.Action.SHOW_ENTITY;
break;
default:
throw new IllegalStateException("Illegal hover event action read: '" + actionId + "'");
}
break;
case HOVER_EVENT_CONTENTS:
requireState(hoverEventContents == null);
requireState(hoverEventAction != null);
switch (hoverEventAction.toString()) {
case SHOW_TEXT:
requireComponentType(hoverType);
hoverEventContents = readComponent(input, hoverType, depth + 1);
break;
case SHOW_ITEM:
if (hoverType == TagType.STRING) {
String itemId = input.readUTF();
hoverEventContents = showItem(key(itemId), 1);
} else {
requireType(hoverType, TagType.COMPOUND);
String itemId = null;
int count = 1;
String tag = null;
TagType itemType;
while ((itemType = resolveNbtType(input.readByte())) != TagType.END) {
String itemKey = input.readUTF();
switch (itemKey) {
case ITEM_ID:
requireType(itemType, TagType.STRING);
requireState(itemId == null);
itemId = input.readUTF();
break;
case ITEM_COUNT:
requireType(itemType, TagType.INT);
count = input.readInt();
break;
case ITEM_TAG:
requireType(itemType, TagType.STRING);
tag = input.readUTF();
break;
}
}
requireState(itemId != null);
hoverEventContents = showItem(key(itemId), count,
tag == null ? null : binaryTagHolder(tag));
}
break;
case SHOW_ENTITY:
requireType(hoverType, TagType.COMPOUND);
String entityType = null;
UUID entityId = null;
Component entityName = null;
TagType itemType;
while ((itemType = resolveNbtType(input.readByte())) != TagType.END) {
String itemKey = input.readUTF();
switch (itemKey) {
case ENTITY_TYPE:
requireType(itemType, TagType.STRING);
requireState(entityType == null);
entityType = input.readUTF();
break;
case ENTITY_ID:
requireType(itemType, TagType.INT_ARRAY);
requireState(entityId == null);
entityId = readUniqueId(input);
break;
case ENTITY_NAME:
requireComponentType(itemType);
requireState(entityName == null);
entityName = readComponent(input, itemType, depth + 1);
break;
}
}
requireState(entityType != null && entityId != null);
hoverEventContents = showEntity(key(entityType), entityId, entityName);
break;
}
break;
default:
throw new IllegalStateException("Illegal hover event nbt key read: '" + hoverKey + "'");
}
}
requireState(hoverEventContents != null);
break;
default:
throw new IllegalStateException("Illegal component nbt key read: '" + key + "'");
if (style == null) {
style = Style.style();
}
readStyle(style, key, type, input, depth);
break;
}
}
@@ -538,37 +777,8 @@ public final class AdventureNBTSerialization {
throw new IllegalStateException("Illegal nbt component, component type could not be determined");
}
if (font != null) {
builder.font(key(font));
}
if (color != null) {
builder.color(parseColor(color));
}
if (obfuscated != TextDecoration.State.NOT_SET) {
builder.decoration(TextDecoration.OBFUSCATED, obfuscated);
}
if (bold != TextDecoration.State.NOT_SET) {
builder.decoration(TextDecoration.BOLD, bold);
}
if (strikethrough != TextDecoration.State.NOT_SET) {
builder.decoration(TextDecoration.STRIKETHROUGH, strikethrough);
}
if (underlined != TextDecoration.State.NOT_SET) {
builder.decoration(TextDecoration.UNDERLINED, underlined);
}
if (italic != TextDecoration.State.NOT_SET) {
builder.decoration(TextDecoration.ITALIC, italic);
}
if (insertion != null) {
builder.insertion(insertion);
}
if (clickEventAction != null) {
builder.clickEvent(ClickEvent.clickEvent(clickEventAction, clickEventValue));
}
if (hoverEventAction != null) {
// this is not unchecked, as it will 100% never fail - validated while reading
HoverEvent.Action<? super Object> unsafeAction = (HoverEvent.Action<? super Object>) hoverEventAction;
builder.hoverEvent(HoverEvent.hoverEvent(unsafeAction, hoverEventContents));
if (style != null) {
builder.style(style.build());
}
if (extra != null) {
@@ -577,6 +787,10 @@ public final class AdventureNBTSerialization {
return builder.build();
}
public static void writeComponent(Object byteBuf, Component component) throws IOException {
writeComponent(new ByteBufOutputStream(byteBuf), component);
}
public static void writeComponent(DataOutput output, Component component) throws IOException {
TagType tagType = getComponentTagType(component);
output.writeByte(tagType.getId());
@@ -706,181 +920,7 @@ public final class AdventureNBTSerialization {
}
if (component.hasStyling()) {
// font
Key font = component.font();
if (font != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(FONT);
output.writeUTF(font.asString());
}
// color
TextColor color = component.color();
if (color != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(COLOR);
output.writeUTF(stringifyColor(color));
}
// bold
TextDecoration.State bold = component.decoration(TextDecoration.BOLD);
if (bold != TextDecoration.State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(BOLD);
output.writeBoolean(bold == TextDecoration.State.TRUE);
}
// italic
TextDecoration.State italic = component.decoration(TextDecoration.ITALIC);
if (italic != TextDecoration.State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(ITALIC);
output.writeBoolean(italic == TextDecoration.State.TRUE);
}
// underlined
TextDecoration.State underlined = component.decoration(TextDecoration.UNDERLINED);
if (underlined != TextDecoration.State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(UNDERLINED);
output.writeBoolean(underlined == TextDecoration.State.TRUE);
}
// strikethrough
TextDecoration.State strikethrough = component.decoration(TextDecoration.STRIKETHROUGH);
if (strikethrough != TextDecoration.State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(STRIKETHROUGH);
output.writeBoolean(strikethrough == TextDecoration.State.TRUE);
}
// obfuscated
TextDecoration.State obfuscated = component.decoration(TextDecoration.OBFUSCATED);
if (obfuscated != TextDecoration.State.NOT_SET) {
output.writeByte(TagType.BYTE.getId());
output.writeUTF(OBFUSCATED);
output.writeBoolean(obfuscated == TextDecoration.State.TRUE);
}
// insertion
String insertion = component.insertion();
if (insertion != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(INSERTION);
output.writeUTF(insertion);
}
// click event
ClickEvent clickEvent = component.clickEvent();
if (clickEvent != null) {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(CLICK_EVENT);
// click event action
ClickEvent.Action action = clickEvent.action();
output.writeByte(TagType.STRING.getId());
output.writeUTF(CLICK_EVENT_ACTION);
output.writeUTF(action.toString());
// click event value
String value = clickEvent.value();
output.writeByte(TagType.STRING.getId());
output.writeUTF(CLICK_EVENT_VALUE);
output.writeUTF(value);
output.writeByte(TagType.END.getId()); // ends compound
}
// hover event
HoverEvent<?> hoverEvent = component.hoverEvent();
if (hoverEvent != null) {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT);
// hover event action
HoverEvent.Action<?> action = hoverEvent.action();
output.writeByte(TagType.STRING.getId());
output.writeUTF(HOVER_EVENT_ACTION);
output.writeUTF(action.toString());
// hover event contents
switch (action.toString()) {
case SHOW_TEXT:
Component text = (Component) hoverEvent.value();
TagType textTagType = getComponentTagType(text);
output.writeByte(textTagType.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
writeComponent(output, text, textTagType);
break;
case SHOW_ITEM:
HoverEvent.ShowItem item = (HoverEvent.ShowItem) hoverEvent.value();
Key itemId = item.item();
int count = item.count();
BinaryTagHolder nbt = item.nbt();
if (count == 1 && nbt == null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
output.writeUTF(itemId.asString());
} else {
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
// item id
output.writeByte(TagType.STRING.getId());
output.writeUTF(ITEM_ID);
output.writeUTF(itemId.asString());
// item count
if (count != 1) {
output.writeByte(TagType.INT.getId());
output.writeUTF(ITEM_COUNT);
output.writeInt(count);
}
// item nbt
if (nbt != null) {
output.writeByte(TagType.STRING.getId());
output.writeUTF(ITEM_TAG);
output.writeUTF(nbt.string());
}
output.writeByte(TagType.END.getId()); // ends compound
}
break;
case SHOW_ENTITY:
HoverEvent.ShowEntity entity = (HoverEvent.ShowEntity) hoverEvent.value();
Key entityType = entity.type();
UUID entityId = entity.id();
Component entityName = entity.name();
// nested compound
output.writeByte(TagType.COMPOUND.getId());
output.writeUTF(HOVER_EVENT_CONTENTS);
// entity type
output.writeByte(TagType.STRING.getId());
output.writeUTF(ENTITY_TYPE);
output.writeUTF(entityType.asString());
// entity uuid
output.writeByte(TagType.INT_ARRAY.getId());
output.writeUTF(ENTITY_ID);
writeUniqueId(output, entityId);
// entity name
if (entityName != null) {
TagType nameTagType = getComponentTagType(entityName);
output.writeByte(nameTagType.getId());
output.writeUTF(ENTITY_NAME);
writeComponent(output, entityName, nameTagType);
}
output.writeByte(TagType.END.getId()); // ends compound
break;
}
output.writeByte(TagType.END.getId()); // ends compound
}
writeStyle(output, component.style(), TagType.COMPOUND);
}
// component children
@@ -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");
@@ -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;
}
@@ -25,7 +25,6 @@ import com.github.retrooper.packetevents.event.ProtocolPacketEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.manager.server.VersionComparison;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.netty.buffer.ByteBufOutputStream;
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
@@ -68,6 +67,7 @@ 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;
@@ -185,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) {
@@ -193,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.
@@ -210,6 +210,11 @@ public class PacketWrapper<T extends PacketWrapper> {
write();
}
@ApiStatus.Internal
public final void prepareForSend(Object channel, boolean outgoing) {
prepareForSend(channel, outgoing, PacketEvents.getAPI().getInjector().isProxy());
}
public void read() {
}
@@ -542,7 +547,7 @@ public class PacketWrapper<T extends PacketWrapper> {
public void writeComponentAsNBT(Component component) {
try {
AdventureNBTSerialization.writeComponent(new ByteBufOutputStream(this.buffer), component);
AdventureNBTSerialization.writeComponent(this.buffer, component);
} catch (IOException exception) {
throw new IllegalStateException(exception);
}
@@ -553,6 +558,22 @@ public class PacketWrapper<T extends PacketWrapper> {
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) {
return new ResourceLocation(readString(maxLen));
}
@@ -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;
}
}
@@ -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
@@ -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;
}
}
@@ -67,7 +67,7 @@ public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlay
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) {
@@ -84,7 +84,7 @@ public class WrapperPlayServerResourcePackSend extends PacketWrapper<WrapperPlay
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) {
@@ -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];
}
}
}
}
@@ -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();
@@ -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();
}
}
@@ -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.2.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 {
@@ -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) {
+1 -1
View File
@@ -1,4 +1,4 @@
name: packetevents
version: 2.2.0 #//TODO UPDATE
version: 2.2.1 #//TODO UPDATE
main: io.github.retrooper.packetevents.PacketEventsPlugin
author: retrooper
Binary file not shown.
+2 -1
View File
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+17 -12
View File
@@ -83,10 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,10 +131,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -45,6 +45,7 @@ import io.github.retrooper.packetevents.util.protocolsupport.ProtocolSupportUtil
import io.github.retrooper.packetevents.util.viaversion.CustomPipelineUtil;
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
@@ -164,6 +165,13 @@ public class SpigotPacketEventsBuilder {
checkCompatibility();
}
//Map player instances to the already registered channels (likely a reload)
for (Player player : Bukkit.getOnlinePlayers()) {
User user = PacketEvents.getAPI().getPlayerManager().getUser(player);
SpigotChannelInjector injector = (SpigotChannelInjector) PacketEvents.getAPI().getInjector();
injector.updatePlayer(user, player);
}
initialized = true;
}
}
@@ -115,7 +115,7 @@ public class SpigotChannelInjector implements ChannelInjector {
try {
ServerConnectionInitializer.initChannel(channel, ConnectionState.PLAY);
} catch (Exception e) {
System.out.println("Spigot injector failed to inject into an existing channel.");
PacketEvents.getAPI().getLogManager().severe("Spigot injector failed to inject into an existing channel.");
e.printStackTrace();
}
}
@@ -154,7 +154,7 @@ public final class SpigotReflectionUtil {
}
CRAFT_ITEM_STACK_AS_BUKKIT_COPY = Reflection.getMethod(CRAFT_ITEM_STACK_CLASS, "asBukkitCopy", 0);
CRAFT_ITEM_STACK_AS_NMS_COPY = Reflection.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", 0);
CRAFT_ITEM_STACK_AS_NMS_COPY = Reflection.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class);
// Had to hardcode the 1.12 vanilla names because some jar was screwing with it, fall back to normal mappings if not found
READ_ITEM_STACK_IN_PACKET_DATA_SERIALIZER_METHOD = Reflection.getMethodExact(NMS_PACKET_DATA_SERIALIZER_CLASS, "k", NMS_ITEM_STACK_CLASS);
@@ -865,7 +865,7 @@ public final class SpigotReflectionUtil {
}
}
} catch (Exception ex) {
System.out.println("Failed to find entity by id on 1.19.3!");
PacketEvents.getAPI().getLogManager().warn("Failed to find entity by id on 1.19.3!");
throw ex;
//We are retrying below
}
@@ -18,6 +18,7 @@
package io.github.retrooper.packetevents.util.viaversion;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.util.reflection.Reflection;
import io.netty.channel.Channel;
@@ -79,7 +80,7 @@ public class ViaVersionUtil {
Object protocolInfo = Reflection.getField(connection.getClass(), "protocolInfo").get(connection);
return (int) Reflection.getField(protocolInfo.getClass(), "protocolVersion").get(protocolInfo);
} catch (Exception e) {
System.out.println("Unable to grab ViaVersion client version for player!");
PacketEvents.getAPI().getLogManager().warn("Unable to grab ViaVersion client version for player!");
return -1;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: packetevents
version: 2.2.0 #//TODO UPDATE
version: 2.2.1 #//TODO UPDATE
api-version: 1.13
main: io.github.retrooper.packetevents.PacketEventsPlugin
author: retrooper
@@ -28,27 +28,30 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import io.github.retrooper.packetevents.bstats.Metrics;
import io.github.retrooper.packetevents.velocity.factory.VelocityPacketEventsBuilder;
import org.slf4j.Logger;
import java.util.logging.Logger;
import java.nio.file.Path;
@Plugin(id = "packetevents", name = "PacketEvents", version = "2.2.0") //TODO UPDATE
@Plugin(id = "packetevents", name = "PacketEvents",
description = "Packet library.", authors = {"retrooper"},
version = "2.2.1") //TODO UPDATE
public class PacketEventsPlugin {
private final ProxyServer server;
private final Logger logger;
private final PluginContainer pluginContainer;
public final Metrics.Factory metricsFactory;
private final Path dataDirectory;
@Inject
public PacketEventsPlugin(final ProxyServer server,
final Logger logger,
final PluginContainer pluginContainer, final Metrics.Factory metricsFactory) {
final PluginContainer pluginContainer, @DataDirectory Path dataDirectory) {
this.server = server;
this.logger = logger;
this.pluginContainer = pluginContainer;
this.metricsFactory = metricsFactory;
this.dataDirectory = dataDirectory;
logger.info("Plugin started");
}
@@ -56,9 +59,8 @@ public class PacketEventsPlugin {
@Subscribe
public void onProxyInitialize(ProxyInitializeEvent event) {
logger.info("Injecting packetevents...");
PacketEvents.setAPI(VelocityPacketEventsBuilder.build(server, pluginContainer));
PacketEvents.setAPI(VelocityPacketEventsBuilder.build(server, pluginContainer, logger, dataDirectory));
PacketEvents.getAPI().load();
PacketEvents.getAPI().getSettings().reEncodeByDefault(false);
// It should only be enabled in a development environment, not globally
// PacketEvents.getAPI().getSettings().debug(true);
PacketListenerAbstract listener = new PacketListenerAbstract() {
@@ -65,6 +65,12 @@ public class Metrics {
}
}
//PacketEvents - Start
public static Metrics createInstance(Object plugin, ProxyServer server, Logger logger, Path dataDirectory, int serviceId) {
return new Metrics(plugin, server, logger, dataDirectory, serviceId);
}
//PacketEvents - End
private final PluginContainer pluginContainer;
private final ProxyServer server;
private final MetricsBase metricsBase;
@@ -62,8 +62,14 @@ public class PacketEventsEncoder extends MessageToByteEncoder<ByteBuf> {
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
if (!msg.isReadable()) return;
read(ctx, msg);
out.writeBytes(msg);
ByteBuf transformed = ctx.alloc().buffer().writeBytes(msg);
try {
read(ctx, transformed);
out.writeBytes(transformed);
} finally {
transformed.release();
}
}
@Override
@@ -18,12 +18,6 @@
package io.github.retrooper.packetevents.velocity.factory;
import java.util.logging.Level;
import io.github.retrooper.packetevents.PacketEventsPlugin;
import io.github.retrooper.packetevents.bstats.Metrics;
import org.jetbrains.annotations.Nullable;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.event.UserLoginEvent;
@@ -43,7 +37,7 @@ import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
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;
@@ -51,6 +45,11 @@ import io.github.retrooper.packetevents.impl.netty.manager.server.ServerManagerA
import io.github.retrooper.packetevents.injector.VelocityPipelineInjector;
import io.github.retrooper.packetevents.manager.PlayerManagerImpl;
import net.kyori.adventure.text.format.NamedTextColor;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import java.nio.file.Path;
import java.util.logging.Level;
public class VelocityPacketEventsBuilder {
private static PacketEventsAPI<PluginContainer> INSTANCE;
@@ -59,26 +58,26 @@ public class VelocityPacketEventsBuilder {
INSTANCE = null;
}
public static PacketEventsAPI<PluginContainer> build(ProxyServer server, PluginContainer plugin) {
public static PacketEventsAPI<PluginContainer> build(ProxyServer server, PluginContainer plugin, Logger logger, Path dataDirectory) {
if (INSTANCE == null) {
INSTANCE = buildNoCache(server, plugin);
INSTANCE = buildNoCache(server, plugin, logger, dataDirectory);
}
return INSTANCE;
}
public static PacketEventsAPI<PluginContainer> build(ProxyServer server, PluginContainer plugin,
public static PacketEventsAPI<PluginContainer> build(ProxyServer server, PluginContainer plugin, Logger logger, Path dataDirectory,
PacketEventsSettings settings) {
if (INSTANCE == null) {
INSTANCE = buildNoCache(server, plugin, settings);
INSTANCE = buildNoCache(server, plugin, logger, dataDirectory, settings);
}
return INSTANCE;
}
public static PacketEventsAPI<PluginContainer> buildNoCache(ProxyServer server, PluginContainer plugin) {
return buildNoCache(server, plugin, new PacketEventsSettings());
public static PacketEventsAPI<PluginContainer> buildNoCache(ProxyServer server, PluginContainer plugin, Logger logger, Path dataDirectory) {
return buildNoCache(server, plugin, logger, dataDirectory, new PacketEventsSettings());
}
public static PacketEventsAPI<PluginContainer> buildNoCache(ProxyServer server, PluginContainer plugin,
public static PacketEventsAPI<PluginContainer> buildNoCache(ProxyServer server, PluginContainer plugin, Logger logger, Path dataDirectory,
PacketEventsSettings inSettings) {
return new PacketEventsAPI<PluginContainer>() {
private final PacketEventsSettings settings = inSettings;
@@ -171,9 +170,9 @@ public class VelocityPacketEventsBuilder {
}
if (settings.isbStatsEnabled()) {
PacketEventsPlugin instance = (PacketEventsPlugin) plugin.getInstance().orElse(null);
Object instance = plugin.getInstance().orElse(null);
if (instance != null) {
Metrics metrics = instance.metricsFactory.make(plugin, 11327);
Metrics metrics = Metrics.createInstance(plugin, server, logger, dataDirectory, 11327);
//Just to have an idea of which versions of packetevents people use
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
return getVersion().toString();