From df86e822dbededc648e5c6c44a4c6ec1898f6cc5 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 18 May 2025 00:18:22 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat(bukkit):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=99=90=E5=88=B6=E5=8F=AF=E8=A7=86=E5=AE=B6=E5=85=B7=E6=95=B0?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/command/feature/TestCommand.java | 32 ++-- .../plugin/network/PacketConsumers.java | 27 ++- .../plugin/user/BukkitServerPlayer.java | 29 ++++ .../core/plugin/network/NetWorkUser.java | 3 + .../core/util/DynamicPriorityTracker.java | 161 ++++++++++++++++++ 5 files changed, 238 insertions(+), 14 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index ab1b59966..33a9ac417 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -1,6 +1,9 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; +import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import org.bukkit.Material; @@ -38,19 +41,26 @@ public class TestCommand extends BukkitCommandFeature { public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { return builder .senderType(Player.class) - .required("reset", BooleanParser.booleanParser()) - .required("setTag", NamespacedKeyParser.namespacedKeyParser()) - .required("targetBlock", StringParser.stringComponent(StringParser.StringMode.GREEDY_FLAG_YIELDING).suggestionProvider(new SuggestionProvider<>() { - @Override - public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { - return CompletableFuture.completedFuture(TARGET_BLOCK_SUGGESTIONS); - } - })) + // .required("reset", BooleanParser.booleanParser()) + // .required("setTag", NamespacedKeyParser.namespacedKeyParser()) + // .required("targetBlock", StringParser.stringComponent(StringParser.StringMode.GREEDY_FLAG_YIELDING).suggestionProvider(new SuggestionProvider<>() { + // @Override + // public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + // return CompletableFuture.completedFuture(TARGET_BLOCK_SUGGESTIONS); + // } + // })) .handler(context -> { Player player = context.sender(); - player.sendMessage("开始测试"); - NamespacedKey key = context.get("setTag"); - player.sendMessage("结束测试"); + BukkitServerPlayer cePlayer = plugin().adapt(player); + player.sendMessage("visualFurnitureView1: " + cePlayer.visualFurnitureView().getTotalMembers()); + cePlayer.visualFurnitureView().getAllElements().forEach(element -> { + LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + if (furniture == null || !player.canSee(furniture.baseEntity())) { + cePlayer.visualFurnitureView().removeByEntityId(element.entityId()); + player.sendMessage("remove: " + element.entityId()); + } + }); + player.sendMessage("visualFurnitureView2: " + cePlayer.visualFurnitureView().getTotalMembers()); }); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index abd76f731..37948856d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1598,8 +1598,28 @@ public class PacketConsumers { // Furniture LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId); if (furniture != null) { - user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(furniture.fakeEntityIds())); - user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false); + Player player = (Player) user.platformPlayer(); + List fakeEntityIds = furniture.fakeEntityIds(); + user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(fakeEntityIds)); + if (user.visualFurnitureView().getTotalMembers() <= 100) { + user.sendPacket(furniture.spawnPacket(player), false); + } + int[] entityIdsArray = new int[fakeEntityIds.size() + 1]; + entityIdsArray[0] = entityId; + for (int i = 0; i < fakeEntityIds.size(); i++) { + entityIdsArray[i + 1] = fakeEntityIds.get(i); + } + double distance = player.getLocation().distance(furniture.location()); + Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); + DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); + for (DynamicPriorityTracker.Element element : result.getEntered()) { + LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + if (updateFurniture == null || !updateFurniture.isValid()) continue; + user.sendPacket(updateFurniture.spawnPacket(player), false); + } + for (DynamicPriorityTracker.Element element : result.getExited()) { + user.sendPacket(element.removePacket(), false); + } if (Config.hideBaseEntity() && !furniture.hasExternalModel()) { event.setCancelled(true); } @@ -1645,6 +1665,7 @@ public class PacketConsumers { int entityId = intList.getInt(i); EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); if (handler != null && handler.handleEntitiesRemove(intList)) { + // user.visualFurnitureView().removeByEntityId(entityId); isChange = true; } } @@ -1726,7 +1747,7 @@ public class PacketConsumers { .withParameter(DirectContextParameters.FURNITURE, furniture) .withParameter(DirectContextParameters.POSITION, new WorldPosition(furniture.world(), furniture.position())) ); - furniture.config().execute(context, EventTrigger.RIGHT_CLICK);; + furniture.config().execute(context, EventTrigger.RIGHT_CLICK); if (player.isSneaking()) { // try placing another furniture above it 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 5e045570f..97d23c5e2 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 @@ -4,6 +4,8 @@ import com.google.common.collect.Lists; import io.netty.channel.Channel; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; +import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -23,6 +25,7 @@ import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler; import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; import net.momirealms.craftengine.core.util.Direction; +import net.momirealms.craftengine.core.util.DynamicPriorityTracker; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; @@ -97,6 +100,7 @@ public class BukkitServerPlayer extends Player { private double cachedInteractionRange; private final Map entityTypeView = new ConcurrentHashMap<>(); + private final DynamicPriorityTracker visualFurnitureView = new DynamicPriorityTracker(100); public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) { this.channel = channel; @@ -344,6 +348,7 @@ public class BukkitServerPlayer extends Player { } if (this.gameTicks % 30 == 0) { this.updateGUI(); + this.updateVisualFurnitureView(); } if (this.isDestroyingBlock) { this.tickBlockDestroy(); @@ -368,6 +373,25 @@ public class BukkitServerPlayer extends Player { } } + private void updateVisualFurnitureView() { + if (visualFurnitureView().getTotalMembers() <= 100) return; + for (DynamicPriorityTracker.Element element : visualFurnitureView().getAllElements()) { + LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + if (furniture == null || !furniture.isValid()) continue; + double distance = platformPlayer().getLocation().distance(furniture.location()); + DynamicPriorityTracker.Element newElement = new DynamicPriorityTracker.Element(element.entityId(), distance, element.removePacket()); + DynamicPriorityTracker.UpdateResult result = visualFurnitureView().addOrUpdateElement(newElement); + for (DynamicPriorityTracker.Element resultElement : result.getEntered()) { + LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(resultElement.entityId()); + if (updateFurniture == null || !updateFurniture.isValid()) continue; + sendPacket(updateFurniture.spawnPacket(platformPlayer()), false); + } + for (DynamicPriorityTracker.Element resultElement : result.getExited()) { + sendPacket(resultElement.removePacket(), false); + } + } + } + @Override public float getDestroyProgress(Object blockState, BlockPos pos) { return FastNMS.INSTANCE.method$BlockStateBase$getDestroyProgress(blockState, serverPlayer(), FastNMS.INSTANCE.field$CraftWorld$ServerLevel(platformPlayer().getWorld()), LocationUtils.toBlockPos(pos)); @@ -738,6 +762,11 @@ public class BukkitServerPlayer extends Player { return this.entityTypeView; } + @Override + public DynamicPriorityTracker visualFurnitureView() { + return this.visualFurnitureView; + } + public void setResendSound() { resentSoundTick = gameTicks(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java index cf9442fee..d442edb97 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java @@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.plugin.network; import io.netty.channel.Channel; import net.momirealms.craftengine.core.plugin.Plugin; +import net.momirealms.craftengine.core.util.DynamicPriorityTracker; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.ApiStatus; @@ -43,6 +44,8 @@ public interface NetWorkUser { Map entityPacketHandlers(); + DynamicPriorityTracker visualFurnitureView(); + boolean clientModEnabled(); void setClientModState(boolean enable); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java new file mode 100644 index 000000000..02e7f7a67 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java @@ -0,0 +1,161 @@ +package net.momirealms.craftengine.core.util; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +public class DynamicPriorityTracker { + + public static class Element { + private final int entityId; + private volatile double distance; + private final Object removePacket; + + public Element(int entityId, double distance, Object removePacket) { + this.entityId = entityId; + this.distance = distance; + this.removePacket = removePacket; + } + + public int entityId() { + return entityId; + } + public double distance() { + return distance; + } + public void setDistance(double distance) { + this.distance = distance; + } + public Object removePacket() { + return removePacket; + } + } + + public static class UpdateResult { + private final List entered = new ArrayList<>(); + private final List exited = new ArrayList<>(); + + public List getEntered() { + return entered; + } + public List getExited() { + return exited; + } + + void addEntered(Element e) { + entered.add(e); + } + void addExited(Element e) { + exited.add(e); + } + } + + private final int capacity; + private final PriorityQueue maxHeap; + private final Map elementMap = new ConcurrentHashMap<>(); + private final Set inHeapSet = ConcurrentHashMap.newKeySet(); + private final ReentrantLock heapLock = new ReentrantLock(); + + public DynamicPriorityTracker(int capacity) { + this.capacity = capacity; + this.maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b.distance, a.distance)); + } + + public UpdateResult addOrUpdateElement(Element newElement) { + UpdateResult result = new UpdateResult(); + heapLock.lock(); + try { + Element existing = elementMap.get(newElement.entityId); + + if (existing != null) { + return handleExistingElement(existing, newElement, result); + } else { + return handleNewElement(newElement, result); + } + } finally { + heapLock.unlock(); + } + } + + private UpdateResult handleNewElement(Element newElement, UpdateResult result) { + elementMap.put(newElement.entityId, newElement); + + if (maxHeap.size() < capacity) { + maxHeap.offer(newElement); + inHeapSet.add(newElement.entityId); + result.addEntered(newElement); + } else if (maxHeap.peek() != null && newElement.distance < maxHeap.peek().distance) { + Element removed = maxHeap.poll(); + inHeapSet.remove(removed.entityId); + result.addExited(removed); + + maxHeap.offer(newElement); + inHeapSet.add(newElement.entityId); + result.addEntered(newElement); + } + return result; + } + + private UpdateResult handleExistingElement(Element existing, Element newElement, UpdateResult result) { + existing.setDistance(newElement.distance); + + boolean wasInHeap = inHeapSet.contains(existing.entityId); + boolean nowInHeap = checkIfShouldBeInHeap(existing.distance); + + if (wasInHeap) { + maxHeap.remove(existing); + maxHeap.offer(existing); + } else if (nowInHeap) { + if (maxHeap.size() < capacity) { + maxHeap.offer(existing); + inHeapSet.add(existing.entityId); + result.addEntered(existing); + } else if (maxHeap.peek() != null && existing.distance < maxHeap.peek().distance) { + Element removed = maxHeap.poll(); + inHeapSet.remove(removed.entityId); + result.addExited(removed); + + maxHeap.offer(existing); + inHeapSet.add(existing.entityId); + result.addEntered(existing); + } + } + return result; + } + + private boolean checkIfShouldBeInHeap(double distance) { + if (maxHeap.size() < capacity) return true; + return maxHeap.peek() != null && distance < maxHeap.peek().distance; + } + + public int getTotalMembers() { + heapLock.lock(); + try { + return elementMap.size(); + } finally { + heapLock.unlock(); + } + } + + public List getAllElements() { + heapLock.lock(); + try { + return List.copyOf(elementMap.values()); + } finally { + heapLock.unlock(); + } + } + + public Element removeByEntityId(int entityId) { + heapLock.lock(); + try { + Element removed = elementMap.remove(entityId); + if (removed != null) { + maxHeap.remove(removed); + } + return removed; + } finally { + heapLock.unlock(); + } + } +} From 3a7276c30962b9a91abd496c9cb2e059aeae2dba Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 18 May 2025 00:52:15 +0800 Subject: [PATCH 02/11] =?UTF-8?q?feat(bukkit):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/config.yml | 4 ++ .../plugin/network/PacketConsumers.java | 38 ++++++++++--------- .../plugin/user/BukkitServerPlayer.java | 5 ++- .../core/plugin/config/Config.java | 12 ++++++ .../core/util/DynamicPriorityTracker.java | 12 +++--- gradle.properties | 2 +- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 22eebce60..095aed474 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -183,6 +183,10 @@ furniture: # interaction (best performance) # boat (better compatibility with some anti-cheat plugin) collision-entity-type: interaction + # Limit the maximum amount of furniture that players can see by default + max-visible-furniture: + enable: false + amount: 100 emoji: chat: true diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 37948856d..65cb5f409 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1601,25 +1601,29 @@ public class PacketConsumers { Player player = (Player) user.platformPlayer(); List fakeEntityIds = furniture.fakeEntityIds(); user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(fakeEntityIds)); - if (user.visualFurnitureView().getTotalMembers() <= 100) { + if (Config.enableMaxVisibleFurniture()) { + if (user.visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) { + user.sendPacket(furniture.spawnPacket(player), false); + } + int[] entityIdsArray = new int[fakeEntityIds.size() + 1]; + entityIdsArray[0] = entityId; + for (int i = 0; i < fakeEntityIds.size(); i++) { + entityIdsArray[i + 1] = fakeEntityIds.get(i); + } + double distance = player.getLocation().distance(furniture.location()); + Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); + DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); + for (DynamicPriorityTracker.Element element : result.getEntered()) { + LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + if (updateFurniture == null || !updateFurniture.isValid()) continue; + user.sendPacket(updateFurniture.spawnPacket(player), false); + } + for (DynamicPriorityTracker.Element element : result.getExited()) { + user.sendPacket(element.removePacket(), false); + } + } else { user.sendPacket(furniture.spawnPacket(player), false); } - int[] entityIdsArray = new int[fakeEntityIds.size() + 1]; - entityIdsArray[0] = entityId; - for (int i = 0; i < fakeEntityIds.size(); i++) { - entityIdsArray[i + 1] = fakeEntityIds.get(i); - } - double distance = player.getLocation().distance(furniture.location()); - Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); - DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); - for (DynamicPriorityTracker.Element element : result.getEntered()) { - LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); - if (updateFurniture == null || !updateFurniture.isValid()) continue; - user.sendPacket(updateFurniture.spawnPacket(player), false); - } - for (DynamicPriorityTracker.Element element : result.getExited()) { - user.sendPacket(element.removePacket(), false); - } if (Config.hideBaseEntity() && !furniture.hasExternalModel()) { event.setCancelled(true); } 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 97d23c5e2..8e30e0dca 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 @@ -100,7 +100,7 @@ public class BukkitServerPlayer extends Player { private double cachedInteractionRange; private final Map entityTypeView = new ConcurrentHashMap<>(); - private final DynamicPriorityTracker visualFurnitureView = new DynamicPriorityTracker(100); + private final DynamicPriorityTracker visualFurnitureView = new DynamicPriorityTracker(); public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) { this.channel = channel; @@ -374,7 +374,8 @@ public class BukkitServerPlayer extends Player { } private void updateVisualFurnitureView() { - if (visualFurnitureView().getTotalMembers() <= 100) return; + if (!Config.enableMaxVisibleFurniture()) return; + if (visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) return; for (DynamicPriorityTracker.Element element : visualFurnitureView().getAllElements()) { LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); if (furniture == null || !furniture.isValid()) continue; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index d6faf0675..d8eb431f2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -110,6 +110,8 @@ public class Config { protected Map furniture$handle_invalid_furniture_on_chunk_load$mapping; protected boolean furniture$hide_base_entity; protected ColliderType furniture$collision_entity_type; + protected boolean furniture$max_visible_furniture_enable; + protected int furniture$max_visible_furniture_amount; protected boolean block$sound_system$enable; protected boolean block$simplify_adventure_break_check; @@ -300,6 +302,8 @@ public class Config { furniture$handle_invalid_furniture_on_chunk_load$mapping = builder.build(); furniture$hide_base_entity = config.getBoolean("furniture.hide-base-entity", true); furniture$collision_entity_type = ColliderType.valueOf(config.getString("furniture.collision-entity-type", "interaction").toUpperCase(Locale.ENGLISH)); + furniture$max_visible_furniture_enable = config.getBoolean("furniture.max-visible-furniture.enable", false); + furniture$max_visible_furniture_amount = config.getInt("furniture.max-visible-furniture.amount", 100); // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); @@ -417,6 +421,14 @@ public class Config { return instance.resource_pack$supported_version$min; } + public static boolean enableMaxVisibleFurniture() { + return instance.furniture$max_visible_furniture_enable; + } + + public static int maxVisibleFurniture() { + return instance.furniture$max_visible_furniture_amount; + } + public static float packMaxVersion() { return instance.resource_pack$supported_version$max; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java index 02e7f7a67..50ebee72d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.core.util; +import net.momirealms.craftengine.core.plugin.config.Config; + import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; @@ -50,14 +52,12 @@ public class DynamicPriorityTracker { } } - private final int capacity; private final PriorityQueue maxHeap; private final Map elementMap = new ConcurrentHashMap<>(); private final Set inHeapSet = ConcurrentHashMap.newKeySet(); private final ReentrantLock heapLock = new ReentrantLock(); - public DynamicPriorityTracker(int capacity) { - this.capacity = capacity; + public DynamicPriorityTracker() { this.maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b.distance, a.distance)); } @@ -80,7 +80,7 @@ public class DynamicPriorityTracker { private UpdateResult handleNewElement(Element newElement, UpdateResult result) { elementMap.put(newElement.entityId, newElement); - if (maxHeap.size() < capacity) { + if (maxHeap.size() < Config.maxVisibleFurniture()) { maxHeap.offer(newElement); inHeapSet.add(newElement.entityId); result.addEntered(newElement); @@ -106,7 +106,7 @@ public class DynamicPriorityTracker { maxHeap.remove(existing); maxHeap.offer(existing); } else if (nowInHeap) { - if (maxHeap.size() < capacity) { + if (maxHeap.size() < Config.maxVisibleFurniture()) { maxHeap.offer(existing); inHeapSet.add(existing.entityId); result.addEntered(existing); @@ -124,7 +124,7 @@ public class DynamicPriorityTracker { } private boolean checkIfShouldBeInHeap(double distance) { - if (maxHeap.size() < capacity) return true; + if (maxHeap.size() < Config.maxVisibleFurniture()) return true; return maxHeap.peek() != null && distance < maxHeap.peek().distance; } diff --git a/gradle.properties b/gradle.properties index e2b6917ae..cc8e14db4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] project_version=0.0.54 -config_version=32 +config_version=33 lang_version=12 project_group=net.momirealms latest_supported_version=1.21.5 From 924a992921daf1f222282e99fc2910f32eb605cb Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Mon, 19 May 2025 13:01:50 +0800 Subject: [PATCH 03/11] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/commands.yml | 7 +++ .../plugin/command/BukkitCommandManager.java | 3 +- .../SetMaxVisibleFurnitureCommand.java | 36 ++++++++++++++++ .../plugin/command/feature/TestCommand.java | 19 ++++---- .../plugin/network/PacketConsumers.java | 29 +++++++++---- .../plugin/user/BukkitServerPlayer.java | 27 +++++++++--- .../craftengine/core/plugin/CraftEngine.java | 4 ++ .../core/plugin/network/NetWorkUser.java | 2 + .../core/util/DynamicPriorityTracker.java | 43 ++++++++++++++++--- gradle.properties | 2 +- 10 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index fdf4e1613..7dbe7a78a 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -111,6 +111,13 @@ list_resource: - /craftengine resource list - /ce resource list +set_max_visible_furniture: + enable: true + permission: ce.command.player.set_max_visible_furniture + usage: + - /craftengine feature set-max-visible-furniture + - /ce feature set-max-visible-furniture + # Debug commands debug_set_block: enable: true diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index c1f1c3f39..40cbc68ee 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -52,7 +52,8 @@ public class BukkitCommandManager extends AbstractCommandManager new DisableResourceCommand(this, plugin), new ListResourceCommand(this, plugin), new UploadPackCommand(this, plugin), - new SendResourcePackCommand(this, plugin) + new SendResourcePackCommand(this, plugin), + new SetMaxVisibleFurnitureCommand(this, plugin) )); final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager(); manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java new file mode 100644 index 000000000..e07630d36 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java @@ -0,0 +1,36 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.parser.standard.IntegerParser; + +public class SetMaxVisibleFurnitureCommand extends BukkitCommandFeature { + + public SetMaxVisibleFurnitureCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { + return builder + .senderType(Player.class) + .required("max", IntegerParser.integerParser(1)) + .handler(context -> { + // 需要找一个更好的存储方案 + BukkitServerPlayer cePlayer = plugin().adapt(context.sender()); + Integer max = context.get("max"); + cePlayer.setMaxVisibleFurniture(max, true); + }); + } + + @Override + public String getFeatureID() { + return "set_max_visible_furniture"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index 33a9ac417..8ce4d7495 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -52,15 +52,16 @@ public class TestCommand extends BukkitCommandFeature { .handler(context -> { Player player = context.sender(); BukkitServerPlayer cePlayer = plugin().adapt(player); - player.sendMessage("visualFurnitureView1: " + cePlayer.visualFurnitureView().getTotalMembers()); - cePlayer.visualFurnitureView().getAllElements().forEach(element -> { - LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); - if (furniture == null || !player.canSee(furniture.baseEntity())) { - cePlayer.visualFurnitureView().removeByEntityId(element.entityId()); - player.sendMessage("remove: " + element.entityId()); - } - }); - player.sendMessage("visualFurnitureView2: " + cePlayer.visualFurnitureView().getTotalMembers()); + player.sendMessage("visualFurnitureView: " + cePlayer.visualFurnitureView().getTotalMembers()); + player.sendMessage(cePlayer.visualFurnitureView() + "\n==============================="); + // cePlayer.visualFurnitureView().getAllElements().forEach(element -> { + // LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + // if (furniture == null || !player.canSee(furniture.baseEntity())) { + // cePlayer.visualFurnitureView().removeByEntityId(element.entityId()); + // player.sendMessage("remove: " + element.entityId()); + // } + // }); + // player.sendMessage("visualFurnitureView2: " + cePlayer.visualFurnitureView().getTotalMembers()); }); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 65cb5f409..301b54540 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1605,12 +1605,13 @@ public class PacketConsumers { if (user.visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) { user.sendPacket(furniture.spawnPacket(player), false); } - int[] entityIdsArray = new int[fakeEntityIds.size() + 1]; - entityIdsArray[0] = entityId; + int[] entityIdsArray = new int[fakeEntityIds.size() + 2]; + entityIdsArray[0] = -114514; + entityIdsArray[1] = entityId; for (int i = 0; i < fakeEntityIds.size(); i++) { - entityIdsArray[i + 1] = fakeEntityIds.get(i); + entityIdsArray[i + 2] = fakeEntityIds.get(i); } - double distance = player.getLocation().distance(furniture.location()); + double distance = furniture.location().distanceSquared(player.getLocation()); Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); for (DynamicPriorityTracker.Element element : result.getEntered()) { @@ -1665,12 +1666,24 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); boolean isChange = false; IntList intList = buf.readIntIdList(); + int first = intList.getFirst(); for (int i = 0, size = intList.size(); i < size; i++) { int entityId = intList.getInt(i); - EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); - if (handler != null && handler.handleEntitiesRemove(intList)) { - // user.visualFurnitureView().removeByEntityId(entityId); - isChange = true; + if (first != -114514) { + EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); + if (handler != null && handler.handleEntitiesRemove(intList)) { + user.visualFurnitureView().removeByEntityId(entityId); + isChange = true; + } + } else { + if (entityId == first) { + intList.removeFirst(); + isChange = true; + } + EntityPacketHandler handler = user.entityPacketHandlers().get(entityId); + if (handler != null && handler.handleEntitiesRemove(intList)) { + isChange = true; + } } } if (isChange) { 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 8e30e0dca..090cfbb82 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 @@ -31,16 +31,14 @@ import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldEvents; -import org.bukkit.FluidCollisionMode; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.SoundCategory; +import org.bukkit.*; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.block.Block; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; +import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.RayTraceResult; import org.jetbrains.annotations.Nullable; @@ -50,6 +48,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class BukkitServerPlayer extends Player { + public static final NamespacedKey MAX_VISIBLE_FURNITURE_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:max_visible_furniture")); private final BukkitCraftEngine plugin; // handshake private ProtocolVersion protocolVersion = ProtocolVersion.UNKNOWN; @@ -98,6 +97,7 @@ public class BukkitServerPlayer extends Player { // cache interaction range here private int lastUpdateInteractionRangeTick; private double cachedInteractionRange; + private Integer maxVisibleFurniture = -1; private final Map entityTypeView = new ConcurrentHashMap<>(); private final DynamicPriorityTracker visualFurnitureView = new DynamicPriorityTracker(); @@ -112,6 +112,9 @@ public class BukkitServerPlayer extends Player { this.serverPlayerRef = new WeakReference<>(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)); this.uuid = player.getUniqueId(); this.name = player.getName(); + this.maxVisibleFurniture = player.getPersistentDataContainer() + .getOrDefault(MAX_VISIBLE_FURNITURE_KEY, PersistentDataType.INTEGER, -1); + this.visualFurnitureView.setMaxVisibleFurniture(this.maxVisibleFurniture); } @Override @@ -348,11 +351,11 @@ public class BukkitServerPlayer extends Player { } if (this.gameTicks % 30 == 0) { this.updateGUI(); - this.updateVisualFurnitureView(); } if (this.isDestroyingBlock) { this.tickBlockDestroy(); } + this.updateVisualFurnitureView(); if (Config.predictBreaking() && !this.isDestroyingCustomBlock) { // if it's not destroying blocks, we do predict if ((gameTicks() + entityID()) % Config.predictBreakingInterval() == 0) { @@ -379,7 +382,7 @@ public class BukkitServerPlayer extends Player { for (DynamicPriorityTracker.Element element : visualFurnitureView().getAllElements()) { LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); if (furniture == null || !furniture.isValid()) continue; - double distance = platformPlayer().getLocation().distance(furniture.location()); + double distance = furniture.location().distanceSquared(platformPlayer().getLocation()); DynamicPriorityTracker.Element newElement = new DynamicPriorityTracker.Element(element.entityId(), distance, element.removePacket()); DynamicPriorityTracker.UpdateResult result = visualFurnitureView().addOrUpdateElement(newElement); for (DynamicPriorityTracker.Element resultElement : result.getEntered()) { @@ -768,6 +771,18 @@ public class BukkitServerPlayer extends Player { return this.visualFurnitureView; } + @Override + public void setMaxVisibleFurniture(int maxVisibleFurniture, boolean fromCommand) { + if (fromCommand) { + platformPlayer().getPersistentDataContainer() + .set(MAX_VISIBLE_FURNITURE_KEY, PersistentDataType.INTEGER, maxVisibleFurniture); + this.maxVisibleFurniture = maxVisibleFurniture; + } + this.visualFurnitureView.setMaxVisibleFurniture( + this.maxVisibleFurniture == -1 ? maxVisibleFurniture : this.maxVisibleFurniture + ); + } + public void setResendSound() { resentSoundTick = gameTicks(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 53f8b5da5..f04069413 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.plugin; import net.momirealms.craftengine.core.advancement.AdvancementManager; import net.momirealms.craftengine.core.block.BlockManager; import net.momirealms.craftengine.core.entity.furniture.FurnitureManager; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.entity.projectile.ProjectileManager; import net.momirealms.craftengine.core.font.FontManager; import net.momirealms.craftengine.core.item.ItemManager; @@ -131,6 +132,9 @@ public abstract class CraftEngine implements Plugin { long time1 = System.currentTimeMillis(); // firstly reload main config this.config.load(); + for (Player player : this.networkManager().onlineUsers()) { + player.setMaxVisibleFurniture(Config.maxVisibleFurniture(), false); + } // reset debugger this.debugger = Config.debug() ? (s) -> logger.info("[Debug] " + s.get()) : (s) -> {}; // now we reload the translations diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java index d442edb97..a0283efab 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java @@ -46,6 +46,8 @@ public interface NetWorkUser { DynamicPriorityTracker visualFurnitureView(); + void setMaxVisibleFurniture(int maxVisibleFurniture, boolean fromCommand); + boolean clientModEnabled(); void setClientModState(boolean enable); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java index 50ebee72d..f538a6269 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java @@ -31,6 +31,15 @@ public class DynamicPriorityTracker { public Object removePacket() { return removePacket; } + + @Override + public String toString() { + return "Element{" + + "entityId=" + entityId + + ", distance=" + distance + + ", removePacket=" + removePacket + + '}'; + } } public static class UpdateResult { @@ -50,17 +59,31 @@ public class DynamicPriorityTracker { void addExited(Element e) { exited.add(e); } + + @Override + public String toString() { + return "UpdateResult{" + + "entered=" + entered + + ", exited=" + exited + + '}'; + } } + private Integer maxVisibleFurniture; private final PriorityQueue maxHeap; private final Map elementMap = new ConcurrentHashMap<>(); private final Set inHeapSet = ConcurrentHashMap.newKeySet(); private final ReentrantLock heapLock = new ReentrantLock(); public DynamicPriorityTracker() { + this.maxVisibleFurniture = Config.maxVisibleFurniture(); this.maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b.distance, a.distance)); } + public void setMaxVisibleFurniture(int maxVisibleFurniture) { + this.maxVisibleFurniture = maxVisibleFurniture; + } + public UpdateResult addOrUpdateElement(Element newElement) { UpdateResult result = new UpdateResult(); heapLock.lock(); @@ -80,7 +103,7 @@ public class DynamicPriorityTracker { private UpdateResult handleNewElement(Element newElement, UpdateResult result) { elementMap.put(newElement.entityId, newElement); - if (maxHeap.size() < Config.maxVisibleFurniture()) { + if (maxHeap.size() < maxVisibleFurniture) { maxHeap.offer(newElement); inHeapSet.add(newElement.entityId); result.addEntered(newElement); @@ -106,7 +129,7 @@ public class DynamicPriorityTracker { maxHeap.remove(existing); maxHeap.offer(existing); } else if (nowInHeap) { - if (maxHeap.size() < Config.maxVisibleFurniture()) { + if (maxHeap.size() < maxVisibleFurniture) { maxHeap.offer(existing); inHeapSet.add(existing.entityId); result.addEntered(existing); @@ -124,7 +147,7 @@ public class DynamicPriorityTracker { } private boolean checkIfShouldBeInHeap(double distance) { - if (maxHeap.size() < Config.maxVisibleFurniture()) return true; + if (maxHeap.size() < maxVisibleFurniture) return true; return maxHeap.peek() != null && distance < maxHeap.peek().distance; } @@ -146,16 +169,26 @@ public class DynamicPriorityTracker { } } - public Element removeByEntityId(int entityId) { + public void removeByEntityId(int entityId) { heapLock.lock(); try { Element removed = elementMap.remove(entityId); if (removed != null) { maxHeap.remove(removed); + inHeapSet.remove(entityId); } - return removed; } finally { heapLock.unlock(); } } + + @Override + public String toString() { + return "DynamicPriorityTracker{" + + "maxHeap=" + maxHeap + + ", elementMap=" + elementMap + + ", inHeapSet=" + inHeapSet + + ", heapLock=" + heapLock + + '}'; + } } diff --git a/gradle.properties b/gradle.properties index a350543e3..a493a2f38 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] project_version=0.0.54.2 -config_version=33 +config_version=34 lang_version=13 project_group=net.momirealms latest_supported_version=1.21.5 From 32e720d6b2683d902f015edf9947917f7b106134 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Mon, 19 May 2025 13:03:05 +0800 Subject: [PATCH 04/11] =?UTF-8?q?fix(bukkit):=20=E5=85=88=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E4=B8=8D=E5=90=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/commands.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index 7dbe7a78a..313d117b4 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -112,7 +112,7 @@ list_resource: - /ce resource list set_max_visible_furniture: - enable: true + enable: false permission: ce.command.player.set_max_visible_furniture usage: - /craftengine feature set-max-visible-furniture From d827140547d3caac6ebc18a28dc3b322a28cab95 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Mon, 19 May 2025 13:05:13 +0800 Subject: [PATCH 05/11] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/command/feature/SetMaxVisibleFurnitureCommand.java | 2 +- .../craftengine/bukkit/plugin/user/BukkitServerPlayer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java index e07630d36..e71b6f43d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java @@ -22,7 +22,7 @@ public class SetMaxVisibleFurnitureCommand extends BukkitCommandFeature { - // 需要找一个更好的存储方案 + // 需要找一个更好的存储方案去兼容跨服和在初始化的时候加载 BukkitServerPlayer cePlayer = plugin().adapt(context.sender()); Integer max = context.get("max"); cePlayer.setMaxVisibleFurniture(max, true); 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 090cfbb82..d1f37059a 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 @@ -351,11 +351,11 @@ public class BukkitServerPlayer extends Player { } if (this.gameTicks % 30 == 0) { this.updateGUI(); + this.updateVisualFurnitureView(); } if (this.isDestroyingBlock) { this.tickBlockDestroy(); } - this.updateVisualFurnitureView(); if (Config.predictBreaking() && !this.isDestroyingCustomBlock) { // if it's not destroying blocks, we do predict if ((gameTicks() + entityID()) % Config.predictBreakingInterval() == 0) { From 70f0d5d9b4bafc816ddb6c45fb1be546bf33a439 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Mon, 19 May 2025 13:12:35 +0800 Subject: [PATCH 06/11] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/PacketConsumers.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 301b54540..63392db00 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1667,22 +1667,23 @@ public class PacketConsumers { boolean isChange = false; IntList intList = buf.readIntIdList(); int first = intList.getFirst(); - for (int i = 0, size = intList.size(); i < size; i++) { - int entityId = intList.getInt(i); - if (first != -114514) { + if (first != -114514) { + for (int i = 0, size = intList.size(); i < size; i++) { + int entityId = intList.getInt(i); EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); if (handler != null && handler.handleEntitiesRemove(intList)) { user.visualFurnitureView().removeByEntityId(entityId); isChange = true; } - } else { - if (entityId == first) { - intList.removeFirst(); - isChange = true; - } + } + } else { + intList.removeFirst(); + isChange = true; + for (int i = 0, size = intList.size(); i < size; i++) { + int entityId = intList.getInt(i); EntityPacketHandler handler = user.entityPacketHandlers().get(entityId); - if (handler != null && handler.handleEntitiesRemove(intList)) { - isChange = true; + if (handler != null) { + handler.handleEntitiesRemove(intList); } } } From e5a372b0481bb244ccb86735208a3aa89c37500e Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 23 May 2025 00:05:03 +0800 Subject: [PATCH 07/11] =?UTF-8?q?fix(bukkit):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=89=E5=8F=89=E6=88=9F=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projectile/BukkitProjectileManager.java | 33 ++++++++----------- .../plugin/command/feature/TestCommand.java | 1 - .../plugin/network/PacketConsumers.java | 2 +- .../plugin/user/BukkitServerPlayer.java | 6 ++-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java index 6bef2fecf..9fb5c698f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.entity.projectile; +import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent; import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; import io.papermc.paper.event.player.PlayerStopUsingItemEvent; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; @@ -21,6 +22,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.event.world.EntitiesLoadEvent; @@ -57,18 +59,15 @@ public class BukkitProjectileManager implements Listener, ProjectileManager { return Optional.ofNullable(this.projectiles.get(entityId)); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onProjectileLaunch(ProjectileLaunchEvent event) { - Projectile projectile = event.getEntity(); - handleProjectileLoad(projectile); + handleProjectileLoad(event.getEntity()); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) - public void onEntitiesLoad(EntitiesLoadEvent event) { - for (Entity entity : event.getEntities()) { - if (entity instanceof Projectile projectile) { - handleProjectileLoad(projectile); - } + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onEntityAdd(EntityAddToWorldEvent event) { + if (event.getEntity() instanceof Projectile projectile) { + handleProjectileLoad(projectile); } } @@ -99,10 +98,9 @@ public class BukkitProjectileManager implements Listener, ProjectileManager { @EventHandler public void onPlayerInteract(PlayerItemConsumeEvent event) { - ItemStack item = event.getItem(); - String type = getType(item); + String type = getType(event.getItem()); if (type == null) return; - if (type.equals("bow") || type.equals("spear")) { + if (type.equals("bow") || type.equals("trident")) { event.setCancelled(true); } } @@ -114,17 +112,14 @@ public class BukkitProjectileManager implements Listener, ProjectileManager { if (type == null) return; int ticksHeldFor = event.getTicksHeldFor(); Player player = event.getPlayer(); - if (type.equals("bow")) { - if (ticksHeldFor < 3) return; - // player.sendMessage("可以投出自定义弓: " + item.getType() + " 持续 " + ticksHeldFor + " 刻"); - } else if (type.equals("trident")) { + if (type.equals("trident")) { if (ticksHeldFor < 10) return; - // player.sendMessage("可以投出自定义三叉戟: " + item.getType() + " 持续 " + ticksHeldFor + " 刻"); Object nmsItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(item); Object nmsServerLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld()); Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(player); - boolean success = TridentRelease.releaseUsing(nmsItemStack, nmsServerLevel, nmsEntity); - // player.sendMessage("释放成功: " + success); + TridentRelease.releaseUsing(nmsItemStack, nmsServerLevel, nmsEntity); + } else if (type.equals("bow")) { + if (ticksHeldFor < 3) return; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index 8ce4d7495..00e8c84de 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; -import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.core.plugin.CraftEngine; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 9a18a9994..2719be684 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1617,7 +1617,7 @@ public class PacketConsumers { Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); for (DynamicPriorityTracker.Element element : result.getEntered()) { - LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + BukkitFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); if (updateFurniture == null || !updateFurniture.isValid()) continue; user.sendPacket(updateFurniture.spawnPacket(player), false); } 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 debbbe0d0..b04238a43 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 @@ -4,8 +4,8 @@ import com.google.common.collect.Lists; import io.netty.channel.Channel; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; -import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -382,13 +382,13 @@ public class BukkitServerPlayer extends Player { if (!Config.enableMaxVisibleFurniture()) return; if (visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) return; for (DynamicPriorityTracker.Element element : visualFurnitureView().getAllElements()) { - LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); + BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); if (furniture == null || !furniture.isValid()) continue; double distance = furniture.location().distanceSquared(platformPlayer().getLocation()); DynamicPriorityTracker.Element newElement = new DynamicPriorityTracker.Element(element.entityId(), distance, element.removePacket()); DynamicPriorityTracker.UpdateResult result = visualFurnitureView().addOrUpdateElement(newElement); for (DynamicPriorityTracker.Element resultElement : result.getEntered()) { - LoadedFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(resultElement.entityId()); + BukkitFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(resultElement.entityId()); if (updateFurniture == null || !updateFurniture.isValid()) continue; sendPacket(updateFurniture.spawnPacket(platformPlayer()), false); } From 768b5de5ba31a61bcde5d3970cf3247c5b0553b0 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 23 May 2025 00:34:57 +0800 Subject: [PATCH 08/11] =?UTF-8?q?fix(bukkit):=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E9=83=A8=E5=88=861.21.4=E7=89=88=E6=9C=AC=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=89=93=E5=BC=80=E5=AE=B9=E5=99=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/gui/BukkitGuiManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java index 9062dc5b6..f08eca613 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java @@ -7,6 +7,7 @@ import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.gui.*; +import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -16,9 +17,11 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.MenuType; public class BukkitGuiManager implements GuiManager, Listener { + private static final boolean useNewOpenInventory = ReflectionUtils.getDeclaredMethod(InventoryView.class, void.class, new String[]{"open"}) != null; private final BukkitCraftEngine plugin; public BukkitGuiManager(BukkitCraftEngine plugin) { @@ -39,7 +42,7 @@ public class BukkitGuiManager implements GuiManager, Listener { @Override public void openInventory(net.momirealms.craftengine.core.entity.player.Player player, GuiType guiType) { Player bukkitPlayer = (Player) player.platformPlayer(); - if (VersionHelper.isOrAbove1_21_4()) { + if (useNewOpenInventory) { switch (guiType) { case ANVIL -> MenuType.ANVIL.create(bukkitPlayer).open(); case LOOM -> MenuType.LOOM.create(bukkitPlayer).open(); From 35c4e22f2027b98ad85bba6a3b4645c7c0de78aa Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 23 May 2025 04:49:42 +0800 Subject: [PATCH 09/11] =?UTF-8?q?refactor(bukkit):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E5=8F=AF=E8=A7=81=E5=AE=B6=E5=85=B7=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E9=99=90=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/commands.yml | 7 - bukkit/loader/src/main/resources/config.yml | 4 - .../plugin/command/BukkitCommandManager.java | 3 +- .../SetMaxVisibleFurnitureCommand.java | 36 ---- .../plugin/command/feature/TestCommand.java | 32 +-- .../plugin/network/PacketConsumers.java | 53 +---- .../plugin/user/BukkitServerPlayer.java | 48 ----- .../craftengine/core/plugin/CraftEngine.java | 3 - .../core/plugin/config/Config.java | 12 -- .../core/plugin/network/NetWorkUser.java | 5 - .../core/util/DynamicPriorityTracker.java | 194 ------------------ gradle.properties | 2 +- 12 files changed, 20 insertions(+), 379 deletions(-) delete mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java delete mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index 313d117b4..fdf4e1613 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -111,13 +111,6 @@ list_resource: - /craftengine resource list - /ce resource list -set_max_visible_furniture: - enable: false - permission: ce.command.player.set_max_visible_furniture - usage: - - /craftengine feature set-max-visible-furniture - - /ce feature set-max-visible-furniture - # Debug commands debug_set_block: enable: true diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 8d6d19bfe..18053ebc2 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -181,10 +181,6 @@ furniture: # interaction (best performance) # boat (better compatibility with some anti-cheat plugin) collision-entity-type: interaction - # Limit the maximum amount of furniture that players can see by default - max-visible-furniture: - enable: false - amount: 100 emoji: chat: true diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index 40cbc68ee..c1f1c3f39 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -52,8 +52,7 @@ public class BukkitCommandManager extends AbstractCommandManager new DisableResourceCommand(this, plugin), new ListResourceCommand(this, plugin), new UploadPackCommand(this, plugin), - new SendResourcePackCommand(this, plugin), - new SetMaxVisibleFurnitureCommand(this, plugin) + new SendResourcePackCommand(this, plugin) )); final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager(); manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java deleted file mode 100644 index e71b6f43d..000000000 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/SetMaxVisibleFurnitureCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.momirealms.craftengine.bukkit.plugin.command.feature; - -import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; -import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.incendo.cloud.Command; -import org.incendo.cloud.CommandManager; -import org.incendo.cloud.parser.standard.IntegerParser; - -public class SetMaxVisibleFurnitureCommand extends BukkitCommandFeature { - - public SetMaxVisibleFurnitureCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { - super(commandManager, plugin); - } - - @Override - public Command.Builder assembleCommand(CommandManager manager, Command.Builder builder) { - return builder - .senderType(Player.class) - .required("max", IntegerParser.integerParser(1)) - .handler(context -> { - // 需要找一个更好的存储方案去兼容跨服和在初始化的时候加载 - BukkitServerPlayer cePlayer = plugin().adapt(context.sender()); - Integer max = context.get("max"); - cePlayer.setMaxVisibleFurniture(max, true); - }); - } - - @Override - public String getFeatureID() { - return "set_max_visible_furniture"; - } -} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index 00e8c84de..ab1b59966 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -1,8 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; -import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; -import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; import org.bukkit.Material; @@ -40,27 +38,19 @@ public class TestCommand extends BukkitCommandFeature { public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { return builder .senderType(Player.class) - // .required("reset", BooleanParser.booleanParser()) - // .required("setTag", NamespacedKeyParser.namespacedKeyParser()) - // .required("targetBlock", StringParser.stringComponent(StringParser.StringMode.GREEDY_FLAG_YIELDING).suggestionProvider(new SuggestionProvider<>() { - // @Override - // public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { - // return CompletableFuture.completedFuture(TARGET_BLOCK_SUGGESTIONS); - // } - // })) + .required("reset", BooleanParser.booleanParser()) + .required("setTag", NamespacedKeyParser.namespacedKeyParser()) + .required("targetBlock", StringParser.stringComponent(StringParser.StringMode.GREEDY_FLAG_YIELDING).suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(TARGET_BLOCK_SUGGESTIONS); + } + })) .handler(context -> { Player player = context.sender(); - BukkitServerPlayer cePlayer = plugin().adapt(player); - player.sendMessage("visualFurnitureView: " + cePlayer.visualFurnitureView().getTotalMembers()); - player.sendMessage(cePlayer.visualFurnitureView() + "\n==============================="); - // cePlayer.visualFurnitureView().getAllElements().forEach(element -> { - // LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); - // if (furniture == null || !player.canSee(furniture.baseEntity())) { - // cePlayer.visualFurnitureView().removeByEntityId(element.entityId()); - // player.sendMessage("remove: " + element.entityId()); - // } - // }); - // player.sendMessage("visualFurnitureView2: " + cePlayer.visualFurnitureView().getTotalMembers()); + player.sendMessage("开始测试"); + NamespacedKey key = context.get("setTag"); + player.sendMessage("结束测试"); }); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 2719be684..66f26b85a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1600,33 +1600,8 @@ public class PacketConsumers { // Furniture BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId); if (furniture != null) { - Player player = (Player) user.platformPlayer(); - List fakeEntityIds = furniture.fakeEntityIds(); - user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(fakeEntityIds)); - if (Config.enableMaxVisibleFurniture()) { - if (user.visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) { - user.sendPacket(furniture.spawnPacket(player), false); - } - int[] entityIdsArray = new int[fakeEntityIds.size() + 2]; - entityIdsArray[0] = -114514; - entityIdsArray[1] = entityId; - for (int i = 0; i < fakeEntityIds.size(); i++) { - entityIdsArray[i + 2] = fakeEntityIds.get(i); - } - double distance = furniture.location().distanceSquared(player.getLocation()); - Object removePacket = Reflections.constructor$ClientboundRemoveEntitiesPacket.newInstance(entityIdsArray); - DynamicPriorityTracker.UpdateResult result = user.visualFurnitureView().addOrUpdateElement(new DynamicPriorityTracker.Element(entityId, distance, removePacket)); - for (DynamicPriorityTracker.Element element : result.getEntered()) { - BukkitFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); - if (updateFurniture == null || !updateFurniture.isValid()) continue; - user.sendPacket(updateFurniture.spawnPacket(player), false); - } - for (DynamicPriorityTracker.Element element : result.getExited()) { - user.sendPacket(element.removePacket(), false); - } - } else { - user.sendPacket(furniture.spawnPacket(player), false); - } + user.entityPacketHandlers().computeIfAbsent(entityId, k -> new FurniturePacketHandler(furniture.fakeEntityIds())); + user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false); if (Config.hideBaseEntity() && !furniture.hasExternalModel()) { event.setCancelled(true); } @@ -1668,25 +1643,11 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); boolean isChange = false; IntList intList = buf.readIntIdList(); - int first = intList.getFirst(); - if (first != -114514) { - for (int i = 0, size = intList.size(); i < size; i++) { - int entityId = intList.getInt(i); - EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); - if (handler != null && handler.handleEntitiesRemove(intList)) { - user.visualFurnitureView().removeByEntityId(entityId); - isChange = true; - } - } - } else { - intList.removeFirst(); - isChange = true; - for (int i = 0, size = intList.size(); i < size; i++) { - int entityId = intList.getInt(i); - EntityPacketHandler handler = user.entityPacketHandlers().get(entityId); - if (handler != null) { - handler.handleEntitiesRemove(intList); - } + for (int i = 0, size = intList.size(); i < size; i++) { + int entityId = intList.getInt(i); + EntityPacketHandler handler = user.entityPacketHandlers().remove(entityId); + if (handler != null && handler.handleEntitiesRemove(intList)) { + isChange = true; } } if (isChange) { 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 b04238a43..40fac266a 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 @@ -4,8 +4,6 @@ import com.google.common.collect.Lists; import io.netty.channel.Channel; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; -import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; -import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -25,7 +23,6 @@ import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler; import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; import net.momirealms.craftengine.core.util.Direction; -import net.momirealms.craftengine.core.util.DynamicPriorityTracker; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.BlockPos; @@ -40,7 +37,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.RayTraceResult; import org.jetbrains.annotations.Nullable; @@ -50,7 +46,6 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class BukkitServerPlayer extends Player { - public static final NamespacedKey MAX_VISIBLE_FURNITURE_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:max_visible_furniture")); private final BukkitCraftEngine plugin; // handshake private ProtocolVersion protocolVersion = ProtocolVersion.UNKNOWN; @@ -99,10 +94,8 @@ public class BukkitServerPlayer extends Player { // cache interaction range here private int lastUpdateInteractionRangeTick; private double cachedInteractionRange; - private Integer maxVisibleFurniture = -1; private final Map entityTypeView = new ConcurrentHashMap<>(); - private final DynamicPriorityTracker visualFurnitureView = new DynamicPriorityTracker(); public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) { this.channel = channel; @@ -114,9 +107,6 @@ public class BukkitServerPlayer extends Player { this.serverPlayerRef = new WeakReference<>(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)); this.uuid = player.getUniqueId(); this.name = player.getName(); - this.maxVisibleFurniture = player.getPersistentDataContainer() - .getOrDefault(MAX_VISIBLE_FURNITURE_KEY, PersistentDataType.INTEGER, -1); - this.visualFurnitureView.setMaxVisibleFurniture(this.maxVisibleFurniture); } @Override @@ -353,7 +343,6 @@ public class BukkitServerPlayer extends Player { } if (this.gameTicks % 30 == 0) { this.updateGUI(); - this.updateVisualFurnitureView(); } if (this.isDestroyingBlock) { this.tickBlockDestroy(); @@ -378,26 +367,6 @@ public class BukkitServerPlayer extends Player { } } - private void updateVisualFurnitureView() { - if (!Config.enableMaxVisibleFurniture()) return; - if (visualFurnitureView().getTotalMembers() <= Config.maxVisibleFurniture()) return; - for (DynamicPriorityTracker.Element element : visualFurnitureView().getAllElements()) { - BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(element.entityId()); - if (furniture == null || !furniture.isValid()) continue; - double distance = furniture.location().distanceSquared(platformPlayer().getLocation()); - DynamicPriorityTracker.Element newElement = new DynamicPriorityTracker.Element(element.entityId(), distance, element.removePacket()); - DynamicPriorityTracker.UpdateResult result = visualFurnitureView().addOrUpdateElement(newElement); - for (DynamicPriorityTracker.Element resultElement : result.getEntered()) { - BukkitFurniture updateFurniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(resultElement.entityId()); - if (updateFurniture == null || !updateFurniture.isValid()) continue; - sendPacket(updateFurniture.spawnPacket(platformPlayer()), false); - } - for (DynamicPriorityTracker.Element resultElement : result.getExited()) { - sendPacket(resultElement.removePacket(), false); - } - } - } - @Override public float getDestroyProgress(Object blockState, BlockPos pos) { return FastNMS.INSTANCE.method$BlockStateBase$getDestroyProgress(blockState, serverPlayer(), FastNMS.INSTANCE.field$CraftWorld$ServerLevel(platformPlayer().getWorld()), LocationUtils.toBlockPos(pos)); @@ -773,23 +742,6 @@ public class BukkitServerPlayer extends Player { return this.entityTypeView; } - @Override - public DynamicPriorityTracker visualFurnitureView() { - return this.visualFurnitureView; - } - - @Override - public void setMaxVisibleFurniture(int maxVisibleFurniture, boolean fromCommand) { - if (fromCommand) { - platformPlayer().getPersistentDataContainer() - .set(MAX_VISIBLE_FURNITURE_KEY, PersistentDataType.INTEGER, maxVisibleFurniture); - this.maxVisibleFurniture = maxVisibleFurniture; - } - this.visualFurnitureView.setMaxVisibleFurniture( - this.maxVisibleFurniture == -1 ? maxVisibleFurniture : this.maxVisibleFurniture - ); - } - public void setResendSound() { resentSoundTick = gameTicks(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 96d399ae3..304a9abed 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -132,9 +132,6 @@ public abstract class CraftEngine implements Plugin { long time1 = System.currentTimeMillis(); // firstly reload main config this.config.load(); - for (Player player : this.networkManager().onlineUsers()) { - player.setMaxVisibleFurniture(Config.maxVisibleFurniture(), false); - } // reset debugger this.debugger = Config.debug() ? (s) -> logger.info("[Debug] " + s.get()) : (s) -> {}; // now we reload the translations diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index 6099fd69d..be96fe1ed 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -110,8 +110,6 @@ public class Config { protected Map furniture$handle_invalid_furniture_on_chunk_load$mapping; protected boolean furniture$hide_base_entity; protected ColliderType furniture$collision_entity_type; - protected boolean furniture$max_visible_furniture_enable; - protected int furniture$max_visible_furniture_amount; protected boolean block$sound_system$enable; protected boolean block$simplify_adventure_break_check; @@ -302,8 +300,6 @@ public class Config { furniture$handle_invalid_furniture_on_chunk_load$mapping = builder.build(); furniture$hide_base_entity = config.getBoolean("furniture.hide-base-entity", true); furniture$collision_entity_type = ColliderType.valueOf(config.getString("furniture.collision-entity-type", "interaction").toUpperCase(Locale.ENGLISH)); - furniture$max_visible_furniture_enable = config.getBoolean("furniture.max-visible-furniture.enable", false); - furniture$max_visible_furniture_amount = config.getInt("furniture.max-visible-furniture.amount", 100); // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); @@ -421,14 +417,6 @@ public class Config { return instance.resource_pack$supported_version$min; } - public static boolean enableMaxVisibleFurniture() { - return instance.furniture$max_visible_furniture_enable; - } - - public static int maxVisibleFurniture() { - return instance.furniture$max_visible_furniture_amount; - } - public static float packMaxVersion() { return instance.resource_pack$supported_version$max; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java index a0283efab..cf9442fee 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.plugin.network; import io.netty.channel.Channel; import net.momirealms.craftengine.core.plugin.Plugin; -import net.momirealms.craftengine.core.util.DynamicPriorityTracker; import net.momirealms.craftengine.core.util.Key; import org.jetbrains.annotations.ApiStatus; @@ -44,10 +43,6 @@ public interface NetWorkUser { Map entityPacketHandlers(); - DynamicPriorityTracker visualFurnitureView(); - - void setMaxVisibleFurniture(int maxVisibleFurniture, boolean fromCommand); - boolean clientModEnabled(); void setClientModState(boolean enable); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java b/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java deleted file mode 100644 index f538a6269..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/util/DynamicPriorityTracker.java +++ /dev/null @@ -1,194 +0,0 @@ -package net.momirealms.craftengine.core.util; - -import net.momirealms.craftengine.core.plugin.config.Config; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.ReentrantLock; - -public class DynamicPriorityTracker { - - public static class Element { - private final int entityId; - private volatile double distance; - private final Object removePacket; - - public Element(int entityId, double distance, Object removePacket) { - this.entityId = entityId; - this.distance = distance; - this.removePacket = removePacket; - } - - public int entityId() { - return entityId; - } - public double distance() { - return distance; - } - public void setDistance(double distance) { - this.distance = distance; - } - public Object removePacket() { - return removePacket; - } - - @Override - public String toString() { - return "Element{" + - "entityId=" + entityId + - ", distance=" + distance + - ", removePacket=" + removePacket + - '}'; - } - } - - public static class UpdateResult { - private final List entered = new ArrayList<>(); - private final List exited = new ArrayList<>(); - - public List getEntered() { - return entered; - } - public List getExited() { - return exited; - } - - void addEntered(Element e) { - entered.add(e); - } - void addExited(Element e) { - exited.add(e); - } - - @Override - public String toString() { - return "UpdateResult{" + - "entered=" + entered + - ", exited=" + exited + - '}'; - } - } - - private Integer maxVisibleFurniture; - private final PriorityQueue maxHeap; - private final Map elementMap = new ConcurrentHashMap<>(); - private final Set inHeapSet = ConcurrentHashMap.newKeySet(); - private final ReentrantLock heapLock = new ReentrantLock(); - - public DynamicPriorityTracker() { - this.maxVisibleFurniture = Config.maxVisibleFurniture(); - this.maxHeap = new PriorityQueue<>((a, b) -> Double.compare(b.distance, a.distance)); - } - - public void setMaxVisibleFurniture(int maxVisibleFurniture) { - this.maxVisibleFurniture = maxVisibleFurniture; - } - - public UpdateResult addOrUpdateElement(Element newElement) { - UpdateResult result = new UpdateResult(); - heapLock.lock(); - try { - Element existing = elementMap.get(newElement.entityId); - - if (existing != null) { - return handleExistingElement(existing, newElement, result); - } else { - return handleNewElement(newElement, result); - } - } finally { - heapLock.unlock(); - } - } - - private UpdateResult handleNewElement(Element newElement, UpdateResult result) { - elementMap.put(newElement.entityId, newElement); - - if (maxHeap.size() < maxVisibleFurniture) { - maxHeap.offer(newElement); - inHeapSet.add(newElement.entityId); - result.addEntered(newElement); - } else if (maxHeap.peek() != null && newElement.distance < maxHeap.peek().distance) { - Element removed = maxHeap.poll(); - inHeapSet.remove(removed.entityId); - result.addExited(removed); - - maxHeap.offer(newElement); - inHeapSet.add(newElement.entityId); - result.addEntered(newElement); - } - return result; - } - - private UpdateResult handleExistingElement(Element existing, Element newElement, UpdateResult result) { - existing.setDistance(newElement.distance); - - boolean wasInHeap = inHeapSet.contains(existing.entityId); - boolean nowInHeap = checkIfShouldBeInHeap(existing.distance); - - if (wasInHeap) { - maxHeap.remove(existing); - maxHeap.offer(existing); - } else if (nowInHeap) { - if (maxHeap.size() < maxVisibleFurniture) { - maxHeap.offer(existing); - inHeapSet.add(existing.entityId); - result.addEntered(existing); - } else if (maxHeap.peek() != null && existing.distance < maxHeap.peek().distance) { - Element removed = maxHeap.poll(); - inHeapSet.remove(removed.entityId); - result.addExited(removed); - - maxHeap.offer(existing); - inHeapSet.add(existing.entityId); - result.addEntered(existing); - } - } - return result; - } - - private boolean checkIfShouldBeInHeap(double distance) { - if (maxHeap.size() < maxVisibleFurniture) return true; - return maxHeap.peek() != null && distance < maxHeap.peek().distance; - } - - public int getTotalMembers() { - heapLock.lock(); - try { - return elementMap.size(); - } finally { - heapLock.unlock(); - } - } - - public List getAllElements() { - heapLock.lock(); - try { - return List.copyOf(elementMap.values()); - } finally { - heapLock.unlock(); - } - } - - public void removeByEntityId(int entityId) { - heapLock.lock(); - try { - Element removed = elementMap.remove(entityId); - if (removed != null) { - maxHeap.remove(removed); - inHeapSet.remove(entityId); - } - } finally { - heapLock.unlock(); - } - } - - @Override - public String toString() { - return "DynamicPriorityTracker{" + - "maxHeap=" + maxHeap + - ", elementMap=" + elementMap + - ", inHeapSet=" + inHeapSet + - ", heapLock=" + heapLock + - '}'; - } -} diff --git a/gradle.properties b/gradle.properties index afbc44234..c17776f19 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] project_version=0.0.54.6 -config_version=34 +config_version=33 lang_version=13 project_group=net.momirealms latest_supported_version=1.21.5 From 4624d57cc4ed7388d1b3a30ffd1ec7cf29b8b73d Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 23 May 2025 04:51:13 +0800 Subject: [PATCH 10/11] =?UTF-8?q?refactor(bukkit):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E5=8F=AF=E8=A7=81=E5=AE=B6=E5=85=B7=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E9=99=90=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/net/momirealms/craftengine/core/plugin/CraftEngine.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index c24dc315a..cf5e56691 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin; import net.momirealms.craftengine.core.advancement.AdvancementManager; import net.momirealms.craftengine.core.block.BlockManager; import net.momirealms.craftengine.core.entity.furniture.FurnitureManager; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.entity.projectile.ProjectileManager; import net.momirealms.craftengine.core.font.FontManager; import net.momirealms.craftengine.core.item.ItemManager; From 1edafae8247072cdf8c0c129ed92ebcbfd2f380c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 23 May 2025 04:56:44 +0800 Subject: [PATCH 11/11] =?UTF-8?q?fix(bukkit):=20=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E4=B8=8D=E4=BC=9A=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/entity/projectile/BukkitProjectileManager.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java index 9fb5c698f..1bc6d280d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/projectile/BukkitProjectileManager.java @@ -64,6 +64,11 @@ public class BukkitProjectileManager implements Listener, ProjectileManager { handleProjectileLoad(event.getEntity()); } + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onEntityPortal(EntityPortalEvent event) { + this.projectiles.remove(event.getEntity().getEntityId()); + } + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) public void onEntityAdd(EntityAddToWorldEvent event) { if (event.getEntity() instanceof Projectile projectile) {