Skip to content

Commit eecf17b

Browse files
committed
Handle Canvas region state during player NPC spawn
1 parent fee527a commit eecf17b

4 files changed

Lines changed: 59 additions & 3 deletions

File tree

v1_21_R7/src/main/java/net/citizensnpcs/nms/v1_21_R7/entity/HumanController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
4242
final GameProfile profile = new GameProfile(uuid, name);
4343
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
4444
ClientInformation.createDefault(), npc);
45+
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
4546
Skin skin = handle.getSkinTracker().getSkin();
4647
if (skin != null) {
4748
skin.apply(handle);

v26_1_R1/src/main/java/net/citizensnpcs/nms/v26_1_R1/entity/HumanController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
4242
final GameProfile profile = new GameProfile(uuid, name);
4343
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
4444
ClientInformation.createDefault(), npc);
45+
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
4546
Skin skin = handle.getSkinTracker().getSkin();
4647
if (skin != null) {
4748
skin.apply(handle);

v26_1_R1/src/main/java/net/citizensnpcs/nms/v26_1_R1/util/NMSImpl.java

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,19 +428,32 @@ public void activate(org.bukkit.entity.Entity entity) {
428428

429429
@Override
430430
public void addEntityToWorld(org.bukkit.entity.Entity entity, SpawnReason custom, Consumer<Boolean> isAdded) {
431+
boolean canvasPlayer = "Canvas".equals(Bukkit.getName()) && entity instanceof Player;
431432
Runnable task = () -> {
432433
Entity handle = getHandle(entity);
433434
ServerLevel level = (ServerLevel) handle.level();
435+
ServerPlayer player = canvasPlayer ? (ServerPlayer) handle : null;
436+
Collection<Connection> regionConnections = player == null ? null : getCanvasRegionConnections(level);
437+
Connection connection = player == null ? null : getCanvasConnection(player);
438+
boolean addedConnection = regionConnections != null && connection != null
439+
&& !regionConnections.contains(connection) && regionConnections.add(connection);
434440
int viewDistance = -1;
435441
ChunkMap chunkMap = null;
436442
if (entity instanceof Player) {
437443
chunkMap = level.getChunkSource().chunkMap;
438444
viewDistance = chunkMap.serverViewDistance;
439445
chunkMap.serverViewDistance = -1;
440446
}
441-
boolean success = level.addFreshEntity(handle, custom);
442-
if (chunkMap != null) {
443-
chunkMap.serverViewDistance = viewDistance;
447+
boolean success;
448+
try {
449+
success = level.addFreshEntity(handle, custom);
450+
} finally {
451+
if (addedConnection) {
452+
regionConnections.remove(connection);
453+
}
454+
if (chunkMap != null) {
455+
chunkMap.serverViewDistance = viewDistance;
456+
}
444457
}
445458
isAdded.accept(success);
446459
};
@@ -453,6 +466,28 @@ public void addEntityToWorld(org.bukkit.entity.Entity entity, SpawnReason custom
453466
}
454467
}
455468

469+
private static Connection getCanvasConnection(ServerPlayer player) {
470+
if (CANVAS_CONNECTION == null)
471+
return null;
472+
try {
473+
return (Connection) CANVAS_CONNECTION.invoke(player.connection);
474+
} catch (Throwable e) {
475+
e.printStackTrace();
476+
return null;
477+
}
478+
}
479+
480+
private static Collection<Connection> getCanvasRegionConnections(ServerLevel level) {
481+
if (CANVAS_CURRENT_WORLD_DATA == null || CANVAS_REGION_CONNECTIONS == null)
482+
return null;
483+
try {
484+
return (Collection<Connection>) CANVAS_REGION_CONNECTIONS.invoke(CANVAS_CURRENT_WORLD_DATA.invoke(level));
485+
} catch (Throwable e) {
486+
e.printStackTrace();
487+
return null;
488+
}
489+
}
490+
456491
@Override
457492
public void addOrRemoveFromPlayerList(org.bukkit.entity.Entity entity, boolean remove) {
458493
if (entity == null)
@@ -2941,6 +2976,13 @@ public <U> void acceptEmpty(MemoryModuleType<U> type) {
29412976
private static final MethodHandle BRAIN_SENSORS_GETTER = NMS.getGetter(Brain.class, "sensors");
29422977
private static final MethodHandle BRAIN_SETTER = NMS.getFirstSetter(LivingEntity.class, Brain.class);
29432978
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
2979+
private static final MethodHandle CANVAS_CONNECTION = "Canvas".equals(Bukkit.getName())
2980+
? NMS.getGetter(ServerGamePacketListenerImpl.class.getSuperclass(), "connection", false)
2981+
: null;
2982+
private static final MethodHandle CANVAS_CURRENT_WORLD_DATA = "Canvas".equals(Bukkit.getName())
2983+
? NMS.getMethodHandle(Level.class, "getCurrentWorldData", false)
2984+
: null;
2985+
private static final MethodHandle CANVAS_REGION_CONNECTIONS = loadCanvasRegionConnectionsGetter();
29442986
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class,
29452987
"updatePlayerStatus", true, ServerPlayer.class, boolean.class);
29462988
private static final MethodHandle CLIENT_LOADED_TIMEOUT_TIMER = NMS.getSetter(ServerGamePacketListenerImpl.class,
@@ -3032,6 +3074,17 @@ public <U> void acceptEmpty(MemoryModuleType<U> type) {
30323074
public static final MethodHandle WAITING_FOR_RESPAWN = NMS.getSetter(ServerGamePacketListenerImpl.class,
30333075
"waitingForRespawn");
30343076

3077+
private static MethodHandle loadCanvasRegionConnectionsGetter() {
3078+
if (!"Canvas".equals(Bukkit.getName()))
3079+
return null;
3080+
try {
3081+
return NMS.getGetter(Class.forName("io.papermc.paper.threadedregions.RegionizedWorldData"), "connections",
3082+
false);
3083+
} catch (ClassNotFoundException e) {
3084+
return null;
3085+
}
3086+
}
3087+
30353088
static {
30363089
if (NMS.getMethodHandle(CraftBlock.class, "getNMS", false) != null) {
30373090
GET_BLOCK_STATE = NMS.getMethodHandle(CraftBlock.class, "getNMS", false);

v26_2_R1/src/main/java/net/citizensnpcs/nms/v26_2_R1/entity/HumanController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
4242
final GameProfile profile = new GameProfile(uuid, name);
4343
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
4444
ClientInformation.createDefault(), npc);
45+
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
4546
Skin skin = handle.getSkinTracker().getSkin();
4647
if (skin != null) {
4748
skin.apply(handle);

0 commit comments

Comments
 (0)