diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 49ffc0057..37c8f19c8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -167,6 +167,7 @@ public final class BlockEventListener implements Listener { // Restore sounds in cancelled events else { if (Config.processCancelledBreak()) { + if (BukkitItemUtils.isDebugStick(itemInHand)) return; serverPlayer.playSound(position, state.settings().sounds().breakSound(), SoundSource.BLOCK); } } @@ -196,6 +197,7 @@ public final class BlockEventListener implements Listener { } // sound system if (Config.enableSoundSystem() && (!event.isCancelled() || Config.processCancelledBreak())) { + if (BukkitItemUtils.isDebugStick(itemInHand)) return; Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); Object soundEvent = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java index 09446dee3..1d13954b2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurniture.java @@ -52,27 +52,29 @@ public class BukkitFurniture extends Furniture { } @Override - public boolean setVariant(String variantName) { + public boolean setVariant(String variantName, boolean force) { FurnitureVariant variant = this.config.getVariant(variantName); if (variant == null) return false; if (this.currentVariant == variant) return false; // 检查新位置是否可用 - List aabbs = new ArrayList<>(); - WorldPosition position = position(); - for (FurnitureHitBoxConfig hitBoxConfig : variant.hitBoxConfigs()) { - hitBoxConfig.prepareBoundingBox(position, aabbs::add, false); - } - if (!aabbs.isEmpty()) { - if (!FastNMS.INSTANCE.checkEntityCollision(position.world.serverWorld(), aabbs.stream().map(it -> FastNMS.INSTANCE.constructor$AABB(it.minX, it.minY, it.minZ, it.maxX, it.maxY, it.maxZ)).toList(), - o -> { - for (Collider collider : super.colliders) { - if (o == collider.handle()) { - return false; + if (!force) { + List aabbs = new ArrayList<>(); + WorldPosition position = position(); + for (FurnitureHitBoxConfig hitBoxConfig : variant.hitBoxConfigs()) { + hitBoxConfig.prepareBoundingBox(position, aabbs::add, false); + } + if (!aabbs.isEmpty()) { + if (!FastNMS.INSTANCE.checkEntityCollision(position.world.serverWorld(), aabbs.stream().map(it -> FastNMS.INSTANCE.constructor$AABB(it.minX, it.minY, it.minZ, it.maxX, it.maxY, it.maxZ)).toList(), + o -> { + for (Collider collider : super.colliders) { + if (o == collider.handle()) { + return false; + } } - } - return true; - })) { - return false; + return true; + })) { + return false; + } } } // 删除椅子 @@ -88,25 +90,27 @@ public class BukkitFurniture extends Furniture { @SuppressWarnings("deprecation") @Override - public CompletableFuture moveTo(WorldPosition position) { + public CompletableFuture moveTo(WorldPosition position, boolean force) { ItemDisplay itemDisplay = this.metaEntity.get(); if (itemDisplay == null) return CompletableFuture.completedFuture(false); - // 检查新位置是否可用 - List aabbs = new ArrayList<>(); - for (FurnitureHitBoxConfig hitBoxConfig : getCurrentVariant().hitBoxConfigs()) { - hitBoxConfig.prepareBoundingBox(position, aabbs::add, false); - } - if (!aabbs.isEmpty()) { - if (!FastNMS.INSTANCE.checkEntityCollision(position.world.serverWorld(), aabbs.stream().map(it -> FastNMS.INSTANCE.constructor$AABB(it.minX, it.minY, it.minZ, it.maxX, it.maxY, it.maxZ)).toList(), - o -> { - for (Collider collider : super.colliders) { - if (o == collider.handle()) { - return false; + if (!force) { + // 检查新位置是否可用 + List aabbs = new ArrayList<>(); + for (FurnitureHitBoxConfig hitBoxConfig : getCurrentVariant().hitBoxConfigs()) { + hitBoxConfig.prepareBoundingBox(position, aabbs::add, false); + } + if (!aabbs.isEmpty()) { + if (!FastNMS.INSTANCE.checkEntityCollision(position.world.serverWorld(), aabbs.stream().map(it -> FastNMS.INSTANCE.constructor$AABB(it.minX, it.minY, it.minZ, it.maxX, it.maxY, it.maxZ)).toList(), + o -> { + for (Collider collider : super.colliders) { + if (o == collider.handle()) { + return false; + } } - } - return true; - })) { - return CompletableFuture.completedFuture(false); + return true; + })) { + return CompletableFuture.completedFuture(false); + } } } // 删除椅子 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java index a73595f1b..b46d17d88 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/FurnitureEventListener.java @@ -4,15 +4,18 @@ import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent; import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; +import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.bukkit.util.BukkitItemUtils; import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.world.BukkitWorldManager; +import net.momirealms.craftengine.core.entity.furniture.FurnitureDebugStickState; import net.momirealms.craftengine.core.entity.player.InteractionHand; import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemKeys; -import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.chunk.CEChunk; import org.bukkit.entity.Entity; @@ -27,8 +30,10 @@ import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; public class FurnitureEventListener implements Listener { private final BukkitFurnitureManager manager; @@ -118,44 +123,66 @@ public class FurnitureEventListener implements Listener { } } + @SuppressWarnings("DuplicatedCode") + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void onFurniturePreBreak(FurnitureAttemptBreakEvent event) { + Player bukkitPlayer = event.getPlayer(); + BukkitServerPlayer player = BukkitAdaptors.adapt(bukkitPlayer); + Item itemInHand = player.getItemInHand(InteractionHand.MAIN_HAND); + if (!BukkitItemUtils.isDebugStick(itemInHand)) return; + if (!(player.canInstabuild() && player.hasPermission("minecraft.debugstick")) && !player.hasPermission("minecraft.debugstick.always")) { + return; + } + event.setCancelled(true); + BukkitFurniture furniture = event.furniture(); + Object storedData = itemInHand.getJavaTag("craftengine:debug_stick_state"); + if (storedData == null) storedData = new HashMap<>(); + if (storedData instanceof Map map) { + Map data = new HashMap<>(MiscUtils.castToMap(map, false)); + FurnitureDebugStickState state = ResourceConfigUtils.getAsEnum(data.get("furniture"), FurnitureDebugStickState.class, FurnitureDebugStickState.VARIANT); + state = player.isSecondaryUseActive() ? state.previous() : state.next(); + String propertyName = state.name().toLowerCase(Locale.ROOT); + data.put("furniture", propertyName); + itemInHand.setTag(data, "craftengine:debug_stick_state"); + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( + ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.select") + .arguments( + Component.text(propertyName), + Component.text(state.format(furniture)) + )), true); + player.sendPacket(systemChatPacket, false); + } + } + + @SuppressWarnings("DuplicatedCode") @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onInteractFurniture(FurnitureInteractEvent event) { Player bukkitPlayer = event.getPlayer(); BukkitServerPlayer player = BukkitAdaptors.adapt(bukkitPlayer); + Item itemInHand = player.getItemInHand(InteractionHand.MAIN_HAND); + if (!BukkitItemUtils.isDebugStick(itemInHand)) return; if (!(player.canInstabuild() && player.hasPermission("minecraft.debugstick")) && !player.hasPermission("minecraft.debugstick.always")) { return; } - Item itemInHand = player.getItemInHand(InteractionHand.MAIN_HAND); - if (!itemInHand.vanillaId().equals(ItemKeys.DEBUG_STICK)) return; - BukkitFurniture furniture = event.furniture(); - List variants = new ArrayList<>(furniture.config.variants().keySet()); - if (variants.size() == 1) { - try { - Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( + Object storedData = itemInHand.getJavaTag("craftengine:debug_stick_state"); + if (storedData == null) storedData = new HashMap<>(); + if (storedData instanceof Map map) { + Map data = new HashMap<>(MiscUtils.castToMap(map, false)); + FurnitureDebugStickState state = ResourceConfigUtils.getAsEnum(data.get("furniture"), FurnitureDebugStickState.class, FurnitureDebugStickState.VARIANT); + BukkitFurniture furniture = event.furniture(); + state.handler().onInteract(player.isSecondaryUseActive(), furniture, (s1, s2) -> { + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( + ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.update") + .arguments( + Component.text(s1), + Component.text(s2) + )), true); + player.sendPacket(systemChatPacket, false); + }, () -> { + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.empty").arguments(Component.text(furniture.id().asString()))), true); player.sendPacket(systemChatPacket, false); - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().warn("Could not create system chat packet", e); - } - } else { - String variantName = furniture.getCurrentVariant().name(); - int index = variants.indexOf(variantName) + 1; - if (index >= variants.size()) { - index = 0; - } - if (furniture.setVariant(variants.get(index))) { - try { - Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( - ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.update") - .arguments( - Component.text("variant"), - Component.text(variants.get(index)) - )), true); - player.sendPacket(systemChatPacket, false); - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().warn("Could not create system chat packet", e); - } - } + }); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java index bb182cc20..19d2aab15 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java @@ -4,9 +4,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent; import io.papermc.paper.event.player.AsyncChatDecorateEvent; -import net.kyori.adventure.key.Key; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.paper.PaperReflections; @@ -18,7 +16,6 @@ import net.momirealms.craftengine.core.font.*; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.MinecraftVersion; import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Bukkit; import org.bukkit.entity.Player; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java index 0a21878f0..e9dbcc5bb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/DebugStickListener.java @@ -5,9 +5,9 @@ import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; -import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.bukkit.util.BukkitItemUtils; import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.core.block.CustomBlock; @@ -16,7 +16,6 @@ import net.momirealms.craftengine.core.block.UpdateOption; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.entity.player.InteractionHand; import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.util.MiscUtils; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -46,7 +45,7 @@ public class DebugStickListener implements Listener { Player bukkitPlayer = event.getPlayer(); BukkitServerPlayer player = BukkitAdaptors.adapt(bukkitPlayer); Item itemInHand = player.getItemInHand(event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND); - if (!itemInHand.vanillaId().equals(ItemKeys.DEBUG_STICK)) return; + if (!BukkitItemUtils.isDebugStick(itemInHand)) return; if (!(player.canInstabuild() && player.hasPermission("minecraft.debugstick")) && !player.hasPermission("minecraft.debugstick.always")) { return; } @@ -64,47 +63,43 @@ public class DebugStickListener implements Listener { CustomBlock block = customState.owner().value(); Collection> properties = block.properties(); String blockId = block.id().toString(); - try { - if (properties.isEmpty()) { - Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( - ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.empty").arguments(Component.text(blockId))), true); - player.sendPacket(systemChatPacket, false); - } else { - Object storedData = itemInHand.getJavaTag("craftengine:debug_stick_state"); - if (storedData == null) storedData = new HashMap<>(); - if (storedData instanceof Map map) { - Map data = new HashMap<>(MiscUtils.castToMap(map, false)); - String currentPropertyName = (String) data.get(blockId); - Property currentProperty = block.getProperty(currentPropertyName); - if (currentProperty == null) { - currentProperty = properties.iterator().next(); - } - if (update) { - ImmutableBlockState nextState = cycleState(customState, currentProperty, player.isSecondaryUseActive()); - CraftEngineBlocks.place(clickedBlock.getLocation(), nextState, new UpdateOption.Builder().updateClients().updateKnownShape().build(), false); - Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( - ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.update") - .arguments( - Component.text(currentProperty.name()), - Component.text(getNameHelper(nextState, currentProperty)) - )), true); - player.sendPacket(systemChatPacket, false); - } else { - currentProperty = getRelative(properties, currentProperty, player.isSecondaryUseActive()); - data.put(blockId, currentProperty.name()); - itemInHand.setTag(data, "craftengine:debug_stick_state"); - Object systemChatPacket = NetworkReflections.constructor$ClientboundSystemChatPacket.newInstance( - ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.select") - .arguments( - Component.text(currentProperty.name()), - Component.text(getNameHelper(customState, currentProperty)) - )), true); - player.sendPacket(systemChatPacket, false); - } + if (properties.isEmpty()) { + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( + ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.empty").arguments(Component.text(blockId))), true); + player.sendPacket(systemChatPacket, false); + } else { + Object storedData = itemInHand.getJavaTag("craftengine:debug_stick_state"); + if (storedData == null) storedData = new HashMap<>(); + if (storedData instanceof Map map) { + Map data = new HashMap<>(MiscUtils.castToMap(map, false)); + String currentPropertyName = (String) data.get(blockId); + Property currentProperty = block.getProperty(currentPropertyName); + if (currentProperty == null) { + currentProperty = properties.iterator().next(); + } + if (update) { + ImmutableBlockState nextState = cycleState(customState, currentProperty, player.isSecondaryUseActive()); + CraftEngineBlocks.place(clickedBlock.getLocation(), nextState, new UpdateOption.Builder().updateClients().updateKnownShape().build(), false); + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( + ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.update") + .arguments( + Component.text(currentProperty.name()), + Component.text(getNameHelper(nextState, currentProperty)) + )), true); + player.sendPacket(systemChatPacket, false); + } else { + currentProperty = getRelative(properties, currentProperty, player.isSecondaryUseActive()); + data.put(blockId, currentProperty.name()); + itemInHand.setTag(data, "craftengine:debug_stick_state"); + Object systemChatPacket = FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket( + ComponentUtils.adventureToMinecraft(Component.translatable("item.minecraft.debug_stick.select") + .arguments( + Component.text(currentProperty.name()), + Component.text(getNameHelper(customState, currentProperty)) + )), true); + player.sendPacket(systemChatPacket, false); } } - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to send system chat packet", e); } }); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 5546b0734..d9cafa4fa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -67,7 +67,6 @@ import net.momirealms.craftengine.core.font.FontManager; import net.momirealms.craftengine.core.font.IllegalCharacterProcessResult; import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Item; -import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.context.UseOnContext; import net.momirealms.craftengine.core.item.recipe.network.legacy.LegacyRecipeHolder; @@ -3814,7 +3813,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes return; } // 不处理调试棒 - if (itemInHand.vanillaId().equals(ItemKeys.DEBUG_STICK)) { + if (BukkitItemUtils.isDebugStick(itemInHand)) { return; } // 已经有过交互了 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java index 698ce1fc9..257449280 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/payload/protocol/ClientCustomBlockPacket.java @@ -12,7 +12,6 @@ import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkRefl import net.momirealms.craftengine.bukkit.plugin.reflection.paper.PaperReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.RegistryUtils; -import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.logger.Debugger; import net.momirealms.craftengine.core.plugin.network.ModPacket; import net.momirealms.craftengine.core.plugin.network.NetWorkUser; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MItems.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MItems.java index 258666205..b08176a87 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MItems.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/MItems.java @@ -11,6 +11,7 @@ public final class MItems { public static final Object AIR; public static final Object WATER_BUCKET; public static final Object BARRIER; + public static final Object DEBUG_STICK; @Nullable private static Object getById(String id) { @@ -27,5 +28,6 @@ public final class MItems { AIR = getById("air"); WATER_BUCKET = getById("water_bucket"); BARRIER = getById("barrier"); + DEBUG_STICK = getById("debug_stick"); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java index 9b1e00511..048e99073 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java @@ -52,9 +52,9 @@ public final class NetworkReflections { ) ); - public static final Constructor constructor$ClientboundSystemChatPacket = requireNonNull( - ReflectionUtils.getConstructor(clazz$ClientboundSystemChatPacket, CoreReflections.clazz$Component, boolean.class) - ); +// public static final Constructor constructor$ClientboundSystemChatPacket = requireNonNull( +// ReflectionUtils.getConstructor(clazz$ClientboundSystemChatPacket, CoreReflections.clazz$Component, boolean.class) +// ); public static final Field field$ClientboundSystemChatPacket$overlay = requireNonNull( ReflectionUtils.getDeclaredField( 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 d690465e9..7f4b54512 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 @@ -897,12 +897,17 @@ public class BukkitServerPlayer extends Player { Object blockPos = LocationUtils.toBlockPos(hitPos); Object serverPlayer = serverPlayer(); + // check item in hand + Item item = this.getItemInHand(InteractionHand.MAIN_HAND); + // send hit sound if the sound is removed if (currentTick - this.lastHitBlockTime > 3) { - Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(destroyedState); - Object soundEvent = FastNMS.INSTANCE.field$SoundType$hitSound(soundType); - Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); - player.playSound(location, soundId.toString(), SoundCategory.BLOCKS, 0.5F, 0.5F); + if (!BukkitItemUtils.isDebugStick(item)) { + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(destroyedState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$hitSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + player.playSound(location, soundId.toString(), SoundCategory.BLOCKS, 0.5F, 0.5F); + } this.lastHitBlockTime = currentTick; } @@ -911,8 +916,6 @@ public class BukkitServerPlayer extends Player { // prevent server from taking over breaking custom blocks Object gameMode = FastNMS.INSTANCE.field$ServerPlayer$gameMode(serverPlayer); CoreReflections.field$ServerPlayerGameMode$isDestroyingBlock.set(gameMode, false); - // check item in hand - Item item = this.getItemInHand(InteractionHand.MAIN_HAND); if (!item.isEmpty()) { Material itemMaterial = item.getItem().getType(); // creative mode + invalid item in hand diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitItemUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitItemUtils.java new file mode 100644 index 000000000..0690ee094 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitItemUtils.java @@ -0,0 +1,15 @@ +package net.momirealms.craftengine.bukkit.util; + +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems; +import net.momirealms.craftengine.core.item.Item; +import org.bukkit.inventory.ItemStack; + +public final class BukkitItemUtils { + + private BukkitItemUtils() {} + + public static boolean isDebugStick(Item item) { + return FastNMS.INSTANCE.method$ItemStack$getItem(item.getLiteralObject()) == MItems.DEBUG_STICK; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Furniture.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Furniture.java index 18e3d467c..d90d8de79 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Furniture.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/Furniture.java @@ -65,9 +65,17 @@ public abstract class Furniture implements Cullable { return this.currentVariant; } - public abstract boolean setVariant(String variantName); + public boolean setVariant(String variantName) { + return this.setVariant(variantName, false); + } - public abstract CompletableFuture moveTo(WorldPosition position); + public abstract boolean setVariant(String variantName, boolean force); + + public CompletableFuture moveTo(WorldPosition position) { + return this.moveTo(position, false); + } + + public abstract CompletableFuture moveTo(WorldPosition position, boolean force); protected abstract void refresh(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureDebugStickState.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureDebugStickState.java new file mode 100644 index 000000000..615420361 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/FurnitureDebugStickState.java @@ -0,0 +1,167 @@ +package net.momirealms.craftengine.core.entity.furniture; + +import net.momirealms.craftengine.core.world.WorldPosition; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; + +public enum FurnitureDebugStickState { + VARIANT(f -> f.getCurrentVariant().name(), new VariantHandler()), + X_0_1(f -> String.format("%.2f", f.position().x), new XPositionHandler(0.1)), + X_0_0_1(f -> String.format("%.2f", f.position().x), new XPositionHandler(0.01)), + Y_0_1(f -> String.format("%.2f", f.position().y), new YPositionHandler(0.1)), + Y_0_0_1(f -> String.format("%.2f", f.position().y), new YPositionHandler(0.01)), + Z_0_1(f -> String.format("%.2f", f.position().z), new ZPositionHandler(0.1)), + Z_0_0_1(f -> String.format("%.2f", f.position().z), new ZPositionHandler(0.01)), + ROTATION_90(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(90)), + ROTATION_45(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(45)), + ROTATION_22_5(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(22.5f)), + ROTATION_15(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(15)), + ROTATION_5(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(5)), + ROTATION_1(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(1)), + ROTATION_0_5(f -> String.format("%.2f", f.position().yRot()), new RotateHandler(0.5f)); + + public static final FurnitureDebugStickState[] VALUES = values(); + private final Function formatter; + private final DebugStickHandler handler; + + FurnitureDebugStickState(Function formatter, DebugStickHandler handler) { + this.formatter = formatter; + this.handler = handler; + } + + public DebugStickHandler handler() { + return handler; + } + + public FurnitureDebugStickState next() { + int ordinal = this.ordinal(); + if (ordinal == VALUES.length - 1) { + return VALUES[0]; // 循环到第一个 + } + return VALUES[ordinal + 1]; + } + + public FurnitureDebugStickState previous() { + int ordinal = this.ordinal(); + if (ordinal == 0) { + return VALUES[VALUES.length - 1]; // 循环到最后一个 + } + return VALUES[ordinal - 1]; + } + + public String format(Furniture furniture) { + return this.formatter.apply(furniture); + } + + public interface DebugStickHandler { + + void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange); + } + + public static class VariantHandler implements DebugStickHandler { + + @Override + public void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange) { + List variants = new ArrayList<>(furniture.config.variants().keySet()); + if (variants.size() == 1) { + noChange.run(); + } else { + String variantName = furniture.getCurrentVariant().name(); + int index; + if (isSecondaryUsage) { + index = variants.indexOf(variantName) - 1; + if (index < 0) { + index = variants.size() - 1; + } + } else { + index = variants.indexOf(variantName) + 1; + if (index >= variants.size()) { + index = 0; + } + } + if (furniture.setVariant(variants.get(index), true)) { + changed.accept("variant", variants.get(index)); + } + } + } + } + + public static class RotateHandler implements DebugStickHandler { + private final float angle; + + public RotateHandler(float angle) { + this.angle = angle; + } + + @Override + public void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange) { + WorldPosition position = furniture.position(); + float yaw = isSecondaryUsage ? position.yRot() - angle : position.yRot() + angle; + furniture.moveTo(new WorldPosition(position.world, position.x, position.y, position.z, position.xRot, yaw), true).thenAccept(success -> { + if (success) { + changed.accept("rotation", String.format("%.2f", yaw)); + } + }); + } + } + + public static class XPositionHandler implements DebugStickHandler { + private final double delta; + + public XPositionHandler(double delta) { + this.delta = delta; + } + + @Override + public void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange) { + WorldPosition position = furniture.position(); + double x = isSecondaryUsage ? position.x - delta : position.x + delta; + furniture.moveTo(new WorldPosition(position.world, x, position.y, position.z, position.xRot, position.yRot), true).thenAccept(success -> { + if (success) { + changed.accept("x", String.format("%.2f", x)); + } + }); + } + } + + public static class YPositionHandler implements DebugStickHandler { + private final double delta; + + public YPositionHandler(double delta) { + this.delta = delta; + } + + @Override + public void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange) { + WorldPosition position = furniture.position(); + double y = isSecondaryUsage ? position.y - delta : position.y + delta; + furniture.moveTo(new WorldPosition(position.world, position.x, y, position.z, position.xRot, position.yRot), true).thenAccept(success -> { + if (success) { + changed.accept("y", String.format("%.2f", y)); + } + }); + } + } + + public static class ZPositionHandler implements DebugStickHandler { + private final double delta; + + public ZPositionHandler(double delta) { + this.delta = delta; + } + + @Override + public void onInteract(boolean isSecondaryUsage, Furniture furniture, BiConsumer changed, Runnable noChange) { + WorldPosition position = furniture.position(); + double z = isSecondaryUsage ? position.z - delta : position.z + delta; + furniture.moveTo(new WorldPosition(position.world, position.x, position.y, z, position.xRot, position.yRot), true).thenAccept(success -> { + if (success) { + changed.accept("z", String.format("%.2f", z)); + } + }); + } + } +} \ No newline at end of file