9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 12:29:15 +00:00

更好的match property

This commit is contained in:
XiaoMoMi
2025-08-25 15:49:15 +08:00
parent 8d648f7d1b
commit c1e6410d47
54 changed files with 272 additions and 232 deletions

View File

@@ -4,7 +4,7 @@ import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.Location;
@@ -29,8 +29,8 @@ public final class BukkitAdaptors {
return new BukkitEntity(entity);
}
public static BukkitBlockInWorld adapt(final Block block) {
return new BukkitBlockInWorld(block);
public static BukkitExistingBlock adapt(final Block block) {
return new BukkitExistingBlock(block);
}
public static Location toLocation(WorldPosition position) {

View File

@@ -126,7 +126,7 @@ public final class CraftEngineBlocks {
boolean success;
Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld());
Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
Object blockState = block.customBlockState().handle();
Object blockState = block.customBlockState().literalObject();
Object oldBlockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(worldServer, blockPos);
success = FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState, option.flags());
if (success) {
@@ -249,6 +249,6 @@ public final class CraftEngineBlocks {
*/
@NotNull
public static BlockData getBukkitBlockData(@NotNull ImmutableBlockState blockState) {
return BlockStateUtils.fromBlockData(blockState.customBlockState().handle());
return BlockStateUtils.fromBlockData(blockState.customBlockState().literalObject());
}
}

View File

@@ -9,7 +9,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflect
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.*;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
@@ -82,7 +82,7 @@ public final class BlockEventListener implements Listener {
try {
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType);
player.playSound(block.getLocation().add(0.5D, 0.5D, 0.5D), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
} catch (ReflectiveOperationException e) {
this.plugin.logger().warn("Failed to get sound type", e);
}
@@ -99,7 +99,7 @@ public final class BlockEventListener implements Listener {
Object ownerBlock = BlockStateUtils.getBlockOwner(blockState);
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType);
player.playSound(block.getLocation().add(0.5D, 0.5D, 0.5D), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
} catch (ReflectiveOperationException e) {
this.plugin.logger().warn("Failed to get sound type", e);
}
@@ -124,7 +124,7 @@ public final class BlockEventListener implements Listener {
Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled);
optionalCustomItem.get().execute(
PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.PLAYER, serverPlayer)
.withParameter(DirectContextParameters.EVENT, cancellable)
@@ -156,7 +156,7 @@ public final class BlockEventListener implements Listener {
// execute functions
Cancellable cancellable = Cancellable.of(event::isCancelled, event::setCancelled);
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, state)
.withParameter(DirectContextParameters.EVENT, cancellable)
.withParameter(DirectContextParameters.POSITION, position)
@@ -179,7 +179,7 @@ public final class BlockEventListener implements Listener {
event.setExpToDrop(0);
}
ContextHolder lootContext = ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.PLAYER, serverPlayer)
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, ItemUtils.isEmpty(itemInHand) ? null : itemInHand).build();
@@ -198,7 +198,7 @@ public final class BlockEventListener implements Listener {
try {
Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock);
Object breakSound = CoreReflections.field$SoundType$breakSound.get(soundType);
block.getWorld().playSound(block.getLocation().add(0.5D, 0.5D, 0.5D), FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
block.getWorld().playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f);
} catch (ReflectiveOperationException e) {
this.plugin.logger().warn("Failed to get sound type", e);
}
@@ -224,7 +224,7 @@ public final class BlockEventListener implements Listener {
WorldPosition position = new WorldPosition(world, location.getBlockX() + 0.5, location.getBlockY() + 0.5, location.getBlockZ() + 0.5);
ContextHolder.Builder builder = ContextHolder.builder()
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block));
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block));
for (LootTable<?> lootTable : it.lootTables()) {
for (Item<?> item : lootTable.getRandomItems(builder.build(), world, null)) {
world.dropItemNaturally(position, item);
@@ -250,7 +250,7 @@ public final class BlockEventListener implements Listener {
state.owner().value().execute(PlayerOptionalContext.of(BukkitAdaptors.adapt(player), ContextHolder.builder()
.withParameter(DirectContextParameters.EVENT, cancellable)
.withParameter(DirectContextParameters.POSITION, new WorldPosition(new BukkitWorld(event.getWorld()), LocationUtils.toVec3d(location)))
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, state)
), EventTrigger.STEP);
if (cancellable.isCancelled()) {

View File

@@ -181,14 +181,14 @@ public final class BukkitBlockManager extends AbstractBlockManager {
@Nullable
@Override
public BlockStateWrapper createPackedBlockState(String blockState) {
public BlockStateWrapper createBlockState(String blockState) {
ImmutableBlockState state = BlockStateParser.deserialize(blockState);
if (state != null) {
return state.customBlockState();
}
try {
BlockData blockData = Bukkit.createBlockData(blockState);
return BlockStateUtils.toPackedBlockState(blockData);
return BlockStateUtils.toBlockStateWrapper(blockData);
} catch (IllegalArgumentException e) {
return null;
}
@@ -231,7 +231,7 @@ public final class BukkitBlockManager extends AbstractBlockManager {
@Override
public Key getBlockOwnerId(BlockStateWrapper state) {
return BlockStateUtils.getBlockOwnerIdFromState(state.handle());
return BlockStateUtils.getBlockOwnerIdFromState(state.literalObject());
}
@Override
@@ -258,9 +258,9 @@ public final class BukkitBlockManager extends AbstractBlockManager {
int size = RegistryUtils.currentBlockRegistrySize();
BlockStateWrapper[] states = new BlockStateWrapper[size];
for (int i = 0; i < size; i++) {
states[i] = BlockStateWrapper.create(BlockStateUtils.idToBlockState(i), i, BlockStateUtils.isVanillaBlock(i));
states[i] = new BukkitBlockStateWrapper(BlockStateUtils.idToBlockState(i), i);
}
BlockRegistryMirror.init(states, BlockStateWrapper.vanilla(MBlocks.STONE$defaultState, BlockStateUtils.blockStateToId(MBlocks.STONE$defaultState)));
BlockRegistryMirror.init(states, new BukkitBlockStateWrapper(MBlocks.STONE$defaultState, BlockStateUtils.blockStateToId(MBlocks.STONE$defaultState)));
}
private void registerEmptyBlock() {

View File

@@ -0,0 +1,23 @@
package net.momirealms.craftengine.bukkit.block;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
public class BukkitBlockStateWrapper implements BlockStateWrapper {
private final Object blockState;
private final int registryId;
public BukkitBlockStateWrapper(Object blockState, int registryId) {
this.blockState = blockState;
this.registryId = registryId;
}
@Override
public Object literalObject() {
return this.blockState;
}
@Override
public int registryId() {
return this.registryId;
}
}

View File

@@ -82,7 +82,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
CraftEngine.instance().logger().warn("Could not find custom block immutableBlockState for " + immutableBlockState + ". This might cause errors!");
continue;
}
DelegatingBlockState nmsState = (DelegatingBlockState) immutableBlockState.customBlockState().handle();
DelegatingBlockState nmsState = (DelegatingBlockState) immutableBlockState.customBlockState().literalObject();
nmsState.setBlockState(immutableBlockState);
BlockSettings settings = immutableBlockState.settings();
@@ -98,10 +98,10 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
Object pushReaction = ((Object[]) CoreReflections.method$PushReaction$values.invoke(null))[settings.pushReaction().ordinal()];
CoreReflections.field$BlockStateBase$pushReaction.set(nmsState, pushReaction);
boolean canOcclude = settings.canOcclude() == Tristate.UNDEFINED ? BlockStateUtils.isOcclude(immutableBlockState.vanillaBlockState().handle()) : settings.canOcclude().asBoolean();
boolean canOcclude = settings.canOcclude() == Tristate.UNDEFINED ? BlockStateUtils.isOcclude(immutableBlockState.vanillaBlockState().literalObject()) : settings.canOcclude().asBoolean();
CoreReflections.field$BlockStateBase$canOcclude.set(nmsState, canOcclude);
boolean useShapeForLightOcclusion = settings.useShapeForLightOcclusion() == Tristate.UNDEFINED ? CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.getBoolean(immutableBlockState.vanillaBlockState().handle()) : settings.useShapeForLightOcclusion().asBoolean();
boolean useShapeForLightOcclusion = settings.useShapeForLightOcclusion() == Tristate.UNDEFINED ? CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.getBoolean(immutableBlockState.vanillaBlockState().literalObject()) : settings.useShapeForLightOcclusion().asBoolean();
CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.set(nmsState, useShapeForLightOcclusion);
CoreReflections.field$BlockStateBase$isRedstoneConductor.set(nmsState, settings.isRedstoneConductor().asBoolean() ? ALWAYS_TRUE : ALWAYS_FALSE);
@@ -111,7 +111,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
// set parent block properties
DelegatingBlock nmsBlock = (DelegatingBlock) BlockStateUtils.getBlockOwner(nmsState);
ObjectHolder<BlockShape> shapeHolder = nmsBlock.shapeDelegate();
shapeHolder.bindValue(new BukkitBlockShape(immutableBlockState.vanillaBlockState().handle(), Optional.ofNullable(immutableBlockState.settings().supportShapeBlockState()).map(it -> {
shapeHolder.bindValue(new BukkitBlockShape(immutableBlockState.vanillaBlockState().literalObject(), Optional.ofNullable(immutableBlockState.settings().supportShapeBlockState()).map(it -> {
try {
Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(it));
if (!BlockStateUtils.isVanillaBlock(blockState)) {
@@ -140,7 +140,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
}
// modify cache
if (VersionHelper.isOrAbove1_21_2()) {
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(immutableBlockState.vanillaBlockState().handle());
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(immutableBlockState.vanillaBlockState().literalObject());
// set block light
CoreReflections.field$BlockStateBase$lightBlock.set(nmsState, blockLight);
// set propagates skylight
@@ -149,11 +149,11 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
} else if (settings.propagatesSkylightDown() == Tristate.FALSE) {
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, false);
} else {
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, CoreReflections.field$BlockStateBase$propagatesSkylightDown.getBoolean(immutableBlockState.vanillaBlockState().handle()));
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, CoreReflections.field$BlockStateBase$propagatesSkylightDown.getBoolean(immutableBlockState.vanillaBlockState().literalObject()));
}
} else {
Object cache = CoreReflections.field$BlockStateBase$cache.get(nmsState);
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$Cache$lightBlock.getInt(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().handle()));
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$Cache$lightBlock.getInt(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().literalObject()));
// set block light
CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, blockLight);
// set propagates skylight
@@ -162,7 +162,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock {
} else if (settings.propagatesSkylightDown() == Tristate.FALSE) {
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, false);
} else {
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.getBoolean(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().handle())));
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.getBoolean(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().literalObject())));
}
if (!isConditionallyFullOpaque) {
CoreReflections.field$BlockStateBase$opacityIfCached.set(nmsState, blockLight);

View File

@@ -31,11 +31,11 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
Direction.Axis axis = blockState.get(axisProperty);
return switch (rotation) {
case COUNTERCLOCKWISE_90, CLOCKWISE_90 -> switch (axis) {
case X -> blockState.with(axisProperty, Direction.Axis.Z).customBlockState().handle();
case Z -> blockState.with(axisProperty, Direction.Axis.X).customBlockState().handle();
default -> blockState.customBlockState().handle();
case X -> blockState.with(axisProperty, Direction.Axis.Z).customBlockState().literalObject();
case Z -> blockState.with(axisProperty, Direction.Axis.X).customBlockState().literalObject();
default -> blockState.customBlockState().literalObject();
};
default -> blockState.customBlockState().handle();
default -> blockState.customBlockState().literalObject();
};
};
});
@@ -45,7 +45,7 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
Property<HorizontalDirection> directionProperty = (Property<HorizontalDirection>) property;
behavior.rotateFunction = (thisBlock, blockState, rotation) ->
blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty).toDirection()).toHorizontalDirection())
.customBlockState().handle();
.customBlockState().literalObject();
behavior.mirrorFunction = (thisBlock, blockState, mirror) -> {
Rotation rotation = mirror.getRotation(blockState.get(directionProperty).toDirection());
return behavior.rotateFunction.rotate(thisBlock, blockState, rotation);
@@ -55,7 +55,7 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
Property<Direction> directionProperty = (Property<Direction>) property;
behavior.rotateFunction = (thisBlock, blockState, rotation) ->
blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty)))
.customBlockState().handle();
.customBlockState().literalObject();
behavior.mirrorFunction = (thisBlock, blockState, mirror) -> {
Rotation rotation = mirror.getRotation(blockState.get(directionProperty));
return behavior.rotateFunction.rotate(thisBlock, blockState, rotation);
@@ -68,7 +68,7 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
Property<HorizontalDirection> directionProperty = (Property<HorizontalDirection>) property;
behavior.rotateFunction = (thisBlock, blockState, rotation) ->
blockState.with(directionProperty, rotation.rotate(blockState.get(directionProperty).toDirection()).toHorizontalDirection())
.customBlockState().handle();
.customBlockState().literalObject();
behavior.mirrorFunction = (thisBlock, blockState, mirror) -> {
Rotation rotation = mirror.getRotation(blockState.get(directionProperty).toDirection());
return behavior.rotateFunction.rotate(thisBlock, blockState, rotation);
@@ -139,7 +139,7 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
if (optionalCustomState.isEmpty()) return CoreReflections.instance$ItemStack$EMPTY;
ImmutableBlockState immutableBlockState = optionalCustomState.get();
if (immutableBlockState.get(this.waterloggedProperty)) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().handle(), 3);
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, pos, immutableBlockState.with(this.waterloggedProperty, false).customBlockState().literalObject(), 3);
return FastNMS.INSTANCE.constructor$ItemStack(MItems.WATER_BUCKET, 1);
}
return CoreReflections.instance$ItemStack$EMPTY;
@@ -154,7 +154,7 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
ImmutableBlockState immutableBlockState = optionalCustomState.get();
Object fluidType = FastNMS.INSTANCE.method$FluidState$getType(args[3]);
if (!immutableBlockState.get(this.waterloggedProperty) && fluidType == MFluids.WATER) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().handle(), 3);
FastNMS.INSTANCE.method$LevelWriter$setBlock(args[0], args[1], immutableBlockState.with(this.waterloggedProperty, true).customBlockState().literalObject(), 3);
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleFluidTick(args[0], args[1], fluidType, 5);
return true;
}
@@ -182,6 +182,6 @@ public class BukkitBlockBehavior extends AbstractBlockBehavior {
if (optionalCustomState.isEmpty()) return false;
BlockStateWrapper vanillaState = optionalCustomState.get().vanillaBlockState();
if (vanillaState == null) return false;
return FastNMS.INSTANCE.method$BlockStateBase$isPathFindable(vanillaState.handle(), VersionHelper.isOrAbove1_20_5() ? null : args[1], VersionHelper.isOrAbove1_20_5() ? null : args[2], args[isPathFindable$type]);
return FastNMS.INSTANCE.method$BlockStateBase$isPathFindable(vanillaState.literalObject(), VersionHelper.isOrAbove1_20_5() ? null : args[1], VersionHelper.isOrAbove1_20_5() ? null : args[2], args[isPathFindable$type]);
}
}

View File

@@ -48,7 +48,7 @@ public class ConcretePowderBlockBehavior extends BukkitBlockBehavior {
Optional<CustomBlock> optionalCustomBlock = BukkitBlockManager.instance().blockById(this.targetBlock);
if (optionalCustomBlock.isPresent()) {
CustomBlock customBlock = optionalCustomBlock.get();
this.defaultBlockState = customBlock.defaultState().customBlockState().handle();
this.defaultBlockState = customBlock.defaultState().customBlockState().literalObject();
this.defaultImmutableBlockState = customBlock.defaultState();
} else {
CraftEngine.instance().logger().warn("Failed to create solid block " + this.targetBlock + " in ConcretePowderBlockBehavior");

View File

@@ -94,7 +94,7 @@ public class CropBlockBehavior extends BukkitBlockBehavior {
BlockStateUtils.getOptionalCustomBlockState(state).ifPresent(customState -> {
int age = this.getAge(customState);
if (age < this.ageProperty.max && RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, customState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, customState.with(this.ageProperty, age + 1).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
}
});
}
@@ -133,7 +133,7 @@ public class CropBlockBehavior extends BukkitBlockBehavior {
if (isMaxAge(state))
return InteractionResult.PASS;
boolean sendSwing = false;
Object visualState = state.vanillaBlockState().handle();
Object visualState = state.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), visualState);
@@ -156,7 +156,7 @@ public class CropBlockBehavior extends BukkitBlockBehavior {
}
ImmutableBlockState customState = optionalCustomState.get();
boolean sendParticles = false;
Object visualState = customState.vanillaBlockState().handle();
Object visualState = customState.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, level, pos, visualState);
@@ -180,7 +180,7 @@ public class CropBlockBehavior extends BukkitBlockBehavior {
if (i > maxAge) {
i = maxAge;
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, customState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, customState.with(this.ageProperty, i).customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
if (sendParticles) {
world.spawnParticle(ParticleUtils.HAPPY_VILLAGER, x + 0.5, y + 0.5, z + 0.5, 15, 0.25, 0.25, 0.25);
}

View File

@@ -107,7 +107,7 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
return MBlocks.AIR$defaultState;
}
if (neighborState.get(anotherDoorBehavior.get().halfProperty) != half) {
return neighborState.with(anotherDoorBehavior.get().halfProperty, half).customBlockState().handle();
return neighborState.with(anotherDoorBehavior.get().halfProperty, half).customBlockState().literalObject();
}
return MBlocks.AIR$defaultState;
} else {
@@ -245,7 +245,7 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
public void setOpen(@Nullable Player player, Object serverLevel, ImmutableBlockState state, BlockPos pos, boolean isOpen) {
if (isOpen(state) != isOpen) {
org.bukkit.World world = FastNMS.INSTANCE.method$Level$getCraftWorld(serverLevel);
FastNMS.INSTANCE.method$LevelWriter$setBlock(serverLevel, LocationUtils.toBlockPos(pos), state.with(this.openProperty, isOpen).customBlockState().handle(), UpdateOption.builder().updateImmediate().updateClients().build().flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(serverLevel, LocationUtils.toBlockPos(pos), state.with(this.openProperty, isOpen).customBlockState().literalObject(), UpdateOption.builder().updateImmediate().updateClients().build().flags());
world.sendGameEvent(player == null ? null : (org.bukkit.entity.Player) player.platformPlayer(), isOpen ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, new Vector(pos.x(), pos.y(), pos.z()));
SoundData soundData = isOpen ? this.openSound : this.closeSound;
if (soundData != null) {
@@ -307,7 +307,7 @@ public class DoorBlockBehavior extends AbstractCanSurviveBlockBehavior {
);
}
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, flag).with(this.openProperty, flag).customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS);
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, flag).with(this.openProperty, flag).customBlockState().literalObject(), UpdateOption.Flags.UPDATE_CLIENTS);
}
}

View File

@@ -63,7 +63,7 @@ public class DoubleHighBlockBehavior extends BukkitBlockBehavior {
World level = context.getLevel();
BlockPos anotherHalfPos = context.getClickedPos().relative(Direction.UP);
BlockStateWrapper blockStateWrapper = state.with(this.halfProperty, DoubleBlockHalf.UPPER).customBlockState();
FastNMS.INSTANCE.method$LevelWriter$setBlock(level.serverWorld(), LocationUtils.toBlockPos(anotherHalfPos), blockStateWrapper.handle(), UpdateOption.Flags.UPDATE_CLIENTS);
FastNMS.INSTANCE.method$LevelWriter$setBlock(level.serverWorld(), LocationUtils.toBlockPos(anotherHalfPos), blockStateWrapper.literalObject(), UpdateOption.Flags.UPDATE_CLIENTS);
}
@Override

View File

@@ -113,7 +113,7 @@ public class FenceGateBlockBehavior extends BukkitBlockBehavior {
if (relativeStateIsWall) {
// TODO: 连接原版方块
}
return customState.with(this.inWallProperty, flag).customBlockState().handle();
return customState.with(this.inWallProperty, flag).customBlockState().literalObject();
}
@Override
@@ -148,7 +148,7 @@ public class FenceGateBlockBehavior extends BukkitBlockBehavior {
private void playerToggle(UseOnContext context, ImmutableBlockState state) {
Player player = context.getPlayer();
this.toggle(state, context.getLevel(), context.getClickedPos(), player);
if (!InteractUtils.isInteractable((org.bukkit.entity.Player) player.platformPlayer(), BlockStateUtils.fromBlockData(state.vanillaBlockState().handle()), context.getHitResult(), (Item<ItemStack>) context.getItem())) {
if (!InteractUtils.isInteractable((org.bukkit.entity.Player) player.platformPlayer(), BlockStateUtils.fromBlockData(state.vanillaBlockState().literalObject()), context.getHitResult(), (Item<ItemStack>) context.getItem())) {
player.swingHand(context.getHand());
}
}
@@ -223,7 +223,7 @@ public class FenceGateBlockBehavior extends BukkitBlockBehavior {
this.playSound(LocationUtils.fromBlockPos(blockPos), world, hasSignal);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, hasSignal).customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS);
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, hasSignal).customBlockState().literalObject(), UpdateOption.Flags.UPDATE_CLIENTS);
}
private void toggle(ImmutableBlockState state, World world, BlockPos pos, @Nullable Player player) {
@@ -240,7 +240,7 @@ public class FenceGateBlockBehavior extends BukkitBlockBehavior {
}
newState = blockState.with(this.openProperty, true);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
boolean open = isOpen(newState);
((org.bukkit.World) world.platformWorld()).sendGameEvent(
player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null,

View File

@@ -8,7 +8,7 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.FeatureUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.util.ParticleUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.block.BlockBehavior;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
@@ -59,7 +59,7 @@ public class GrassBlockBehavior extends BukkitBlockBehavior {
}
boolean sendParticles = false;
ImmutableBlockState customState = optionalCustomState.get();
Object visualState = customState.vanillaBlockState().handle();
Object visualState = customState.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, level, blockPos, visualState);
@@ -86,12 +86,12 @@ public class GrassBlockBehavior extends BukkitBlockBehavior {
if (ItemUtils.isEmpty(item) || !item.vanillaId().equals(ItemKeys.BONE_MEAL) || context.getPlayer().isAdventureMode())
return InteractionResult.PASS;
BlockPos pos = context.getClickedPos();
BukkitBlockInWorld upper = (BukkitBlockInWorld) context.getLevel().getBlockAt(pos.x(), pos.y() + 1, pos.z());
BukkitExistingBlock upper = (BukkitExistingBlock) context.getLevel().getBlockAt(pos.x(), pos.y() + 1, pos.z());
Block block = upper.block();
if (!block.isEmpty())
return InteractionResult.PASS;
boolean sendSwing = false;
Object visualState = state.vanillaBlockState().handle();
Object visualState = state.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), visualState);

