From f28e03dc9ef9fcead4ea52a0b4f3b4afb63d95df Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Tue, 17 Jun 2025 03:47:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0=E6=B4=BB?= =?UTF-8?q?=E6=9D=BF=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BukkitCompatibilityManager.java | 2 +- .../bukkit/block/BukkitCustomBlock.java | 4 +- .../AbstractCanSurviveBlockBehavior.java | 4 +- .../behavior/ConcretePowderBlockBehavior.java | 4 +- .../block/behavior/FallingBlockBehavior.java | 4 +- .../block/behavior/LampBlockBehavior.java | 3 +- .../block/behavior/LeavesBlockBehavior.java | 2 +- .../behavior/NearLiquidBlockBehavior.java | 18 +- .../block/behavior/OnLiquidBlockBehavior.java | 14 +- .../block/behavior/SaplingBlockBehavior.java | 2 +- .../block/behavior/TrapDoorBlockBehavior.java | 175 ++++++++++++++++-- .../behavior/WaterLoggedBlockBehavior.java | 2 +- .../bukkit/item/BukkitItemManager.java | 8 +- .../behavior/CompostableItemBehavior.java | 3 +- .../behavior/FlintAndSteelItemBehavior.java | 1 - .../item/factory/BukkitItemFactory.java | 1 - .../item/listener/ItemEventListener.java | 8 - .../plugin/injector/BlockGenerator.java | 24 +++ .../plugin/network/PacketConsumers.java | 3 +- .../reflection/minecraft/CoreReflections.java | 22 ++- .../plugin/reflection/minecraft/MFluids.java | 24 +-- .../plugin/user/BukkitServerPlayer.java | 1 - .../bukkit/world/BukkitBlockInWorld.java | 15 +- .../craftengine/core/block/BlockBehavior.java | 21 +++ .../core/entity/player/Player.java | 1 - .../craftengine/core/item/CustomItem.java | 1 - .../craftengine/core/item/ItemKeys.java | 1 + .../core/plugin/context/ViewerContext.java | 1 - .../minimessage/RelationalPlaceholderTag.java | 1 - .../craftengine/core/util/DamageSource.java | 1 - .../core/util/HorizontalDirection.java | 12 ++ gradle.properties | 2 +- 32 files changed, 283 insertions(+), 102 deletions(-) diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java index 518dca60b..7fb8b5e10 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -1,13 +1,13 @@ package net.momirealms.craftengine.bukkit.compatibility; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; -import net.momirealms.craftengine.bukkit.compatibility.model.bettermodel.BetterModelModel; import net.momirealms.craftengine.bukkit.compatibility.item.CustomFishingProvider; import net.momirealms.craftengine.bukkit.compatibility.item.MMOItemsProvider; import net.momirealms.craftengine.bukkit.compatibility.item.MythicMobsProvider; import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider; import net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld.LegacySlimeFormatStorageAdaptor; import net.momirealms.craftengine.bukkit.compatibility.leveler.*; +import net.momirealms.craftengine.bukkit.compatibility.model.bettermodel.BetterModelModel; import net.momirealms.craftengine.bukkit.compatibility.model.modelengine.ModelEngineModel; import net.momirealms.craftengine.bukkit.compatibility.model.modelengine.ModelEngineUtils; import net.momirealms.craftengine.bukkit.compatibility.mythicmobs.MythicMobsListener; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java index b2da03528..0531bf14e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java @@ -138,9 +138,9 @@ public class BukkitCustomBlock extends AbstractCustomBlock { } // set fluid later if (settings.fluidState()) { - CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, CoreReflections.method$FlowingFluid$getSource.invoke(MFluids.instance$Fluids$WATER, false)); + CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, CoreReflections.method$FlowingFluid$getSource.invoke(MFluids.WATER, false)); } else { - CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, MFluids.instance$Fluids$EMPTY$defaultState); + CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, MFluids.EMPTY$defaultState); } // set random tick later BlockStateUtils.setIsRandomlyTicking(mcBlockState, settings.isRandomlyTicking()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java index 75d0ebf53..ffaded853 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/AbstractCanSurviveBlockBehavior.java @@ -65,7 +65,7 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio public void onPlace(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object world = args[1]; Object blockPos = args[2]; - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(world, blockPos, thisBlock, 2); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 2); } @Override @@ -86,7 +86,7 @@ public abstract class AbstractCanSurviveBlockBehavior extends BukkitBlockBehavio return state; } if (this.delay != 0) { - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(level, blockPos, thisBlock, this.delay); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(level, blockPos, thisBlock, this.delay); return state; } if (!canSurvive(thisBlock, new Object[] {state, level, blockPos}, () -> true)) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index 69a0ccd89..d1691eecf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -126,8 +126,8 @@ public class ConcretePowderBlockBehavior extends BukkitBlockBehavior { private static boolean canSolidify(Object state) throws ReflectiveOperationException { Object fluidState = CoreReflections.field$BlockStateBase$fluidState.get(state); if (fluidState == null) return false; - Object fluidType = CoreReflections.method$FluidState$getType.invoke(fluidState); - return fluidType == MFluids.instance$Fluids$WATER || fluidType == MFluids.instance$Fluids$FLOWING_WATER; + Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(fluidState); + return fluidType == MFluids.WATER || fluidType == MFluids.FLOWING_WATER; } private static boolean touchesLiquid(Object level, Object pos) throws ReflectiveOperationException { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java index 3e7cc6771..496fb42ff 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java @@ -36,7 +36,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { public void onPlace(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object world = args[1]; Object blockPos = args[2]; - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(world, blockPos, thisBlock, 2); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 2); } @Override @@ -50,7 +50,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { world = args[3]; blockPos = args[4]; } - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(world, blockPos, thisBlock, 2); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 2); return args[0]; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java index ddf3a3c64..bac1372d6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LampBlockBehavior.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.BlockBehavior; @@ -62,7 +61,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior { boolean lit = state.get(this.litProperty); if (lit != FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(world, blockPos)) { if (lit) { - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(world, blockPos, thisBlock, 4); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 4); } else { // TODO Call Event FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, state.cycle(this.litProperty).customBlockState().handle(), 2); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java index 29d203086..c443a1f27 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java @@ -85,7 +85,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior { LeavesBlockBehavior behavior = optionalBehavior.get(); int distance = behavior.getDistanceAt(neighborState) + 1; if (distance != 1 || behavior.getDistance(thisState) != distance) { - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(world, blockPos, thisBlock, 1); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(world, blockPos, thisBlock, 1); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java index 37d9b651a..c377fec32 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/NearLiquidBlockBehavior.java @@ -19,8 +19,8 @@ import java.util.List; import java.util.Map; public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { - private static final List WATER = List.of(MFluids.instance$Fluids$WATER, MFluids.instance$Fluids$FLOWING_WATER); - private static final List LAVA = List.of(MFluids.instance$Fluids$LAVA, MFluids.instance$Fluids$FLOWING_LAVA); + private static final List WATER = List.of(MFluids.WATER, MFluids.FLOWING_WATER); + private static final List LAVA = List.of(MFluids.LAVA, MFluids.FLOWING_LAVA); public static final Factory FACTORY = new Factory(); private final boolean onWater; private final boolean onLava; @@ -64,7 +64,7 @@ public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { } @Override - protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) throws ReflectiveOperationException { + protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) { int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos); int x = FastNMS.INSTANCE.field$Vec3i$x(blockPos); int z = FastNMS.INSTANCE.field$Vec3i$z(blockPos); @@ -89,16 +89,16 @@ public class NearLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { return false; } - protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException { - Object fluidState = CoreReflections.method$Level$getFluidState.invoke(world, belowPos); - Object fluidStateAbove = CoreReflections.method$Level$getFluidState.invoke(world, LocationUtils.above(belowPos)); - if (CoreReflections.method$FluidState$getType.invoke(fluidStateAbove) != MFluids.instance$Fluids$EMPTY) { + protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) { + Object fluidState = FastNMS.INSTANCE.method$Level$getFluidState(world, belowPos); + Object fluidStateAbove = FastNMS.INSTANCE.method$Level$getFluidState(world, LocationUtils.above(belowPos)); + if (FastNMS.INSTANCE.method$FluidState$getType(fluidStateAbove) != MFluids.EMPTY) { return false; } - if (this.onWater && (WATER.contains(CoreReflections.method$FluidState$getType.invoke(fluidState)) || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == MBlocks.ICE)) { + if (this.onWater && (WATER.contains(FastNMS.INSTANCE.method$FluidState$getType(fluidState)) || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == MBlocks.ICE)) { return true; } - if (this.onLava && LAVA.contains(CoreReflections.method$FluidState$getType.invoke(fluidState))) { + if (this.onLava && LAVA.contains(FastNMS.INSTANCE.method$FluidState$getType(fluidState))) { return true; } return false; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java index 94ebcc6ce..8e459c02c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/OnLiquidBlockBehavior.java @@ -49,7 +49,7 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { } @Override - protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) throws ReflectiveOperationException { + protected boolean canSurvive(Object thisBlock, Object state, Object world, Object blockPos) { int y = FastNMS.INSTANCE.field$Vec3i$y(blockPos); int x = FastNMS.INSTANCE.field$Vec3i$x(blockPos); int z = FastNMS.INSTANCE.field$Vec3i$z(blockPos); @@ -58,7 +58,7 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { return mayPlaceOn(belowState, world, belowPos); } - protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException { + protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) { if (this.stackable) { int id = BlockStateUtils.blockStateToId(belowState); if (!BlockStateUtils.isVanillaBlock(id)) { @@ -68,15 +68,15 @@ public class OnLiquidBlockBehavior extends AbstractCanSurviveBlockBehavior { } } } - Object fluidState = CoreReflections.method$Level$getFluidState.invoke(world, belowPos); - Object fluidStateAbove = CoreReflections.method$Level$getFluidState.invoke(world, LocationUtils.above(belowPos)); - if (CoreReflections.method$FluidState$getType.invoke(fluidStateAbove) != MFluids.instance$Fluids$EMPTY) { + Object fluidState = FastNMS.INSTANCE.method$Level$getFluidState(world, belowPos); + Object fluidStateAbove = FastNMS.INSTANCE.method$Level$getFluidState(world, LocationUtils.above(belowPos)); + if (FastNMS.INSTANCE.method$FluidState$getType(fluidStateAbove) != MFluids.EMPTY) { return false; } - if (this.onWater && (CoreReflections.method$FluidState$getType.invoke(fluidState) == MFluids.instance$Fluids$WATER || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == MBlocks.ICE)) { + if (this.onWater && (FastNMS.INSTANCE.method$FluidState$getType(fluidState) == MFluids.WATER || FastNMS.INSTANCE.method$BlockState$getBlock(belowState) == MBlocks.ICE)) { return true; } - if (this.onLava && CoreReflections.method$FluidState$getType.invoke(fluidState) == MFluids.instance$Fluids$LAVA) { + if (this.onLava && FastNMS.INSTANCE.method$FluidState$getType(fluidState) == MFluids.LAVA) { return true; } return false; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java index 8569e6ca9..bc30eb7b7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SaplingBlockBehavior.java @@ -87,7 +87,7 @@ public class SaplingBlockBehavior extends BukkitBlockBehavior { } Object chunkGenerator = CoreReflections.method$ServerChunkCache$getGenerator.invoke(FastNMS.INSTANCE.method$ServerLevel$getChunkSource(world)); Object configuredFeature = CoreReflections.method$Holder$value.invoke(holder.get()); - Object fluidState = CoreReflections.method$Level$getFluidState.invoke(world, blockPos); + Object fluidState = FastNMS.INSTANCE.method$Level$getFluidState(world, blockPos); Object legacyState = CoreReflections.method$FluidState$createLegacyBlock.invoke(fluidState); FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, legacyState, UpdateOption.UPDATE_NONE.flags()); if ((boolean) CoreReflections.method$ConfiguredFeature$place.invoke(configuredFeature, world, chunkGenerator, randomSource, blockPos)) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java index 86387b3fd..7879d6fbf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/TrapDoorBlockBehavior.java @@ -1,14 +1,34 @@ package net.momirealms.craftengine.bukkit.block.behavior; +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MFluids; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.LocationUtils; +import net.momirealms.craftengine.bukkit.world.BukkitWorld; import net.momirealms.craftengine.core.block.BlockBehavior; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UpdateOption; import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory; import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.entity.player.InteractionResult; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.item.context.BlockPlaceContext; -import net.momirealms.craftengine.core.util.Half; -import net.momirealms.craftengine.core.util.HorizontalDirection; -import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.item.context.UseOnContext; +import net.momirealms.craftengine.core.util.*; +import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.World; +import org.bukkit.Bukkit; +import org.bukkit.GameEvent; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -20,33 +40,154 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior { private final Property directionProperty; private final Property poweredProperty; private final Property openProperty; + private final boolean canOpenWithHand; + private final boolean canOpenByWindCharge; public TrapDoorBlockBehavior(CustomBlock block, @Nullable Property waterloggedProperty, Property halfProperty, Property directionProperty, Property poweredProperty, - Property openProperty) { + Property openProperty, + boolean canOpenWithHand, + boolean canOpenByWindCharge) { super(block, waterloggedProperty); this.halfProperty = halfProperty; this.directionProperty = directionProperty; this.poweredProperty = poweredProperty; this.openProperty = openProperty; - } -// -// @Override -// public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { -// -// } - - @Override - public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { - + this.canOpenWithHand = canOpenWithHand; + this.canOpenByWindCharge = canOpenByWindCharge; } @Override - public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) throws Exception { + public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) { + Object blockState = args[0]; + if (this.waterloggedProperty != null) { + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); + if (state != null && !state.isEmpty() && state.get(this.waterloggedProperty)) { + FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(VersionHelper.isOrAbove1_21_2() ? args[2] : args[3], VersionHelper.isOrAbove1_21_2() ? args[3] : args[4], MFluids.WATER, 5); + } + } + return blockState; + } + @Override + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { + Object level = context.getLevel().serverWorld(); + Object clickedPos = LocationUtils.toBlockPos(context.getClickedPos()); + Direction clickedFace = context.getClickedFace(); + if (!context.replacingClickedOnBlock() && clickedFace.axis().isHorizontal()) { + state = state.with(this.directionProperty, clickedFace.toHorizontalDirection()) + .with(this.halfProperty, context.getClickLocation().y - context.getClickedPos().y() > 0.5 ? Half.TOP : Half.BOTTOM); + } else { + state = state.with(this.directionProperty, context.getHorizontalDirection().opposite().toHorizontalDirection()) + .with(this.halfProperty, clickedFace == Direction.UP ? Half.BOTTOM : Half.TOP); + } + if (FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, clickedPos)) { + state = state.with(this.poweredProperty, true); + } + if (this.waterloggedProperty != null && FastNMS.INSTANCE.method$FluidState$getType(FastNMS.INSTANCE.method$Level$getFluidState(level, clickedPos)) == MFluids.WATER) { + state = state.with(this.waterloggedProperty, true); + } + return state; + } + + @Override + public InteractionResult useOnBlock(UseOnContext context, ImmutableBlockState state) { + if (!this.canOpenWithHand) { + return InteractionResult.PASS; + } + this.toggle(state, context.getLevel(), context.getClickedPos(), context.getPlayer()); + return InteractionResult.SUCCESS; + } + + @Override + public boolean isPathFindable(Object thisBlock, Object[] args, Callable superMethod) { + Object type = VersionHelper.isOrAbove1_20_5() ? args[1] : args[3]; + Object blockState = args[0]; + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); + if (state == null || state.isEmpty()) return false; + if (type == CoreReflections.instance$PathComputationType$LAND || type == CoreReflections.instance$PathComputationType$AIR) { + return state.get(this.openProperty); + } else if (type == CoreReflections.instance$PathComputationType$WATER) { + return state.get(super.waterloggedProperty); + } + return false; + } + + @Override + public void onExplosionHit(Object thisBlock, Object[] args, Callable superMethod) { + if (this.canOpenByWindCharge && FastNMS.INSTANCE.method$Explosion$canTriggerBlocks(args[3])) { + ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(args[0])); + if (state == null || state.isEmpty()) return; + this.toggle(state, new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(args[1])), LocationUtils.fromBlockPos(args[2]), null); + } + } + + @SuppressWarnings("UnstableApiUsage") + @Override + public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) { + Object blockState = args[0]; + ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState)); + if (immutableBlockState == null || immutableBlockState.isEmpty()) return; + Object level = args[1]; + Object blockPos = args[2]; + boolean hasSignal = FastNMS.INSTANCE.method$SignalGetter$hasNeighborSignal(level, blockPos); + if (hasSignal == immutableBlockState.get(this.poweredProperty)) return; + + Block bblock = FastNMS.INSTANCE.method$CraftBlock$at(level, blockPos); + int power = bblock.getBlockPower(); + int oldPower = immutableBlockState.get(this.openProperty) ? 15 : 0; + Object neighborBlock = args[3]; + + if (oldPower == 0 ^ power == 0 || FastNMS.INSTANCE.method$BlockStateBase$isSignalSource(FastNMS.INSTANCE.method$Block$defaultState(neighborBlock))) { + BlockRedstoneEvent event = new BlockRedstoneEvent(bblock, oldPower, power); + Bukkit.getPluginManager().callEvent(event); + hasSignal = event.getNewCurrent() > 0; + } + + boolean willChange = immutableBlockState.get(this.openProperty) != hasSignal; + if (hasSignal && willChange) { + Object abovePos = LocationUtils.above(blockPos); + Object aboveBlockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, abovePos); + if (CoreReflections.clazz$RedStoneWireBlock.isInstance(FastNMS.INSTANCE.method$BlockState$getBlock(aboveBlockState))) { + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, abovePos, MBlocks.AIR$defaultState, UpdateOption.UPDATE_ALL.flags()); + World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); + world.dropItemNaturally( + new Vec3d(FastNMS.INSTANCE.field$Vec3i$x(abovePos) + 0.5, FastNMS.INSTANCE.field$Vec3i$y(abovePos) + 0.5, FastNMS.INSTANCE.field$Vec3i$z(abovePos) + 0.5), + BukkitItemManager.instance().createWrappedItem(ItemKeys.REDSTONE, null) + ); + if (FastNMS.INSTANCE.method$BlockGetter$getBlockState(level, blockPos) != blockPos) { + return; + } + } + } + + if (willChange) { + immutableBlockState = immutableBlockState.with(this.openProperty, hasSignal); + // todo 播放声音 + FastNMS.INSTANCE.method$Level$getCraftWorld(level).sendGameEvent(null, + immutableBlockState.get(this.openProperty) ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, + new Vector(FastNMS.INSTANCE.field$Vec3i$x(blockPos), FastNMS.INSTANCE.field$Vec3i$y(blockPos), FastNMS.INSTANCE.field$Vec3i$z(blockPos)) + ); + } + + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, immutableBlockState.customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS); + if (this.waterloggedProperty != null && immutableBlockState.get(this.waterloggedProperty)) { + FastNMS.INSTANCE.method$LevelAccessor$scheduleFluidTick(level, blockPos, MFluids.WATER, 5); + } + } + + private void toggle(ImmutableBlockState state, World world, BlockPos pos, @Nullable Player player) { + ImmutableBlockState newState = state.cycle(this.openProperty); + FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS); + // todo 播放声音,需要补一套交互的声音系统 + ((org.bukkit.World) world.platformWorld()).sendGameEvent( + player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null, + newState.get(this.openProperty) ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, + new Vector(pos.x(), pos.y(), pos.z()) + ); } @SuppressWarnings("unchecked") @@ -58,7 +199,9 @@ public class TrapDoorBlockBehavior extends WaterLoggedBlockBehavior { Property direction = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("direction"), "warning.config.block.behavior.trapdoor.missing_direction"); Property open = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_open"); Property powered = (Property) ResourceConfigUtils.requireNonNullOrThrow(block.getProperty("open"), "warning.config.block.behavior.trapdoor.missing_powered"); - return new TrapDoorBlockBehavior(block, waterlogged, half, direction, powered, open); + boolean canOpenWithHand = (boolean) arguments.getOrDefault("can-open-with-hand", true); + boolean canOpenByWindCharge = (boolean) arguments.getOrDefault("can-open-by-wind-charge", true); + return new TrapDoorBlockBehavior(block, waterlogged, half, direction, powered, open, canOpenWithHand, canOpenByWindCharge); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java index e980902fc..80990325d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/WaterLoggedBlockBehavior.java @@ -11,7 +11,7 @@ import java.util.Map; public class WaterLoggedBlockBehavior extends BukkitBlockBehavior { public static final Factory FACTORY = new Factory(); @Nullable - private final Property waterloggedProperty; + protected final Property waterloggedProperty; public WaterLoggedBlockBehavior(CustomBlock block, @Nullable Property waterloggedProperty) { super(block); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index a74547ea7..ca8ad91d8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -13,7 +13,6 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.bukkit.util.ItemUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.player.Player; @@ -26,7 +25,6 @@ import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.registry.WritableRegistry; import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.util.ResourceKey; import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Bukkit; @@ -165,12 +163,12 @@ public class BukkitItemManager extends AbstractItemManager { this.plugin.logger().warn(id + " is not a valid namespaced key"); return new ItemStack(Material.AIR); } - Material material = Registry.MATERIAL.get(key); - if (material == null) { + Object item = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(id)); + if (item == null) { this.plugin.logger().warn(id + " is not a valid material"); return new ItemStack(Material.AIR); } - return new ItemStack(material); + return FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(item, 1)); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/CompostableItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/CompostableItemBehavior.java index 25a02d9f3..8803e18a2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/CompostableItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/CompostableItemBehavior.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.item.behavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.EventUtils; @@ -61,7 +60,7 @@ public class CompostableItemBehavior extends ItemBehavior { context.getLevel().levelEvent(WorldEvents.COMPOSTER_COMPOSTS, context.getClickedPos(), willRaise ? 1 : 0); ((World) context.getLevel().platformWorld()).sendGameEvent((Entity) context.getPlayer().platformPlayer(), GameEvent.BLOCK_CHANGE, new Vector(block.x() + 0.5, block.y() + 0.5, block.z() + 0.5)); if (currentLevel + 1 == 7) { - FastNMS.INSTANCE.method$LevelAccessor$scheduleTick(context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), blockOwner, 20); + FastNMS.INSTANCE.method$LevelAccessor$scheduleBlockTick(context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), blockOwner, 20); } if (!context.getPlayer().canInstabuild()) { context.getItem().shrink(1); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java index 9d46867ed..397477d31 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/FlintAndSteelItemBehavior.java @@ -21,7 +21,6 @@ import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.RandomUtils; import net.momirealms.craftengine.core.world.BlockPos; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index 2d283d73f..ebb1e5c30 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.item.factory; import com.google.gson.JsonElement; import com.saicone.rtag.item.ItemTagStream; -import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.ItemTags; import net.momirealms.craftengine.core.item.ItemFactory; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index 9e5c4b3f8..a88d37316 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -4,7 +4,6 @@ import io.papermc.paper.event.block.CompostItemEvent; import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.item.BukkitCustomItem; -import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; @@ -31,30 +30,23 @@ import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.Vec3d; import org.bukkit.GameMode; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.enchantment.PrepareItemEnchantEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.EnchantingInventory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; import java.util.ArrayList; import java.util.List; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java index e27aeb338..cff9733d3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BlockGenerator.java @@ -29,6 +29,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.util.concurrent.Callable; +import java.util.function.BiConsumer; public final class BlockGenerator { private static final BukkitBlockShape STONE_SHAPE = @@ -140,6 +141,15 @@ public final class BlockGenerator { .and(ElementMatchers.takesArgument(1, CoreReflections.clazz$LevelReader).or(ElementMatchers.takesArgument(1, CoreReflections.clazz$Direction))) .and(ElementMatchers.named("updateShape").or(ElementMatchers.named("a")))) .intercept(MethodDelegation.to(UpdateShapeInterceptor.INSTANCE)) + // onExplosionHit 1.21+ + .method(ElementMatchers.returns(void.class) + .and(ElementMatchers.takesArgument(0, CoreReflections.clazz$BlockState)) + .and(ElementMatchers.takesArgument(1, CoreReflections.clazz$ServerLevel)) + .and(ElementMatchers.takesArgument(2, CoreReflections.clazz$BlockPos)) + .and(ElementMatchers.takesArgument(3, CoreReflections.clazz$Explosion)) + .and(ElementMatchers.takesArgument(4, BiConsumer.class)) + ) + .intercept(MethodDelegation.to(OnExplosionHitInterceptor.INSTANCE)) // neighborChanged .method(ElementMatchers.is(CoreReflections.method$BlockBehaviour$neighborChanged)) .intercept(MethodDelegation.to(NeighborChangedInterceptor.INSTANCE)); @@ -444,4 +454,18 @@ public final class BlockGenerator { } } } + + public static class OnExplosionHitInterceptor { + public static final OnExplosionHitInterceptor INSTANCE = new OnExplosionHitInterceptor(); + + @RuntimeType + public void intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) { + ObjectHolder holder = ((BehaviorHolder) thisObj).getBehaviorHolder(); + try { + holder.value().onExplosionHit(thisObj, args, superMethod); + } catch (Exception e) { + CraftEngine.instance().logger().severe("Failed to run onExplosionHit", e); + } + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 9db9963f1..02b885dcb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -10,14 +10,13 @@ import it.unimi.dsi.fastutil.ints.IntList; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TranslationArgument; import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; +import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; -import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptBreakEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.projectile.BukkitProjectileManager; -import net.momirealms.craftengine.bukkit.item.BukkitCustomItem; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index c67515c75..17178d986 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -1801,10 +1801,6 @@ public final class CoreReflections { ReflectionUtils.getMethod(clazz$FlowingFluid, clazz$FluidState, boolean.class) ); - public static final Method method$Level$getFluidState = requireNonNull( - ReflectionUtils.getMethod(clazz$Level, clazz$FluidState, CoreReflections.clazz$BlockPos) - ); - public static final Method method$FluidState$isSource = requireNonNull( ReflectionUtils.getMethod(clazz$FluidState, boolean.class, new String[]{"isSource", "b"}) ); @@ -2189,10 +2185,6 @@ public final class CoreReflections { .map(it -> ReflectionUtils.getDeclaredField(it, int.class, 0)) .orElse(null); - public static final Method method$FluidState$getType = requireNonNull( - ReflectionUtils.getMethod(clazz$FluidState, clazz$Fluid) - ); - public static final Class clazz$CustomRecipe = requireNonNull( BukkitReflectionUtils.findReobfOrMojmapClass( "world.item.crafting.IRecipeComplex", @@ -3347,4 +3339,18 @@ public final class CoreReflections { "world.inventory.EnchantmentMenu" ) ); + + public static final Class clazz$RedStoneWireBlock = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.BlockRedstoneWire", + "world.level.block.RedStoneWireBlock" + ) + ); + + public static final Class clazz$Explosion = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.Explosion", + "world.level.Explosion" + ) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java index c7aacbda1..a0412aac8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MFluids.java @@ -6,12 +6,12 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitExcepti public final class MFluids { private MFluids() {} - public static final Object instance$Fluids$WATER; - public static final Object instance$Fluids$FLOWING_WATER; - public static final Object instance$Fluids$LAVA; - public static final Object instance$Fluids$FLOWING_LAVA; - public static final Object instance$Fluids$EMPTY; - public static final Object instance$Fluids$EMPTY$defaultState; + public static final Object WATER; + public static final Object FLOWING_WATER; + public static final Object LAVA; + public static final Object FLOWING_LAVA; + public static final Object EMPTY; + public static final Object EMPTY$defaultState; private static Object getById(String id) throws ReflectiveOperationException { Object rl = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", id); @@ -20,12 +20,12 @@ public final class MFluids { static { try { - instance$Fluids$WATER = getById("water"); - instance$Fluids$FLOWING_WATER = getById("flowing_water"); - instance$Fluids$LAVA = getById("lava"); - instance$Fluids$FLOWING_LAVA = getById("flowing_lava"); - instance$Fluids$EMPTY = getById("empty"); - instance$Fluids$EMPTY$defaultState = CoreReflections.method$Fluid$defaultFluidState.invoke(instance$Fluids$EMPTY); + WATER = getById("water"); + FLOWING_WATER = getById("flowing_water"); + LAVA = getById("lava"); + FLOWING_LAVA = getById("flowing_lava"); + EMPTY = getById("empty"); + EMPTY$defaultState = CoreReflections.method$Fluid$defaultFluidState.invoke(EMPTY); } catch (ReflectiveOperationException e) { throw new ReflectionInitException("Failed to init Fluids", e); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 8adcef88f..a21f131ce 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -35,7 +35,6 @@ import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; -import net.momirealms.craftengine.core.world.Position; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldEvents; import org.bukkit.*; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java index cbaa5b445..fe55475e4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitBlockInWorld.java @@ -57,16 +57,11 @@ public class BukkitBlockInWorld implements BlockInWorld { @Override public boolean isWaterSource(BlockPlaceContext blockPlaceContext) { - try { - Location location = this.block.getLocation(); - Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.block.getWorld()); - Object fluidData = CoreReflections.method$Level$getFluidState.invoke(serverLevel, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - if (fluidData == null) return false; - return CoreReflections.method$FluidState$getType.invoke(fluidData) == MFluids.instance$Fluids$WATER; - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().warn("Failed to check if water source is available", e); - return false; - } + Location location = this.block.getLocation(); + Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.block.getWorld()); + Object fluidData = FastNMS.INSTANCE.method$Level$getFluidState(serverLevel, LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + if (fluidData == null) return false; + return FastNMS.INSTANCE.method$FluidState$getType(fluidData) == MFluids.WATER; } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java index f4ad8fb6c..a1dd27069 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java @@ -17,59 +17,80 @@ public abstract class BlockBehavior { return Optional.empty(); } + // BlockState state, Rotation rotation public Object rotate(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return superMethod.call(); } + // BlockState state, Mirror mirror public Object mirror(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return superMethod.call(); } + // 1.20.1-1.21.1 Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos + // 1.21.2+ LevelReader level, ScheduledTickAccess scheduledTickAccess, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return args[0]; } + // BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston public void neighborChanged(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } + // ServerLevel level, BlockPos pos, RandomSource random public void tick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } + // ServerLevel level, BlockPos pos, RandomSource random public void randomTick(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } + // 1.20-1.20.4 BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify, UseOnContext context + // 1.20.5+ Level level, BlockPos pos, BlockState oldState, boolean movedByPiston public void onPlace(Object thisBlock, Object[] args, Callable superMethod) throws Exception { superMethod.call(); } + // 1.20+ BlockState state, LevelReader world, BlockPos pos public boolean canSurvive(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return (boolean) superMethod.call(); } + // 1.20-1.20.4 BlockState state, BlockGetter world, BlockPos pos, PathComputationType type + // 1.20.5+ BlockState state, PathComputationType pathComputationType public boolean isPathFindable(Object thisBlock, Object[] args, Callable superMethod) throws Exception { return (boolean) superMethod.call(); } + // Level level, BlockPos pos, FallingBlockEntity fallingBlock public void onBrokenAfterFall(Object thisBlock, Object[] args) throws Exception { } + // Level level, BlockPos pos, BlockState state, BlockState replaceableState, FallingBlockEntity fallingBlock public void onLand(Object thisBlock, Object[] args) throws Exception { } + // LevelReader level, BlockPos pos, BlockState state public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) throws Exception { return false; } + // Level level, RandomSource random, BlockPos pos, BlockState state public boolean isBoneMealSuccess(Object thisBlock, Object[] args) throws Exception { return false; } + // ServerLevel level, RandomSource random, BlockPos pos, BlockState state public void performBoneMeal(Object thisBlock, Object[] args) throws Exception { } + // 1.21+ BlockState state, ServerLevel level, BlockPos pos, Explosion explosion, BiConsumer dropConsumer + public void onExplosionHit(Object thisBlock, Object[] args, Callable superMethod) { + } + public ImmutableBlockState updateStateForPlacement(BlockPlaceContext context, ImmutableBlockState state) { return state; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index 75b10c4f2..e0b2d0394 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -8,7 +8,6 @@ import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.sound.SoundSource; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.world.BlockPos; -import net.momirealms.craftengine.core.world.Position; import org.jetbrains.annotations.Nullable; import java.util.List; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java index 01512fa5a..f3dd338a7 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java @@ -9,7 +9,6 @@ import net.momirealms.craftengine.core.plugin.context.function.Function; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java index a90a44e69..89916d9e3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemKeys.java @@ -32,6 +32,7 @@ public class ItemKeys { public static final Key TOTEM_OF_UNDYING = Key.of("minecraft:totem_of_undying"); public static final Key BARRIER = Key.of("minecraft:barrier"); public static final Key CACTUS = Key.of("minecraft:cactus"); + public static final Key REDSTONE = Key.of("minecraft:redstone"); public static final Key[] AXES = new Key[] { WOODEN_AXE, STONE_AXE, IRON_AXE, GOLDEN_AXE, DIAMOND_AXE, NETHERITE_AXE diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java index affc6cd72..98a476a3d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/ViewerContext.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.core.plugin.context; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.text.minimessage.*; import java.util.Optional; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java index 4815ec310..b874b9b30 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/RelationalPlaceholderTag.java @@ -7,7 +7,6 @@ import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext; import net.momirealms.craftengine.core.plugin.context.RelationalContext; import net.momirealms.craftengine.core.util.AdventureHelper; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DamageSource.java b/core/src/main/java/net/momirealms/craftengine/core/util/DamageSource.java index 738295b77..b892f299d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/DamageSource.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/DamageSource.java @@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Optional; public enum DamageSource { BLOCK_EXPLOSION, diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/HorizontalDirection.java b/core/src/main/java/net/momirealms/craftengine/core/util/HorizontalDirection.java index 2231c725d..cc8143e12 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/HorizontalDirection.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/HorizontalDirection.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.core.util; +import org.jetbrains.annotations.NotNull; + public enum HorizontalDirection { NORTH, SOUTH, @@ -14,4 +16,14 @@ public enum HorizontalDirection { case EAST -> Direction.EAST; }; } + + @NotNull + public HorizontalDirection opposite() { + return switch (this) { + case EAST -> WEST; + case WEST -> EAST; + case NORTH -> SOUTH; + case SOUTH -> NORTH; + }; + } } diff --git a/gradle.properties b/gradle.properties index 5533dc3ae..fb495de39 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.67.18 +nms_helper_version=0.67.24 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23