LoadBlockSectionPacketSystem class

Пакет: com.hypixel.hytale.server.core.universe.world.chunk.section

Файл: com/hypixel/hytale/server/core/universe/world/chunk/section/BlockSection.java

extends: ChunkStore.LoadFuturePacketDataQuerySystem

Поля (4)

МодификаторыТипИмя
private final ComponentType<ChunkStore, BlockSection> componentType
private final Query<ChunkStore> query
BlockSection var7
ChunkSection var8

Методы (3)

МодификаторыВозвратСигнатура
public void fetchpublic void fetch(int var1, @Nonnull ArchetypeChunk<ChunkStore> var2, Store<ChunkStore> var3, CommandBuffer<ChunkStore> var4, PlayerRef var5, @Nonnull List<CompletableFuture<ToClientPacket>> var6)
public Query<ChunkStore> getQuerypublic Query<ChunkStore> getQuery()
if if(var1x != null)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world.chunk.section;

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.ExtraInfo;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.common.util.BitSetUtil;
class="kw">import com.hypixel.hytale.component.ArchetypeChunk;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Component;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.query.Query;
class="kw">import com.hypixel.hytale.function.consumer.BiIntConsumer;
class="kw">import com.hypixel.hytale.function.predicate.ObjectPositionBlockFunction;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.protocol.CachedPacket;
class="kw">import com.hypixel.hytale.protocol.ToClientPacket;
class="kw">import com.hypixel.hytale.protocol.packets.world.PaletteType;
class="kw">import com.hypixel.hytale.protocol.packets.world.SetChunk;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktick.BlockTickStrategy;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockMigration;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
class="kw">import com.hypixel.hytale.server.core.modules.LegacyModule;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.palette.AbstractSectionPalette;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.palette.EmptySectionPalette;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.palette.PaletteTypeEnum;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.util.io.MemorySegmentUtil;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ShortMap;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectHeapPriorityQueue;
class="kw">import java.lang.foreign.MemorySegment;
class="kw">import java.lang.foreign.ValueLayout;
class="kw">import java.lang.ref.SoftReference;
class="kw">import java.time.Instant;
class="kw">import java.util.BitSet;
class="kw">import java.util.Comparator;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.locks.StampedLock;
class="kw">import java.util.function.Function;
class="kw">import java.util.function.IntConsumer;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class BlockSection class="kw">implements Component<ChunkStore> {
   class="kw">public class="kw">static class="kw">final int VERSION = 6;
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">public class="kw">static class="kw">final BuilderCodec<BlockSection> CODEC = BuilderCodec.<BlockSection>builder(BlockSection.class, BlockSection::new)
      .versioned()
      .codecVersion(6)
      .append(new KeyedCodec<>("Data", Codec.BYTE_ARRAY), BlockSection::deserialize, BlockSection::serialize)
      .add()
      .build();
   class="kw">private class="kw">final StampedLock chunkSectionLock = new StampedLock();
   class="kw">public boolean loaded = false;
   @Nonnull
   class="kw">private IntOpenHashSet changedPositions = new IntOpenHashSet(0);
   @Nonnull
   class="kw">private IntOpenHashSet swapChangedPositions = new IntOpenHashSet(0);
   class="kw">private AbstractSectionPalette chunkSection;
   class="kw">private AbstractSectionPalette fillerSection;
   class="kw">private AbstractSectionPalette rotationSection;
   class="kw">private ChunkLightData localLight;
   class="kw">private short localChangeCounter;
   class="kw">private ChunkLightData globalLight;
   class="kw">private short globalChangeCounter;
   class="kw">private BitSet tickingBlocks;
   class="kw">private class="kw">final BitSet tickingBlocksCopy;
   @Nonnull
   class="kw">private class="kw">final BitSet tickingWaitAdjacentBlocks;
   class="kw">private int tickingBlocksCount;
   class="kw">private int tickingBlocksCountCopy;
   class="kw">private int tickingWaitAdjacentBlockCount;
   class="kw">private class="kw">final ObjectHeapPriorityQueue<BlockSection.TickRequest> tickRequests;
   class="kw">private double maximumHitboxExtent;
   @Nullable
   class="kw">private class="kw">transient SoftReference<CompletableFuture<CachedPacket<SetChunk>>> cachedChunkPacket;
   class="kw">private class="kw">static class="kw">final AbstractSectionPalette.KeyMemorySerializer FILLER_SERIALIZER = new AbstractSectionPalette.KeyMemorySerializer() {
      @Override
      class="kw">public int serialize(MemorySegment var1, int var2, int var3) {
         var1.set(MemorySegmentUtil.SHORT_BE, var2, (short)var3);
         class="kw">return 2;
      }