View File

@@ -44,7 +44,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
if (FastNMS.INSTANCE.method$CraftEventFactory$callRedstoneChange(world, blockPos, 0, 15).getNewCurrent() != 15) {
return;
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().handle(), 2);
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().literalObject(), 2);
}
}
@@ -64,7 +64,7 @@ public class LampBlockBehavior extends BukkitBlockBehavior {
if (FastNMS.INSTANCE.method$CraftEventFactory$callRedstoneChange(world, blockPos, 0, 15).getNewCurrent() != 15) {
return;
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().handle(), 2);
FastNMS.INSTANCE.method$LevelWriter$setBlock(world, blockPos, customState.cycle(this.litProperty).customBlockState().literalObject(), 2);
}
}
}

View File

@@ -86,10 +86,10 @@ public class LeavesBlockBehavior extends BukkitBlockBehavior {
LeavesBlockBehavior behavior = optionalBehavior.get();
ImmutableBlockState newState = behavior.updateDistance(customState, level, blockPos);
if (newState != customState) {
if (blockState == newState.customBlockState().handle()) {
if (blockState == newState.customBlockState().literalObject()) {
CoreReflections.method$BlockStateBase$updateNeighbourShapes.invoke(blockState, level, blockPos, UpdateOption.UPDATE_ALL.flags(), 512);
} else {
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, newState.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, newState.customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
}
}
}

View File

@@ -121,7 +121,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior {
private Object setSignalForState(Object state, int strength) {
Optional<ImmutableBlockState> optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(state);
if (optionalCustomState.isEmpty()) return state;
return optionalCustomState.get().with(this.poweredProperty, strength > 0).customBlockState().handle();
return optionalCustomState.get().with(this.poweredProperty, strength > 0).customBlockState().literalObject();
}
private void checkPressed(@Nullable Object entity, Object level, Object pos, Object state, int currentSignal, Object thisBlock) {

View File

@@ -114,7 +114,7 @@ public class SaplingBlockBehavior extends BukkitBlockBehavior {
}
ImmutableBlockState customState = optionalCustomState.get();
boolean sendParticles = false;
Object visualState = customState.vanillaBlockState().handle();
Object visualState = customState.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, level, blockPos, visualState);
@@ -151,7 +151,7 @@ public class SaplingBlockBehavior extends BukkitBlockBehavior {
if (ItemUtils.isEmpty(item) || !item.vanillaId().equals(ItemKeys.BONE_MEAL) || context.getPlayer().isAdventureMode())
return InteractionResult.PASS;
boolean sendSwing = false;
Object visualState = state.vanillaBlockState().handle();
Object visualState = state.vanillaBlockState().literalObject();
Object visualStateBlock = BlockStateUtils.getBlockOwner(visualState);
if (CoreReflections.clazz$BonemealableBlock.isInstance(visualStateBlock)) {
boolean is = FastNMS.INSTANCE.method$BonemealableBlock$isValidBonemealTarget(visualStateBlock, context.getLevel().serverWorld(), LocationUtils.toBlockPos(context.getClickedPos()), visualState);

View File

@@ -68,7 +68,7 @@ public class StackableBlockBehavior extends BukkitBlockBehavior {
private void updateStackableBlock(ImmutableBlockState state, BlockPos pos, World world, Item<ItemStack> item, Player player, InteractionHand hand) {
ImmutableBlockState nextStage = state.cycle(this.amountProperty);
Location location = new Location((org.bukkit.World) world.platformWorld(), pos.x(), pos.y(), pos.z());
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), nextStage.customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), nextStage.customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
if (this.stackSound != null) {
world.playBlockSound(new Vec3d(location.getX(), location.getY(), location.getZ()), this.stackSound);
}

View File

@@ -65,7 +65,7 @@ public class StairsBlockBehavior extends BukkitBlockBehavior {
Direction direction = DirectionUtils.fromNMSDirection(VersionHelper.isOrAbove1_21_2() ? args[4] : args[1]);
StairsShape stairsShape = getStairsShape(customState, level, LocationUtils.fromBlockPos(blockPos));
return direction.axis().isHorizontal()
? customState.with(this.shapeProperty, stairsShape).customBlockState().handle()
? customState.with(this.shapeProperty, stairsShape).customBlockState().literalObject()
: superMethod.call();
}

View File

@@ -118,7 +118,7 @@ public class TrapDoorBlockBehavior extends BukkitBlockBehavior {
private void playerToggle(UseOnContext context, ImmutableBlockState state) {
Player player = context.getPlayer();
this.toggle(state, context.getLevel(), context.getClickedPos(), player);
if (!InteractUtils.isInteractable((org.bukkit.entity.Player) player.platformPlayer(), BlockStateUtils.fromBlockData(state.vanillaBlockState().handle()), context.getHitResult(), (Item<ItemStack>) context.getItem())) {
if (!InteractUtils.isInteractable((org.bukkit.entity.Player) player.platformPlayer(), BlockStateUtils.fromBlockData(state.vanillaBlockState().literalObject()), context.getHitResult(), (Item<ItemStack>) context.getItem())) {
player.swingHand(context.getHand());
}
}
@@ -195,7 +195,7 @@ public class TrapDoorBlockBehavior extends BukkitBlockBehavior {
this.playSound(LocationUtils.fromBlockPos(blockPos), world, hasSignal);
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, hasSignal).customBlockState().handle(), UpdateOption.Flags.UPDATE_CLIENTS);
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, customState.with(this.poweredProperty, hasSignal).customBlockState().literalObject(), UpdateOption.Flags.UPDATE_CLIENTS);
if (this.waterloggedProperty != null && customState.get(this.waterloggedProperty)) {
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleFluidTick(level, blockPos, MFluids.WATER, 5);
}
@@ -203,7 +203,7 @@ public class TrapDoorBlockBehavior extends BukkitBlockBehavior {
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.UPDATE_ALL.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(world.serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
boolean open = newState.get(this.openProperty);
((org.bukkit.World) world.platformWorld()).sendGameEvent(
player != null ? (org.bukkit.entity.Player) player.platformPlayer() : null,

View File

@@ -66,13 +66,13 @@ public class VerticalCropBlockBehavior extends BukkitBlockBehavior {
if (age >= this.ageProperty.max || RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) {
Object nextPos = this.direction ? LocationUtils.above(blockPos) : LocationUtils.below(blockPos);
if (VersionHelper.isOrAbove1_21_5()) {
CraftBukkitReflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, nextPos, super.customBlock.defaultState().customBlockState().handle(), UpdateOption.UPDATE_ALL.flags());
CraftBukkitReflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, nextPos, super.customBlock.defaultState().customBlockState().literalObject(), UpdateOption.UPDATE_ALL.flags());
} else {
CraftBukkitReflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, nextPos, super.customBlock.defaultState().customBlockState().handle());
CraftBukkitReflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, nextPos, super.customBlock.defaultState().customBlockState().literalObject());
}
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, this.ageProperty.min).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, this.ageProperty.min).customBlockState().literalObject(), UpdateOption.UPDATE_NONE.flags());
} else if (RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) {
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, age + 1).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(level, blockPos, currentState.with(this.ageProperty, age + 1).customBlockState().literalObject(), UpdateOption.UPDATE_NONE.flags());
}
}
}

View File

@@ -6,7 +6,7 @@ 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.util.*;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.UpdateOption;
@@ -82,12 +82,12 @@ public class AxeItemBehavior extends ItemBehavior {
CompoundTag compoundTag = customState.propertiesNbt();
ImmutableBlockState newState = newCustomBlock.getBlockState(compoundTag);
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(context.getClickedPos());
BukkitExistingBlock clicked = (BukkitExistingBlock) context.getLevel().getBlockAt(context.getClickedPos());
org.bukkit.entity.Player bukkitPlayer = null;
if (player != null) {
bukkitPlayer = ((org.bukkit.entity.Player) player.platformPlayer());
// Call bukkit event
EntityChangeBlockEvent event = new EntityChangeBlockEvent(bukkitPlayer, clicked.block(), BlockStateUtils.fromBlockData(newState.customBlockState().handle()));
EntityChangeBlockEvent event = new EntityChangeBlockEvent(bukkitPlayer, clicked.block(), BlockStateUtils.fromBlockData(newState.customBlockState().literalObject()));
if (EventUtils.fireAndCheckCancel(event)) {
return InteractionResult.FAIL;
}
@@ -98,7 +98,7 @@ public class AxeItemBehavior extends ItemBehavior {
if (ItemUtils.isEmpty(item)) return InteractionResult.FAIL;
BlockPos pos = context.getClickedPos();
context.getLevel().playBlockSound(Vec3d.atCenterOf(pos), AXE_STRIP_SOUND, 1, 1);
FastNMS.INSTANCE.method$LevelWriter$setBlock(context.getLevel().serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().handle(), UpdateOption.UPDATE_ALL_IMMEDIATE.flags());
FastNMS.INSTANCE.method$LevelWriter$setBlock(context.getLevel().serverWorld(), LocationUtils.toBlockPos(pos), newState.customBlockState().literalObject(), UpdateOption.UPDATE_ALL_IMMEDIATE.flags());
clicked.block().getWorld().sendGameEvent(bukkitPlayer, GameEvent.BLOCK_CHANGE, new Vector(pos.x(), pos.y(), pos.z()));
Material material = MaterialUtils.getMaterial(item.vanillaId());
if (bukkitPlayer != null) {
@@ -106,7 +106,7 @@ public class AxeItemBehavior extends ItemBehavior {
// resend swing if it's not interactable on client side
if (!InteractUtils.isInteractable(
bukkitPlayer, BlockStateUtils.fromBlockData(customState.vanillaBlockState().handle()),
bukkitPlayer, BlockStateUtils.fromBlockData(customState.vanillaBlockState().literalObject()),
context.getHitResult(), item
) || player.isSecondaryUseActive()) {
player.swingHand(context.getHand());

View File

@@ -9,7 +9,7 @@ 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.*;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.UpdateOption;
@@ -111,7 +111,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
} else {
ImmutableBlockState customState = optionalCustomState.get();
// custom block
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().handle() : againstBlockState)) {
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().literalObject() : againstBlockState)) {
return InteractionResult.FAIL;
}
}
@@ -157,7 +157,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
WorldPosition position = new WorldPosition(context.getLevel(), pos.x() + 0.5, pos.y() + 0.5, pos.z() + 0.5);
Cancellable dummy = Cancellable.dummy();
PlayerOptionalContext functionContext = PlayerOptionalContext.of(player, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(bukkitBlock))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(bukkitBlock))
.withParameter(DirectContextParameters.POSITION, position)
.withParameter(DirectContextParameters.EVENT, dummy)
.withParameter(DirectContextParameters.HAND, context.getHand())
@@ -196,7 +196,7 @@ public class BlockItemBehavior extends BlockBoundItemBehavior {
try {
Player cePlayer = context.getPlayer();
Object player = cePlayer != null ? cePlayer.serverPlayer() : null;
Object blockState = state.customBlockState().handle();
Object blockState = state.customBlockState().literalObject();
Object blockPos = LocationUtils.toBlockPos(context.getClickedPos());
Object voxelShape;
if (VersionHelper.isOrAbove1_21_6()) {

View File

@@ -5,7 +5,7 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.EventUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
@@ -38,7 +38,7 @@ public class CompostableItemBehavior extends ItemBehavior {
@SuppressWarnings("UnstableApiUsage")
@Override
public InteractionResult useOnBlock(UseOnContext context) {
BukkitBlockInWorld block = (BukkitBlockInWorld) context.getLevel().getBlockAt(context.getClickedPos());
BukkitExistingBlock block = (BukkitExistingBlock) context.getLevel().getBlockAt(context.getClickedPos());
BlockData blockData = block.block().getBlockData();
Object blockOwner = BlockStateUtils.getBlockOwner(BlockStateUtils.blockDataToBlockState(blockData));
if (blockOwner != MBlocks.COMPOSTER) return InteractionResult.PASS;

View File

@@ -6,7 +6,7 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
import net.momirealms.craftengine.bukkit.util.InteractUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.entity.player.InteractionResult;
import net.momirealms.craftengine.core.item.Item;
@@ -40,7 +40,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
if (player == null) return InteractionResult.PASS;
BlockPos clickedPos = context.getClickedPos();
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(clickedPos);
BukkitExistingBlock clicked = (BukkitExistingBlock) context.getLevel().getBlockAt(clickedPos);
Block block = clicked.block();
BlockPos firePos = clickedPos.relative(context.getClickedFace());
Direction direction = context.getHorizontalDirection();
@@ -77,10 +77,10 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
// 点击对象为自定义方块
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
// 原版外观也可燃
if (BlockStateUtils.isBurnable(immutableBlockState.vanillaBlockState().handle())) {
if (BlockStateUtils.isBurnable(immutableBlockState.vanillaBlockState().literalObject())) {
return InteractionResult.PASS;
}
BlockData vanillaBlockState = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().handle());
BlockData vanillaBlockState = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().literalObject());
// 点击的是方块上面则只需要判断shift和可交互
if (direction == Direction.UP) {
// 客户端层面必须可交互
@@ -95,7 +95,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
} else {
// 玩家觉得自定义方块不可燃,且点击了侧面,那么就要判断火源下方的方块是否可燃,如果不可燃,则补发声音
BlockPos belowFirePos = firePos.relative(Direction.DOWN);
BukkitBlockInWorld belowFireBlock = (BukkitBlockInWorld) context.getLevel().getBlockAt(belowFirePos);
BukkitExistingBlock belowFireBlock = (BukkitExistingBlock) context.getLevel().getBlockAt(belowFirePos);
boolean belowCanBurn;
try {
Block belowBlock = belowFireBlock.block();
@@ -134,7 +134,7 @@ public class FlintAndSteelItemBehavior extends ItemBehavior {
for (Direction dir : Direction.values()) {
if (dir == relativeDirection) continue;
BlockPos relPos = firePos.relative(dir);
BukkitBlockInWorld nearByBlock = (BukkitBlockInWorld) context.getLevel().getBlockAt(relPos);
BukkitExistingBlock nearByBlock = (BukkitExistingBlock) context.getLevel().getBlockAt(relPos);
BlockData nearbyBlockData = nearByBlock.block().getBlockData();
Object nearbyBlockState = BlockStateUtils.blockDataToBlockState(nearbyBlockData);
int stateID = BlockStateUtils.blockStateToId(nearbyBlockState);

View File

@@ -11,7 +11,7 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.*;
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.behavior.AbstractBlockBehavior;
@@ -164,7 +164,7 @@ public class ItemEventListener implements Listener {
// fix client side issues
if (action.isRightClick() && hitResult != null &&
InteractUtils.willConsume(player, BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().handle()), hitResult, itemInHand)) {
InteractUtils.willConsume(player, BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().literalObject()), hitResult, itemInHand)) {
player.updateInventory();
//PlayerUtils.resendItemInHand(player);
}
@@ -173,7 +173,7 @@ public class ItemEventListener implements Listener {
// run custom functions
CustomBlock customBlock = immutableBlockState.owner().value();
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, immutableBlockState)
.withParameter(DirectContextParameters.HAND, hand)
.withParameter(DirectContextParameters.EVENT, dummy)
@@ -255,13 +255,13 @@ public class ItemEventListener implements Listener {
if (immutableBlockState != null) {
// client won't have sounds if the clientside block is interactable
// so we should check and resend sounds on BlockPlaceEvent
BlockData craftBlockData = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().handle());
BlockData craftBlockData = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().literalObject());
if (InteractUtils.isInteractable(player, craftBlockData, hitResult, itemInHand)) {
if (!serverPlayer.isSecondaryUseActive()) {
serverPlayer.setResendSound();
}
} else {
if (BlockStateUtils.isReplaceable(immutableBlockState.customBlockState().handle()) && !BlockStateUtils.isReplaceable(immutableBlockState.vanillaBlockState().handle())) {
if (BlockStateUtils.isReplaceable(immutableBlockState.customBlockState().literalObject()) && !BlockStateUtils.isReplaceable(immutableBlockState.vanillaBlockState().literalObject())) {
serverPlayer.setResendSwing();
}
}
@@ -318,7 +318,7 @@ public class ItemEventListener implements Listener {
if (serverPlayer.isSecondaryUseActive() || !InteractUtils.isInteractable(player, blockData, hitResult, itemInHand)) {
Cancellable dummy = Cancellable.dummy();
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withOptionalParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, immutableBlockState)
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand)
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(block.getLocation()))
@@ -339,7 +339,7 @@ public class ItemEventListener implements Listener {
if (hasCustomItem && action == Action.LEFT_CLICK_BLOCK) {
Cancellable dummy = Cancellable.dummy();
PlayerOptionalContext context = PlayerOptionalContext.of(serverPlayer, ContextHolder.builder()
.withParameter(DirectContextParameters.BLOCK, new BukkitBlockInWorld(block))
.withParameter(DirectContextParameters.BLOCK, new BukkitExistingBlock(block))
.withOptionalParameter(DirectContextParameters.CUSTOM_BLOCK_STATE, immutableBlockState)
.withOptionalParameter(DirectContextParameters.ITEM_IN_HAND, itemInHand)
.withParameter(DirectContextParameters.POSITION, LocationUtils.toWorldPosition(block.getLocation()))

View File

@@ -38,7 +38,7 @@ public class DebugGetBlockInternalIdCommand extends BukkitCommandFeature<Command
String data = context.get("id");
ImmutableBlockState state = BlockStateParser.deserialize(data);
if (state == null) return;
context.sender().sendMessage(BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState().handle()).toString());
context.sender().sendMessage(BlockStateUtils.getBlockOwnerIdFromState(state.customBlockState().literalObject()).toString());
});
}

View File

@@ -109,7 +109,7 @@ public final class BlockStateGenerator {
if (optionalPlayer != null && settings.requireCorrectTool()) {
if (item.isEmpty()) return List.of();
if (!settings.isCorrectTool(item.id()) &&
(!settings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool, state.customBlockState().handle()))) {
(!settings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool, state.customBlockState().literalObject()))) {
return List.of();
}
}
@@ -177,7 +177,7 @@ public final class BlockStateGenerator {
if (state == null) return thisObj;
Property<Boolean> waterloggedProperty = (Property<Boolean>) state.owner().value().getProperty("waterlogged");
if (waterloggedProperty == null) return thisObj;
return state.with(waterloggedProperty, (boolean) args[1]).customBlockState().handle();
return state.with(waterloggedProperty, (boolean) args[1]).customBlockState().literalObject();
}
}

View File

@@ -10,6 +10,8 @@ import java.util.Set;
public final class LootEntryInjector {
private LootEntryInjector() {}
public static void init() throws ReflectiveOperationException {
Object registry = MBuiltInRegistries.LOOT_POOL_ENTRY_TYPE;
CoreReflections.field$MappedRegistry$frozen.set(registry, false);

View File

@@ -229,7 +229,7 @@ public final class WorldStorageInjector {
// 自定义块到原版块,只需要判断旧块是否和客户端一直
BlockStateWrapper wrapper = previous.vanillaBlockState();
if (wrapper != null) {
updateLight(holder, wrapper.handle(), previousState, x, y, z);
updateLight(holder, wrapper.literalObject(), previousState, x, y, z);
}
}
}
@@ -245,10 +245,10 @@ public final class WorldStorageInjector {
if (Config.enableLightSystem()) {
if (previousImmutableBlockState.isEmpty()) {
// 原版块到自定义块,只需要判断新块是否和客户端视觉一致
updateLight(holder, immutableBlockState.vanillaBlockState().handle(), newState, x, y, z);
updateLight(holder, immutableBlockState.vanillaBlockState().literalObject(), newState, x, y, z);
} else {
// 自定义块到自定义块
updateLight$complex(holder, immutableBlockState.vanillaBlockState().handle(), newState, previousState, x, y, z);
updateLight$complex(holder, immutableBlockState.vanillaBlockState().literalObject(), newState, previousState, x, y, z);
}
}
}

View File

@@ -1168,7 +1168,7 @@ public class PacketConsumers {
if (player.isAdventureMode()) {
if (Config.simplifyAdventureBreakCheck()) {
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
if (!player.canBreak(pos, state.vanillaBlockState().handle())) {
if (!player.canBreak(pos, state.vanillaBlockState().literalObject())) {
player.preventMiningBlock();
return;
}
@@ -1336,7 +1336,7 @@ public class PacketConsumers {
Key itemId = state.settings().itemId();
// no item available
if (itemId == null) return;
Object vanillaBlock = FastNMS.INSTANCE.method$BlockState$getBlock(state.vanillaBlockState().handle());
Object vanillaBlock = FastNMS.INSTANCE.method$BlockState$getBlock(state.vanillaBlockState().literalObject());
Object vanillaBlockItem = FastNMS.INSTANCE.method$Block$asItem(vanillaBlock);
if (vanillaBlockItem == null) return;
Key addItemId = KeyUtils.namespacedKey2Key(item.getType().getKey());

View File

@@ -541,7 +541,7 @@ public class BukkitServerPlayer extends Player {
if (custom && getDestroyProgress(state, pos) >= 1f) {
BlockStateWrapper vanillaBlockState = immutableBlockState.vanillaBlockState();
// if it's not an instant break on client side, we should resend level event
if (vanillaBlockState != null && getDestroyProgress(vanillaBlockState.handle(), pos) < 1f) {
if (vanillaBlockState != null && getDestroyProgress(vanillaBlockState.literalObject(), pos) < 1f) {
Object levelEventPacket = FastNMS.INSTANCE.constructor$ClientboundLevelEventPacket(
WorldEvents.BLOCK_BREAK_EFFECT, LocationUtils.toBlockPos(pos), BlockStateUtils.blockStateToId(state), false);
sendPacket(levelEventPacket, false);
@@ -703,7 +703,7 @@ public class BukkitServerPlayer extends Player {
// for simplified adventure break, switch mayBuild temporarily
if (isAdventureMode() && Config.simplifyAdventureBreakCheck()) {
// check the appearance state
if (canBreak(hitPos, customState.vanillaBlockState().handle())) {
if (canBreak(hitPos, customState.vanillaBlockState().literalObject())) {
// Error might occur so we use try here
try {
FastNMS.INSTANCE.field$Player$mayBuild(serverPlayer, true);

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.bukkit.block.BukkitBlockStateWrapper;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
@@ -42,10 +43,10 @@ public final class BlockStateUtils {
hasInit = true;
}
public static BlockStateWrapper toPackedBlockState(BlockData blockData) {
public static BlockStateWrapper toBlockStateWrapper(BlockData blockData) {
Object state = blockDataToBlockState(blockData);
int id = blockStateToId(state);
return BlockStateWrapper.create(state, id, isVanillaBlock(id));
return new BukkitBlockStateWrapper(state, id);
}
public static boolean isCorrectTool(@NotNull ImmutableBlockState state, @Nullable Item<ItemStack> itemInHand) {
@@ -53,7 +54,7 @@ public final class BlockStateUtils {
if (settings.requireCorrectTool()) {
if (itemInHand == null || itemInHand.isEmpty()) return false;
return settings.isCorrectTool(itemInHand.id()) ||
(settings.respectToolComponent() && FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(itemInHand.getLiteralObject(), state.customBlockState().handle()));
(settings.respectToolComponent() && FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(itemInHand.getLiteralObject(), state.customBlockState().literalObject()));
}
return true;
}
@@ -145,8 +146,6 @@ public final class BlockStateUtils {
}
public static Object getBlockState(Block block) {
Object worldServer = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld());
Object blockPos = LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ());
return FastNMS.INSTANCE.method$BlockGetter$getBlockState(worldServer, blockPos);
return FastNMS.INSTANCE.method$BlockGetter$getBlockState(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(block.getWorld()), LocationUtils.toBlockPos(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -47,7 +47,7 @@ public final class ParticleUtils {
public static Object toBukkitParticleData(ParticleData particleData, Context context, World world, double x, double y, double z) {
return switch (particleData) {
case BlockStateData data -> BlockStateUtils.fromBlockData(data.blockState().handle());
case BlockStateData data -> BlockStateUtils.fromBlockData(data.blockState().literalObject());
case ColorData data -> ColorUtils.toBukkit(data.color());
case DustData data -> new Particle.DustOptions(ColorUtils.toBukkit(data.color()), data.size());
case DustTransitionData data -> new Particle.DustTransition(ColorUtils.toBukkit(data.from()), ColorUtils.toBukkit(data.to()), data.size());

View File

@@ -7,19 +7,27 @@ 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.core.block.BlockRegistryMirror;
import net.momirealms.craftengine.core.block.BlockStateWrapper;
import net.momirealms.craftengine.core.block.CustomBlock;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.block.state.StatePropertyAccessor;
import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.BlockInWorld;
import net.momirealms.craftengine.core.world.ExistingBlock;
import net.momirealms.craftengine.core.world.World;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BukkitBlockInWorld implements BlockInWorld {
import java.util.Optional;
public class BukkitExistingBlock implements ExistingBlock {
private final Block block;
public BukkitBlockInWorld(Block block) {
public BukkitExistingBlock(Block block) {
this.block = block;
}
@@ -45,6 +53,22 @@ public class BukkitBlockInWorld implements BlockInWorld {
return FastNMS.INSTANCE.method$FluidState$getType(fluidData) == MFluids.WATER;
}
@Override
public @NotNull StatePropertyAccessor createStatePropertyAccessor() {
return FastNMS.INSTANCE.createStatePropertyAccessor(this.block);
}
@Override
public boolean isCustom() {
return CraftEngineBlocks.isCustomBlock(this.block);
}
@Override
public @NotNull BlockStateWrapper blockState() {
Object blockState = BlockStateUtils.getBlockState(this.block);
return BlockRegistryMirror.stateByRegistryId(BlockStateUtils.blockStateToId(blockState));
}
@Override
public int x() {
return this.block.getX();
@@ -62,11 +86,12 @@ public class BukkitBlockInWorld implements BlockInWorld {
@Override
public Key type() {
CustomBlock customBlock = customBlock();
if (customBlock == null) {
return BlockStateUtils.getBlockOwnerIdFromData(this.block.getBlockData());
Object blockState = BlockStateUtils.getBlockState(this.block);
Optional<ImmutableBlockState> optionalCustomBlockState = BlockStateUtils.getOptionalCustomBlockState(blockState);
if (optionalCustomBlockState.isPresent()) {
return optionalCustomBlockState.get().owner().value().id();
}
return customBlock.id();
return BlockStateUtils.getBlockOwnerIdFromState(blockState);
}
@Override

View File

@@ -50,8 +50,8 @@ public class BukkitWorld implements World {
}
@Override
public BlockInWorld getBlockAt(int x, int y, int z) {
return new BukkitBlockInWorld(platformWorld().getBlockAt(x, y, z));
public ExistingBlock getBlockAt(int x, int y, int z) {
return new BukkitExistingBlock(platformWorld().getBlockAt(x, y, z));
}
@Override
@@ -116,7 +116,7 @@ public class BukkitWorld implements World {
public void setBlockAt(int x, int y, int z, BlockStateWrapper blockState, int flags) {
Object worldServer = serverWorld();
Object blockPos = FastNMS.INSTANCE.constructor$BlockPos(x, y, z);
FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState.handle(), flags);
FastNMS.INSTANCE.method$LevelWriter$setBlock(worldServer, blockPos, blockState.literalObject(), flags);
}
@Override

View File

@@ -311,7 +311,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
for (int y = 0; y < 16; y++) {
ImmutableBlockState customState = ceSection.getBlockState(x, y, z);
if (!customState.isEmpty() && customState.vanillaBlockState() != null) {
FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.vanillaBlockState().handle(), false);
FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.vanillaBlockState().literalObject(), false);
unsaved = true;
}
}
@@ -398,7 +398,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
for (int y = 0; y < 16; y++) {
ImmutableBlockState customState = ceSection.getBlockState(x, y, z);
if (!customState.isEmpty() && customState.customBlockState() != null) {
FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.customBlockState().handle(), false);
FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.customBlockState().literalObject(), false);
}
}
}