Refactored Bukkit adapters
This commit is contained in:
parent
83302f59f7
commit
afb13e6677
8 changed files with 944 additions and 358 deletions
|
|
@ -32,9 +32,17 @@ import org.bukkit.potion.PotionType;
|
|||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.utility.BlockUtils;
|
||||
|
||||
/**
|
||||
* Base adapter implementation for Bukkit API compatibility.
|
||||
* Provides default implementations for methods that work across multiple Minecraft versions.
|
||||
* Version-specific implementations extend this class to provide specialized behavior.
|
||||
*/
|
||||
public class BukkitAdapter implements BukkitInterface {
|
||||
|
||||
/** The currently active adapter instance */
|
||||
public static BukkitInterface ADAPTER;
|
||||
|
||||
// Version constants for Bukkit implementations
|
||||
public static final int BUKKIT_V1_13 = 13;
|
||||
public static final int BUKKIT_V1_14 = 14;
|
||||
public static final int BUKKIT_V1_15 = 15;
|
||||
|
|
@ -45,33 +53,39 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
public static final int BUKKIT_V1_20 = 20;
|
||||
public static final int BUKKIT_V1_21 = 21;
|
||||
|
||||
/**
|
||||
* Initializes the appropriate Bukkit adapter based on the server version.
|
||||
* This method should be called during plugin initialization.
|
||||
*/
|
||||
public static void loadAdapter() {
|
||||
switch (ConfigHandler.SERVER_VERSION) {
|
||||
case BUKKIT_V1_13:
|
||||
case BUKKIT_V1_14:
|
||||
case BUKKIT_V1_15:
|
||||
case BUKKIT_V1_16:
|
||||
BukkitAdapter.ADAPTER = new BukkitAdapter();
|
||||
ADAPTER = new BukkitAdapter();
|
||||
break;
|
||||
case BUKKIT_V1_17:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_17();
|
||||
ADAPTER = new Bukkit_v1_17();
|
||||
break;
|
||||
case BUKKIT_V1_18:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_18();
|
||||
ADAPTER = new Bukkit_v1_18();
|
||||
break;
|
||||
case BUKKIT_V1_19:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_19();
|
||||
ADAPTER = new Bukkit_v1_19();
|
||||
break;
|
||||
case BUKKIT_V1_20:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_20();
|
||||
ADAPTER = new Bukkit_v1_20();
|
||||
break;
|
||||
case BUKKIT_V1_21:
|
||||
default:
|
||||
BukkitAdapter.ADAPTER = new Bukkit_v1_21();
|
||||
ADAPTER = new Bukkit_v1_21();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- Basic data conversion methods --------------------
|
||||
|
||||
@Override
|
||||
public String parseLegacyName(String name) {
|
||||
return name;
|
||||
|
|
@ -82,6 +96,8 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// -------------------- Entity methods --------------------
|
||||
|
||||
@Override
|
||||
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
|
||||
return false;
|
||||
|
|
@ -92,6 +108,18 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType(Material material) {
|
||||
switch (material) {
|
||||
case END_CRYSTAL:
|
||||
return EntityType.valueOf("ENDER_CRYSTAL");
|
||||
default:
|
||||
return EntityType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- Item handling methods --------------------
|
||||
|
||||
@Override
|
||||
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot) {
|
||||
return false;
|
||||
|
|
@ -102,6 +130,45 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlantSeeds(Material material) {
|
||||
switch (material) {
|
||||
case WHEAT:
|
||||
return Material.WHEAT_SEEDS;
|
||||
case PUMPKIN_STEM:
|
||||
return Material.PUMPKIN_SEEDS;
|
||||
case MELON_STEM:
|
||||
return Material.MELON_SEEDS;
|
||||
case BEETROOTS:
|
||||
return Material.BEETROOT_SEEDS;
|
||||
default:
|
||||
return material;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack) {
|
||||
PotionData data = arrow.getBasePotionData();
|
||||
if (data.getType() != PotionType.valueOf("UNCRAFTABLE")) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionData(data);
|
||||
for (PotionEffect effect : arrow.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
// -------------------- Block methods --------------------
|
||||
|
||||
@Override
|
||||
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin) {
|
||||
if (blockData instanceof Directional && blockData instanceof FaceAttachable) {
|
||||
|
|
@ -139,9 +206,16 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return Material.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvisible(Material material) {
|
||||
return BlockUtils.isAir(material);
|
||||
}
|
||||
|
||||
// -------------------- Special block type checkers --------------------
|
||||
|
||||
@Override
|
||||
public boolean isItemFrame(Material material) {
|
||||
return (material == Material.ITEM_FRAME);
|
||||
return material == Material.ITEM_FRAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -159,75 +233,6 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return ItemFrame.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaxed(Sign sign) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvisible(Material material) {
|
||||
return BlockUtils.isAir(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Sign sign, boolean isFront, int color) {
|
||||
if (!isFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
sign.setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaxed(Sign sign, boolean isWaxed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getColor().getColor().asRGB();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlantSeeds(Material material) {
|
||||
switch (material) {
|
||||
case WHEAT:
|
||||
material = Material.WHEAT_SEEDS;
|
||||
break;
|
||||
case PUMPKIN_STEM:
|
||||
material = Material.PUMPKIN_SEEDS;
|
||||
break;
|
||||
case MELON_STEM:
|
||||
material = Material.MELON_SEEDS;
|
||||
break;
|
||||
case BEETROOTS:
|
||||
material = Material.BEETROOT_SEEDS;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecoratedPot(Material material) {
|
||||
return false;
|
||||
|
|
@ -258,6 +263,8 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
return null;
|
||||
}
|
||||
|
||||
// -------------------- Sign handling methods --------------------
|
||||
|
||||
@Override
|
||||
public String getLine(Sign sign, int line) {
|
||||
if (line < 4) {
|
||||
|
|
@ -285,31 +292,45 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack) {
|
||||
PotionData data = arrow.getBasePotionData();
|
||||
if (data.getType() != PotionType.valueOf("UNCRAFTABLE")) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionData(data);
|
||||
for (PotionEffect effect : arrow.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType(Material material) {
|
||||
switch (material) {
|
||||
case END_CRYSTAL:
|
||||
return EntityType.valueOf("ENDER_CRYSTAL");
|
||||
default:
|
||||
return EntityType.UNKNOWN;
|
||||
}
|
||||
public boolean isWaxed(Sign sign) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
// Base implementation does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Sign sign, boolean isFront, int color) {
|
||||
if (!isFront) {
|
||||
return;
|
||||
}
|
||||
|
||||
sign.setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWaxed(Sign sign, boolean isWaxed) {
|
||||
// Base implementation does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getColor().getColor().asRGB();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------- Registry methods --------------------
|
||||
|
||||
@Override
|
||||
public Object getRegistryKey(Object value) {
|
||||
return value;
|
||||
|
|
@ -319,5 +340,4 @@ public class BukkitAdapter implements BukkitInterface {
|
|||
public Object getRegistryValue(String key, Object tClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,76 +19,395 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
/**
|
||||
* Interface for Bukkit API compatibility across different Minecraft versions.
|
||||
* Each method provides version-specific implementations to handle differences
|
||||
* between Minecraft/Bukkit API versions.
|
||||
*/
|
||||
public interface BukkitInterface {
|
||||
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack);
|
||||
// --------------------------------------------------------------------------
|
||||
// Block-related methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
public Material getBucketContents(Material material);
|
||||
/**
|
||||
* Checks if a block is attached to another block.
|
||||
*
|
||||
* @param block
|
||||
* The base block
|
||||
* @param scanBlock
|
||||
* The block to check for attachment
|
||||
* @param blockData
|
||||
* The block data
|
||||
* @param scanMin
|
||||
* The minimum scan value
|
||||
* @return true if the block is attached, false otherwise
|
||||
*/
|
||||
boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin);
|
||||
|
||||
public Material getFrameType(Entity entity);
|
||||
/**
|
||||
* Gets the minimum height of a world.
|
||||
*
|
||||
* @param world
|
||||
* The world
|
||||
* @return The minimum height
|
||||
*/
|
||||
int getMinHeight(World world);
|
||||
|
||||
public Material getFrameType(EntityType type);
|
||||
/**
|
||||
* Gets the legacy block ID for a material.
|
||||
*
|
||||
* @param material
|
||||
* The material
|
||||
* @return The legacy block ID, or -1 if not applicable
|
||||
*/
|
||||
int getLegacyBlockId(Material material);
|
||||
|
||||
public Class<?> getFrameClass(Material material);
|
||||
/**
|
||||
* Gets the contents of a bucket material.
|
||||
*
|
||||
* @param material
|
||||
* The bucket material
|
||||
* @return The material inside the bucket, or AIR if not applicable
|
||||
*/
|
||||
Material getBucketContents(Material material);
|
||||
|
||||
public String parseLegacyName(String name);
|
||||
// --------------------------------------------------------------------------
|
||||
// Material type checking methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
public boolean getEntityMeta(LivingEntity entity, List<Object> info);
|
||||
/**
|
||||
* Checks if a material is an item frame.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is an item frame, false otherwise
|
||||
*/
|
||||
boolean isItemFrame(Material material);
|
||||
|
||||
public boolean setEntityMeta(Entity entity, Object value, int count);
|
||||
/**
|
||||
* Checks if a material is invisible.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is invisible, false otherwise
|
||||
*/
|
||||
boolean isInvisible(Material material);
|
||||
|
||||
public boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot);
|
||||
/**
|
||||
* Checks if a material is a decorated pot.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a decorated pot, false otherwise
|
||||
*/
|
||||
boolean isDecoratedPot(Material material);
|
||||
|
||||
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map);
|
||||
/**
|
||||
* Checks if a material is a suspicious block.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a suspicious block, false otherwise
|
||||
*/
|
||||
boolean isSuspiciousBlock(Material material);
|
||||
|
||||
public boolean isAttached(Block block, Block scanBlock, BlockData blockData, int scanMin);
|
||||
/**
|
||||
* Checks if a material is a sign.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a sign, false otherwise
|
||||
*/
|
||||
boolean isSign(Material material);
|
||||
|
||||
public boolean isItemFrame(Material material);
|
||||
/**
|
||||
* Checks if a material is a chiseled bookshelf.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a chiseled bookshelf, false otherwise
|
||||
*/
|
||||
boolean isChiseledBookshelf(Material material);
|
||||
|
||||
public boolean isGlowing(Sign sign, boolean isFront);
|
||||
/**
|
||||
* Checks if a material is a bookshelf book.
|
||||
*
|
||||
* @param material
|
||||
* The material to check
|
||||
* @return true if the material is a bookshelf book, false otherwise
|
||||
*/
|
||||
boolean isBookshelfBook(Material material);
|
||||
|
||||
public boolean isInvisible(Material material);
|
||||
/**
|
||||
* Gets the seeds material for a plant material.
|
||||
*
|
||||
* @param material
|
||||
* The plant material
|
||||
* @return The seeds material
|
||||
*/
|
||||
Material getPlantSeeds(Material material);
|
||||
|
||||
public boolean isWaxed(Sign sign);
|
||||
// --------------------------------------------------------------------------
|
||||
// Item and inventory methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
public int getMinHeight(World world);
|
||||
/**
|
||||
* Adjusts an ingredient in a merchant recipe.
|
||||
*
|
||||
* @param recipe
|
||||
* The merchant recipe
|
||||
* @param itemStack
|
||||
* The item stack
|
||||
* @return The adjusted item stack, or null if not applicable
|
||||
*/
|
||||
ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack);
|
||||
|
||||
public int getLegacyBlockId(Material material);
|
||||
/**
|
||||
* Gets metadata from an item meta.
|
||||
*
|
||||
* @param itemMeta
|
||||
* The item meta
|
||||
* @param list
|
||||
* The list to populate with metadata
|
||||
* @param metadata
|
||||
* The metadata list to populate
|
||||
* @param slot
|
||||
* The slot
|
||||
* @return true if metadata was extracted, false otherwise
|
||||
*/
|
||||
boolean getItemMeta(ItemMeta itemMeta, List<Map<String, Object>> list, List<List<Map<String, Object>>> metadata, int slot);
|
||||
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing);
|
||||
/**
|
||||
* Sets metadata on an item stack.
|
||||
*
|
||||
* @param rowType
|
||||
* The material type
|
||||
* @param itemstack
|
||||
* The item stack
|
||||
* @param map
|
||||
* The metadata map
|
||||
* @return true if metadata was set, false otherwise
|
||||
*/
|
||||
boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map);
|
||||
|
||||
public void setColor(Sign sign, boolean isFront, int color);
|
||||
/**
|
||||
* Gets a book from a chiseled bookshelf.
|
||||
*
|
||||
* @param blockState
|
||||
* The block state
|
||||
* @param event
|
||||
* The player interact event
|
||||
* @return The book item stack, or null if not applicable
|
||||
*/
|
||||
ItemStack getChiseledBookshelfBook(BlockState blockState, PlayerInteractEvent event);
|
||||
|
||||
public void setWaxed(Sign sign, boolean isWaxed);
|
||||
/**
|
||||
* Gets arrow metadata for an item stack.
|
||||
*
|
||||
* @param arrow
|
||||
* The arrow entity
|
||||
* @param itemStack
|
||||
* The item stack
|
||||
* @return The item stack with arrow metadata
|
||||
*/
|
||||
ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack);
|
||||
|
||||
public int getColor(Sign sign, boolean isFront);
|
||||
// --------------------------------------------------------------------------
|
||||
// Entity methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
public Material getPlantSeeds(Material material);
|
||||
/**
|
||||
* Gets metadata from a living entity.
|
||||
*
|
||||
* @param entity
|
||||
* The living entity
|
||||
* @param info
|
||||
* The list to populate with entity metadata
|
||||
* @return true if metadata was extracted, false otherwise
|
||||
*/
|
||||
boolean getEntityMeta(LivingEntity entity, List<Object> info);
|
||||
|
||||
public boolean isDecoratedPot(Material material);
|
||||
/**
|
||||
* Sets metadata on an entity.
|
||||
*
|
||||
* @param entity
|
||||
* The entity
|
||||
* @param value
|
||||
* The metadata value
|
||||
* @param count
|
||||
* The count
|
||||
* @return true if metadata was set, false otherwise
|
||||
*/
|
||||
boolean setEntityMeta(Entity entity, Object value, int count);
|
||||
|
||||
public boolean isSuspiciousBlock(Material material);
|
||||
/**
|
||||
* Gets the frame type for an entity.
|
||||
*
|
||||
* @param entity
|
||||
* The entity
|
||||
* @return The frame material type
|
||||
*/
|
||||
Material getFrameType(Entity entity);
|
||||
|
||||
public boolean isSign(Material material);
|
||||
/**
|
||||
* Gets the frame type for an entity type.
|
||||
*
|
||||
* @param type
|
||||
* The entity type
|
||||
* @return The frame material type
|
||||
*/
|
||||
Material getFrameType(EntityType type);
|
||||
|
||||
public boolean isChiseledBookshelf(Material material);
|
||||
/**
|
||||
* Gets the entity type for a material.
|
||||
*
|
||||
* @param material
|
||||
* The material
|
||||
* @return The entity type
|
||||
*/
|
||||
EntityType getEntityType(Material material);
|
||||
|
||||
public boolean isBookshelfBook(Material material);
|
||||
/**
|
||||
* Gets the frame class for a material.
|
||||
*
|
||||
* @param material
|
||||
* The material
|
||||
* @return The frame class
|
||||
*/
|
||||
Class<?> getFrameClass(Material material);
|
||||
|
||||
public ItemStack getChiseledBookshelfBook(BlockState blockState, PlayerInteractEvent event);
|
||||
// --------------------------------------------------------------------------
|
||||
// Sign methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
public String getLine(Sign sign, int line);
|
||||
/**
|
||||
* Checks if a sign is glowing.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param isFront
|
||||
* Whether to check the front side
|
||||
* @return true if the sign is glowing, false otherwise
|
||||
*/
|
||||
boolean isGlowing(Sign sign, boolean isFront);
|
||||
|
||||
public void setLine(Sign sign, int line, String string);
|
||||
/**
|
||||
* Checks if a sign is waxed.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @return true if the sign is waxed, false otherwise
|
||||
*/
|
||||
boolean isWaxed(Sign sign);
|
||||
|
||||
public boolean isSignFront(SignChangeEvent event);
|
||||
/**
|
||||
* Sets whether a sign is glowing.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param isFront
|
||||
* Whether to set the front side
|
||||
* @param isGlowing
|
||||
* Whether the sign should be glowing
|
||||
*/
|
||||
void setGlowing(Sign sign, boolean isFront, boolean isGlowing);
|
||||
|
||||
public ItemStack getArrowMeta(Arrow arrow, ItemStack itemStack);
|
||||
/**
|
||||
* Sets the color of a sign.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param isFront
|
||||
* Whether to set the front side
|
||||
* @param color
|
||||
* The color RGB value
|
||||
*/
|
||||
void setColor(Sign sign, boolean isFront, int color);
|
||||
|
||||
public EntityType getEntityType(Material material);
|
||||
/**
|
||||
* Sets whether a sign is waxed.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param isWaxed
|
||||
* Whether the sign should be waxed
|
||||
*/
|
||||
void setWaxed(Sign sign, boolean isWaxed);
|
||||
|
||||
public Object getRegistryKey(Object value);
|
||||
/**
|
||||
* Gets the color of a sign.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param isFront
|
||||
* Whether to get the front side color
|
||||
* @return The color RGB value
|
||||
*/
|
||||
int getColor(Sign sign, boolean isFront);
|
||||
|
||||
public Object getRegistryValue(String key, Object tClass);
|
||||
/**
|
||||
* Gets a line of text from a sign.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param line
|
||||
* The line number (0-based)
|
||||
* @return The text on the line
|
||||
*/
|
||||
String getLine(Sign sign, int line);
|
||||
|
||||
/**
|
||||
* Sets a line of text on a sign.
|
||||
*
|
||||
* @param sign
|
||||
* The sign
|
||||
* @param line
|
||||
* The line number (0-based)
|
||||
* @param string
|
||||
* The text to set
|
||||
*/
|
||||
void setLine(Sign sign, int line, String string);
|
||||
|
||||
/**
|
||||
* Checks if a sign change event is for the front side of the sign.
|
||||
*
|
||||
* @param event
|
||||
* The sign change event
|
||||
* @return true if the event is for the front side, false otherwise
|
||||
*/
|
||||
boolean isSignFront(SignChangeEvent event);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Registry methods
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the registry key for a value.
|
||||
*
|
||||
* @param value
|
||||
* The value
|
||||
* @return The registry key
|
||||
*/
|
||||
Object getRegistryKey(Object value);
|
||||
|
||||
/**
|
||||
* Gets a registry value by key and class.
|
||||
*
|
||||
* @param key
|
||||
* The key
|
||||
* @param tClass
|
||||
* The class
|
||||
* @return The registry value
|
||||
*/
|
||||
Object getRegistryValue(String key, Object tClass);
|
||||
|
||||
/**
|
||||
* Parses a legacy material name.
|
||||
*
|
||||
* @param name
|
||||
* The legacy name
|
||||
* @return The parsed name
|
||||
*/
|
||||
String parseLegacyName(String name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,18 +28,44 @@ import net.coreprotect.model.BlockGroup;
|
|||
import net.coreprotect.utility.ItemUtils;
|
||||
import net.coreprotect.utility.MaterialUtils;
|
||||
|
||||
/**
|
||||
* Bukkit adapter implementation for Minecraft 1.17.
|
||||
* Provides version-specific implementations for the BukkitInterface
|
||||
* to handle features introduced in the 1.17 update.
|
||||
*/
|
||||
public class Bukkit_v1_17 extends BukkitAdapter {
|
||||
|
||||
/**
|
||||
* Initializes the Bukkit_v1_17 adapter with 1.17-specific block groups.
|
||||
* Sets up collections of blocks with similar behavior for efficient handling.
|
||||
*/
|
||||
public Bukkit_v1_17() {
|
||||
initializeBlockGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all the block groups for Minecraft 1.17.
|
||||
* This includes new blocks like amethyst, candles, pointed dripstone, etc.
|
||||
*/
|
||||
private void initializeBlockGroups() {
|
||||
BlockGroup.TRACK_ANY = new HashSet<>(Arrays.asList(Material.PISTON_HEAD, Material.LEVER, Material.BELL, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.GLOW_LICHEN));
|
||||
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
|
||||
BlockGroup.TRACK_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.POINTED_DRIPSTONE, Material.BIG_DRIPLEAF_STEM));
|
||||
|
||||
BlockGroup.TRACK_BOTTOM = new HashSet<>(Arrays.asList(Material.WEEPING_VINES, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.HANGING_ROOTS));
|
||||
|
||||
BlockGroup.VINES = new HashSet<>(Arrays.asList(Material.VINE, Material.WEEPING_VINES, Material.TWISTING_VINES, Material.CAVE_VINES));
|
||||
|
||||
BlockGroup.CANDLES = new HashSet<>(Arrays.asList(Material.CANDLE, Material.BLACK_CANDLE, Material.BLUE_CANDLE, Material.BROWN_CANDLE, Material.CYAN_CANDLE, Material.GRAY_CANDLE, Material.GREEN_CANDLE, Material.LIGHT_BLUE_CANDLE, Material.LIGHT_GRAY_CANDLE, Material.LIME_CANDLE, Material.MAGENTA_CANDLE, Material.ORANGE_CANDLE, Material.PINK_CANDLE, Material.PURPLE_CANDLE, Material.RED_CANDLE, Material.WHITE_CANDLE, Material.YELLOW_CANDLE, Material.CANDLE_CAKE, Material.BLACK_CANDLE_CAKE, Material.BLUE_CANDLE_CAKE, Material.BROWN_CANDLE_CAKE, Material.CYAN_CANDLE_CAKE, Material.GRAY_CANDLE_CAKE, Material.GREEN_CANDLE_CAKE, Material.LIGHT_BLUE_CANDLE_CAKE, Material.LIGHT_GRAY_CANDLE_CAKE, Material.LIME_CANDLE_CAKE, Material.MAGENTA_CANDLE_CAKE, Material.ORANGE_CANDLE_CAKE, Material.PINK_CANDLE_CAKE, Material.PURPLE_CANDLE_CAKE, Material.RED_CANDLE_CAKE, Material.WHITE_CANDLE_CAKE, Material.YELLOW_CANDLE_CAKE));
|
||||
|
||||
BlockGroup.AMETHYST = new HashSet<>(Arrays.asList(Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER));
|
||||
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON));
|
||||
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
|
||||
BlockGroup.VERTICAL_TOP_BOTTOM = new HashSet<>(Arrays.asList(Material.BIG_DRIPLEAF_STEM));
|
||||
}
|
||||
|
||||
|
|
@ -47,13 +73,10 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
public String parseLegacyName(String name) {
|
||||
switch (name) {
|
||||
case "GRASS_PATH":
|
||||
name = "DIRT_PATH";
|
||||
break;
|
||||
return "DIRT_PATH";
|
||||
default:
|
||||
break;
|
||||
return name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -71,19 +94,15 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
if (entity instanceof Axolotl) {
|
||||
Axolotl axolotl = (Axolotl) entity;
|
||||
info.add(axolotl.getVariant());
|
||||
return true;
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
info.add(goat.isScreaming());
|
||||
}
|
||||
else if (super.getEntityMeta(entity, info)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.getEntityMeta(entity, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,25 +110,21 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
if (entity instanceof Axolotl) {
|
||||
Axolotl axolotl = (Axolotl) entity;
|
||||
if (count == 0) {
|
||||
org.bukkit.entity.Axolotl.Variant set = (org.bukkit.entity.Axolotl.Variant) value;
|
||||
axolotl.setVariant(set);
|
||||
org.bukkit.entity.Axolotl.Variant variant = (org.bukkit.entity.Axolotl.Variant) value;
|
||||
axolotl.setVariant(variant);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
if (count == 0) {
|
||||
boolean set = (Boolean) value;
|
||||
goat.setScreaming(set);
|
||||
boolean isScreaming = (Boolean) value;
|
||||
goat.setScreaming(isScreaming);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (super.setEntityMeta(entity, value, count)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.setEntityMeta(entity, value, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -131,20 +146,15 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
}
|
||||
metadata.add(list);
|
||||
}
|
||||
}
|
||||
else if (super.getItemMeta(itemMeta, list, metadata, slot)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.getItemMeta(itemMeta, list, metadata, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setItemMeta(Material rowType, ItemStack itemstack, List<Map<String, Object>> map) {
|
||||
if ((rowType == Material.BUNDLE)) {
|
||||
if (rowType == Material.BUNDLE) {
|
||||
BundleMeta meta = (BundleMeta) itemstack.getItemMeta();
|
||||
for (Map<String, Object> itemData : map) {
|
||||
ItemStack itemStack = ItemUtils.unserializeItemStack(itemData);
|
||||
|
|
@ -153,15 +163,10 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
}
|
||||
}
|
||||
itemstack.setItemMeta(meta);
|
||||
}
|
||||
else if (super.setItemMeta(rowType, itemstack, map)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.setItemMeta(rowType, itemstack, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -170,15 +175,10 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
PointedDripstone pointedDripstone = (PointedDripstone) blockData;
|
||||
BlockFace blockFace = pointedDripstone.getVerticalDirection();
|
||||
boolean adjacent = scanBlock.getRelative(blockFace.getOppositeFace()).getLocation().equals(block.getLocation());
|
||||
if (!adjacent) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!super.isAttached(block, scanBlock, blockData, scanMin)) {
|
||||
return false;
|
||||
return adjacent;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.isAttached(block, scanBlock, blockData, scanMin);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -188,7 +188,7 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
|
||||
@Override
|
||||
public Material getBucketContents(Material material) {
|
||||
return (material == Material.POWDER_SNOW_BUCKET ? Material.POWDER_SNOW : Material.AIR);
|
||||
return (material == Material.POWDER_SNOW_BUCKET) ? Material.POWDER_SNOW : Material.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -240,5 +240,4 @@ public class Bukkit_v1_17 extends BukkitAdapter {
|
|||
public boolean isInvisible(Material material) {
|
||||
return material.isAir() || material == Material.LIGHT;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,28 +3,59 @@ package net.coreprotect.bukkit;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
|
||||
/**
|
||||
* Bukkit adapter implementation for Minecraft 1.18.
|
||||
* Provides version-specific implementations for the BukkitInterface
|
||||
* to handle features introduced in the 1.18 update.
|
||||
*/
|
||||
public class Bukkit_v1_18 extends Bukkit_v1_17 {
|
||||
|
||||
private Boolean hasAdjust = null;
|
||||
/**
|
||||
* Flag to track whether the MerchantRecipe.adjust() method is available.
|
||||
* This is initialized on first use and prevents repeated reflection checks.
|
||||
* - null: Not yet checked
|
||||
* - true: Method exists and should be used
|
||||
* - false: Method doesn't exist or failed, fallback to parent implementation
|
||||
*/
|
||||
private Boolean hasAdjustMethod = null;
|
||||
|
||||
/**
|
||||
* Adjusts an ingredient in a merchant recipe for version 1.18+.
|
||||
* This handles changes to the MerchantRecipe API introduced in Bukkit 1.18.1.
|
||||
*
|
||||
* @param recipe
|
||||
* The merchant recipe
|
||||
* @param itemStack
|
||||
* The item stack to adjust
|
||||
* @return The adjusted item stack, or null if adjustment not supported or fails
|
||||
*/
|
||||
@Override
|
||||
public ItemStack adjustIngredient(MerchantRecipe recipe, ItemStack itemStack) {
|
||||
if (itemStack == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (hasAdjust == null) {
|
||||
hasAdjust = true;
|
||||
// First-time detection of adjust method availability
|
||||
if (hasAdjustMethod == null) {
|
||||
hasAdjustMethod = true;
|
||||
// Test if the adjust method exists using reflection
|
||||
MerchantRecipe.class.getMethod("adjust", ItemStack.class); // Bukkit 1.18.1+
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasAdjust)) {
|
||||
return null;
|
||||
// Skip if we've already determined the method isn't available
|
||||
else if (Boolean.FALSE.equals(hasAdjustMethod)) {
|
||||
return super.adjustIngredient(recipe, itemStack);
|
||||
}
|
||||
|
||||
// Create a clone to avoid modifying the original itemStack
|
||||
ItemStack adjustedStack = itemStack.clone();
|
||||
recipe.adjust(adjustedStack);
|
||||
return adjustedStack;
|
||||
}
|
||||
catch (Exception e) {
|
||||
hasAdjust = false;
|
||||
return null;
|
||||
// Method doesn't exist or failed, mark it for future calls
|
||||
hasAdjustMethod = false;
|
||||
return super.adjustIngredient(recipe, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,85 +13,228 @@ import org.bukkit.entity.Tadpole;
|
|||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
/**
|
||||
* Bukkit adapter implementation for Minecraft 1.19.
|
||||
* Provides version-specific implementations for the BukkitInterface
|
||||
* to handle features introduced in the 1.19 update, including:
|
||||
* - New block types (mangrove)
|
||||
* - New entity types (frogs, tadpoles)
|
||||
* - Updates to existing entities (goats)
|
||||
* - Sculk blocks
|
||||
*/
|
||||
public class Bukkit_v1_19 extends Bukkit_v1_18 {
|
||||
|
||||
/**
|
||||
* Initializes the Bukkit_v1_19 adapter with 1.19-specific block groups.
|
||||
* Sets up collections of blocks with similar behavior for efficient handling.
|
||||
*/
|
||||
public Bukkit_v1_19() {
|
||||
initializeBlockGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all the block groups for Minecraft 1.19.
|
||||
* This organizes blocks into functional categories for efficient lookups and operations.
|
||||
*/
|
||||
private void initializeBlockGroups() {
|
||||
// Blocks that need tracking from the top face
|
||||
initializeTrackTopBlocks();
|
||||
|
||||
// Blocks that need tracking from the side
|
||||
initializeTrackSideBlocks();
|
||||
|
||||
// Door blocks
|
||||
initializeDoorBlocks();
|
||||
|
||||
// Button blocks
|
||||
initializeButtonBlocks();
|
||||
|
||||
// Pressure plate blocks
|
||||
initializePressurePlateBlocks();
|
||||
|
||||
// Blocks that can be interacted with
|
||||
initializeInteractBlocks();
|
||||
|
||||
// Blocks that can be safely interacted with (won't cause block updates)
|
||||
initializeSafeInteractBlocks();
|
||||
|
||||
// Blocks that can't have other blocks attached to them
|
||||
initializeNonAttachableBlocks();
|
||||
|
||||
// Sculk blocks (new in 1.19)
|
||||
initializeSculkBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks that need tracking from their top face.
|
||||
*/
|
||||
private void initializeTrackTopBlocks() {
|
||||
BlockGroup.TRACK_TOP = new HashSet<>(Arrays.asList(Material.TORCH, Material.REDSTONE_TORCH, Material.BAMBOO, Material.BAMBOO_SAPLING, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.SCAFFOLDING, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.REDSTONE_WIRE, Material.WHEAT, Material.MANGROVE_SIGN, Material.ACACIA_SIGN, Material.BIRCH_SIGN, Material.DARK_OAK_SIGN, Material.JUNGLE_SIGN, Material.OAK_SIGN, Material.SPRUCE_SIGN, Material.WHITE_BANNER, Material.ORANGE_BANNER, Material.MAGENTA_BANNER, Material.LIGHT_BLUE_BANNER, Material.YELLOW_BANNER, Material.LIME_BANNER, Material.PINK_BANNER, Material.GRAY_BANNER, Material.LIGHT_GRAY_BANNER, Material.CYAN_BANNER, Material.PURPLE_BANNER, Material.BLUE_BANNER, Material.BROWN_BANNER, Material.GREEN_BANNER, Material.RED_BANNER, Material.BLACK_BANNER, Material.RAIL, Material.IRON_DOOR, Material.SNOW, Material.CACTUS, Material.SUGAR_CANE, Material.REPEATER, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.CARROT, Material.POTATO, Material.COMPARATOR, Material.ACTIVATOR_RAIL, Material.SUNFLOWER, Material.LILAC, Material.TALL_GRASS, Material.LARGE_FERN, Material.ROSE_BUSH, Material.PEONY, Material.NETHER_WART, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.KELP, Material.SOUL_TORCH, Material.TWISTING_VINES, Material.CRIMSON_FUNGUS, Material.WARPED_FUNGUS, Material.CRIMSON_ROOTS, Material.WARPED_ROOTS, Material.NETHER_SPROUTS, Material.CRIMSON_SIGN, Material.WARPED_SIGN, Material.AZALEA, Material.FLOWERING_AZALEA, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks that need tracking from their side.
|
||||
*/
|
||||
private void initializeTrackSideBlocks() {
|
||||
BlockGroup.TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.MANGROVE_WALL_SIGN, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER, Material.SOUL_WALL_TORCH, Material.CRIMSON_WALL_SIGN, Material.WARPED_WALL_SIGN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes door blocks.
|
||||
*/
|
||||
private void initializeDoorBlocks() {
|
||||
BlockGroup.DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.MANGROVE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR, Material.CRIMSON_DOOR, Material.WARPED_DOOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes button blocks.
|
||||
*/
|
||||
private void initializeButtonBlocks() {
|
||||
BlockGroup.BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.MANGROVE_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON, Material.POLISHED_BLACKSTONE_BUTTON, Material.CRIMSON_BUTTON, Material.WARPED_BUTTON));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes pressure plate blocks.
|
||||
*/
|
||||
private void initializePressurePlateBlocks() {
|
||||
BlockGroup.PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.MANGROVE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE, Material.CRIMSON_PRESSURE_PLATE, Material.WARPED_PRESSURE_PLATE, Material.POLISHED_BLACKSTONE_PRESSURE_PLATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks that can be interacted with.
|
||||
*/
|
||||
private void initializeInteractBlocks() {
|
||||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks that can be safely interacted with.
|
||||
*/
|
||||
private void initializeSafeInteractBlocks() {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.LEVER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks that can't have other blocks attached to them.
|
||||
*/
|
||||
private void initializeNonAttachableBlocks() {
|
||||
BlockGroup.NON_ATTACHABLE = new HashSet<>(Arrays.asList(Material.AIR, Material.CAVE_AIR, Material.BARRIER, Material.CORNFLOWER, Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SWEET_BERRY_BUSH, Material.OAK_SAPLING, Material.SPRUCE_SAPLING, Material.BIRCH_SAPLING, Material.JUNGLE_SAPLING, Material.MANGROVE_PROPAGULE, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING, Material.WATER, Material.LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FERN, Material.DEAD_BUSH, Material.DANDELION, Material.POPPY, Material.BLUE_ORCHID, Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.LADDER, Material.RAIL, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.SNOW, Material.SUGAR_CANE, Material.NETHER_PORTAL, Material.REPEATER, Material.KELP, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.LIGHT, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF, Material.BIG_DRIPLEAF_STEM, Material.GLOW_LICHEN, Material.HANGING_ROOTS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes sculk blocks (new in 1.19).
|
||||
*/
|
||||
private void initializeSculkBlocks() {
|
||||
BlockGroup.SCULK = new HashSet<>(Arrays.asList(Material.SCULK, Material.SCULK_VEIN, Material.SCULK_SENSOR, Material.SCULK_SHRIEKER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets metadata from a living entity specific to 1.19.
|
||||
* Handles Frog, Tadpole, and updated Goat entities.
|
||||
*
|
||||
* @param entity
|
||||
* The living entity
|
||||
* @param info
|
||||
* The list to populate with entity metadata
|
||||
* @return true if metadata was extracted, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean getEntityMeta(LivingEntity entity, List<Object> info) {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
info.add(BukkitAdapter.ADAPTER.getRegistryKey(frog.getVariant()));
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
info.add(tadpole.getAge());
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
info.add(goat.isScreaming());
|
||||
info.add(goat.hasLeftHorn());
|
||||
info.add(goat.hasRightHorn());
|
||||
}
|
||||
else if (super.getEntityMeta(entity, info)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (entity == null || info == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
try {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
info.add(BukkitAdapter.ADAPTER.getRegistryKey(frog.getVariant()));
|
||||
return true;
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
info.add(tadpole.getAge());
|
||||
return true;
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
info.add(goat.isScreaming());
|
||||
info.add(goat.hasLeftHorn());
|
||||
info.add(goat.hasRightHorn());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fall back to parent implementation if not a known 1.19 entity
|
||||
return super.getEntityMeta(entity, info);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Log error or handle exception if needed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets metadata on an entity specific to 1.19.
|
||||
* Handles Frog, Tadpole, and updated Goat entities.
|
||||
*
|
||||
* @param entity
|
||||
* The entity
|
||||
* @param value
|
||||
* The metadata value
|
||||
* @param count
|
||||
* The index of the metadata property
|
||||
* @return true if metadata was set, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean setEntityMeta(Entity entity, Object value, int count) {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
if (count == 0) {
|
||||
if (value instanceof String) {
|
||||
value = BukkitAdapter.ADAPTER.getRegistryValue((String) value, Frog.Variant.class);
|
||||
}
|
||||
Frog.Variant set = (Frog.Variant) value;
|
||||
frog.setVariant(set);
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
if (count == 0) {
|
||||
int set = (int) value;
|
||||
tadpole.setAge(set);
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
boolean set = (Boolean) value;
|
||||
if (count == 0) {
|
||||
goat.setScreaming(set);
|
||||
}
|
||||
else if (count == 1) {
|
||||
goat.setLeftHorn(set);
|
||||
}
|
||||
else if (count == 2) {
|
||||
goat.setRightHorn(set);
|
||||
}
|
||||
}
|
||||
else if (super.setEntityMeta(entity, value, count)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (entity == null || value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
try {
|
||||
if (entity instanceof Frog) {
|
||||
Frog frog = (Frog) entity;
|
||||
if (count == 0) {
|
||||
// Convert string registry key to variant if needed
|
||||
if (value instanceof String) {
|
||||
value = BukkitAdapter.ADAPTER.getRegistryValue((String) value, Frog.Variant.class);
|
||||
}
|
||||
frog.setVariant((Frog.Variant) value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Tadpole) {
|
||||
Tadpole tadpole = (Tadpole) entity;
|
||||
if (count == 0) {
|
||||
tadpole.setAge((int) value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (entity instanceof Goat) {
|
||||
Goat goat = (Goat) entity;
|
||||
boolean boolValue = (Boolean) value;
|
||||
|
||||
switch (count) {
|
||||
case 0:
|
||||
goat.setScreaming(boolValue);
|
||||
return true;
|
||||
case 1:
|
||||
goat.setLeftHorn(boolValue);
|
||||
return true;
|
||||
case 2:
|
||||
goat.setRightHorn(boolValue);
|
||||
return true;
|
||||
default:
|
||||
// Invalid count for goat
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to parent implementation if not a known 1.19 entity
|
||||
return super.setEntityMeta(entity, value, count);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Log error or handle exception if needed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package net.coreprotect.bukkit;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
|
|
@ -21,67 +22,76 @@ import org.bukkit.potion.PotionType;
|
|||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
/**
|
||||
* Bukkit adapter implementation for Minecraft 1.20.
|
||||
* Provides version-specific implementations for the BukkitInterface
|
||||
* to handle features introduced in the 1.20 update, including:
|
||||
* - Updated sign handling with front/back sides
|
||||
* - New block types (chiseled bookshelf, decorated pot)
|
||||
* - Suspicious blocks (sand/gravel)
|
||||
* - Arrow potion handling
|
||||
*/
|
||||
public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
||||
|
||||
private Boolean hasClickedPosition = null;
|
||||
private Boolean hasBasePotionType = null;
|
||||
private Boolean hasClickedPosition;
|
||||
private Boolean hasBasePotionType;
|
||||
|
||||
/**
|
||||
* Initializes the Bukkit_v1_20 adapter with 1.20-specific block groups and mappings.
|
||||
* Sets up collections of blocks with similar behavior for efficient handling.
|
||||
*/
|
||||
public Bukkit_v1_20() {
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF, Material.DECORATED_POT));
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON, Material.CHISELED_BOOKSHELF));
|
||||
initializeBlockGroups();
|
||||
initializeTaggedBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the block groups specific to Minecraft 1.20.
|
||||
*/
|
||||
private void initializeBlockGroups() {
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF, Material.DECORATED_POT));
|
||||
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON, Material.CHISELED_BOOKSHELF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes blocks based on Bukkit Tags for 1.20.
|
||||
*/
|
||||
private void initializeTaggedBlocks() {
|
||||
// Clear and update button blocks from tag
|
||||
BlockGroup.BUTTONS.clear();
|
||||
BlockGroup.BUTTONS.addAll(Tag.BUTTONS.getValues());
|
||||
|
||||
// Clear and update pressure plate blocks from tag
|
||||
BlockGroup.PRESSURE_PLATES.clear();
|
||||
BlockGroup.PRESSURE_PLATES.addAll(Tag.PRESSURE_PLATES.getValues());
|
||||
|
||||
for (Material value : Tag.DOORS.getValues()) {
|
||||
if (!BlockGroup.DOORS.contains(value)) {
|
||||
BlockGroup.DOORS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.FENCE_GATES.getValues()) {
|
||||
if (!BlockGroup.INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.WOODEN_TRAPDOORS.getValues()) {
|
||||
if (!BlockGroup.INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.CEILING_HANGING_SIGNS.getValues()) {
|
||||
if (!BlockGroup.TRACK_BOTTOM.contains(value)) {
|
||||
BlockGroup.TRACK_BOTTOM.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.WALL_SIGNS.getValues()) {
|
||||
if (!BlockGroup.TRACK_SIDE.contains(value)) {
|
||||
BlockGroup.TRACK_SIDE.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.SAPLINGS.getValues()) {
|
||||
if (!BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
}
|
||||
if (!BlockGroup.NON_ATTACHABLE.contains(value)) {
|
||||
BlockGroup.NON_ATTACHABLE.add(value);
|
||||
}
|
||||
}
|
||||
for (Material value : Tag.FLOWERS.getValues()) {
|
||||
if (!BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
}
|
||||
if (!BlockGroup.NON_ATTACHABLE.contains(value)) {
|
||||
BlockGroup.NON_ATTACHABLE.add(value);
|
||||
}
|
||||
}
|
||||
// Add all doors from tag
|
||||
addMissingTaggedBlocks(Tag.DOORS.getValues(), BlockGroup.DOORS);
|
||||
|
||||
// Add all fence gates to interaction blocks
|
||||
addMissingTaggedBlocks(Tag.FENCE_GATES.getValues(), BlockGroup.INTERACT_BLOCKS);
|
||||
addMissingTaggedBlocks(Tag.FENCE_GATES.getValues(), BlockGroup.SAFE_INTERACT_BLOCKS);
|
||||
|
||||
// Add all wooden trapdoors to interaction blocks
|
||||
addMissingTaggedBlocks(Tag.WOODEN_TRAPDOORS.getValues(), BlockGroup.INTERACT_BLOCKS);
|
||||
addMissingTaggedBlocks(Tag.WOODEN_TRAPDOORS.getValues(), BlockGroup.SAFE_INTERACT_BLOCKS);
|
||||
|
||||
// Add hanging signs to bottom-tracked blocks
|
||||
addMissingTaggedBlocks(Tag.CEILING_HANGING_SIGNS.getValues(), BlockGroup.TRACK_BOTTOM);
|
||||
|
||||
// Add wall signs to side-tracked blocks
|
||||
addMissingTaggedBlocks(Tag.WALL_SIGNS.getValues(), BlockGroup.TRACK_SIDE);
|
||||
|
||||
// Add saplings to top-tracked and non-attachable blocks
|
||||
addMissingTaggedBlocks(Tag.SAPLINGS.getValues(), BlockGroup.TRACK_TOP);
|
||||
addMissingTaggedBlocks(Tag.SAPLINGS.getValues(), BlockGroup.NON_ATTACHABLE);
|
||||
|
||||
// Add flowers to top-tracked and non-attachable blocks
|
||||
addMissingTaggedBlocks(Tag.FLOWERS.getValues(), BlockGroup.TRACK_TOP);
|
||||
addMissingTaggedBlocks(Tag.FLOWERS.getValues(), BlockGroup.NON_ATTACHABLE);
|
||||
|
||||
// Add signs (except wall signs) to top-tracked blocks
|
||||
for (Material value : Tag.SIGNS.getValues()) {
|
||||
if (!Tag.WALL_SIGNS.isTagged(value) && !BlockGroup.TRACK_TOP.contains(value)) {
|
||||
BlockGroup.TRACK_TOP.add(value);
|
||||
|
|
@ -89,48 +99,50 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to add missing blocks from a tag to a block group.
|
||||
*
|
||||
* @param taggedBlocks
|
||||
* The collection of blocks from a tag
|
||||
* @param targetGroup
|
||||
* The block group to add missing blocks to
|
||||
*/
|
||||
private void addMissingTaggedBlocks(Iterable<Material> taggedBlocks, Set<Material> targetGroup) {
|
||||
for (Material value : taggedBlocks) {
|
||||
if (!targetGroup.contains(value)) {
|
||||
targetGroup.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlowing(Sign sign, boolean isFront, boolean isGlowing) {
|
||||
if (isFront) {
|
||||
sign.getSide(Side.FRONT).setGlowingText(isGlowing);
|
||||
}
|
||||
else {
|
||||
sign.getSide(Side.BACK).setGlowingText(isGlowing);
|
||||
}
|
||||
Side side = isFront ? Side.FRONT : Side.BACK;
|
||||
sign.getSide(side).setGlowingText(isGlowing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseLegacyName(String name) {
|
||||
switch (name) {
|
||||
case "GRASS_PATH":
|
||||
name = "DIRT_PATH";
|
||||
break;
|
||||
return "DIRT_PATH";
|
||||
case "GRASS":
|
||||
name = "SHORT_GRASS";
|
||||
break;
|
||||
return "SHORT_GRASS";
|
||||
case "SCUTE":
|
||||
name = "TURTLE_SCUTE";
|
||||
break;
|
||||
return "TURTLE_SCUTE";
|
||||
default:
|
||||
break;
|
||||
// Fallback until this method is moved up into v1_21
|
||||
if ("SHORT_GRASS".equals(name) && Material.getMaterial(name) == null) {
|
||||
return "GRASS";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// fallback until this method is moved up into v1_21
|
||||
if (name.equals("SHORT_GRASS") && Material.getMaterial(name) == null) {
|
||||
name = "GRASS";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Sign sign, boolean isFront, int color) {
|
||||
if (isFront) {
|
||||
sign.getSide(Side.FRONT).setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
else {
|
||||
sign.getSide(Side.BACK).setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
Side side = isFront ? Side.FRONT : Side.BACK;
|
||||
sign.getSide(side).setColor(DyeColor.getByColor(Color.fromRGB(color)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -140,22 +152,14 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
|
||||
@Override
|
||||
public int getColor(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getSide(Side.FRONT).getColor().getColor().asRGB();
|
||||
}
|
||||
else {
|
||||
return sign.getSide(Side.BACK).getColor().getColor().asRGB();
|
||||
}
|
||||
Side side = isFront ? Side.FRONT : Side.BACK;
|
||||
return sign.getSide(side).getColor().getColor().asRGB();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlowing(Sign sign, boolean isFront) {
|
||||
if (isFront) {
|
||||
return sign.getSide(Side.FRONT).isGlowingText();
|
||||
}
|
||||
else {
|
||||
return sign.getSide(Side.BACK).isGlowingText();
|
||||
}
|
||||
Side side = isFront ? Side.FRONT : Side.BACK;
|
||||
return sign.getSide(side).isGlowingText();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -167,24 +171,18 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
public Material getPlantSeeds(Material material) {
|
||||
switch (material) {
|
||||
case WHEAT:
|
||||
material = Material.WHEAT_SEEDS;
|
||||
break;
|
||||
return Material.WHEAT_SEEDS;
|
||||
case PUMPKIN_STEM:
|
||||
material = Material.PUMPKIN_SEEDS;
|
||||
break;
|
||||
return Material.PUMPKIN_SEEDS;
|
||||
case MELON_STEM:
|
||||
material = Material.MELON_SEEDS;
|
||||
break;
|
||||
return Material.MELON_SEEDS;
|
||||
case BEETROOTS:
|
||||
material = Material.BEETROOT_SEEDS;
|
||||
break;
|
||||
return Material.BEETROOT_SEEDS;
|
||||
case TORCHFLOWER_CROP:
|
||||
material = Material.TORCHFLOWER_SEEDS;
|
||||
break;
|
||||
return Material.TORCHFLOWER_SEEDS;
|
||||
default:
|
||||
return material;
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -217,14 +215,17 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
try {
|
||||
if (hasClickedPosition == null) {
|
||||
hasClickedPosition = true;
|
||||
PlayerInteractEvent.class.getMethod("getClickedPosition"); // Bukkit 1.20.1+
|
||||
// Check if getClickedPosition method exists (Bukkit 1.20.1+)
|
||||
PlayerInteractEvent.class.getMethod("getClickedPosition");
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasClickedPosition)) {
|
||||
return null;
|
||||
return null; // Method doesn't exist, return null
|
||||
}
|
||||
|
||||
ChiseledBookshelf chiseledBookshelf = (ChiseledBookshelf) blockState;
|
||||
ItemStack book = chiseledBookshelf.getInventory().getItem(chiseledBookshelf.getSlot(event.getClickedPosition()));
|
||||
ChiseledBookshelf bookshelf = (ChiseledBookshelf) blockState;
|
||||
int slot = bookshelf.getSlot(event.getClickedPosition());
|
||||
ItemStack book = bookshelf.getInventory().getItem(slot);
|
||||
|
||||
return book == null ? new ItemStack(Material.AIR) : book;
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
@ -245,9 +246,7 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
|
||||
@Override
|
||||
public void setLine(Sign sign, int line, String string) {
|
||||
if (string == null) {
|
||||
string = "";
|
||||
}
|
||||
string = string == null ? "" : string;
|
||||
|
||||
if (line < 4) {
|
||||
sign.getSide(Side.FRONT).setLine(line, string);
|
||||
|
|
@ -267,22 +266,27 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
try {
|
||||
if (hasBasePotionType == null) {
|
||||
hasBasePotionType = true;
|
||||
Arrow.class.getMethod("getBasePotionType"); // Bukkit 1.20.2+
|
||||
// Check if getBasePotionType method exists (Bukkit 1.20.2+)
|
||||
Arrow.class.getMethod("getBasePotionType");
|
||||
}
|
||||
else if (Boolean.FALSE.equals(hasBasePotionType)) {
|
||||
return super.getArrowMeta(arrow, itemStack);
|
||||
}
|
||||
|
||||
// Apply potion effects to the arrow
|
||||
PotionType potionType = arrow.getBasePotionType();
|
||||
Color color = arrow.getColor();
|
||||
|
||||
if (potionType != null || color != null) {
|
||||
itemStack = new ItemStack(Material.TIPPED_ARROW);
|
||||
PotionMeta meta = (PotionMeta) itemStack.getItemMeta();
|
||||
meta.setBasePotionType(potionType);
|
||||
meta.setColor(color);
|
||||
|
||||
for (PotionEffect effect : arrow.getCustomEffects()) {
|
||||
meta.addCustomEffect(effect, false);
|
||||
}
|
||||
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
|
|
@ -293,5 +297,4 @@ public class Bukkit_v1_20 extends Bukkit_v1_19 {
|
|||
return super.getArrowMeta(arrow, itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package net.coreprotect.bukkit;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Keyed;
|
||||
|
|
@ -12,27 +13,79 @@ import org.bukkit.entity.EntityType;
|
|||
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
|
||||
/**
|
||||
* Bukkit adapter implementation for Minecraft 1.21.
|
||||
* Provides version-specific implementations for the BukkitInterface
|
||||
* to handle features introduced in the 1.21 update, including:
|
||||
* - New block types (crafter)
|
||||
* - Registry handling for named objects
|
||||
* - Updated interaction blocks
|
||||
*/
|
||||
public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
||||
|
||||
/**
|
||||
* Initializes the Bukkit_v1_21 adapter with 1.21-specific block groups and mappings.
|
||||
* Sets up collections of blocks with similar behavior for efficient handling.
|
||||
*/
|
||||
public Bukkit_v1_21() {
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF, Material.DECORATED_POT, Material.CRAFTER));
|
||||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR, Material.CRAFTER));
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON, Material.CHISELED_BOOKSHELF, Material.CRAFTER));
|
||||
initializeBlockGroups();
|
||||
initializeTrapdoorBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the block groups specific to Minecraft 1.21.
|
||||
* Updates container, interaction, and update state blocks with new 1.21 blocks.
|
||||
*/
|
||||
private void initializeBlockGroups() {
|
||||
// Container blocks in 1.21 (added CRAFTER)
|
||||
BlockGroup.CONTAINERS = new HashSet<>(Arrays.asList(Material.JUKEBOX, Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN, Material.CHISELED_BOOKSHELF, Material.DECORATED_POT, Material.CRAFTER));
|
||||
|
||||
// Interaction blocks in 1.21 (comprehensive list including CRAFTER)
|
||||
BlockGroup.INTERACT_BLOCKS = new HashSet<>(Arrays.asList(Material.SPRUCE_FENCE_GATE, Material.BIRCH_FENCE_GATE, Material.JUNGLE_FENCE_GATE, Material.DARK_OAK_FENCE_GATE, Material.MANGROVE_FENCE_GATE, Material.ACACIA_FENCE_GATE, Material.DISPENSER, Material.NOTE_BLOCK, Material.CHEST, Material.FURNACE, Material.LEVER, Material.REPEATER, Material.MANGROVE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.DARK_OAK_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.OAK_TRAPDOOR, Material.OAK_FENCE_GATE, Material.BREWING_STAND, Material.ANVIL, Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.ENDER_CHEST, Material.TRAPPED_CHEST, Material.COMPARATOR, Material.HOPPER, Material.DROPPER, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.GRINDSTONE, Material.LOOM, Material.SMOKER, Material.CRAFTING_TABLE, Material.CARTOGRAPHY_TABLE, Material.ENCHANTING_TABLE, Material.SMITHING_TABLE, Material.STONECUTTER, Material.CRIMSON_FENCE_GATE, Material.WARPED_FENCE_GATE, Material.CRIMSON_TRAPDOOR, Material.WARPED_TRAPDOOR, Material.CRAFTER));
|
||||
|
||||
// Update state blocks in 1.21 (added CRAFTER to redstone responsive blocks)
|
||||
BlockGroup.UPDATE_STATE = new HashSet<>(Arrays.asList(Material.TORCH, Material.WALL_TORCH, Material.REDSTONE_WIRE, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.FURNACE, Material.BLAST_FURNACE, Material.SMOKER, Material.LEVER, Material.REDSTONE_TORCH, Material.REDSTONE_WALL_TORCH, Material.GLOWSTONE, Material.JACK_O_LANTERN, Material.REPEATER, Material.REDSTONE_LAMP, Material.BEACON, Material.COMPARATOR, Material.DAYLIGHT_DETECTOR, Material.REDSTONE_BLOCK, Material.HOPPER, Material.CHEST, Material.TRAPPED_CHEST, Material.ACTIVATOR_RAIL, Material.SOUL_TORCH, Material.SOUL_WALL_TORCH, Material.SHROOMLIGHT, Material.RESPAWN_ANCHOR, Material.CRYING_OBSIDIAN, Material.TARGET, Material.SMALL_AMETHYST_BUD, Material.MEDIUM_AMETHYST_BUD, Material.LARGE_AMETHYST_BUD, Material.AMETHYST_CLUSTER, Material.CAVE_VINES, Material.CAVE_VINES_PLANT, Material.GLOW_LICHEN, Material.LIGHT, Material.LAVA_CAULDRON, Material.CHISELED_BOOKSHELF, Material.CRAFTER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes trapdoor blocks for interaction handling.
|
||||
* Excludes iron trapdoors as they cannot be directly interacted with.
|
||||
*/
|
||||
private void initializeTrapdoorBlocks() {
|
||||
for (Material value : Tag.TRAPDOORS.getValues()) {
|
||||
// Iron trapdoors are not directly interactable
|
||||
if (value == Material.IRON_TRAPDOOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!BlockGroup.INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
if (!BlockGroup.SAFE_INTERACT_BLOCKS.contains(value)) {
|
||||
BlockGroup.SAFE_INTERACT_BLOCKS.add(value);
|
||||
}
|
||||
// Add to interaction blocks if not already present
|
||||
addToBlockGroupIfMissing(value, BlockGroup.INTERACT_BLOCKS);
|
||||
addToBlockGroupIfMissing(value, BlockGroup.SAFE_INTERACT_BLOCKS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to add a block to a block group if it's not already present.
|
||||
*
|
||||
* @param block
|
||||
* The block to add
|
||||
* @param group
|
||||
* The group to add the block to
|
||||
*/
|
||||
private void addToBlockGroupIfMissing(Material block, Set<Material> group) {
|
||||
if (!group.contains(block)) {
|
||||
group.add(block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EntityType corresponding to a Material.
|
||||
* Maps Material to its equivalent EntityType for entity handling.
|
||||
*
|
||||
* @param material
|
||||
* The material to convert
|
||||
* @return The corresponding EntityType, or UNKNOWN if not mappable
|
||||
*/
|
||||
@Override
|
||||
public EntityType getEntityType(Material material) {
|
||||
switch (material) {
|
||||
|
|
@ -43,17 +96,34 @@ public class Bukkit_v1_21 extends Bukkit_v1_20 implements BukkitInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a registry key string from a keyed object.
|
||||
* Used for serializing objects that implement Keyed.
|
||||
*
|
||||
* @param value
|
||||
* The keyed object
|
||||
* @return The string representation of the registry key
|
||||
*/
|
||||
@Override
|
||||
public Object getRegistryKey(Object value) {
|
||||
return ((Keyed) value).getKey().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a registry value from a key string and class.
|
||||
* Used for deserializing registry objects.
|
||||
*
|
||||
* @param key
|
||||
* The registry key as a string
|
||||
* @param tClass
|
||||
* The class of the registry
|
||||
* @return The registry value
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public Object getRegistryValue(String key, Object tClass) {
|
||||
NamespacedKey namespacedKey = NamespacedKey.fromString(key);
|
||||
// return RegistryAccess.registryAccess().getRegistry(RegistryKey.CAT_VARIANT).get((NamespacedKey)value);
|
||||
return Bukkit.getRegistry((Class) tClass).get(namespacedKey);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue