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] =?UTF-8?q?feat(bukkit):=20=E6=B7=BB=E5=8A=A0=E9=85=8D?= =?UTF-8?q?=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