mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-28 19:39:11 +00:00
0.0.45
This commit is contained in:
@@ -32,12 +32,14 @@ import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
public static final NamespacedKey FURNITURE_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:furniture_id"));
|
||||
public static final NamespacedKey FURNITURE_ANCHOR_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:anchor_type"));
|
||||
public static final NamespacedKey FURNITURE_SEAT_BASE_ENTITY_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_to_base_entity"));
|
||||
public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = Objects.requireNonNull(NamespacedKey.fromString("craftengine:seat_vector"));
|
||||
public static final NamespacedKey FURNITURE_COLLISION = Objects.requireNonNull(NamespacedKey.fromString("craftengine:collision"));
|
||||
private static BukkitFurnitureManager instance;
|
||||
private final BukkitCraftEngine plugin;
|
||||
private final FurnitureParser furnitureParser;
|
||||
@@ -57,6 +59,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
this.furnitureParser = new FurnitureParser();
|
||||
this.furnitureEventListener = new FurnitureEventListener(this);
|
||||
this.dismountListener = VersionHelper.isVersionNewerThan1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount);
|
||||
plugin.scheduler().asyncRepeating(() -> {
|
||||
System.out.println("数量" + furnitureByRealEntityId.size());
|
||||
}, 3, 3, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,7 +78,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
ItemDisplay display = (ItemDisplay) entity;
|
||||
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_KEY, PersistentDataType.STRING, furniture.id().toString());
|
||||
display.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_ANCHOR_KEY, PersistentDataType.STRING, finalAnchorType.name());
|
||||
handleEntityLoadEarly(display);
|
||||
handleBaseEntityLoadEarly(display);
|
||||
});
|
||||
if (playSound) {
|
||||
SoundData data = furniture.settings().sounds().placeSound();
|
||||
@@ -214,7 +219,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
handleEntityLoadEarly(entity);
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
handleBaseEntityLoadEarly(display);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +256,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
return this.furnitureByEntityId.get(entityId);
|
||||
}
|
||||
|
||||
protected void handleBaseFurnitureUnload(Entity entity, boolean unloadColliders) {
|
||||
protected void handleBaseEntityUnload(Entity entity) {
|
||||
int id = entity.getEntityId();
|
||||
LoadedFurniture furniture = this.furnitureByRealEntityId.remove(id);
|
||||
if (furniture != null) {
|
||||
@@ -261,57 +268,97 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
for (int sub : furniture.entityIds()) {
|
||||
this.furnitureByEntityId.remove(sub);
|
||||
}
|
||||
for (CollisionEntity collision : furniture.collisionEntities()) {
|
||||
if (unloadColliders) {
|
||||
this.furnitureByRealEntityId.remove(FastNMS.INSTANCE.method$Entity$getId(collision));
|
||||
}
|
||||
if (!isPreventing) collision.destroy();
|
||||
}
|
||||
// for (CollisionEntity collision : furniture.collisionEntities()) {
|
||||
// this.furnitureByRealEntityId.remove(FastNMS.INSTANCE.method$Entity$getId(collision));
|
||||
// if (!isPreventing) collision.destroy();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleCollisionEntityUnload(Entity entity) {
|
||||
int id = entity.getEntityId();
|
||||
this.furnitureByRealEntityId.remove(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // just a misleading name `getTrackedPlayers`
|
||||
protected void handleEntityLoadLate(Entity entity) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
String id = entity.getPersistentDataContainer().get(FURNITURE_KEY, PersistentDataType.STRING);
|
||||
if (id == null) return;
|
||||
Key key = Key.of(id);
|
||||
Optional<CustomFurniture> optionalFurniture = furnitureById(key);
|
||||
if (optionalFurniture.isEmpty()) return;
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
Location location = entity.getLocation();
|
||||
if (FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
|
||||
return;
|
||||
}
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
|
||||
protected void handleBaseEntityLoadLate(ItemDisplay display, int depth) {
|
||||
// must be a furniture item
|
||||
String id = display.getPersistentDataContainer().get(FURNITURE_KEY, PersistentDataType.STRING);
|
||||
if (id == null) return;
|
||||
|
||||
Key key = Key.of(id);
|
||||
Optional<CustomFurniture> optionalFurniture = furnitureById(key);
|
||||
if (optionalFurniture.isEmpty()) return;
|
||||
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
|
||||
Location location = display.getLocation();
|
||||
if (!FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
|
||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(display, customFurniture));
|
||||
for (Player player : display.getTrackedPlayers()) {
|
||||
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.fakeEntityIds());
|
||||
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket(player));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (depth > 2) return;
|
||||
this.plugin.scheduler().sync().runLater(() -> {
|
||||
handleBaseEntityLoadLate(display, depth + 1);
|
||||
}, 1, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
protected void handleCollisionEntityLoadLate(Shulker shulker, int depth) {
|
||||
// remove the shulker if it's not a collision entity, it might be wrongly copied by WorldEdit
|
||||
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(shulker) instanceof CollisionEntity) {
|
||||
return;
|
||||
}
|
||||
Byte flag = shulker.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE);
|
||||
if (flag != null && flag == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location location = shulker.getLocation();
|
||||
World world = location.getWorld();
|
||||
int chunkX = location.getBlockX() >> 4;
|
||||
int chunkZ = location.getBlockZ() >> 4;
|
||||
if (!FastNMS.INSTANCE.isPreventingStatusUpdates(world, chunkX, chunkZ)) {
|
||||
shulker.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (depth > 2) return;
|
||||
plugin.scheduler().sync().runLater(() -> {
|
||||
handleCollisionEntityLoadLate(shulker, depth + 1);
|
||||
}, 1, world, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
public void handleBaseEntityLoadEarly(ItemDisplay display) {
|
||||
String id = display.getPersistentDataContainer().get(FURNITURE_KEY, PersistentDataType.STRING);
|
||||
if (id == null) return;
|
||||
Key key = Key.of(id);
|
||||
Optional<CustomFurniture> optionalFurniture = furnitureById(key);
|
||||
if (optionalFurniture.isPresent()) {
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
addNewFurniture(display, customFurniture, getAnchorType(display, customFurniture));
|
||||
return;
|
||||
}
|
||||
// Remove the entity if it's not a valid furniture
|
||||
if (Config.removeInvalidFurniture()) {
|
||||
if (Config.furnitureToRemove().isEmpty() || Config.furnitureToRemove().contains(id)) {
|
||||
display.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleEntityLoadEarly(Entity entity) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
String id = entity.getPersistentDataContainer().get(FURNITURE_KEY, PersistentDataType.STRING);
|
||||
if (id == null) return;
|
||||
Key key = Key.of(id);
|
||||
Optional<CustomFurniture> optionalFurniture = furnitureById(key);
|
||||
if (optionalFurniture.isPresent()) {
|
||||
CustomFurniture customFurniture = optionalFurniture.get();
|
||||
LoadedFurniture previous = this.furnitureByRealEntityId.get(display.getEntityId());
|
||||
if (previous != null) return;
|
||||
addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
|
||||
return;
|
||||
}
|
||||
// Remove the entity if it's not a valid furniture
|
||||
if (Config.removeInvalidFurniture()) {
|
||||
if (Config.furnitureToRemove().isEmpty() || Config.furnitureToRemove().contains(id)) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
public void handleCollisionEntityLoadOnEntitiesLoad(Shulker shulker) {
|
||||
// remove the shulker if it's on chunk load stage
|
||||
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(shulker) instanceof CollisionEntity) {
|
||||
shulker.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@ package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent;
|
||||
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -34,7 +31,11 @@ public class FurnitureEventListener implements Listener {
|
||||
public void onEntitiesLoadEarly(EntitiesLoadEvent event) {
|
||||
List<Entity> entities = event.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
this.manager.handleEntityLoadEarly(entity);
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadEarly(itemDisplay);
|
||||
} else if (entity instanceof Shulker shulker) {
|
||||
this.manager.handleCollisionEntityLoadOnEntitiesLoad(shulker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,13 +43,20 @@ public class FurnitureEventListener implements Listener {
|
||||
public void onWorldLoad(WorldLoadEvent event) {
|
||||
List<Entity> entities = event.getWorld().getEntities();
|
||||
for (Entity entity : entities) {
|
||||
this.manager.handleEntityLoadEarly(entity);
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadEarly(itemDisplay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onEntityLoad(EntityAddToWorldEvent event) {
|
||||
this.manager.handleEntityLoadLate(event.getEntity());
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadLate(itemDisplay, 0);
|
||||
} else if (entity instanceof Shulker shulker) {
|
||||
this.manager.handleCollisionEntityLoadLate(shulker, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -59,7 +67,9 @@ public class FurnitureEventListener implements Listener {
|
||||
Entity[] entities = event.getChunk().getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleBaseFurnitureUnload(entity, true);
|
||||
this.manager.handleBaseEntityUnload(entity);
|
||||
} else if (entity instanceof Shulker) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,15 +79,20 @@ public class FurnitureEventListener implements Listener {
|
||||
List<Entity> entities = event.getWorld().getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleBaseFurnitureUnload(entity, true);
|
||||
this.manager.handleBaseEntityUnload(entity);
|
||||
} else if (entity instanceof Shulker) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityUnload(EntityRemoveFromWorldEvent event) {
|
||||
if (event.getEntity() instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseFurnitureUnload(itemDisplay, false);
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof ItemDisplay) {
|
||||
this.manager.handleBaseEntityUnload(entity);
|
||||
} else if (entity instanceof Shulker) {
|
||||
this.manager.handleCollisionEntityUnload(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ public class LoadedFurniture implements Furniture {
|
||||
private final Map<Integer, HitBox> hitBoxes;
|
||||
private final boolean minimized;
|
||||
private final boolean hasExternalModel;
|
||||
private final CustomFurniture.Placement placement;
|
||||
// seats
|
||||
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
|
||||
private final Vector<Entity> seats = new Vector<>();
|
||||
@@ -68,7 +67,6 @@ public class LoadedFurniture implements Furniture {
|
||||
mainEntityIds.add(this.baseEntityId);
|
||||
|
||||
CustomFurniture.Placement placement = furniture.getPlacement(anchorType);
|
||||
this.placement = placement;
|
||||
// bind external furniture
|
||||
Optional<ExternalModel> optionalExternal = placement.externalModel();
|
||||
if (optionalExternal.isPresent()) {
|
||||
@@ -152,6 +150,8 @@ public class LoadedFurniture implements Furniture {
|
||||
Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.location.getWorld());
|
||||
for (CollisionEntity entity : this.collisionEntities) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(world, entity);
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
|
||||
bukkitEntity.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_COLLISION, PersistentDataType.BYTE, (byte) 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
|
||||
public TestCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||
@@ -22,7 +27,14 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
Player player = context.sender();
|
||||
Location location = player.getLocation();
|
||||
try {
|
||||
|
||||
Collection<Entity> entities = player.getLocation().getNearbyEntities(2,2,2);
|
||||
for (Entity entity : entities) {
|
||||
System.out.println(entity.getType());
|
||||
if (FastNMS.INSTANCE.method$CraftEntity$getHandle(entity) instanceof CollisionEntity) {
|
||||
System.out.println(entity.getEntityId());
|
||||
System.out.println(entity.getUniqueId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user