aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch')
-rw-r--r--patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch341
1 files changed, 0 insertions, 341 deletions
diff --git a/patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch b/patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch
deleted file mode 100644
index adb2952c99..0000000000
--- a/patches/unapplied/server/1012-Use-distance-map-to-optimise-entity-tracker.patch
+++ /dev/null
@@ -1,341 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Tue, 5 May 2020 20:18:05 -0700
-Subject: [PATCH] Use distance map to optimise entity tracker
-
-Use the distance map to find candidate players for tracking.
-
-diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 4621c33ed73b0db64e78e7b9be7013a2ba7393c8..48f7997e8a20f5a5a77516cbde990d0aacc2078a 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -149,6 +149,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- // Paper start - distance maps
- private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
-+ // Paper start - use distance map to optimise tracker
-+ public static boolean isLegacyTrackingEntity(Entity entity) {
-+ return entity.isLegacyTrackingEntity;
-+ }
-+
-+ // inlined EnumMap, TrackingRange.TrackingRangeType
-+ static final org.spigotmc.TrackingRange.TrackingRangeType[] TRACKING_RANGE_TYPES = org.spigotmc.TrackingRange.TrackingRangeType.values();
-+ public final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps;
-+ final int[] entityTrackerTrackRanges;
-+ public final int getEntityTrackerRange(final int ordinal) {
-+ return this.entityTrackerTrackRanges[ordinal];
-+ }
-+
-+ private int convertSpigotRangeToVanilla(final int vanilla) {
-+ return net.minecraft.server.MinecraftServer.getServer().getScaledTrackingDistance(vanilla);
-+ }
-+ // Paper end - use distance map to optimise tracker
-
- void addPlayerToDistanceMaps(ServerPlayer player) {
- int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX());
-@@ -156,6 +173,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- // Note: players need to be explicitly added to distance maps before they can be updated
- this.nearbyPlayers.addPlayer(player);
- this.level.playerChunkLoader.addPlayer(player); // Paper - replace chunk loader
-+ // Paper start - use distance map to optimise entity tracker
-+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
-+ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i];
-+ int trackRange = this.entityTrackerTrackRanges[i];
-+
-+ trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player)));
-+ }
-+ // Paper end - use distance map to optimise entity tracker
- }
-
- void removePlayerFromDistanceMaps(ServerPlayer player) {
-@@ -164,6 +189,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- // Note: players need to be explicitly added to distance maps before they can be updated
- this.nearbyPlayers.removePlayer(player);
- this.level.playerChunkLoader.removePlayer(player); // Paper - replace chunk loader
-+ // Paper start - use distance map to optimise tracker
-+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
-+ this.playerEntityTrackerTrackMaps[i].remove(player);
-+ }
-+ // Paper end - use distance map to optimise tracker
- }
-
- void updateMaps(ServerPlayer player) {
-@@ -172,6 +202,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- // Note: players need to be explicitly added to distance maps before they can be updated
- this.nearbyPlayers.tickPlayer(player);
- this.level.playerChunkLoader.updatePlayer(player); // Paper - replace chunk loader
-+ // Paper start - use distance map to optimise entity tracker
-+ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) {
-+ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i];
-+ int trackRange = this.entityTrackerTrackRanges[i];
-+
-+ trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(player)));
-+ }
-+ // Paper end - use distance map to optimise entity tracker
- }
- // Paper end
- // Paper start
-@@ -258,6 +296,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- this.regionManagers.add(this.dataRegionManager);
- this.nearbyPlayers = new io.papermc.paper.util.player.NearbyPlayers(this.level);
- // Paper end
-+ // Paper start - use distance map to optimise entity tracker
-+ this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length];
-+ this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length];
-+
-+ org.spigotmc.SpigotWorldConfig spigotWorldConfig = this.level.spigotConfig;
-+
-+ for (int ordinal = 0, len = TRACKING_RANGE_TYPES.length; ordinal < len; ++ordinal) {
-+ org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = TRACKING_RANGE_TYPES[ordinal];
-+ int configuredSpigotValue;
-+ switch (trackingRangeType) {
-+ case PLAYER:
-+ configuredSpigotValue = spigotWorldConfig.playerTrackingRange;
-+ break;
-+ case ANIMAL:
-+ configuredSpigotValue = spigotWorldConfig.animalTrackingRange;
-+ break;
-+ case MONSTER:
-+ configuredSpigotValue = spigotWorldConfig.monsterTrackingRange;
-+ break;
-+ case MISC:
-+ configuredSpigotValue = spigotWorldConfig.miscTrackingRange;
-+ break;
-+ case OTHER:
-+ configuredSpigotValue = spigotWorldConfig.otherTrackingRange;
-+ break;
-+ case ENDERDRAGON:
-+ configuredSpigotValue = EntityType.ENDER_DRAGON.clientTrackingRange() * 16;
-+ break;
-+ case DISPLAY:
-+ configuredSpigotValue = spigotWorldConfig.displayTrackingRange;
-+ break;
-+ default:
-+ throw new IllegalStateException("Missing case for enum " + trackingRangeType);
-+ }
-+ configuredSpigotValue = convertSpigotRangeToVanilla(configuredSpigotValue);
-+
-+ int trackRange = (configuredSpigotValue >>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0);
-+ this.entityTrackerTrackRanges[ordinal] = trackRange;
-+
-+ this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets);
-+ }
-+ // Paper end - use distance map to optimise entity tracker
- }
-
- // Paper start
-@@ -951,17 +1031,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }
-
- public void move(ServerPlayer player) {
-- ObjectIterator objectiterator = this.entityMap.values().iterator();
--
-- while (objectiterator.hasNext()) {
-- ChunkMap.TrackedEntity playerchunkmap_entitytracker = (ChunkMap.TrackedEntity) objectiterator.next();
--
-- if (playerchunkmap_entitytracker.entity == player) {
-- playerchunkmap_entitytracker.updatePlayers(this.level.players());
-- } else {
-- playerchunkmap_entitytracker.updatePlayer(player);
-- }
-- }
-+ // Paper - delay this logic for the entity tracker tick, no need to duplicate it
-
- SectionPos sectionposition = player.getLastSectionPos();
- SectionPos sectionposition1 = SectionPos.of((EntityAccess) player);
-@@ -1038,7 +1108,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
- this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
-- playerchunkmap_entitytracker.updatePlayers(this.level.players());
-+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players
- if (entity instanceof ServerPlayer) {
- ServerPlayer entityplayer = (ServerPlayer) entity;
-
-@@ -1080,9 +1150,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- entity.tracker = null; // Paper - We're no longer tracked
- }
-
-- protected void tick() {
-- // Paper - replaced by PlayerChunkLoader
-+ // Paper start - optimised tracker
-+ private final void processTrackQueue() {
-+ this.level.timings.tracker1.startTiming();
-+ try {
-+ for (TrackedEntity tracker : this.entityMap.values()) {
-+ // update tracker entry
-+ tracker.updatePlayers(tracker.entity.getPlayersInTrackRange());
-+ }
-+ } finally {
-+ this.level.timings.tracker1.stopTiming();
-+ }
-+
-+
-+ this.level.timings.tracker2.startTiming();
-+ try {
-+ for (TrackedEntity tracker : this.entityMap.values()) {
-+ tracker.serverEntity.sendChanges();
-+ }
-+ } finally {
-+ this.level.timings.tracker2.stopTiming();
-+ }
-+ }
-+ // Paper end - optimised tracker
-
-+ protected void tick() {
-+ // Paper start - optimized tracker
-+ if (true) {
-+ this.processTrackQueue();
-+ return;
-+ }
-+ // Paper end - optimized tracker
- List<ServerPlayer> list = Lists.newArrayList();
- List<ServerPlayer> list1 = this.level.players();
- ObjectIterator objectiterator = this.entityMap.values().iterator();
-@@ -1230,6 +1328,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- this.lastSectionPos = SectionPos.of((EntityAccess) entity);
- }
-
-+ // Paper start - use distance map to optimise tracker
-+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;
-+
-+ final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) {
-+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
-+ this.lastTrackerCandidates = newTrackerCandidates;
-+
-+ if (newTrackerCandidates != null) {
-+ Object[] rawData = newTrackerCandidates.getBackingSet();
-+ for (int i = 0, len = rawData.length; i < len; ++i) {
-+ Object raw = rawData[i];
-+ if (!(raw instanceof ServerPlayer)) {
-+ continue;
-+ }
-+ ServerPlayer player = (ServerPlayer)raw;
-+ this.updatePlayer(player);
-+ }
-+ }
-+
-+ if (oldTrackerCandidates == newTrackerCandidates) {
-+ // this is likely the case.
-+ // means there has been no range changes, so we can just use the above for tracking.
-+ return;
-+ }
-+
-+ // stuff could have been removed, so we need to check the trackedPlayers set
-+ // for players that were removed
-+
-+ for (ServerPlayerConnection conn : this.seenBy.toArray(new ServerPlayerConnection[0])) { // avoid CME
-+ if (newTrackerCandidates == null || !newTrackerCandidates.contains(conn.getPlayer())) {
-+ this.updatePlayer(conn.getPlayer());
-+ }
-+ }
-+ }
-+ // Paper end - use distance map to optimise tracker
-+
- public boolean equals(Object object) {
- return object instanceof ChunkMap.TrackedEntity ? ((ChunkMap.TrackedEntity) object).entity.getId() == this.entity.getId() : false;
- }
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 26b21af65ff63c83fb3be80740e41b40f0feb944..030e20d1030c9e9c26b2bc456ff0b477a048cd03 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -59,6 +59,7 @@ import net.minecraft.network.syncher.SyncedDataHolder;
- import net.minecraft.network.syncher.SynchedEntityData;
- import net.minecraft.resources.ResourceKey;
- import net.minecraft.resources.ResourceLocation;
-+import io.papermc.paper.util.MCUtil;
- import net.minecraft.server.MinecraftServer;
- import net.minecraft.server.level.ServerLevel;
- import net.minecraft.server.level.ServerPlayer;
-@@ -470,6 +471,38 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- this.teleportTo(worldserver, null);
- }
- // Paper end - make end portalling safe
-+ // Paper start - optimise entity tracking
-+ final org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = org.spigotmc.TrackingRange.getTrackingRangeType(this);
-+
-+ public boolean isLegacyTrackingEntity = false;
-+
-+ public final void setLegacyTrackingEntity(final boolean isLegacyTrackingEntity) {
-+ this.isLegacyTrackingEntity = isLegacyTrackingEntity;
-+ }
-+
-+ public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> getPlayersInTrackRange() {
-+ // determine highest range of passengers
-+ if (this.passengers.isEmpty()) {
-+ return ((ServerLevel)this.level).getChunkSource().chunkMap.playerEntityTrackerTrackMaps[this.trackingRangeType.ordinal()]
-+ .getObjectsInRange(MCUtil.getCoordinateKey(this));
-+ }
-+ Iterable<Entity> passengers = this.getIndirectPassengers();
-+ net.minecraft.server.level.ChunkMap chunkMap = ((ServerLevel)this.level).getChunkSource().chunkMap;
-+ org.spigotmc.TrackingRange.TrackingRangeType type = this.trackingRangeType;
-+ int range = chunkMap.getEntityTrackerRange(type.ordinal());
-+
-+ for (Entity passenger : passengers) {
-+ org.spigotmc.TrackingRange.TrackingRangeType passengerType = passenger.trackingRangeType;
-+ int passengerRange = chunkMap.getEntityTrackerRange(passengerType.ordinal());
-+ if (passengerRange > range) {
-+ type = passengerType;
-+ range = passengerRange;
-+ }
-+ }
-+
-+ return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this));
-+ }
-+ // Paper end - optimise entity tracking
- public float getBukkitYaw() {
- return this.yRot;
- }
-diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java
-index bb06f89a29f30144e7e2113e088a503db006a83c..e4425b242fe73d1fd2bd10c313aa16925432329f 100644
---- a/src/main/java/org/spigotmc/TrackingRange.java
-+++ b/src/main/java/org/spigotmc/TrackingRange.java
-@@ -55,4 +55,48 @@ public class TrackingRange
- return config.otherTrackingRange;
- }
- }
-+
-+ // Paper start - optimise entity tracking
-+ // copied from above, TODO check on update
-+ public static TrackingRangeType getTrackingRangeType(Entity entity)
-+ {
-+ if (entity instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon) return TrackingRangeType.ENDERDRAGON; // Paper - enderdragon is exempt
-+ if ( entity instanceof ServerPlayer )
-+ {
-+ return TrackingRangeType.PLAYER;
-+ // Paper start - Simplify and set water mobs to animal tracking range
-+ }
-+ switch (entity.activationType) {
-+ case RAIDER:
-+ case MONSTER:
-+ case FLYING_MONSTER:
-+ return TrackingRangeType.MONSTER;
-+ case WATER:
-+ case VILLAGER:
-+ case ANIMAL:
-+ return TrackingRangeType.ANIMAL;
-+ case MISC:
-+ }
-+ if ( entity instanceof ItemFrame || entity instanceof Painting || entity instanceof ItemEntity || entity instanceof ExperienceOrb )
-+ // Paper end
-+ {
-+ return TrackingRangeType.MISC;
-+ } else if (entity instanceof Display) {
-+ return TrackingRangeType.DISPLAY;
-+ } else
-+ {
-+ return TrackingRangeType.OTHER;
-+ }
-+ }
-+
-+ public static enum TrackingRangeType {
-+ PLAYER,
-+ ANIMAL,
-+ MONSTER,
-+ MISC,
-+ OTHER,
-+ ENDERDRAGON,
-+ DISPLAY;
-+ }
-+ // Paper end - optimise entity tracking
- }