      @Override
      class="kw">public int keySize(int var1) {
         class="kw">return 2;
      }
   };
   class="kw">private class="kw">static class="kw">final AbstractSectionPalette.KeyMemorySerializer ROTATION_SERIALIZER = new AbstractSectionPalette.KeyMemorySerializer() {
      @Override
      class="kw">public int serialize(MemorySegment var1, int var2, int var3) {
         var1.set(ValueLayout.JAVA_BYTE, var2, (byte)var3);
         class="kw">return 1;
      }

      @Override
      class="kw">public int keySize(int var1) {
         class="kw">return 1;
      }
   };
   class="kw">private class="kw">static class="kw">final AbstractSectionPalette.KeyMemoryDeserializer FILLER_DESERIALIZER = new AbstractSectionPalette.KeyMemoryDeserializer() {
      @Override
      class="kw">public int deserialize(MemorySegment var1, int var2) {
         class="kw">return Short.toUnsignedInt(var1.get(MemorySegmentUtil.SHORT_BE, var2));
      }

      @Override
      class="kw">public int keySize(MemorySegment var1, int var2) {
         class="kw">return 2;
      }
   };
   class="kw">private class="kw">static class="kw">final AbstractSectionPalette.KeyMemoryDeserializer ROTATION_DESERIALIZER = new AbstractSectionPalette.KeyMemoryDeserializer() {
      @Override
      class="kw">public int deserialize(MemorySegment var1, int var2) {
         class="kw">return Byte.toUnsignedInt(var1.get(ValueLayout.JAVA_BYTE, var2));
      }

      @Override
      class="kw">public int keySize(MemorySegment var1, int var2) {
         class="kw">return 1;
      }
   };
   class="kw">private class="kw">static class="kw">final Comparator<BlockSection.TickRequest> TICK_REQUEST_COMPARATOR = Comparator.comparing(var0 -> var0.requestedGameTime);

   class="kw">public class="kw">static ComponentType<ChunkStore, BlockSection> getComponentType() {
      class="kw">return LegacyModule.get().getBlockSectionComponentType();
   }

   class="kw">public BlockSection() {
      this(EmptySectionPalette.INSTANCE, EmptySectionPalette.INSTANCE, EmptySectionPalette.INSTANCE);
   }

   class="kw">public BlockSection(AbstractSectionPalette var1, AbstractSectionPalette var2, AbstractSectionPalette var3) {
      this.tickRequests = new ObjectHeapPriorityQueue(TICK_REQUEST_COMPARATOR);
      this.maximumHitboxExtent = -1.0;
      this.chunkSection = var1;
      this.fillerSection = var2;
      this.rotationSection = var3;
      this.tickingBlocks = new BitSet();
      this.tickingBlocksCopy = new BitSet();
      this.tickingWaitAdjacentBlocks = new BitSet();
      this.tickingBlocksCount = 0;
      this.tickingBlocksCountCopy = 0;
      this.localLight = ChunkLightData.EMPTY;
      this.localChangeCounter = 0;
      this.globalLight = ChunkLightData.EMPTY;
      this.globalChangeCounter = 0;
   }

   class="kw">public AbstractSectionPalette getChunkSection() {
      class="kw">return this.chunkSection;
   }

   class="kw">public void setChunkSection(AbstractSectionPalette var1) {
      this.chunkSection = var1;
   }

   class="kw">public void setLocalLight(@Nonnull ChunkLightDataBuilder var1) {
      Objects.requireNonNull(var1);
      this.localLight = var1.build();
   }

   class="kw">public void setGlobalLight(@Nonnull ChunkLightDataBuilder var1) {
      Objects.requireNonNull(var1);
      this.globalLight = var1.build();
   }

   class="kw">public ChunkLightData getLocalLight() {
      class="kw">return this.localLight;
   }

   class="kw">public ChunkLightData getGlobalLight() {
      class="kw">return this.globalLight;
   }

   class="kw">public boolean hasLocalLight() {
      class="kw">return this.localLight.getChangeId() == this.localChangeCounter;
   }

   class="kw">public boolean hasGlobalLight() {
      class="kw">return this.globalLight.getChangeId() == this.globalChangeCounter;
   }

