aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch650
1 files changed, 650 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
new file mode 100644
index 0000000000..cf76deaf1e
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch
@@ -0,0 +1,650 @@
+--- a/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
++++ b/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+@@ -5,18 +5,21 @@
+ import com.google.common.collect.Sets;
+ import com.mojang.logging.LogUtils;
+ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
++import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
+ import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
+ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
+ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+ import it.unimi.dsi.fastutil.longs.LongSet;
+-import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
++import it.unimi.dsi.fastutil.objects.ObjectIterator;
+ import java.io.IOException;
+ import java.io.UncheckedIOException;
+ import java.io.Writer;
+ import java.util.List;
++import java.util.Objects;
+ import java.util.Queue;
+ import java.util.Set;
+ import java.util.UUID;
++import java.util.concurrent.CompletableFuture;
+ import java.util.function.Consumer;
+ import java.util.stream.Collectors;
+ import java.util.stream.Stream;
+@@ -26,41 +29,56 @@
+ import net.minecraft.util.CsvOutput;
+ import net.minecraft.util.VisibleForDebug;
+ import net.minecraft.world.entity.Entity;
+-import net.minecraft.world.level.ChunkPos;
+ import org.slf4j.Logger;
++import net.minecraft.world.level.ChunkPos;
++// CraftBukkit start
++import net.minecraft.world.level.chunk.storage.EntityStorage;
++import org.bukkit.craftbukkit.event.CraftEventFactory;
++// CraftBukkit end
+
+ public class PersistentEntitySectionManager<T extends EntityAccess> implements AutoCloseable {
++
+ static final Logger LOGGER = LogUtils.getLogger();
+ final Set<UUID> knownUuids = Sets.newHashSet();
+ final LevelCallback<T> callbacks;
+- private final EntityPersistentStorage<T> permanentStorage;
+- private final EntityLookup<T> visibleEntityStorage;
++ public final EntityPersistentStorage<T> permanentStorage;
++ private final EntityLookup<T> visibleEntityStorage = new EntityLookup<>();
+ final EntitySectionStorage<T> sectionStorage;
+ private final LevelEntityGetter<T> entityGetter;
+- private final Long2ObjectMap<Visibility> chunkVisibility = new Long2ObjectOpenHashMap<>();
+- private final Long2ObjectMap<PersistentEntitySectionManager.ChunkLoadStatus> chunkLoadStatuses = new Long2ObjectOpenHashMap<>();
++ private final Long2ObjectMap<Visibility> chunkVisibility = new Long2ObjectOpenHashMap();
++ private final Long2ObjectMap<PersistentEntitySectionManager.b> chunkLoadStatuses = new Long2ObjectOpenHashMap();
+ private final LongSet chunksToUnload = new LongOpenHashSet();
+ private final Queue<ChunkEntities<T>> loadingInbox = Queues.newConcurrentLinkedQueue();
+
+ public PersistentEntitySectionManager(Class<T> entityClass, LevelCallback<T> callbacks, EntityPersistentStorage<T> permanentStorage) {
+- this.visibleEntityStorage = new EntityLookup<>();
+ this.sectionStorage = new EntitySectionStorage<>(entityClass, this.chunkVisibility);
+ this.chunkVisibility.defaultReturnValue(Visibility.HIDDEN);
+- this.chunkLoadStatuses.defaultReturnValue(PersistentEntitySectionManager.ChunkLoadStatus.FRESH);
++ this.chunkLoadStatuses.defaultReturnValue(PersistentEntitySectionManager.b.FRESH);
+ this.callbacks = callbacks;
+ this.permanentStorage = permanentStorage;
+ this.entityGetter = new LevelEntityGetterAdapter<>(this.visibleEntityStorage, this.sectionStorage);
+ }
+
+- void removeSectionIfEmpty(long sectionKey, EntitySection<T> section) {
+- if (section.isEmpty()) {
++ // CraftBukkit start - add method to get all entities in chunk
++ public List<Entity> getEntities(ChunkPos chunkCoordIntPair) {
++ return sectionStorage.getExistingSectionsInChunk(chunkCoordIntPair.toLong()).flatMap(EntitySection::getEntities).map(entity -> (Entity) entity).collect(Collectors.toList());
++ }
++
++ public boolean isPending(long pair) {
++ return chunkLoadStatuses.get(pair) == b.PENDING;
++ }
++ // CraftBukkit end
++
++ void removeSectionIfEmpty(long sectionKey, EntitySection<T> entitysection) {
++ if (entitysection.isEmpty()) {
+ this.sectionStorage.remove(sectionKey);
+ }
++
+ }
+
+ private boolean addEntityUuid(T entity) {
+ if (!this.knownUuids.add(entity.getUUID())) {
+- LOGGER.warn("UUID of added entity already exists: {}", entity);
++ PersistentEntitySectionManager.LOGGER.warn("UUID of added entity already exists: {}", entity);
+ return false;
+ } else {
+ return true;
+@@ -75,20 +93,22 @@
+ if (!this.addEntityUuid(entity)) {
+ return false;
+ } else {
+- long _long = SectionPos.asLong(entity.blockPosition());
+- EntitySection<T> section = this.sectionStorage.getOrCreateSection(_long);
+- section.add(entity);
+- entity.setLevelCallback(new PersistentEntitySectionManager.Callback(entity, _long, section));
++ long i = SectionPos.asLong(entity.blockPosition());
++ EntitySection<T> entitysection = this.sectionStorage.getOrCreateSection(i);
++
++ entitysection.add(entity);
++ entity.setLevelCallback(new PersistentEntitySectionManager.Callback(entity, i, entitysection));
+ if (!worldGenSpawned) {
+ this.callbacks.onCreated(entity);
+ }
+
+- Visibility effectiveStatus = getEffectiveStatus(entity, section.getStatus());
+- if (effectiveStatus.isAccessible()) {
++ Visibility visibility = getEffectiveStatus(entity, entitysection.getStatus());
++
++ if (visibility.isAccessible()) {
+ this.startTracking(entity);
+ }
+
+- if (effectiveStatus.isTicking()) {
++ if (visibility.isTicking()) {
+ this.startTicking(entity);
+ }
+
+@@ -101,11 +121,15 @@
+ }
+
+ public void addLegacyChunkEntities(Stream<T> entities) {
+- entities.forEach(entity -> this.addEntity((T)entity, true));
++ entities.forEach((entityaccess) -> {
++ this.addEntity(entityaccess, true);
++ });
+ }
+
+ public void addWorldGenChunkEntities(Stream<T> entities) {
+- entities.forEach(entity -> this.addEntity((T)entity, false));
++ entities.forEach((entityaccess) -> {
++ this.addEntity(entityaccess, false);
++ });
+ }
+
+ void startTicking(T entity) {
+@@ -128,86 +152,116 @@
+
+ public void updateChunkStatus(ChunkPos chunkPos, FullChunkStatus fullChunkStatus) {
+ Visibility visibility = Visibility.fromFullChunkStatus(fullChunkStatus);
++
+ this.updateChunkStatus(chunkPos, visibility);
+ }
+
+ public void updateChunkStatus(ChunkPos pos, Visibility visibility) {
+- long l = pos.toLong();
++ long i = pos.toLong();
++
+ if (visibility == Visibility.HIDDEN) {
+- this.chunkVisibility.remove(l);
+- this.chunksToUnload.add(l);
++ this.chunkVisibility.remove(i);
++ this.chunksToUnload.add(i);
+ } else {
+- this.chunkVisibility.put(l, visibility);
+- this.chunksToUnload.remove(l);
+- this.ensureChunkQueuedForLoad(l);
++ this.chunkVisibility.put(i, visibility);
++ this.chunksToUnload.remove(i);
++ this.ensureChunkQueuedForLoad(i);
+ }
+
+- this.sectionStorage.getExistingSectionsInChunk(l).forEach(entitySection -> {
+- Visibility visibility1 = entitySection.updateChunkStatus(visibility);
+- boolean isAccessible = visibility1.isAccessible();
+- boolean isAccessible1 = visibility.isAccessible();
+- boolean isTicking = visibility1.isTicking();
+- boolean isTicking1 = visibility.isTicking();
+- if (isTicking && !isTicking1) {
+- entitySection.getEntities().filter(entity -> !entity.isAlwaysTicking()).forEach(this::stopTicking);
++ this.sectionStorage.getExistingSectionsInChunk(i).forEach((entitysection) -> {
++ Visibility visibility1 = entitysection.updateChunkStatus(visibility);
++ boolean flag = visibility1.isAccessible();
++ boolean flag1 = visibility.isAccessible();
++ boolean flag2 = visibility1.isTicking();
++ boolean flag3 = visibility.isTicking();
++
++ if (flag2 && !flag3) {
++ entitysection.getEntities().filter((entityaccess) -> {
++ return !entityaccess.isAlwaysTicking();
++ }).forEach(this::stopTicking);
+ }
+
+- if (isAccessible && !isAccessible1) {
+- entitySection.getEntities().filter(entity -> !entity.isAlwaysTicking()).forEach(this::stopTracking);
+- } else if (!isAccessible && isAccessible1) {
+- entitySection.getEntities().filter(entity -> !entity.isAlwaysTicking()).forEach(this::startTracking);
++ if (flag && !flag1) {
++ entitysection.getEntities().filter((entityaccess) -> {
++ return !entityaccess.isAlwaysTicking();
++ }).forEach(this::stopTracking);
++ } else if (!flag && flag1) {
++ entitysection.getEntities().filter((entityaccess) -> {
++ return !entityaccess.isAlwaysTicking();
++ }).forEach(this::startTracking);
+ }
+
+- if (!isTicking && isTicking1) {
+- entitySection.getEntities().filter(entity -> !entity.isAlwaysTicking()).forEach(this::startTicking);
++ if (!flag2 && flag3) {
++ entitysection.getEntities().filter((entityaccess) -> {
++ return !entityaccess.isAlwaysTicking();
++ }).forEach(this::startTicking);
+ }
++
+ });
+ }
+
+- private void ensureChunkQueuedForLoad(long chunkPosValue) {
+- PersistentEntitySectionManager.ChunkLoadStatus chunkLoadStatus = this.chunkLoadStatuses.get(chunkPosValue);
+- if (chunkLoadStatus == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
++ public void ensureChunkQueuedForLoad(long chunkPosValue) {
++ PersistentEntitySectionManager.b persistententitysectionmanager_b = (PersistentEntitySectionManager.b) this.chunkLoadStatuses.get(chunkPosValue);
++
++ if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.FRESH) {
+ this.requestChunkLoad(chunkPosValue);
+ }
++
+ }
+
+- private boolean storeChunkSections(long chunkPosValue, Consumer<T> entityAction) {
+- PersistentEntitySectionManager.ChunkLoadStatus chunkLoadStatus = this.chunkLoadStatuses.get(chunkPosValue);
+- if (chunkLoadStatus == PersistentEntitySectionManager.ChunkLoadStatus.PENDING) {
++ private boolean storeChunkSections(long chunkPosValue, Consumer<T> consumer) {
++ // CraftBukkit start - add boolean for event call
++ return storeChunkSections(chunkPosValue, consumer, false);
++ }
++
++ private boolean storeChunkSections(long i, Consumer<T> consumer, boolean callEvent) {
++ // CraftBukkit end
++ PersistentEntitySectionManager.b persistententitysectionmanager_b = (PersistentEntitySectionManager.b) this.chunkLoadStatuses.get(i);
++
++ if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.PENDING) {
+ return false;
+ } else {
+- List<T> list = this.sectionStorage
+- .getExistingSectionsInChunk(chunkPosValue)
+- .flatMap(entitySection -> entitySection.getEntities().filter(EntityAccess::shouldBeSaved))
+- .collect(Collectors.toList());
++ List<T> list = (List) this.sectionStorage.getExistingSectionsInChunk(i).flatMap((entitysection) -> {
++ return entitysection.getEntities().filter(EntityAccess::shouldBeSaved);
++ }).collect(Collectors.toList());
++
+ if (list.isEmpty()) {
+- if (chunkLoadStatus == PersistentEntitySectionManager.ChunkLoadStatus.LOADED) {
+- this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkPos(chunkPosValue), ImmutableList.of()));
++ if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.LOADED) {
++ if (callEvent) CraftEventFactory.callEntitiesUnloadEvent(((EntityStorage) permanentStorage).level, new ChunkPos(i), ImmutableList.of()); // CraftBukkit
++ this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkPos(i), ImmutableList.of()));
+ }
+
+ return true;
+- } else if (chunkLoadStatus == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
+- this.requestChunkLoad(chunkPosValue);
++ } else if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.FRESH) {
++ this.requestChunkLoad(i);
+ return false;
+ } else {
+- this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkPos(chunkPosValue), list));
+- list.forEach(entityAction);
++ if (callEvent) CraftEventFactory.callEntitiesUnloadEvent(((EntityStorage) permanentStorage).level, new ChunkPos(i), list.stream().map(entity -> (Entity) entity).collect(Collectors.toList())); // CraftBukkit
++ this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkPos(i), list));
++ list.forEach(consumer);
+ return true;
+ }
+ }
+ }
+
+ private void requestChunkLoad(long chunkPosValue) {
+- this.chunkLoadStatuses.put(chunkPosValue, PersistentEntitySectionManager.ChunkLoadStatus.PENDING);
+- ChunkPos chunkPos = new ChunkPos(chunkPosValue);
+- this.permanentStorage.loadEntities(chunkPos).thenAccept(this.loadingInbox::add).exceptionally(throwable -> {
+- LOGGER.error("Failed to read chunk {}", chunkPos, throwable);
++ this.chunkLoadStatuses.put(chunkPosValue, PersistentEntitySectionManager.b.PENDING);
++ ChunkPos chunkcoordintpair = new ChunkPos(chunkPosValue);
++ CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair);
++ Queue queue = this.loadingInbox;
++
++ Objects.requireNonNull(this.loadingInbox);
++ completablefuture.thenAccept(queue::add).exceptionally((throwable) -> {
++ PersistentEntitySectionManager.LOGGER.error("Failed to read chunk {}", chunkcoordintpair, throwable);
+ return null;
+ });
+ }
+
+ private boolean processChunkUnload(long chunkPosValue) {
+- boolean flag = this.storeChunkSections(chunkPosValue, entity -> entity.getPassengersAndSelf().forEach(this::unloadEntity));
++ boolean flag = this.storeChunkSections(chunkPosValue, (entityaccess) -> {
++ entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
++ }, true); // CraftBukkit - add boolean for event call
++
+ if (!flag) {
+ return false;
+ } else {
+@@ -222,16 +276,25 @@
+ }
+
+ private void processUnloads() {
+- this.chunksToUnload
+- .removeIf(packedChunkPos -> this.chunkVisibility.get(packedChunkPos) != Visibility.HIDDEN || this.processChunkUnload(packedChunkPos));
++ this.chunksToUnload.removeIf((java.util.function.LongPredicate) (i) -> { // CraftBukkit - decompile error
++ return this.chunkVisibility.get(i) != Visibility.HIDDEN ? true : this.processChunkUnload(i);
++ });
+ }
+
+ private void processPendingLoads() {
+- ChunkEntities<T> chunkEntities;
+- while ((chunkEntities = this.loadingInbox.poll()) != null) {
+- chunkEntities.getEntities().forEach(entity -> this.addEntity((T)entity, true));
+- this.chunkLoadStatuses.put(chunkEntities.getPos().toLong(), PersistentEntitySectionManager.ChunkLoadStatus.LOADED);
++ ChunkEntities<T> chunkentities; // CraftBukkit - decompile error
++
++ while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) {
++ chunkentities.getEntities().forEach((entityaccess) -> {
++ this.addEntity(entityaccess, true);
++ });
++ this.chunkLoadStatuses.put(chunkentities.getPos().toLong(), PersistentEntitySectionManager.b.LOADED);
++ // CraftBukkit start - call entity load event
++ List<Entity> entities = getEntities(chunkentities.getPos());
++ CraftEventFactory.callEntitiesLoadEvent(((EntityStorage) permanentStorage).level, chunkentities.getPos(), entities);
++ // CraftBukkit end
+ }
++
+ }
+
+ public void tick() {
+@@ -240,38 +303,44 @@
+ }
+
+ private LongSet getAllChunksToSave() {
+- LongSet allChunksWithExistingSections = this.sectionStorage.getAllChunksWithExistingSections();
++ LongSet longset = this.sectionStorage.getAllChunksWithExistingSections();
++ ObjectIterator objectiterator = Long2ObjectMaps.fastIterable(this.chunkLoadStatuses).iterator();
+
+- for (Entry<PersistentEntitySectionManager.ChunkLoadStatus> entry : Long2ObjectMaps.fastIterable(this.chunkLoadStatuses)) {
+- if (entry.getValue() == PersistentEntitySectionManager.ChunkLoadStatus.LOADED) {
+- allChunksWithExistingSections.add(entry.getLongKey());
++ while (objectiterator.hasNext()) {
++ Entry<PersistentEntitySectionManager.b> entry = (Entry) objectiterator.next();
++
++ if (entry.getValue() == PersistentEntitySectionManager.b.LOADED) {
++ longset.add(entry.getLongKey());
+ }
+ }
+
+- return allChunksWithExistingSections;
++ return longset;
+ }
+
+ public void autoSave() {
+- this.getAllChunksToSave().forEach(packedChunkPos -> {
+- boolean flag = this.chunkVisibility.get(packedChunkPos) == Visibility.HIDDEN;
++ this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
++ boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
++
+ if (flag) {
+- this.processChunkUnload(packedChunkPos);
++ this.processChunkUnload(i);
+ } else {
+- this.storeChunkSections(packedChunkPos, entity -> {
++ this.storeChunkSections(i, (entityaccess) -> {
+ });
+ }
++
+ });
+ }
+
+ public void saveAll() {
+- LongSet allChunksToSave = this.getAllChunksToSave();
++ LongSet longset = this.getAllChunksToSave();
+
+- while (!allChunksToSave.isEmpty()) {
++ while (!longset.isEmpty()) {
+ this.permanentStorage.flush(false);
+ this.processPendingLoads();
+- allChunksToSave.removeIf(packedChunkPos -> {
+- boolean flag = this.chunkVisibility.get(packedChunkPos) == Visibility.HIDDEN;
+- return flag ? this.processChunkUnload(packedChunkPos) : this.storeChunkSections(packedChunkPos, entity -> {
++ longset.removeIf((java.util.function.LongPredicate) (i) -> { // CraftBukkit - decompile error
++ boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
++
++ return flag ? this.processChunkUnload(i) : this.storeChunkSections(i, (entityaccess) -> {
+ });
+ });
+ }
+@@ -279,9 +348,16 @@
+ this.permanentStorage.flush(true);
+ }
+
+- @Override
+ public void close() throws IOException {
+- this.saveAll();
++ // CraftBukkit start - add save boolean
++ close(true);
++ }
++
++ public void close(boolean save) throws IOException {
++ if (save) {
++ this.saveAll();
++ }
++ // CraftBukkit end
+ this.permanentStorage.close();
+ }
+
+@@ -294,71 +370,43 @@
+ }
+
+ public boolean canPositionTick(BlockPos pos) {
+- return this.chunkVisibility.get(ChunkPos.asLong(pos)).isTicking();
++ return ((Visibility) this.chunkVisibility.get(ChunkPos.asLong(pos))).isTicking();
+ }
+
+ public boolean canPositionTick(ChunkPos chunkPos) {
+- return this.chunkVisibility.get(chunkPos.toLong()).isTicking();
++ return ((Visibility) this.chunkVisibility.get(chunkPos.toLong())).isTicking();
+ }
+
+ public boolean areEntitiesLoaded(long chunkPos) {
+- return this.chunkLoadStatuses.get(chunkPos) == PersistentEntitySectionManager.ChunkLoadStatus.LOADED;
++ return this.chunkLoadStatuses.get(chunkPos) == PersistentEntitySectionManager.b.LOADED;
+ }
+
+ public void dumpSections(Writer writer) throws IOException {
+- CsvOutput csvOutput = CsvOutput.builder()
+- .addColumn("x")
+- .addColumn("y")
+- .addColumn("z")
+- .addColumn("visibility")
+- .addColumn("load_status")
+- .addColumn("entity_count")
+- .build(writer);
+- this.sectionStorage
+- .getAllChunksWithExistingSections()
+- .forEach(
+- packedChunkPos -> {
+- PersistentEntitySectionManager.ChunkLoadStatus chunkLoadStatus = this.chunkLoadStatuses.get(packedChunkPos);
+- this.sectionStorage
+- .getExistingSectionPositionsInChunk(packedChunkPos)
+- .forEach(
+- packedSectionPos -> {
+- EntitySection<T> section = this.sectionStorage.getSection(packedSectionPos);
+- if (section != null) {
+- try {
+- csvOutput.writeRow(
+- SectionPos.x(packedSectionPos),
+- SectionPos.y(packedSectionPos),
+- SectionPos.z(packedSectionPos),
+- section.getStatus(),
+- chunkLoadStatus,
+- section.size()
+- );
+- } catch (IOException var7) {
+- throw new UncheckedIOException(var7);
+- }
+- }
+- }
+- );
++ CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("visibility").addColumn("load_status").addColumn("entity_count").build(writer);
++
++ this.sectionStorage.getAllChunksWithExistingSections().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
++ PersistentEntitySectionManager.b persistententitysectionmanager_b = (PersistentEntitySectionManager.b) this.chunkLoadStatuses.get(i);
++
++ this.sectionStorage.getExistingSectionPositionsInChunk(i).forEach((j) -> {
++ EntitySection<T> entitysection = this.sectionStorage.getSection(j);
++
++ if (entitysection != null) {
++ try {
++ csvwriter.writeRow(SectionPos.x(j), SectionPos.y(j), SectionPos.z(j), entitysection.getStatus(), persistententitysectionmanager_b, entitysection.size());
++ } catch (IOException ioexception) {
++ throw new UncheckedIOException(ioexception);
++ }
+ }
+- );
++
++ });
++ });
+ }
+
+ @VisibleForDebug
+ public String gatherStats() {
+- return this.knownUuids.size()
+- + ","
+- + this.visibleEntityStorage.count()
+- + ","
+- + this.sectionStorage.count()
+- + ","
+- + this.chunkLoadStatuses.size()
+- + ","
+- + this.chunkVisibility.size()
+- + ","
+- + this.loadingInbox.size()
+- + ","
+- + this.chunksToUnload.size();
++ int i = this.knownUuids.size();
++
++ return i + "," + this.visibleEntityStorage.count() + "," + this.sectionStorage.count() + "," + this.chunkLoadStatuses.size() + "," + this.chunkVisibility.size() + "," + this.loadingInbox.size() + "," + this.chunksToUnload.size();
+ }
+
+ @VisibleForDebug
+@@ -366,80 +414,96 @@
+ return this.visibleEntityStorage.count();
+ }
+
+- class Callback implements EntityInLevelCallback {
++ private static enum b {
++
++ FRESH, PENDING, LOADED;
++
++ private b() {}
++ }
++
++ private class Callback implements EntityInLevelCallback {
++
+ private final T entity;
+ private long currentSectionKey;
+ private EntitySection<T> currentSection;
+
+- Callback(T entity, long currentSectionKey, EntitySection<T> currentSection) {
+- this.entity = entity;
+- this.currentSectionKey = currentSectionKey;
+- this.currentSection = currentSection;
++ Callback(EntityAccess entityaccess, long i, EntitySection entitysection) {
++ this.entity = (T) entityaccess; // CraftBukkit - decompile error
++ this.currentSectionKey = i;
++ this.currentSection = entitysection;
+ }
+
+ @Override
+ public void onMove() {
+- BlockPos blockPos = this.entity.blockPosition();
+- long _long = SectionPos.asLong(blockPos);
+- if (_long != this.currentSectionKey) {
+- Visibility status = this.currentSection.getStatus();
++ BlockPos blockposition = this.entity.blockPosition();
++ long i = SectionPos.asLong(blockposition);
++
++ if (i != this.currentSectionKey) {
++ Visibility visibility = this.currentSection.getStatus();
++
+ if (!this.currentSection.remove(this.entity)) {
+- PersistentEntitySectionManager.LOGGER
+- .warn("Entity {} wasn't found in section {} (moving to {})", this.entity, SectionPos.of(this.currentSectionKey), _long);
++ PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (moving to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), i});
+ }
+
+ PersistentEntitySectionManager.this.removeSectionIfEmpty(this.currentSectionKey, this.currentSection);
+- EntitySection<T> section = PersistentEntitySectionManager.this.sectionStorage.getOrCreateSection(_long);
+- section.add(this.entity);
+- this.currentSection = section;
+- this.currentSectionKey = _long;
+- this.updateStatus(status, section.getStatus());
++ EntitySection<T> entitysection = PersistentEntitySectionManager.this.sectionStorage.getOrCreateSection(i);
++
++ entitysection.add(this.entity);
++ this.currentSection = entitysection;
++ this.currentSectionKey = i;
++ this.updateStatus(visibility, entitysection.getStatus());
+ }
++
+ }
+
+ private void updateStatus(Visibility oldVisibility, Visibility newVisibility) {
+- Visibility effectiveStatus = PersistentEntitySectionManager.getEffectiveStatus(this.entity, oldVisibility);
+- Visibility effectiveStatus1 = PersistentEntitySectionManager.getEffectiveStatus(this.entity, newVisibility);
+- if (effectiveStatus == effectiveStatus1) {
+- if (effectiveStatus1.isAccessible()) {
++ Visibility visibility2 = PersistentEntitySectionManager.getEffectiveStatus(this.entity, oldVisibility);
++ Visibility visibility3 = PersistentEntitySectionManager.getEffectiveStatus(this.entity, newVisibility);
++
++ if (visibility2 == visibility3) {
++ if (visibility3.isAccessible()) {
+ PersistentEntitySectionManager.this.callbacks.onSectionChange(this.entity);
+ }
++
+ } else {
+- boolean isAccessible = effectiveStatus.isAccessible();
+- boolean isAccessible1 = effectiveStatus1.isAccessible();
+- if (isAccessible && !isAccessible1) {
++ boolean flag = visibility2.isAccessible();
++ boolean flag1 = visibility3.isAccessible();
++
++ if (flag && !flag1) {
+ PersistentEntitySectionManager.this.stopTracking(this.entity);
+- } else if (!isAccessible && isAccessible1) {
++ } else if (!flag && flag1) {
+ PersistentEntitySectionManager.this.startTracking(this.entity);
+ }
+
+- boolean isTicking = effectiveStatus.isTicking();
+- boolean isTicking1 = effectiveStatus1.isTicking();
+- if (isTicking && !isTicking1) {
++ boolean flag2 = visibility2.isTicking();
++ boolean flag3 = visibility3.isTicking();
++
++ if (flag2 && !flag3) {
+ PersistentEntitySectionManager.this.stopTicking(this.entity);
+- } else if (!isTicking && isTicking1) {
++ } else if (!flag2 && flag3) {
+ PersistentEntitySectionManager.this.startTicking(this.entity);
+ }
+
+- if (isAccessible1) {
++ if (flag1) {
+ PersistentEntitySectionManager.this.callbacks.onSectionChange(this.entity);
+ }
++
+ }
+ }
+
+ @Override
+ public void onRemove(Entity.RemovalReason reason) {
+ if (!this.currentSection.remove(this.entity)) {
+- PersistentEntitySectionManager.LOGGER
+- .warn("Entity {} wasn't found in section {} (destroying due to {})", this.entity, SectionPos.of(this.currentSectionKey), reason);
++ PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
+ }
+
+- Visibility effectiveStatus = PersistentEntitySectionManager.getEffectiveStatus(this.entity, this.currentSection.getStatus());
+- if (effectiveStatus.isTicking()) {
++ Visibility visibility = PersistentEntitySectionManager.getEffectiveStatus(this.entity, this.currentSection.getStatus());
++
++ if (visibility.isTicking()) {
+ PersistentEntitySectionManager.this.stopTicking(this.entity);
+ }
+
+- if (effectiveStatus.isAccessible()) {
++ if (visibility.isAccessible()) {
+ PersistentEntitySectionManager.this.stopTracking(this.entity);
+ }
+
+@@ -448,14 +512,8 @@
+ }
+
+ PersistentEntitySectionManager.this.knownUuids.remove(this.entity.getUUID());
+- this.entity.setLevelCallback(NULL);
++ this.entity.setLevelCallback(PersistentEntitySectionManager.Callback.NULL);
+ PersistentEntitySectionManager.this.removeSectionIfEmpty(this.currentSectionKey, this.currentSection);
+ }
+ }
+-
+- static enum ChunkLoadStatus {
+- FRESH,
+- PENDING,
+- LOADED;
+- }
+ }