Add workaround for async entity tracker server forks

This commit is contained in:
fullwall 2023-06-08 20:53:38 +08:00
parent 0473887462
commit 2466677cc3
5 changed files with 41 additions and 6 deletions

View File

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -22,6 +23,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemFlag;
@ -58,6 +60,22 @@ public class Util {
}
}
public static void callPossiblyAsyncEvent(Event event, boolean sync) {
try {
Callable<Void> callable = () -> {
Bukkit.getPluginManager().callEvent(event);
return null;
};
if (sync) {
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), callable).get();
} else {
callable.call();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Vector callPushEvent(NPC npc, double x, double y, double z) {
boolean allowed = npc == null || !npc.isProtected()
|| (npc.data().has(NPC.Metadata.COLLIDABLE) && npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE));

View File

@ -13,6 +13,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_17_R1.entity.EntityHumanNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ChunkMap.TrackedEntity;
@ -53,8 +54,11 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
public void updatePlayer(final ServerPlayer entityplayer) {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -113,7 +117,9 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
}
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

View File

@ -13,6 +13,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ChunkMap.TrackedEntity;
@ -53,8 +54,11 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
public void updatePlayer(final ServerPlayer entityplayer) {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -113,7 +117,9 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
}
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

View File

@ -16,6 +16,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ChunkMap.TrackedEntity;
@ -80,8 +81,11 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -137,6 +141,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

View File

@ -872,11 +872,11 @@ public class NMSImpl implements NMSBridge {
// minecraft requires that an entity fit onto both blocks if width >= 1f, but we'd prefer to
// make it just fit on 1 so hack around it a bit.
}
if (params.debug() && getPathEntity(navigation) != null) {
Util.sendBlockChanges(getBlocks(entity, getPathEntity(navigation)), Material.DANDELION);
}
lastSpeed = params.speed();
}
if (params.debug() && !navigation.isDone()) {
Util.sendBlockChanges(getBlocks(entity, getPathEntity(navigation)), Material.DANDELION);
}
navigation.setSpeedModifier(params.speed());
return navigation.isDone();
}