geforkt von Mirrors/AxiomPaperPlugin
Increase protocol version to 6, implement PlayerInteractEvent in SetBlockPacketListener
Dieser Commit ist enthalten in:
Ursprung
aff54bcd34
Commit
95ac82cf73
@ -12,7 +12,7 @@ public class AxiomConstants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int API_VERSION = 5;
|
public static final int API_VERSION = 6;
|
||||||
public static final NamespacedKey ACTIVE_HOTBAR_INDEX = new NamespacedKey("axiom", "active_hotbar_index");
|
public static final NamespacedKey ACTIVE_HOTBAR_INDEX = new NamespacedKey("axiom", "active_hotbar_index");
|
||||||
public static final NamespacedKey HOTBAR_DATA = new NamespacedKey("axiom", "hotbar_data");
|
public static final NamespacedKey HOTBAR_DATA = new NamespacedKey("axiom", "hotbar_data");
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import net.minecraft.core.SectionPos;
|
|||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
@ -16,9 +18,14 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
|||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LightEngine;
|
import net.minecraft.world.level.lighting.LightEngine;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlock;
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||||
@ -61,97 +68,130 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
|||||||
|
|
||||||
// Read packet
|
// Read packet
|
||||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||||
BlockPos blockPos = friendlyByteBuf.readBlockPos();
|
Map<BlockPos, BlockState> blocks = friendlyByteBuf.readMap(FriendlyByteBuf::readBlockPos, buf -> buf.readById(Block.BLOCK_STATE_REGISTRY));
|
||||||
BlockState blockState = friendlyByteBuf.readById(Block.BLOCK_STATE_REGISTRY);
|
|
||||||
boolean updateNeighbors = friendlyByteBuf.readBoolean();
|
boolean updateNeighbors = friendlyByteBuf.readBoolean();
|
||||||
int sequenceId = friendlyByteBuf.readInt();
|
|
||||||
|
int reason = friendlyByteBuf.readVarInt();
|
||||||
|
boolean breaking = friendlyByteBuf.readBoolean();
|
||||||
|
BlockHitResult blockHit = friendlyByteBuf.readBlockHitResult();
|
||||||
|
InteractionHand hand = friendlyByteBuf.readEnum(InteractionHand.class);
|
||||||
|
int sequenceId = friendlyByteBuf.readVarInt();
|
||||||
|
|
||||||
ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle();
|
ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle();
|
||||||
|
|
||||||
|
org.bukkit.inventory.ItemStack heldItem;
|
||||||
|
if (hand == InteractionHand.MAIN_HAND) {
|
||||||
|
heldItem = bukkitPlayer.getInventory().getItemInMainHand();
|
||||||
|
} else {
|
||||||
|
heldItem = bukkitPlayer.getInventory().getItemInOffHand();
|
||||||
|
}
|
||||||
|
|
||||||
|
org.bukkit.block.Block blockClicked = bukkitPlayer.getWorld().getBlockAt(blockHit.getBlockPos().getX(),
|
||||||
|
blockHit.getBlockPos().getY(), blockHit.getBlockPos().getZ());
|
||||||
|
|
||||||
|
BlockFace blockFace = CraftBlock.notchToBlockFace(blockHit.getDirection());
|
||||||
|
|
||||||
|
// Call interact event
|
||||||
|
PlayerInteractEvent playerInteractEvent = new PlayerInteractEvent(bukkitPlayer,
|
||||||
|
breaking ? Action.LEFT_CLICK_BLOCK : Action.RIGHT_CLICK_BLOCK, heldItem, blockClicked, blockFace);
|
||||||
|
if (!playerInteractEvent.callEvent()) {
|
||||||
|
if (sequenceId >= 0) {
|
||||||
|
player.connection.ackBlockChangesUpTo(sequenceId);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update blocks
|
// Update blocks
|
||||||
if (updateNeighbors) {
|
if (updateNeighbors) {
|
||||||
player.level().setBlock(blockPos, blockState, 3);
|
for (Map.Entry<BlockPos, BlockState> entry : blocks.entrySet()) {
|
||||||
|
player.level().setBlock(entry.getKey(), entry.getValue(), 3);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int bx = blockPos.getX();
|
for (Map.Entry<BlockPos, BlockState> entry : blocks.entrySet()) {
|
||||||
int by = blockPos.getY();
|
BlockPos blockPos = entry.getKey();
|
||||||
int bz = blockPos.getZ();
|
BlockState blockState = entry.getValue();
|
||||||
int x = bx & 0xF;
|
|
||||||
int y = by & 0xF;
|
|
||||||
int z = bz & 0xF;
|
|
||||||
int cx = bx >> 4;
|
|
||||||
int cy = by >> 4;
|
|
||||||
int cz = bz >> 4;
|
|
||||||
|
|
||||||
ServerLevel level = player.serverLevel();
|
int bx = blockPos.getX();
|
||||||
LevelChunk chunk = level.getChunk(cx, cz);
|
int by = blockPos.getY();
|
||||||
chunk.setUnsaved(true);
|
int bz = blockPos.getZ();
|
||||||
|
int x = bx & 0xF;
|
||||||
|
int y = by & 0xF;
|
||||||
|
int z = bz & 0xF;
|
||||||
|
int cx = bx >> 4;
|
||||||
|
int cy = by >> 4;
|
||||||
|
int cz = bz >> 4;
|
||||||
|
|
||||||
LevelChunkSection section = chunk.getSection(level.getSectionIndexFromSectionY(cy));
|
ServerLevel level = player.serverLevel();
|
||||||
boolean hasOnlyAir = section.hasOnlyAir();
|
LevelChunk chunk = level.getChunk(cx, cz);
|
||||||
|
chunk.setUnsaved(true);
|
||||||
|
|
||||||
Heightmap worldSurface = null;
|
LevelChunkSection section = chunk.getSection(level.getSectionIndexFromSectionY(cy));
|
||||||
Heightmap oceanFloor = null;
|
boolean hasOnlyAir = section.hasOnlyAir();
|
||||||
Heightmap motionBlocking = null;
|
|
||||||
Heightmap motionBlockingNoLeaves = null;
|
|
||||||
for (Map.Entry<Heightmap.Types, Heightmap> heightmap : chunk.getHeightmaps()) {
|
|
||||||
switch (heightmap.getKey()) {
|
|
||||||
case WORLD_SURFACE -> worldSurface = heightmap.getValue();
|
|
||||||
case OCEAN_FLOOR -> oceanFloor = heightmap.getValue();
|
|
||||||
case MOTION_BLOCKING -> motionBlocking = heightmap.getValue();
|
|
||||||
case MOTION_BLOCKING_NO_LEAVES -> motionBlockingNoLeaves = heightmap.getValue();
|
|
||||||
default -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockState old = section.setBlockState(x, y, z, blockState, false);
|
Heightmap worldSurface = null;
|
||||||
if (blockState != old) {
|
Heightmap oceanFloor = null;
|
||||||
Block block = blockState.getBlock();
|
Heightmap motionBlocking = null;
|
||||||
motionBlocking.update(x, by, z, blockState);
|
Heightmap motionBlockingNoLeaves = null;
|
||||||
motionBlockingNoLeaves.update(x, by, z, blockState);
|
for (Map.Entry<Heightmap.Types, Heightmap> heightmap : chunk.getHeightmaps()) {
|
||||||
oceanFloor.update(x, by, z, blockState);
|
switch (heightmap.getKey()) {
|
||||||
worldSurface.update(x, by, z, blockState);
|
case WORLD_SURFACE -> worldSurface = heightmap.getValue();
|
||||||
|
case OCEAN_FLOOR -> oceanFloor = heightmap.getValue();
|
||||||
if (blockState.hasBlockEntity()) {
|
case MOTION_BLOCKING -> motionBlocking = heightmap.getValue();
|
||||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
case MOTION_BLOCKING_NO_LEAVES -> motionBlockingNoLeaves = heightmap.getValue();
|
||||||
|
default -> {}
|
||||||
if (blockEntity == null) {
|
|
||||||
// There isn't a block entity here, create it!
|
|
||||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
|
||||||
if (blockEntity != null) {
|
|
||||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
|
||||||
}
|
|
||||||
} else if (blockEntity.getType().isValid(blockState)) {
|
|
||||||
// Block entity is here and the type is correct
|
|
||||||
// Just update the state and ticker and move on
|
|
||||||
blockEntity.setBlockState(blockState);
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.updateBlockEntityTicker.invoke(chunk, blockEntity);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Block entity type isn't correct, we need to recreate it
|
|
||||||
chunk.removeBlockEntity(blockPos);
|
|
||||||
|
|
||||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
|
||||||
if (blockEntity != null) {
|
|
||||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (old.hasBlockEntity()) {
|
|
||||||
chunk.removeBlockEntity(blockPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
level.getChunkSource().blockChanged(blockPos);
|
BlockState old = section.setBlockState(x, y, z, blockState, false);
|
||||||
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
if (blockState != old) {
|
||||||
level.getChunkSource().getLightEngine().checkBlock(blockPos);
|
Block block = blockState.getBlock();
|
||||||
}
|
motionBlocking.update(x, by, z, blockState);
|
||||||
}
|
motionBlockingNoLeaves.update(x, by, z, blockState);
|
||||||
|
oceanFloor.update(x, by, z, blockState);
|
||||||
|
worldSurface.update(x, by, z, blockState);
|
||||||
|
|
||||||
boolean nowHasOnlyAir = section.hasOnlyAir();
|
if (blockState.hasBlockEntity()) {
|
||||||
if (hasOnlyAir != nowHasOnlyAir) {
|
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||||
level.getChunkSource().getLightEngine().updateSectionStatus(SectionPos.of(cx, cy, cz), nowHasOnlyAir);
|
|
||||||
|
if (blockEntity == null) {
|
||||||
|
// There isn't a block entity here, create it!
|
||||||
|
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||||
|
if (blockEntity != null) {
|
||||||
|
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||||
|
}
|
||||||
|
} else if (blockEntity.getType().isValid(blockState)) {
|
||||||
|
// Block entity is here and the type is correct
|
||||||
|
// Just update the state and ticker and move on
|
||||||
|
blockEntity.setBlockState(blockState);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.updateBlockEntityTicker.invoke(chunk, blockEntity);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Block entity type isn't correct, we need to recreate it
|
||||||
|
chunk.removeBlockEntity(blockPos);
|
||||||
|
|
||||||
|
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||||
|
if (blockEntity != null) {
|
||||||
|
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (old.hasBlockEntity()) {
|
||||||
|
chunk.removeBlockEntity(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
level.getChunkSource().blockChanged(blockPos);
|
||||||
|
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
||||||
|
level.getChunkSource().getLightEngine().checkBlock(blockPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean nowHasOnlyAir = section.hasOnlyAir();
|
||||||
|
if (hasOnlyAir != nowHasOnlyAir) {
|
||||||
|
level.getChunkSource().getLightEngine().updateSectionStatus(SectionPos.of(cx, cy, cz), nowHasOnlyAir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren