Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
final GameProfile profile = new GameProfile(uuid, name);
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
ClientInformation.createDefault(), npc);
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
Skin skin = handle.getSkinTracker().getSkin();
if (skin != null) {
skin.apply(handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
final GameProfile profile = new GameProfile(uuid, name);
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
ClientInformation.createDefault(), npc);
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
Skin skin = handle.getSkinTracker().getSkin();
if (skin != null) {
skin.apply(handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,19 +428,32 @@ public void activate(org.bukkit.entity.Entity entity) {

@Override
public void addEntityToWorld(org.bukkit.entity.Entity entity, SpawnReason custom, Consumer<Boolean> isAdded) {
boolean canvasPlayer = "Canvas".equals(Bukkit.getName()) && entity instanceof Player;
Runnable task = () -> {
Entity handle = getHandle(entity);
ServerLevel level = (ServerLevel) handle.level();
ServerPlayer player = canvasPlayer ? (ServerPlayer) handle : null;
Collection<Connection> regionConnections = player == null ? null : getCanvasRegionConnections(level);
Connection connection = player == null ? null : getCanvasConnection(player);
boolean addedConnection = regionConnections != null && connection != null
&& !regionConnections.contains(connection) && regionConnections.add(connection);
int viewDistance = -1;
ChunkMap chunkMap = null;
if (entity instanceof Player) {
chunkMap = level.getChunkSource().chunkMap;
viewDistance = chunkMap.serverViewDistance;
chunkMap.serverViewDistance = -1;
}
boolean success = level.addFreshEntity(handle, custom);
if (chunkMap != null) {
chunkMap.serverViewDistance = viewDistance;
boolean success;
try {
success = level.addFreshEntity(handle, custom);
} finally {
if (addedConnection) {
regionConnections.remove(connection);
}
if (chunkMap != null) {
chunkMap.serverViewDistance = viewDistance;
}
}
isAdded.accept(success);
};
Expand All @@ -453,6 +466,28 @@ public void addEntityToWorld(org.bukkit.entity.Entity entity, SpawnReason custom
}
}

private static Connection getCanvasConnection(ServerPlayer player) {
if (CANVAS_CONNECTION == null)
return null;
try {
return (Connection) CANVAS_CONNECTION.invoke(player.connection);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}

private static Collection<Connection> getCanvasRegionConnections(ServerLevel level) {
if (CANVAS_CURRENT_WORLD_DATA == null || CANVAS_REGION_CONNECTIONS == null)
return null;
try {
return (Collection<Connection>) CANVAS_REGION_CONNECTIONS.invoke(CANVAS_CURRENT_WORLD_DATA.invoke(level));
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}

@Override
public void addOrRemoveFromPlayerList(org.bukkit.entity.Entity entity, boolean remove) {
if (entity == null)
Expand Down Expand Up @@ -2941,6 +2976,13 @@ public <U> void acceptEmpty(MemoryModuleType<U> type) {
private static final MethodHandle BRAIN_SENSORS_GETTER = NMS.getGetter(Brain.class, "sensors");
private static final MethodHandle BRAIN_SETTER = NMS.getFirstSetter(LivingEntity.class, Brain.class);
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
private static final MethodHandle CANVAS_CONNECTION = "Canvas".equals(Bukkit.getName())
? NMS.getGetter(ServerGamePacketListenerImpl.class.getSuperclass(), "connection", false)
: null;
private static final MethodHandle CANVAS_CURRENT_WORLD_DATA = "Canvas".equals(Bukkit.getName())
? NMS.getMethodHandle(Level.class, "getCurrentWorldData", false)
: null;
private static final MethodHandle CANVAS_REGION_CONNECTIONS = loadCanvasRegionConnectionsGetter();
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class,
"updatePlayerStatus", true, ServerPlayer.class, boolean.class);
private static final MethodHandle CLIENT_LOADED_TIMEOUT_TIMER = NMS.getSetter(ServerGamePacketListenerImpl.class,
Expand Down Expand Up @@ -3032,6 +3074,17 @@ public <U> void acceptEmpty(MemoryModuleType<U> type) {
public static final MethodHandle WAITING_FOR_RESPAWN = NMS.getSetter(ServerGamePacketListenerImpl.class,
"waitingForRespawn");

private static MethodHandle loadCanvasRegionConnectionsGetter() {
if (!"Canvas".equals(Bukkit.getName()))
return null;
try {
return NMS.getGetter(Class.forName("io.papermc.paper.threadedregions.RegionizedWorldData"), "connections",
false);
} catch (ClassNotFoundException e) {
return null;
}
}

static {
if (NMS.getMethodHandle(CraftBlock.class, "getNMS", false) != null) {
GET_BLOCK_STATE = NMS.getMethodHandle(CraftBlock.class, "getNMS", false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ protected Entity createEntity(final Location at, final NPC npc) {
final GameProfile profile = new GameProfile(uuid, name);
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile,
ClientInformation.createDefault(), npc);
handle.absSnapTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
Skin skin = handle.getSkinTracker().getSkin();
if (skin != null) {
skin.apply(handle);
Expand Down