   class="kw">public void invalidateLocalLight() {
      this.localChangeCounter++;
      this.invalidateGlobalLight();
   }

   class="kw">public void invalidateGlobalLight() {
      this.globalChangeCounter++;
   }

   class="kw">public short getLocalChangeCounter() {
      class="kw">return this.localChangeCounter;
   }

   class="kw">public short getGlobalChangeCounter() {
      class="kw">return this.globalChangeCounter;
   }

   class="kw">public void invalidate() {
      this.cachedChunkPacket = null;
   }

   class="kw">public int get(int var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      int var4 = this.chunkSection.get(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.get(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public int getFiller(int var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      int var4 = this.fillerSection.get(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.fillerSection.get(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public int getFiller(int var1, int var2, int var3) {
      class="kw">return this.getFiller(ChunkUtil.indexBlock(var1, var2, var3));
   }

   class="kw">public int getRotationIndex(int var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      int var4 = this.rotationSection.get(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.rotationSection.get(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public int getRotationIndex(int var1, int var2, int var3) {
      class="kw">return this.getRotationIndex(ChunkUtil.indexBlock(var1, var2, var3));
   }

   class="kw">public RotationTuple getRotation(int var1) {
      class="kw">return RotationTuple.get(this.getRotationIndex(var1));
   }

   class="kw">public RotationTuple getRotation(int var1, int var2, int var3) {
      class="kw">return this.getRotation(ChunkUtil.indexBlock(var1, var2, var3));
   }

   class="kw">public boolean set(int var1, int var2, int var3, int var4) {
      if (var3 >= 0 && var3 < RotationTuple.VALUES.length) {
         long var6 = this.chunkSectionLock.writeLock();

         boolean var14;
         try {
            AbstractSectionPalette.SetResult var8 = this.chunkSection.set(var1, var2);
            if (var8 == AbstractSectionPalette.SetResult.REQUIRES_PROMOTE) {
               this.chunkSection = this.chunkSection.promote();
               AbstractSectionPalette.SetResult var9 = this.chunkSection.set(var1, var2);
               if (var9 != AbstractSectionPalette.SetResult.ADDED_OR_REMOVED) {
                  throw new IllegalStateException("Promoted chunk section failed to correctly add the new block!");
               }
            } else {
               if (var8 == AbstractSectionPalette.SetResult.ADDED_OR_REMOVED) {
                  this.maximumHitboxExtent = -1.0;
               }

               if (this.chunkSection.shouldDemote()) {
                  this.chunkSection = this.chunkSection.demote();
               }
            }

            var14 = var8 != AbstractSectionPalette.SetResult.UNCHANGED;
            var8 = this.fillerSection.set(var1, var4);
            if (var8 == AbstractSectionPalette.SetResult.REQUIRES_PROMOTE) {
               this.fillerSection = this.fillerSection.promote();
               AbstractSectionPalette.SetResult var17 = this.fillerSection.set(var1, var4);
               if (var17 != AbstractSectionPalette.SetResult.ADDED_OR_REMOVED) {
                  throw new IllegalStateException("Promoted chunk section failed to correctly add the new block!");
               }
            } else if (this.fillerSection.shouldDemote()) {
               this.fillerSection = this.fillerSection.demote();
            }

            var14 |= var8 != AbstractSectionPalette.SetResult.UNCHANGED;
            var8 = this.rotationSection.set(var1, var3);
            if (var8 == AbstractSectionPalette.SetResult.REQUIRES_PROMOTE) {
               this.rotationSection = this.rotationSection.promote();
               AbstractSectionPalette.SetResult var18 = this.rotationSection.set(var1, var3);
               if (var18 != AbstractSectionPalette.SetResult.ADDED_OR_REMOVED) {
                  throw new IllegalStateException("Promoted chunk section failed to correctly add the new block!");
               }
            } else if (this.rotationSection.shouldDemote()) {
               this.rotationSection = this.rotationSection.demote();
            }

            var14 |= var8 != AbstractSectionPalette.SetResult.UNCHANGED;
            if (var14 && this.loaded) {
               this.changedPositions.add(var1);
            }
         } class="kw">finally {
            this.chunkSectionLock.unlockWrite(var6);
         }

         if (var14) {
            this.invalidateLocalLight();
         }

         class="kw">return var14;
      } else {
         throw new IllegalArgumentException("Rotation index out of bounds. Got " + var3 + " but expected 0-" + (RotationTuple.VALUES.length - 1));
      }
   }

   @Nonnull
   class="kw">public IntOpenHashSet getAndClearChangedPositions() {
      long var1 = this.chunkSectionLock.writeLock();

      try {
         this.swapChangedPositions.clear();
         IntOpenHashSet var3 = this.changedPositions;
         this.changedPositions = this.swapChangedPositions;
         this.swapChangedPositions = var3;
         class="kw">return var3;
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var1);
      }
   }

   class="kw">public boolean contains(int var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      boolean var4 = this.chunkSection.contains(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.contains(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public boolean containsAny(IntList var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      boolean var4 = this.chunkSection.containsAny(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.containsAny(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public int count() {
      long var1 = this.chunkSectionLock.tryOptimisticRead();
      int var3 = this.chunkSection.count();
      if (!this.chunkSectionLock.validate(var1)) {
         var1 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.count();
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var1);
         }
      } else {
         class="kw">return var3;
      }
   }

   class="kw">public int count(int var1) {
      long var2 = this.chunkSectionLock.tryOptimisticRead();
      int var4 = this.chunkSection.count(var1);
      if (!this.chunkSectionLock.validate(var2)) {
         var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.count(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return var4;
      }
   }

   class="kw">public IntSet values() {
      long var1 = this.chunkSectionLock.tryOptimisticRead();
      IntSet var3 = this.chunkSection.values();
      if (!this.chunkSectionLock.validate(var1)) {
         var1 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.values();
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var1);
         }
      } else {
         class="kw">return var3;
      }
   }

   class="kw">public void forEachValue(IntConsumer var1) {
      long var2 = this.chunkSectionLock.readLock();

      try {
         this.chunkSection.forEachValue(var1);
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var2);
      }
   }

   class="kw">public Int2ShortMap valueCounts() {
      long var1 = this.chunkSectionLock.tryOptimisticRead();
      Int2ShortMap var3 = this.chunkSection.valueCounts();
      if (!this.chunkSectionLock.validate(var1)) {
         var1 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.valueCounts();
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var1);
         }
      } else {
         class="kw">return var3;
      }
   }

   class="kw">public boolean isSolidAir() {
      long var1 = this.chunkSectionLock.tryOptimisticRead();
      boolean var3 = this.chunkSection.isSolid(0);
      if (!this.chunkSectionLock.validate(var1)) {
         var1 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.chunkSection.isSolid(0);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var1);
         }
      } else {
         class="kw">return var3;
      }
   }

   @Deprecated(since = "2026-02-26", forRemoval = true)
   class="kw">public void find(IntList var1, IntSet var2, IntConsumer var3) {
      this.find(var1, var3);
   }

   class="kw">public void find(IntList var1, IntConsumer var2) {
      long var3 = this.chunkSectionLock.readLock();

      try {
         this.chunkSection.find(var1, var2);
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var3);
      }
   }

   class="kw">public void find(IntList var1, BiIntConsumer var2) {
      long var3 = this.chunkSectionLock.readLock();

      try {
         this.chunkSection.find(var1, var2);
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var3);
      }
   }

   class="kw">public boolean setTicking(int var1, boolean var2) {
      long var3 = this.chunkSectionLock.readLock();

      try {
         if (this.tickingBlocks.get(var1) == var2) {
            class="kw">return false;
         }
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var3);
      }

      long var5 = this.chunkSectionLock.writeLock();

      try {
         if (this.tickingBlocks.get(var1) != var2) {
            if (var2) {
               this.tickingBlocksCount++;
            } else {
               this.tickingBlocksCount--;
            }

            this.tickingBlocks.set(var1, var2);
            class="kw">return true;
         } else {
            class="kw">return false;
         }
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var5);
      }
   }

   class="kw">public int setTicking(@Nonnull IntList var1, boolean var2) {
      long var3 = this.chunkSectionLock.writeLock();

      try {
         int var5 = 0;

         for (int var6 = 0; var6 < var1.size(); var6++) {
            int var7 = var1.getInt(var6);
            if (this.tickingBlocks.get(var7) != var2) {
               if (var2) {
                  this.tickingBlocksCount++;
               } else {
                  this.tickingBlocksCount--;
               }

               this.tickingBlocks.set(var7, var2);
               var5++;
            }
         }

         class="kw">return var5;
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var3);
      }
   }

   class="kw">public int getTickingBlocksCount() {
      class="kw">return this.tickingBlocksCount > 0 ? this.tickingBlocksCount : 0;
   }

   class="kw">public int getTickingBlocksCountCopy() {
      class="kw">return this.tickingBlocksCountCopy;
   }

   class="kw">public boolean hasTicking() {
      class="kw">return this.tickingBlocksCount > 0;
   }

   class="kw">public boolean isTicking(int var1) {
      if (this.tickingBlocksCount > 0) {
         long var2 = this.chunkSectionLock.readLock();

         try {
            class="kw">return this.tickingBlocks.get(var1);
         } class="kw">finally {
            this.chunkSectionLock.unlockRead(var2);
         }
      } else {
         class="kw">return false;
      }
   }

   class="kw">public void scheduleTick(int var1, @Nullable Instant var2) {
      if (var2 != null) {
         this.tickRequests.enqueue(new BlockSection.TickRequest(var1, var2));
      }
   }

   class="kw">public void preTick(Instant var1) {
      BlockSection.TickRequest var2;
      while (!this.tickRequests.isEmpty() && (var2 = (BlockSection.TickRequest)this.tickRequests.first()).requestedGameTime.isBefore(var1)) {
         this.tickRequests.dequeue();
         this.setTicking(var2.index, true);
      }

      long var3 = this.chunkSectionLock.writeLock();

      try {
         if (this.tickingBlocksCount != 0) {
            BitSetUtil.copyValues(this.tickingBlocks, this.tickingBlocksCopy);
            this.tickingBlocksCountCopy = this.tickingBlocksCount;
            this.tickingBlocks.clear();
            this.tickingBlocksCount = 0;
            class="kw">return;
         }

         this.tickingBlocksCountCopy = 0;
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var3);
      }
   }

