9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2026-01-04 15:41:38 +00:00

添加切换实体剔除指令

This commit is contained in:
XiaoMoMi
2025-12-01 16:45:26 +08:00
parent 93da1f98f3
commit f0f2181a18
8 changed files with 129 additions and 28 deletions

View File

@@ -43,6 +43,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new TestCommand(this, plugin),
new SetLocaleCommand(this, plugin),
new SetEntityViewDistanceScaleCommand(this, plugin),
new ToggleEntityCullingCommand(this, plugin),
new UnsetLocaleCommand(this, plugin),
new DebugGetBlockStateRegistryIdCommand(this, plugin),
new DebugGetBlockInternalIdCommand(this, plugin),

View File

@@ -1,12 +1,14 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
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 net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.locale.MessageConstants;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -27,6 +29,14 @@ public class SetEntityViewDistanceScaleCommand extends BukkitCommandFeature<Comm
.required("player", PlayerParser.playerParser())
.required("scale", DoubleParser.doubleParser(0.125, 8))
.handler(context -> {
if (!Config.enableEntityCulling()) {
context.sender().sendMessage(Component.text("Entity culling is not enabled on this server").color(NamedTextColor.RED));
return;
}
if (Config.entityCullingViewDistance() <= 0) {
context.sender().sendMessage(Component.text("View distance is not enabled on this server").color(NamedTextColor.RED));
return;
}
Player player = context.get("player");
double scale = context.get("scale");
BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);

View File

@@ -0,0 +1,57 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
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 net.momirealms.craftengine.core.plugin.command.FlagKeys;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.locale.MessageConstants;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.incendo.cloud.Command;
import org.incendo.cloud.bukkit.parser.PlayerParser;
import org.incendo.cloud.parser.standard.BooleanParser;
import org.incendo.cloud.parser.standard.DoubleParser;
import java.util.Optional;
public class ToggleEntityCullingCommand extends BukkitCommandFeature<CommandSender> {
public ToggleEntityCullingCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
super(commandManager, plugin);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.flag(FlagKeys.SILENT_FLAG)
.required("player", PlayerParser.playerParser())
.optional("state", BooleanParser.booleanParser())
.handler(context -> {
if (!Config.enableEntityCulling()) {
context.sender().sendMessage(Component.text("Entity culling is not enabled on this server").color(NamedTextColor.RED));
return;
}
Player player = context.get("player");
BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
Optional<Boolean> state = context.optional("state");
boolean isEnabled = serverPlayer.enableEntityCulling();
if (state.isPresent()) {
serverPlayer.setEnableEntityCulling(state.get());
handleFeedback(context, MessageConstants.COMMAND_TOGGLE_ENTITY_CULLING_SUCCESS, Component.text(state.get()), Component.text(player.getName()));
} else {
serverPlayer.setEnableEntityCulling(!isEnabled);
handleFeedback(context, MessageConstants.COMMAND_TOGGLE_ENTITY_CULLING_SUCCESS, Component.text(!isEnabled), Component.text(player.getName()));
}
});
}
@Override
public String getFeatureID() {
return "toggle_entity_culling";
}
}

View File

