|
381 | 381 | } |
382 | 382 | } |
383 | 383 |
|
384 | | -@@ -1303,6 +_,177 @@ |
| 384 | +@@ -1303,6 +_,91 @@ |
385 | 385 | this.range = range; |
386 | 386 | this.lastSectionPos = SectionPos.of(entity); |
387 | 387 | } |
|
469 | 469 | + seenByLock.unlock(); |
470 | 470 | + } |
471 | 471 | + } |
472 | | -+ // ShreddedPaper end - maximum trackers per entity |
473 | | -+ |
474 | | -+ |
475 | | -+ // ShreddedPaper start - maximum trackers per entity |
476 | | -+ private record DistancedServerPlayer(ServerPlayer serverPlayer, double distanceSqr, boolean hasBypassPerm) implements Comparable<DistancedServerPlayer> { |
477 | | -+ DistancedServerPlayer(ServerPlayer serverPlayer, Entity entity) { |
478 | | -+ this(serverPlayer, distanceBetween(serverPlayer, entity), serverPlayer.hasMaximumTrackerBypassPermission); |
479 | | -+ } |
480 | | -+ |
481 | | -+ private static double distanceBetween(ServerPlayer serverPlayer, Entity entity) { |
482 | | -+ double vec3d_dx = serverPlayer.getX() - entity.getX(); |
483 | | -+ double vec3d_dz = serverPlayer.getZ() - entity.getZ(); |
484 | | -+ return vec3d_dx * vec3d_dx + vec3d_dz * vec3d_dz; |
485 | | -+ } |
486 | | -+ |
487 | | -+ @Override |
488 | | -+ public int compareTo(@NotNull ChunkMap.TrackedEntity.DistancedServerPlayer o) { |
489 | | -+ int compareResult = Double.compare(hasBypassPerm ? 0 : this.distanceSqr, o.hasBypassPerm ? 0 : o.distanceSqr); |
490 | | -+ return compareResult == 0 ? Integer.compare(this.serverPlayer.getId(), o.serverPlayer.getId()) : compareResult; |
491 | | -+ } |
492 | | -+ } |
493 | | -+ |
494 | | -+ public void updatePlayersLimitedAndOrdered(ca.spottedleaf.moonrise.common.list.ReferenceList<ServerPlayer> players, boolean hasTrackerCandidatesChanged, boolean fullTrackerUpdate) { |
495 | | -+ if (!hasTrackerCandidatesChanged && !fullTrackerUpdate) return; |
496 | | -+ |
497 | | -+ TreeSet<DistancedServerPlayer> playerSet = new TreeSet<>(); |
498 | | -+ final ServerPlayer[] playersRaw = players.getRawDataUnchecked(); |
499 | | -+ |
500 | | -+ for (int index = 0, len = players.size(); index < len; ++index) { |
501 | | -+ ServerPlayer player = playersRaw[index]; |
502 | | -+ if (player == null || player == this.entity) continue; |
503 | | -+ DistancedServerPlayer distancedPlayer = new DistancedServerPlayer(player, this.entity); |
504 | | -+ int i = ChunkMap.this.getPlayerViewDistance(player); |
505 | | -+ double d0 = (double) Math.min(this.getEffectiveRange(), i * 16); |
506 | | -+ double d2 = d0 * d0; |
507 | | -+ boolean flag = distancedPlayer.distanceSqr <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z); |
508 | | -+ // Paper start - Configurable entity tracking range by Y |
509 | | -+ if (flag && level.paperConfig().entities.trackingRangeY.enabled) { |
510 | | -+ double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1); |
511 | | -+ if (rangeY != -1) { |
512 | | -+ double vec3d_dy = player.getY() - this.entity.getY(); |
513 | | -+ flag = vec3d_dy * vec3d_dy <= rangeY * rangeY; |
514 | | -+ } |
515 | | -+ } |
516 | | -+ // Paper end - Configurable entity tracking range by Y |
517 | | -+ |
518 | | -+ // CraftBukkit start - respect vanish API |
519 | | -+ if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits |
520 | | -+ flag = false; |
521 | | -+ } |
522 | | -+ |
523 | | -+ if (flag) { |
524 | | -+ playerSet.add(distancedPlayer); |
525 | | -+ } |
526 | | -+ } |
527 | | -+ |
528 | | -+ seenByLock.lock(); |
529 | | -+ try { |
530 | | -+ Set<ServerPlayer> canBeSeenBy = new ReferenceOpenHashSet<>(Math.min(ShreddedPaperConfiguration.get().optimizations.maximumTrackersPerEntity, playerSet.size())); |
531 | | -+ java.util.Iterator<DistancedServerPlayer> playerSetIterator = playerSet.iterator(); |
532 | | -+ int count = 0; |
533 | | -+ while (playerSetIterator.hasNext() && count++ < ShreddedPaperConfiguration.get().optimizations.maximumTrackersPerEntity) { // ShreddedPaper - maximum trackers per entity |
534 | | -+ DistancedServerPlayer distancedPlayer = playerSetIterator.next(); |
535 | | -+ ServerPlayer player = distancedPlayer.serverPlayer(); |
536 | | -+ canBeSeenBy.add(player); |
537 | | -+ if (this.seenBy.add(player.connection)) { |
538 | | -+ // Paper start - entity tracking events |
539 | | -+ if (io.papermc.paper.event.player.PlayerTrackEntityEvent.getHandlerList().getRegisteredListeners().length == 0 || new io.papermc.paper.event.player.PlayerTrackEntityEvent(player.getBukkitEntity(), this.entity.getBukkitEntity()).callEvent()) { |
540 | | -+ this.serverEntity.addPairing(player); |
541 | | -+ } |
542 | | -+ // Paper end - entity tracking events |
543 | | -+ this.serverEntity.onPlayerAdd(); // Paper - fix desync when a player is added to the tracker |
544 | | -+ } |
545 | | -+ } |
546 | | -+ |
547 | | -+ if (this.seenBy.size() != canBeSeenBy.size()) { |
548 | | -+ for (ServerPlayerConnection conn : this.seenBy.toArray(new ServerPlayerConnection[0])) { // avoid CME |
549 | | -+ if (!canBeSeenBy.contains(conn.getPlayer()) && this.seenBy.remove(conn)) { |
550 | | -+ this.serverEntity.removePairing(conn.getPlayer()); |
551 | | -+ } |
552 | | -+ } |
553 | | -+ } |
554 | | -+ } finally { |
555 | | -+ seenByLock.unlock(); |
556 | | -+ } |
557 | | -+ } |
558 | 472 | + // ShreddedPaper end - maximum trackers per entity |
559 | 473 |
|
560 | 474 | @Override |
|
0 commit comments