   class="kw">public <T, V> int forEachTicking(T var1, V var2, int var3, @Nonnull ObjectPositionBlockFunction<T, V, BlockTickStrategy> var4) {
      if (this.tickingBlocksCountCopy == 0) {
         class="kw">return 0;
      }

      int var5 = var3 << 5;
      int var6 = 0;

      for (int var7 = this.tickingBlocksCopy.nextSetBit(0); var7 >= 0; var7 = this.tickingBlocksCopy.nextSetBit(var7 + 1)) {
         int var8 = ChunkUtil.xFromIndex(var7);
         int var9 = ChunkUtil.yFromIndex(var7);
         int var10 = ChunkUtil.zFromIndex(var7);
         BlockTickStrategy var11 = var4.accept(var1, var2, var8, var9 | var5, var10, this.get(var7));
         long var12 = this.chunkSectionLock.writeLock();

         try {
            class="kw">switch (var11) {
               case WAIT_FOR_ADJACENT_CHUNK_LOAD:
                  if (!this.tickingWaitAdjacentBlocks.get(var7)) {
                     this.tickingWaitAdjacentBlockCount++;
                     this.tickingWaitAdjacentBlocks.set(var7, true);
                  }
                  break;
               case CONTINUE:
                  if (!this.tickingBlocks.get(var7)) {
                     this.tickingBlocksCount++;
                     this.tickingBlocks.set(var7, true);
                  }
               case SLEEP:
               case IGNORED:
            }
         } class="kw">finally {
            this.chunkSectionLock.unlockWrite(var12);
         }

         var6++;
      }

