9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-29 03:49:15 +00:00

fixed the weird furniture behavior on 1.20

This commit is contained in:
XiaoMoMi
2025-03-23 04:34:43 +08:00
parent ad12125585
commit 96ae21d4b3
6 changed files with 25 additions and 50 deletions

View File

@@ -1,7 +1,5 @@
package net.momirealms.craftengine.bukkit.entity.furniture;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.util.EntityUtils;
import net.momirealms.craftengine.core.entity.furniture.*;
@@ -37,11 +35,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
private final Map<Integer, LoadedFurniture> furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f);
private final Map<Integer, LoadedFurniture> furnitureByInteractionEntityId = new ConcurrentHashMap<>(512, 0.5f);
private final Map<Integer, int[]> baseEntity2SubEntities = new ConcurrentHashMap<>(256, 0.5f);
// Delay furniture cache remove for about 4-5 ticks
private static final int DELAYED_TICK = 5;
private final IntSet[] delayedRemove = new IntSet[DELAYED_TICK];
// Event listeners
private final Listener dismountListener;
private final FurnitureEventListener furnitureEventListener;
@@ -56,9 +49,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
this.plugin = plugin;
this.furnitureEventListener = new FurnitureEventListener(this);
this.dismountListener = VersionHelper.isVersionNewerThan1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount);
for (int i = 0; i < DELAYED_TICK; i++) {
this.delayedRemove[i] = new IntOpenHashSet();
}
instance = this;
}
@@ -171,18 +161,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
}
public void tick() {
IntSet first = this.delayedRemove[0];
for (int i : first) {
// unloaded furniture might be loaded again
LoadedFurniture furniture = getLoadedFurnitureByBaseEntityId(i);
if (furniture == null)
this.baseEntity2SubEntities.remove(i);
}
first.clear();
for (int i = 1; i < DELAYED_TICK; i++) {
this.delayedRemove[i - 1] = this.delayedRemove[i];
}
this.delayedRemove[DELAYED_TICK-1] = first;
}
@Override
@@ -224,12 +202,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
return Optional.ofNullable(this.byId.get(id));
}
@Nullable
@Override
public int[] getSubEntityIdsByBaseEntityId(int entityId) {
return this.baseEntity2SubEntities.get(entityId);
}
@Override
public boolean isFurnitureBaseEntity(int entityId) {
return this.furnitureByBaseEntityId.containsKey(entityId);
@@ -253,7 +225,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
for (int sub : furniture.interactionEntityIds()) {
this.furnitureByInteractionEntityId.remove(sub);
}
this.delayedRemove[DELAYED_TICK-1].add(id);
}
}
@@ -270,6 +241,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
if (previous != null) return;
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
for (Player player : display.getTrackedPlayers()) {
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket());
}
}
@@ -316,7 +288,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) {
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType);
this.furnitureByBaseEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture);
this.baseEntity2SubEntities.put(loadedFurniture.baseEntityId(), loadedFurniture.subEntityIds());
for (int entityId : loadedFurniture.interactionEntityIds()) {
this.furnitureByInteractionEntityId.put(entityId, loadedFurniture);
}

View File

@@ -41,9 +41,9 @@ public class LoadedFurniture {
private final WeakReference<Entity> baseEntity;
private final int baseEntityId;
// includes elements + interactions
private final int[] subEntityIds;
private final List<Integer> subEntityIds;
// interactions
private final int[] interactionEntityIds;
private final List<Integer> interactionEntityIds;
// seats
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
private final Vector<Entity> seats = new Vector<>();
@@ -73,14 +73,8 @@ public class LoadedFurniture {
interactionEntityIds.add(entityId);
this.hitBoxes.put(entityId, hitBox);
}
this.subEntityIds = new int[entityIds.size()];
for (int i = 0; i < entityIds.size(); ++i) {
this.subEntityIds[i] = entityIds.get(i);
}
this.interactionEntityIds = new int[interactionEntityIds.size()];
for (int i = 0; i < interactionEntityIds.size(); ++i) {
this.interactionEntityIds[i] = interactionEntityIds.get(i);
}
this.subEntityIds = entityIds;
this.interactionEntityIds = interactionEntityIds;
this.resetSpawnPackets();
}
@@ -229,11 +223,11 @@ public class LoadedFurniture {
return baseEntityId;
}
public int[] interactionEntityIds() {
public List<Integer> interactionEntityIds() {
return interactionEntityIds;
}
public int[] subEntityIds() {
public List<Integer> subEntityIds() {
return this.subEntityIds;
}

View File

@@ -33,9 +33,7 @@ import org.bukkit.util.RayTraceResult;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -534,6 +532,7 @@ public class PacketConsumers {
int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet);
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId);
if (furniture != null) {
user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
user.sendPacket(furniture.spawnPacket(), false);
}
}
@@ -568,7 +567,7 @@ public class PacketConsumers {
try {
IntList intList = (IntList) Reflections.field$ClientboundRemoveEntitiesPacket$entityIds.get(packet);
for (int i = 0, size = intList.size(); i < size; i++) {
int[] entities = BukkitFurnitureManager.instance().getSubEntityIdsByBaseEntityId(intList.getInt(i));
List<Integer> entities = user.furnitureView().remove(intList.getInt(i));
if (entities == null) continue;
for (int entityId : entities) {
intList.add(entityId);

View File

@@ -29,7 +29,10 @@ import org.jetbrains.annotations.Nullable;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class BukkitServerPlayer extends Player {
private final Channel channel;
@@ -60,6 +63,8 @@ public class BukkitServerPlayer extends Player {
private Key lastUsedRecipe = null;
private Map<Integer, List<Integer>> furnitureView = new ConcurrentHashMap<>();
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
this.channel = channel;
this.plugin = plugin;
@@ -583,6 +588,11 @@ public class BukkitServerPlayer extends Player {
return playerRef.get();
}
@Override
public Map<Integer, List<Integer>> furnitureView() {
return this.furnitureView;
}
public void setResendSound() {
resentSoundTick = gameTicks();
}