@@ -74,6 +74,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class BukkitServerPlayer extends Player {
public static final Key SELECTED_LOCALE_KEY = Key.of("craftengine:locale");
public static final Key ENTITY_CULLING_VIEW_DISTANCE_SCALE = Key.of("craftengine:entity_culling_view_distance_scale");
public static final Key ENABLE_ENTITY_CULLING = Key.of("craftengine:enable_entity_culling");
private final BukkitCraftEngine plugin;
// connection state
@@ -146,6 +147,8 @@ public class BukkitServerPlayer extends Player {
private final EntityCulling culling;
private Vec3d firstPersonCameraVec3;
private Vec3d thirdPersonCameraVec3;
// 是否启用实体剔除
private boolean enableEntityCulling;
// 玩家眼睛所在位置
private Location eyeLocation;
@@ -174,6 +177,7 @@ public class BukkitServerPlayer extends Player {
byte[] bytes = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(CooldownData.COOLDOWN_KEY), PersistentDataType.BYTE_ARRAY);
String locale = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(SELECTED_LOCALE_KEY), PersistentDataType.STRING);
Double scale = player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(ENTITY_CULLING_VIEW_DISTANCE_SCALE), PersistentDataType.DOUBLE);
this.enableEntityCulling = Optional.ofNullable(player.getPersistentDataContainer().get(KeyUtils.toNamespacedKey(ENABLE_ENTITY_CULLING), PersistentDataType.BOOLEAN)).orElse(true);
this.culling.setDistanceScale(Optional.ofNullable(scale).orElse(1.0));
this.selectedLocale = TranslationManager.parseLocale(locale);
this.trackedChunks = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(512, 0.5f);
@@ -597,38 +601,44 @@ public class BukkitServerPlayer extends Player {
public void entityCullingTick() {
this.culling.restoreTokenOnTick();
boolean useRayTracing = Config.entityCullingRayTracing();
for (VirtualCullableObject cullableObject : this.trackedBlockEntityRenderers.values()) {
CullingData cullingData = cullableObject.cullable.cullingData();
if (cullingData != null) {
boolean firstPersonVisible = this.culling.isVisible(cullingData, this.firstPersonCameraVec3, useRayTracing);
// 之前可见
if (cullableObject.isShown) {
boolean thirdPersonVisible = this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing);
if (!firstPersonVisible && !thirdPersonVisible) {
cullableObject.setShown(this, false);
if (this.enableEntityCulling) {
for (VirtualCullableObject cullableObject : this.trackedBlockEntityRenderers.values()) {
CullingData cullingData = cullableObject.cullable.cullingData();
if (cullingData != null) {
boolean firstPersonVisible = this.culling.isVisible(cullingData, this.firstPersonCameraVec3, useRayTracing);
// 之前可见
if (cullableObject.isShown) {
boolean thirdPersonVisible = this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing);
if (!firstPersonVisible && !thirdPersonVisible) {
cullableObject.setShown(this, false);
}
}
}
// 之前不可见
else {
// 但是第一人称可见了
if (firstPersonVisible) {
// 下次再说
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
// 之前不可见
else {
// 但是第一人称可见了
if (firstPersonVisible) {
// 下次再说
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
continue;
}
cullableObject.setShown(this, true);
continue;
}
cullableObject.setShown(this, true);
continue;
}
if (this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing)) {
// 下次再说
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
continue;
if (this.culling.isVisible(cullingData, this.thirdPersonCameraVec3, useRayTracing)) {
// 下次再说
if (Config.enableEntityCullingRateLimiting() && !this.culling.takeToken()) {
continue;
}
cullableObject.setShown(this, true);
}
cullableObject.setShown(this, true);
// 仍然不可见
}
// 仍然不可见
} else {
cullableObject.setShown(this, true);
}
} else {
}
} else {
for (VirtualCullableObject cullableObject : this.trackedBlockEntityRenderers.values()) {
cullableObject.setShown(this, true);
}
}
@@ -1341,6 +1351,17 @@ public class BukkitServerPlayer extends Player {
platformPlayer().getPersistentDataContainer().set(KeyUtils.toNamespacedKey(ENTITY_CULLING_VIEW_DISTANCE_SCALE), PersistentDataType.DOUBLE, value);
}
@Override
public void setEnableEntityCulling(boolean enable) {
this.enableEntityCulling = enable;
platformPlayer().getPersistentDataContainer().set(KeyUtils.toNamespacedKey(ENABLE_ENTITY_CULLING), PersistentDataType.BOOLEAN, enable);
}
@Override
public boolean enableEntityCulling() {
return enableEntityCulling;
}
@Override
public void giveExperiencePoints(int xpPoints) {
platformPlayer().giveExp(xpPoints);

View File

@@ -135,6 +135,12 @@ set_entity_view_distance_scale:
usage:
- /ce feature entity-view-distance-scale set
toggle_entity_culling:
enable: true
permission: ce.command.admin.toggle_entity_culling
usage:
- /ce feature toggle-entity-culling
# Debug commands
debug_set_block:
enable: true

View File

@@ -72,9 +72,10 @@ command.upload.on_progress: "<white>Started uploading progress. Check the consol
command.send_resource_pack.success.single: "<white>Sent resource pack to <arg:0>.</white>"
command.send_resource_pack.success.multiple: "<white>Send resource packs to <arg:0> players.</white>"
command.locale.set.failure: "<red>Invalid locale format: <arg:0></red>"
command.locale.set.success: "<white>Updated selected locale to <arg:0> for <arg:1></white>"
command.locale.set.success: "<white>Selected locale has been set to <arg:0> for <arg:1></white>"
command.locale.unset.success: "<white>Cleared selected locale for <arg:0></white>"
command.entity_view_distance_scale.set.success: "<white>Updated entity view distance scale to <arg:0> for <arg:1></white>"
command.entity_view_distance_scale.set.success: "<white>Entity view distance scale updated to <arg:0> for <arg:1></white>"
command.entity_culling.toggle.success: "<white>Entity culling status updated to <arg:0> for <arg:1></white>"
warning.network.resource_pack.unverified_uuid: "<yellow>Player <arg:0> is attempting to request a resource pack using a UUID (<arg:1>) that is not authenticated by the server.</yellow>"
warning.config.pack.duplicated_files: "<red>Duplicated files Found. Please resolve them through config.yml 'resource-pack.duplicated-files-handler' section.</red>"
warning.config.yaml.duplicated_key: "<red>Issue found in file <arg:0> - Found duplicated key '<arg:1>' at line <arg:2>, this might cause unexpected results.</red>"

View File

@@ -193,6 +193,10 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
public abstract void setEntityCullingViewDistanceScale(double value);
public abstract void setEnableEntityCulling(boolean enable);
public abstract boolean enableEntityCulling();
public abstract void giveExperiencePoints(int xpPoints);
public abstract void giveExperienceLevels(int levels);

View File

@@ -42,4 +42,5 @@ public interface MessageConstants {
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_TEST_SINGLE = Component.translatable().key("command.item.clear.test.single");
TranslatableComponent.Builder COMMAND_ITEM_CLEAR_TEST_MULTIPLE = Component.translatable().key("command.item.clear.test.multiple");
TranslatableComponent.Builder COMMAND_ENTITY_VIEW_DISTANCE_SCALE_SET_SUCCESS = Component.translatable().key("command.entity_view_distance_scale.set.success");
TranslatableComponent.Builder COMMAND_TOGGLE_ENTITY_CULLING_SUCCESS = Component.translatable().key("command.entity_culling.toggle.success");
}