      class="kw">return var6;
   }

   class="kw">public void mergeTickingBlocks() {
      long var1 = this.chunkSectionLock.writeLock();

      try {
         this.tickingBlocks.or(this.tickingWaitAdjacentBlocks);
         this.tickingBlocksCount = this.tickingBlocks.cardinality();
         this.tickingWaitAdjacentBlocks.clear();
         this.tickingWaitAdjacentBlockCount = 0;
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var1);
      }
   }

   class="kw">public double getMaximumHitboxExtent() {
      double var1 = this.maximumHitboxExtent;
      if (var1 != -1.0) {
         class="kw">return var1;
      }

      double var3 = BlockBoundingBoxes.UNIT_BOX_MAXIMUM_EXTENT;
      long var5 = this.chunkSectionLock.readLock();

      try {
         IndexedLookupTableAssetMap var7 = BlockBoundingBoxes.getAssetMap();
         BlockTypeAssetMap var8 = BlockType.getAssetMap();

         for (int var9 = 0; var9 < 32768; var9++) {
            int var10 = this.chunkSection.get(var9);
            if (var10 != 0) {
               int var11 = this.rotationSection.get(var9);
               BlockType var12 = var8.getAsset(var10);
               if (var12 != null && !var12.isUnknown()) {
                  BlockBoundingBoxes var13 = var7.getAsset(var12.getHitboxTypeIndex());
                  if (var13 != BlockBoundingBoxes.UNIT_BOX) {
                     double var14 = var13.get(var11).getBoundingBox().getMaximumExtent();
                     if (var14 > var3) {
                        var3 = var14;
                     }
                  }
               }
            }
         }
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var5);
      }

      class="kw">return this.maximumHitboxExtent = var3;
   }

   @Deprecated
   class="kw">public void invalidateBlock(int var1, int var2, int var3) {
      long var4 = this.chunkSectionLock.writeLock();

      try {
         this.changedPositions.add(ChunkUtil.indexBlock(var1, var2, var3));
      } class="kw">finally {
         this.chunkSectionLock.unlockWrite(var4);
      }
   }

   class="kw">public byte[] serializeForPacket() {
      long var1 = this.chunkSectionLock.readLock();

      try {
         byte[] var3 = new byte[1
            + this.chunkSection.serializedPacketByteSize()
            + 1
            + this.fillerSection.serializedPacketByteSize()
            + 1
            + this.rotationSection.serializedPacketByteSize()];
         MemorySegment var4 = MemorySegment.ofArray(var3);
         PaletteType var5 = this.chunkSection.getPaletteType();
         byte var6 = (byte)var5.ordinal();
         var4.set(ValueLayout.JAVA_BYTE, 0L, var6);
         int var7 = 1 + this.chunkSection.serializeForPacket(var4, 1);
         PaletteType var8 = this.fillerSection.getPaletteType();
         byte var9 = (byte)var8.ordinal();
         var4.set(ValueLayout.JAVA_BYTE, var7, var9);
         var7 += 1 + this.fillerSection.serializeForPacket(var4, var7 + 1);
         PaletteType var10 = this.rotationSection.getPaletteType();
         byte var11 = (byte)var10.ordinal();
         var4.set(ValueLayout.JAVA_BYTE, var7, var11);
         this.rotationSection.serializeForPacket(var4, var7 + 1);
         class="kw">return var3;
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var1);
      }
   }

   class="kw">public byte[] serialize(ExtraInfo var1) {
      long var2 = this.chunkSectionLock.readLock();

      try {
         PaletteType var4 = this.chunkSection.getPaletteType();
         BitSet var5;
         long[] var6;
         if (var4 != PaletteType.Empty) {
            var5 = (BitSet)this.tickingBlocks.clone();
            var5.or(this.tickingWaitAdjacentBlocks);
            var6 = var5.toLongArray();
         } else {
            var5 = null;
            var6 = null;
         }

         ChunkLightData var7 = this.localLight;
         ChunkLightData var8 = this.globalLight;
         byte[] var9 = new byte[5
            + this.chunkSection.serializedByteSize(BlockType.KEY_MEMORY_SERIALIZER)
            + (var4 != PaletteType.Empty ? 4 + var6.length * 8 : 0)
            + 1
            + this.fillerSection.serializedByteSize(FILLER_SERIALIZER)
            + 1
            + this.rotationSection.serializedByteSize(ROTATION_SERIALIZER)
            + var7.serializedByteSize()
            + var8.serializedByteSize()
            + 2
            + 2];
         MemorySegment var10 = MemorySegment.ofArray(var9);
         var10.set(MemorySegmentUtil.INT_BE, 0L, BlockMigration.getAssetMap().getAssetCount());
         var10.set(ValueLayout.JAVA_BYTE, 4L, (byte)var4.ordinal());
         int var11 = 5 + this.chunkSection.serialize(BlockType.KEY_MEMORY_SERIALIZER, var10, 5);
         if (var4 != PaletteType.Empty) {
            var10.set(MemorySegmentUtil.SHORT_BE, var11, (short)var5.cardinality());
            var10.set(MemorySegmentUtil.SHORT_BE, var11 + 2, (short)var6.length);
            MemorySegment.copy(var6, 0, var10, MemorySegmentUtil.LONG_BE, var11 + 4, var6.length);
            var11 += 4 + var6.length * 8;
         }

         var10.set(ValueLayout.JAVA_BYTE, var11, (byte)this.fillerSection.getPaletteType().ordinal());
         var11 += 1 + this.fillerSection.serialize(FILLER_SERIALIZER, var10, var11 + 1);
         var10.set(ValueLayout.JAVA_BYTE, var11, (byte)this.rotationSection.getPaletteType().ordinal());
         var11 += 1 + this.rotationSection.serialize(ROTATION_SERIALIZER, var10, var11 + 1);
         var11 += var7.serialize(var10, var11);
         var11 += var8.serialize(var10, var11);
         var10.set(MemorySegmentUtil.SHORT_BE, var11, this.localChangeCounter);
         var10.set(MemorySegmentUtil.SHORT_BE, var11 + 2, this.globalChangeCounter);
         class="kw">return var9;
      } class="kw">finally {
         this.chunkSectionLock.unlockRead(var2);
      }
   }

   class="kw">public void deserialize(@Nonnull byte[] var1, @Nonnull ExtraInfo var2) {
      MemorySegment var3 = MemorySegment.ofArray(var1);
      int var4 = var2.getVersion();
      if (var4 < 6) {
         throw new IllegalArgumentException("Version not supported: " + var4);
      }

      int var5 = var3.get(MemorySegmentUtil.INT_BE, 0L);
      Function var6 = null;
      Map var7 = BlockMigration.getAssetMap().getAssetMap();

      for (BlockMigration var8 = var7.get(var5); var8 != null; var8 = var7.get(++var5)) {
         if (var6 == null) {
            var6 = var8::getMigration;
         } else {
            var6 = var6.andThen(var8::getMigration);
         }
      }

      PaletteTypeEnum var9 = PaletteTypeEnum.get(var3.get(ValueLayout.JAVA_BYTE, 4L));
      PaletteType var10 = var9.getPaletteType();
      this.chunkSection = var9.getConstructor().get();
      int var11 = 5;
      if (var6 != null) {
         class="kw">final Function var12 = var6;
         var11 += this.chunkSection.deserialize(new AbstractSectionPalette.KeyMemoryDeserializer() {
            @Override
            class="kw">public int deserialize(MemorySegment var1, int var2x) {
               String var3 = var12.apply(MemorySegmentUtil.readUTF(var1, var2x));
               class="kw">return BlockType.getBlockIdOrUnknown(var3, "Unknown BlockType %s", var3);
            }

            @Override
            class="kw">public int keySize(MemorySegment var1, int var2x) {
               class="kw">return MemorySegmentUtil.utf8Size(var1, var2x);
            }
         }, var3, var11);
      } else {
         var11 += this.chunkSection.deserialize(BlockType.KEY_MEMORY_DESERIALIZER, var3, var11);
      }

      if (var10 != PaletteType.Empty) {
         this.tickingBlocksCount = Short.toUnsignedInt(var3.get(MemorySegmentUtil.SHORT_BE, var11));
         int var20 = Short.toUnsignedInt(var3.get(MemorySegmentUtil.SHORT_BE, var11 + 2));
         var11 += 4;
         long[] var13 = var3.asSlice(var11, var20 * 8L).toArray(MemorySegmentUtil.LONG_BE);
         var11 += var20 * 8;
         this.tickingBlocks = BitSet.valueOf(var13);
         this.tickingBlocksCount = this.tickingBlocks.cardinality();
      }

      PaletteTypeEnum var21 = PaletteTypeEnum.get(var3.get(ValueLayout.JAVA_BYTE, var11));
      this.fillerSection = var21.getConstructor().get();
      var11 += 1 + this.fillerSection.deserialize(FILLER_DESERIALIZER, var3, var11 + 1);
      PaletteTypeEnum var22 = PaletteTypeEnum.get(var3.get(ValueLayout.JAVA_BYTE, var11));
      this.rotationSection = var22.getConstructor().get();
      var11 += 1 + this.rotationSection.deserialize(ROTATION_DESERIALIZER, var3, var11 + 1);
      this.localLight = ChunkLightData.deserialize(var3, var11);
      var11 += this.localLight.serializedByteSize();
      this.globalLight = ChunkLightData.deserialize(var3, var11);
      var11 += this.globalLight.serializedByteSize();
      this.localChangeCounter = var3.get(MemorySegmentUtil.SHORT_BE, var11);
      this.globalChangeCounter = var3.get(MemorySegmentUtil.SHORT_BE, var11 + 2);
   }

   @Override
   class="kw">public Component<ChunkStore> clone() {
      throw new UnsupportedOperationException("Not implemented!");
   }

   @Nonnull
   @Override
   class="kw">public Component<ChunkStore> cloneSerializable() {
      class="kw">return this;
   }

   @Nonnull
   class="kw">public CompletableFuture<CachedPacket<SetChunk>> getCachedChunkPacket(int var1, int var2, int var3) {
      SoftReference var4 = this.cachedChunkPacket;
      CompletableFuture var5 = var4 != null ? var4.get() : null;
      if (var5 != null) {
         class="kw">return var5;
      }

      var5 = CompletableFuture.supplyAsync(() -> {
         byte[] var4 = null;
         byte[] var5 = null;
         byte[] var6 = null;
         if (BlockChunk.SEND_LOCAL_LIGHTING_DATA && this.hasLocalLight()) {
            ChunkLightData var7 = this.getLocalLight();
            var4 = new byte[var7.serializedForPacketByteSize()];
            MemorySegment var8 = MemorySegment.ofArray(var4);
            var7.serializeForPacket(var8, 0);
            if (this.getLocalChangeCounter() != var7.getChangeId()) {
               var4 = null;
            }
         }

         if (BlockChunk.SEND_GLOBAL_LIGHTING_DATA && this.hasGlobalLight()) {
            ChunkLightData var9 = this.getGlobalLight();
            var5 = new byte[var9.serializedForPacketByteSize()];
            MemorySegment var11 = MemorySegment.ofArray(var5);
            var9.serializeForPacket(var11, 0);
            if (this.getGlobalChangeCounter() != var9.getChangeId()) {
               var5 = null;
            }
         }

         if (!this.isSolidAir()) {
            var6 = this.serializeForPacket();
         }

         SetChunk var10 = new SetChunk(var1, var2, var3, var4, var5, var6);
         class="kw">return CachedPacket.cache(var10);
      });
      this.cachedChunkPacket = new SoftReference<>(var5);
      class="kw">return var5;
   }

   class="kw">public int get(int var1, int var2, int var3) {
      class="kw">return this.get(ChunkUtil.indexBlock(var1, var2, var3));
   }

   class="kw">public boolean set(int var1, int var2, int var3, int var4, int var5, int var6) {
      class="kw">return this.set(ChunkUtil.indexBlock(var1, var2, var3), var4, var5, var6);
   }

   class="kw">public boolean setTicking(int var1, int var2, int var3, boolean var4) {
      class="kw">return this.setTicking(ChunkUtil.indexBlock(var1, var2, var3), var4);
   }

   class="kw">public boolean isTicking(int var1, int var2, int var3) {
      class="kw">return this.isTicking(ChunkUtil.indexBlock(var1, var2, var3));
   }

   class="kw">public class="kw">static class LoadBlockSectionPacketSystem class="kw">extends ChunkStore.LoadFuturePacketDataQuerySystem {
      class="kw">private class="kw">final ComponentType<ChunkStore, BlockSection> componentType;
      class="kw">private class="kw">final Query<ChunkStore> query;

      class="kw">public LoadBlockSectionPacketSystem(ComponentType<ChunkStore, BlockSection> var1) {
         this.componentType = var1;
         this.query = Query.and(var1, ChunkSection.getComponentType());
      }

      @Override
      class="kw">public Query<ChunkStore> getQuery() {
         class="kw">return this.query;
      }

      class="kw">public void fetch(
         int var1,
         @Nonnull ArchetypeChunk<ChunkStore> var2,
         Store<ChunkStore> var3,
         CommandBuffer<ChunkStore> var4,
         PlayerRef var5,
         @Nonnull List<CompletableFuture<ToClientPacket>> var6
      ) {
         BlockSection var7 = var2.getComponent(var1, this.componentType);
         assert var7 != null;
         ChunkSection var8 = var2.getComponent(var1, ChunkSection.getComponentType());
         assert var8 != null;
         var6.add(
            var7.getCachedChunkPacket(var8.getX(), var8.getY(), var8.getZ())
               .exceptionally(
                  var1x -> {
                     if (var1x != null) {
                        ((HytaleLogger.Api)BlockSection.LOGGER.at(Level.SEVERE).withCause(var1x))
                           .log("Exception while compressing set chunk (%d, %d, %d):", var8.getX(), var8.getY(), var8.getZ());
                     }

                     class="kw">return null;
                  }
               )
               .thenApply(Function.identity())
         );
      }
   }

   class="kw">private record TickRequest(int index, @Nonnull Instant requestedGameTime) {
      class="kw">private TickRequest {
      }
   }
}