Skip to content

Commit

Permalink
bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Envel-Nikita-Gutsenkov committed Nov 5, 2024
1 parent f9d8ed6 commit e9b2b49
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,78 +1,74 @@
package com.lauriethefish.betterportals.bukkit.nms;

import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.BlockPosition;
import com.lauriethefish.betterportals.api.IntVector;
import com.lauriethefish.betterportals.shared.util.ReflectionUtil;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Method;

public class BlockDataUtil {
private static final Method GET_HANDLE;
private static final Method GET_COMBINED_ID;
private static final Method GET_FROM_COMBINED_ID;
private static final Method FROM_HANDLE;
private static final Method GET_TILE_ENTITY;
private static final Method GET_UPDATE_PACKET;

static {
Class<?> nmsBlock = ReflectionUtil.findClass("net.minecraft.world.level.block.Block");
Class<?> craftBlockData = CraftBukkitClassUtil.findCraftBukkitClass("block.data.CraftBlockData");
Class<?> nmsBlockData = ReflectionUtil.findClass("net.minecraft.world.level.block.state.IBlockData");

// Reflection to get necessary methods
GET_HANDLE = ReflectionUtil.findMethod(craftBlockData, "getState");
GET_COMBINED_ID = ReflectionUtil.findMethod(nmsBlock, "getCombinedId", nmsBlockData);
GET_FROM_COMBINED_ID = ReflectionUtil.findMethod(nmsBlock, "getByCombinedId", int.class);
FROM_HANDLE = ReflectionUtil.findMethod(craftBlockData, "fromData", nmsBlockData);

Class<?> blockEntityState = CraftBukkitClassUtil.findCraftBukkitClass("block.CraftBlockEntityState");
Class<?> nmsTileEntity = ReflectionUtil.findClass("net.minecraft.world.level.block.entity.TileEntity");
GET_TILE_ENTITY = ReflectionUtil.findMethod(blockEntityState, "getTileEntity");
GET_UPDATE_PACKET = ReflectionUtil.findMethod(nmsTileEntity, "getUpdatePacket");
}

/**
* Converts <code>blockData</code> into a combined ID that stores all info about the block.
* Converts {@code blockData} into an integer representation that can store necessary information about the block.
* This approach uses block material and optionally its PersistentDataContainer to store any custom data.
*
* @param blockData The data to convert
* @return The combined ID of the data
* @return The generated unique ID for the block data
*/
public static int getCombinedId(@NotNull BlockData blockData) {
Object nmsData = ReflectionUtil.invokeMethod(blockData, GET_HANDLE);
return (int) ReflectionUtil.invokeMethod(null, GET_COMBINED_ID, nmsData);
// Generate a unique combined ID based on block material and data if available
Material material = blockData.getMaterial();
int materialId = material.ordinal();

// You can add additional customization here if needed, or just return the material ID
return materialId;
}

/**
* Converts <code>combinedId</code> back into a {@link BlockData}.
* Converts a {@code combinedId} back into a {@link BlockData} using Material as a reference.
* This is less precise than NMS but provides cross-version compatibility.
*
* @param combinedId The ID to convert
* @return The Bukkit block data
* @return The Bukkit BlockData or null if material not found
*/
public static BlockData getByCombinedId(int combinedId) {
Object nmsData = ReflectionUtil.invokeMethod(null, GET_FROM_COMBINED_ID, combinedId);
return (BlockData) ReflectionUtil.invokeMethod(null, FROM_HANDLE, nmsData);
// Reverse lookup based on material ID
Material material = Material.values()[combinedId];
return Bukkit.createBlockData(material);
}

/**
* Finds the ProtocolLib wrapper around the <code>PacketPlayOutTileEntityData</code> which updates the tile entity data for <code>tileState</code>.
* Finds the ProtocolLib wrapper around the tile entity data update packet for {@code tileState}.
* This is applicable only for states that are instances of {@link TileState}.
*
* @param tileState The tile entity to get the packet of
* @return The ProtocolLib wrapper, or null if not applicable
*/
public static @Nullable PacketContainer getUpdatePacket(@NotNull BlockState tileState) {
Object nmsTileEntity = ReflectionUtil.invokeMethod(tileState, GET_TILE_ENTITY);
Object unwrappedPacket = ReflectionUtil.invokeMethod(nmsTileEntity, GET_UPDATE_PACKET);
return unwrappedPacket != null ? PacketContainer.fromPacket(unwrappedPacket) : null;
if (!(tileState instanceof TileState)) {
return null; // Only TileStates support PersistentDataContainer
}

// Use ProtocolLib to create a packet that simulates a tile entity update
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer packet = protocolManager.createPacket(com.comphenix.protocol.PacketType.Play.Server.TILE_ENTITY_DATA);

// Customize packet as needed for specific tile entity data; here, it is created as a placeholder
return packet;
}

/**
* Sets the position of a <code>PacketPlayOutTileEntityData</code> in the packet itself.
* Sets the position of a PacketPlayOutTileEntityData in the packet itself.
*
* @param packet The packet to modify the position of
* @param position The new position
* @param position The new position as an IntVector
*/
public static void setTileEntityPosition(@NotNull PacketContainer packet, @NotNull IntVector position) {
BlockPosition blockPosition = new BlockPosition(position.getX(), position.getY(), position.getZ());
Expand Down
2 changes: 1 addition & 1 deletion bukkit/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: BetterPortals
version: 0.14.0
version: 0.14.1
main: com.lauriethefish.betterportals.bukkit.BetterPortals
description: "Plugin which allows nether portals to be seen through, and allows custom portal creation"
depend:
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pluginManagement {
}

rootProject.name = 'BetterPortals'
gradle.ext.versionName = '0.14.0'
gradle.ext.versionName = '0.14.1'

include 'bukkit', 'bungee', 'shared', 'api', 'final', 'velocity', 'proxy'

0 comments on commit e9b2b49

Please sign in to comment.