From 0750e5fe343e02d340fe5e7565b9d86eaa89d5ac Mon Sep 17 00:00:00 2001 From: Arthur Blanchot Date: Tue, 28 Jun 2022 21:25:08 +0200 Subject: [PATCH] Add more patches back --- .../0071-lithium-chunk.serialization.patch | 458 ++++++++++++++++++ ...072-Configurable-criterion-triggers.patch} | 0 ...73-Set-item-stuck-sleep-to-15-ticks.patch} | 0 ... => 0074-Smarter-statistics-ticking.patch} | 0 ..._entity_tracking-and-ai.nearby_enti.patch} | 0 ...atch => 0076-some-entity-micro-opts.patch} | 0 ...nt-eat-blocks-in-non-ticking-chunks.patch} | 0 ...heck.patch => 0078-Fast-speed-check.patch} | 0 .../0079-lithium-cache-iterate-outwards.patch | 175 +++++++ patches/server/0080-lithium-ai.raid.patch | 79 +++ ...ithium-gen.cached_generator_settings.patch | 38 -- ...1-lithium-block.moving_block_shapes.patch} | 0 ...082-lithium-shapes.blockstate_cache.patch} | 0 patches/server/0083-lithium-gen.patch | 243 ++++++++++ ...e-look-changes-from-crashing-the-se.patch} | 0 ...-more-collision-code-skipping-logic.patch} | 0 ...p-for-entity-trackers-for-faster-it.patch} | 0 patches/server/0087-c2me-reduce_allocs.patch | 258 ++++++++++ ...088-lithium-ai.sensor.secondary_poi.patch} | 0 ...ck-function-tag-running-before-load.patch} | 0 ...n.patch => 0090-lithium-suffocation.patch} | 0 ...Optimize-default-values-for-configs.patch} | 0 ...92-Configurable-map-update-interval.patch} | 0 ...er-saturation-depleting-on-peaceful.patch} | 0 ... 0094-Fix-mobs-attacking-themselves.patch} | 0 ...s-resetting-their-brewTime-when-bei.patch} | 0 ...> 0096-lithium-world.tick_scheduler.patch} | 0 ... 0097-Save-Json-list-asynchronously.patch} | 0 ...ps-the-predicate-order-of-collision.patch} | 0 ... 0099-Fix-head-rotation-packet-spam.patch} | 0 ...-Cache-block-break-animation-packet.patch} | 0 ...1-Use-more-fastutil-data-structures.patch} | 0 32 files changed, 1213 insertions(+), 38 deletions(-) create mode 100644 patches/server/0071-lithium-chunk.serialization.patch rename patches/server/{0071-Configurable-criterion-triggers.patch => 0072-Configurable-criterion-triggers.patch} (100%) rename patches/server/{0072-Set-item-stuck-sleep-to-15-ticks.patch => 0073-Set-item-stuck-sleep-to-15-ticks.patch} (100%) rename patches/server/{0073-Smarter-statistics-ticking.patch => 0074-Smarter-statistics-ticking.patch} (100%) rename patches/server/{0074-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch => 0075-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch} (100%) rename patches/server/{0075-some-entity-micro-opts.patch => 0076-some-entity-micro-opts.patch} (100%) rename patches/server/{0076-Dont-eat-blocks-in-non-ticking-chunks.patch => 0077-Dont-eat-blocks-in-non-ticking-chunks.patch} (100%) rename patches/server/{0077-Fast-speed-check.patch => 0078-Fast-speed-check.patch} (100%) create mode 100644 patches/server/0079-lithium-cache-iterate-outwards.patch create mode 100644 patches/server/0080-lithium-ai.raid.patch delete mode 100644 patches/server/0080-lithium-gen.cached_generator_settings.patch rename patches/server/{0078-lithium-block.moving_block_shapes.patch => 0081-lithium-block.moving_block_shapes.patch} (100%) rename patches/server/{0079-lithium-shapes.blockstate_cache.patch => 0082-lithium-shapes.blockstate_cache.patch} (100%) create mode 100644 patches/server/0083-lithium-gen.patch rename patches/server/{0081-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch => 0084-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch} (100%) rename patches/server/{0082-PaperPR-Add-more-collision-code-skipping-logic.patch => 0085-PaperPR-Add-more-collision-code-skipping-logic.patch} (100%) rename patches/server/{0083-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch => 0086-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch} (100%) create mode 100644 patches/server/0087-c2me-reduce_allocs.patch rename patches/server/{0084-lithium-ai.sensor.secondary_poi.patch => 0088-lithium-ai.sensor.secondary_poi.patch} (100%) rename patches/server/{0085-Fix-tick-function-tag-running-before-load.patch => 0089-Fix-tick-function-tag-running-before-load.patch} (100%) rename patches/server/{0086-lithium-suffocation.patch => 0090-lithium-suffocation.patch} (100%) rename patches/server/{0087-Optimize-default-values-for-configs.patch => 0091-Optimize-default-values-for-configs.patch} (100%) rename patches/server/{0088-Configurable-map-update-interval.patch => 0092-Configurable-map-update-interval.patch} (100%) rename patches/server/{0089-Fix-hunger-saturation-depleting-on-peaceful.patch => 0093-Fix-hunger-saturation-depleting-on-peaceful.patch} (100%) rename patches/server/{0090-Fix-mobs-attacking-themselves.patch => 0094-Fix-mobs-attacking-themselves.patch} (100%) rename patches/server/{0091-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch => 0095-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch} (100%) rename patches/server/{0092-lithium-world.tick_scheduler.patch => 0096-lithium-world.tick_scheduler.patch} (100%) rename patches/server/{0093-Save-Json-list-asynchronously.patch => 0097-Save-Json-list-asynchronously.patch} (100%) rename patches/server/{0094-Swaps-the-predicate-order-of-collision.patch => 0098-Swaps-the-predicate-order-of-collision.patch} (100%) rename patches/server/{0095-Fix-head-rotation-packet-spam.patch => 0099-Fix-head-rotation-packet-spam.patch} (100%) rename patches/server/{0096-Cache-block-break-animation-packet.patch => 0100-Cache-block-break-animation-packet.patch} (100%) rename patches/server/{0097-Use-more-fastutil-data-structures.patch => 0101-Use-more-fastutil-data-structures.patch} (100%) diff --git a/patches/server/0071-lithium-chunk.serialization.patch b/patches/server/0071-lithium-chunk.serialization.patch new file mode 100644 index 0000000..a45e792 --- /dev/null +++ b/patches/server/0071-lithium-chunk.serialization.patch @@ -0,0 +1,458 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: jellysquid3 +Date: Mon, 10 Jan 2022 15:27:58 -0500 +Subject: [PATCH] lithium: chunk.serialization + +Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0 +You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings) + +diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java +new file mode 100644 +index 0000000000000000000000000000000000000000..16debe176798f316c122e8e7aef2b50ecb9883a6 +--- /dev/null ++++ b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java +@@ -0,0 +1,189 @@ ++package me.jellysquid.mods.lithium.common.world.chunk; ++ ++import com.google.common.collect.ImmutableList; ++import it.unimi.dsi.fastutil.HashCommon; ++import it.unimi.dsi.fastutil.objects.Reference2IntMap; ++import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; ++import java.util.Arrays; ++import java.util.List; ++import java.util.function.Predicate; ++import net.minecraft.core.IdMap; ++import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.world.level.chunk.Palette; ++import net.minecraft.world.level.chunk.PaletteResize; ++ ++import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR; ++ ++/** ++ * Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling ++ * {@link LithiumHashPalette#idFor(Object)} through using a faster backing map and reducing pointer chasing. ++ */ ++public class LithiumHashPalette implements Palette { ++ private static final int ABSENT_VALUE = -1; ++ ++ private final IdMap idList; ++ private final PaletteResize resizeHandler; ++ private final int indexBits; ++ ++ private final Reference2IntMap table; ++ private T[] entries; ++ private int size = 0; ++ ++ public LithiumHashPalette(IdMap idList, PaletteResize resizeHandler, int indexBits, T[] entries, Reference2IntMap table, int size) { ++ this.idList = idList; ++ this.resizeHandler = resizeHandler; ++ this.indexBits = indexBits; ++ this.entries = entries; ++ this.table = table; ++ this.size = size; ++ } ++ ++ public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler, List list) { ++ this(idList, bits, resizeHandler); ++ ++ for (T t : list) { ++ this.addEntry(t); ++ } ++ } ++ ++ @SuppressWarnings("unchecked") ++ public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler) { ++ this.idList = idList; ++ this.indexBits = bits; ++ this.resizeHandler = resizeHandler; ++ ++ int capacity = 1 << bits; ++ ++ this.entries = (T[]) new Object[capacity]; ++ this.table = new Reference2IntOpenHashMap<>(capacity, FAST_LOAD_FACTOR); ++ this.table.defaultReturnValue(ABSENT_VALUE); ++ } ++ ++ @Override ++ public int idFor(T obj) { ++ int id = this.table.getInt(obj); ++ ++ if (id == ABSENT_VALUE) { ++ id = this.computeEntry(obj); ++ } ++ ++ return id; ++ } ++ ++ @Override ++ public boolean maybeHas(Predicate predicate) { ++ for (int i = 0; i < this.size; ++i) { ++ if (predicate.test(this.entries[i])) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ private int computeEntry(T obj) { ++ int id = this.addEntry(obj); ++ ++ if (id >= 1 << this.indexBits) { ++ if (this.resizeHandler == null) { ++ throw new IllegalStateException("Cannot grow"); ++ } else { ++ id = this.resizeHandler.onResize(this.indexBits + 1, obj); ++ } ++ } ++ ++ return id; ++ } ++ ++ private int addEntry(T obj) { ++ int nextId = this.size; ++ ++ if (nextId >= this.entries.length) { ++ this.resize(this.size); ++ } ++ ++ this.table.put(obj, nextId); ++ this.entries[nextId] = obj; ++ ++ this.size++; ++ ++ return nextId; ++ } ++ ++ private void resize(int neededCapacity) { ++ this.entries = Arrays.copyOf(this.entries, HashCommon.nextPowerOfTwo(neededCapacity + 1)); ++ } ++ ++ @Override ++ public T valueFor(int id) { ++ T[] entries = this.entries; ++ ++ if (id >= 0 && id < entries.length) { ++ return entries[id]; ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public void read(FriendlyByteBuf buf) { ++ this.clear(); ++ ++ int entryCount = buf.readVarInt(); ++ ++ for (int i = 0; i < entryCount; ++i) { ++ this.addEntry(this.idList.byId(buf.readVarInt())); ++ } ++ } ++ ++ @Override ++ public void write(FriendlyByteBuf buf) { ++ int size = this.size; ++ buf.writeVarInt(size); ++ ++ for (int i = 0; i < size; ++i) { ++ buf.writeVarInt(this.idList.getId(this.valueFor(i))); ++ } ++ } ++ ++ @Override ++ public int getSerializedSize() { ++ int size = FriendlyByteBuf.getVarIntSize(this.size); ++ ++ for (int i = 0; i < this.size; ++i) { ++ size += FriendlyByteBuf.getVarIntSize(this.idList.getId(this.valueFor(i))); ++ } ++ ++ return size; ++ } ++ ++ @Override ++ public int getSize() { ++ return this.size; ++ } ++ ++ @Override ++ public Palette copy() { ++ return new LithiumHashPalette<>(this.idList, this.resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size); ++ } ++ ++ private void clear() { ++ Arrays.fill(this.entries, null); ++ this.table.clear(); ++ this.size = 0; ++ } ++ ++ public List getElements() { ++ ImmutableList.Builder builder = new ImmutableList.Builder<>(); ++ for (T entry : this.entries) { ++ if (entry != null) { ++ builder.add(entry); ++ } ++ } ++ return builder.build(); ++ } ++ ++ public static Palette create(int bits, IdMap idList, PaletteResize listener, List list) { ++ return new LithiumHashPalette<>(idList, bits, listener, list); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java +index 106610ccc74b70b557b01c61262d56c4f1147acf..fc986f02290fbe20246022072944980f35dd200c 100644 +--- a/src/main/java/net/minecraft/util/BitStorage.java ++++ b/src/main/java/net/minecraft/util/BitStorage.java +@@ -1,6 +1,7 @@ + package net.minecraft.util; + + import java.util.function.IntConsumer; ++import net.minecraft.world.level.chunk.Palette; // JettPack + + public interface BitStorage { + int getAndSet(int index, int value); +@@ -31,4 +32,6 @@ public interface BitStorage { + + } + // Paper end ++ ++ void compact(Palette srcPalette, Palette dstPalette, short[] out); // JettPack - lithium: chunk.serialization + } +diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java +index 36e33923bf48e56c743ed043bcbc66bc32f0422f..0272dee738e86e066108f5cc3729136335d8197e 100644 +--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java ++++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java +@@ -2,6 +2,7 @@ package net.minecraft.util; + + import java.util.function.IntConsumer; + import javax.annotation.Nullable; ++import net.minecraft.world.level.chunk.Palette; // JettPack + import org.apache.commons.lang3.Validate; + + public class SimpleBitStorage implements BitStorage { +@@ -201,4 +202,44 @@ public class SimpleBitStorage implements BitStorage { + super(message); + } + } ++ ++ // JettPack start - lithium: chunk.serialization ++ @Override ++ public void compact(Palette srcPalette, Palette dstPalette, short[] out) { ++ if (this.size >= Short.MAX_VALUE) { ++ throw new IllegalStateException("Array too large"); ++ } ++ ++ if (this.size != out.length) { ++ throw new IllegalStateException("Array size mismatch"); ++ } ++ ++ short[] mappings = new short[(int) (this.mask + 1)]; ++ ++ int idx = 0; ++ ++ for (long word : this.data) { ++ long bits = word; ++ ++ for (int elementIdx = 0; elementIdx < this.valuesPerLong; ++elementIdx) { ++ int value = (int) (bits & this.mask); ++ int remappedId = mappings[value]; ++ ++ if (remappedId == 0) { ++ remappedId = dstPalette.idFor(srcPalette.valueFor(value)) + 1; ++ mappings[value] = (short) remappedId; ++ } ++ ++ out[idx] = (short) (remappedId - 1); ++ bits >>= this.bits; ++ ++ ++idx; ++ ++ if (idx >= this.size) { ++ return; ++ } ++ } ++ } ++ } ++ // JettPack end + } +diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java +index 97c744508cc535418eba65fa722859c81c22d647..a2ea0a2864b9c4f847f1a14ffc0900e67c18f9ee 100644 +--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java ++++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java +@@ -2,6 +2,7 @@ package net.minecraft.util; + + import java.util.Arrays; + import java.util.function.IntConsumer; ++import net.minecraft.world.level.chunk.Palette; // JettPack + import org.apache.commons.lang3.Validate; + + public class ZeroBitStorage implements BitStorage { +@@ -72,4 +73,6 @@ public class ZeroBitStorage implements BitStorage { + public BitStorage copy() { + return this; + } ++ ++ @Override public void compact(Palette srcPalette, Palette dstPalette, short[] out) {} // JettPack + } +diff --git a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java b/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java +index acae3eb30e0689048937f479dc3070f0688abdad..9c2b79655f2c63a208c7087d5d897db0fb23f697 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java ++++ b/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java +@@ -1,5 +1,5 @@ + package net.minecraft.world.level.chunk; + +-interface PaletteResize { ++public interface PaletteResize { // JettPack - make public + int onResize(int newBits, T object); + } +diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +index 08e1309e618377d170c446a1568c21b7bf4e5683..0b4f66d0ef963d6f47b20469b7a1e3f6c3da7c83 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java ++++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +@@ -22,8 +22,23 @@ import net.minecraft.util.Mth; + import net.minecraft.util.SimpleBitStorage; + import net.minecraft.util.ThreadingDetector; + import net.minecraft.util.ZeroBitStorage; ++import me.jellysquid.mods.lithium.common.world.chunk.LithiumHashPalette; // JettPack + + public class PalettedContainer implements PaletteResize, PalettedContainerRO { ++ // JettPack start - lithium: chunk.serialization ++ private static final ThreadLocal CACHED_ARRAY_4096 = ThreadLocal.withInitial(() -> new short[4096]); ++ private static final ThreadLocal CACHED_ARRAY_64 = ThreadLocal.withInitial(() -> new short[64]); ++ private Optional asOptional(long[] data) { ++ return Optional.of(Arrays.stream(data)); ++ } ++ private short[] getOrCreate(int size) { ++ return switch (size) { ++ case 64 -> CACHED_ARRAY_64.get(); ++ case 4096 -> CACHED_ARRAY_4096.get(); ++ default -> new short[size]; ++ }; ++ } ++ // JettPack end + private static final int MIN_PALETTE_BITS = 0; + private final PaletteResize dummyPaletteResize = (newSize, added) -> { + return 0; +@@ -298,30 +313,54 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + public synchronized PalettedContainerRO.PackedData pack(IdMap idMap, PalettedContainer.Strategy strategy) { // Paper - synchronize + this.acquire(); + +- PalettedContainerRO.PackedData var12; ++ // JettPack start - lithium: chunk.serialization ++ Optional data = Optional.empty(); ++ List elements = null; + try { +- HashMapPalette hashMapPalette = new HashMapPalette<>(idMap, this.data.storage.getBits(), this.dummyPaletteResize); +- int i = strategy.size(); +- int[] is = new int[i]; +- this.data.storage.unpack(is); +- swapPalette(is, (ix) -> { +- return hashMapPalette.idFor(this.data.palette.valueFor(ix)); +- }); +- int j = strategy.calculateBitsForSerialization(idMap, hashMapPalette.getSize()); +- Optional optional; +- if (j != 0) { +- SimpleBitStorage simpleBitStorage = new SimpleBitStorage(j, i, is); +- optional = Optional.of(Arrays.stream(simpleBitStorage.getRaw())); +- } else { +- optional = Optional.empty(); ++ // The palette that will be serialized ++ LithiumHashPalette hashPalette = null; ++ ++ final Palette palette = this.data.palette(); ++ final BitStorage storage = this.data.storage(); ++ if (storage instanceof ZeroBitStorage || palette.getSize() == 1) { ++ // If the palette only contains one entry, don't attempt to repack it. ++ elements = List.of(palette.valueFor(0)); ++ } else if (palette instanceof LithiumHashPalette lithiumHashPalette) { ++ hashPalette = lithiumHashPalette; + } + +- var12 = new PalettedContainerRO.PackedData<>(hashMapPalette.getEntries(), optional); ++ if (elements == null) { ++ LithiumHashPalette compactedPalette = new LithiumHashPalette<>(idMap, storage.getBits(), this.dummyPaletteResize); ++ short[] array = this.getOrCreate(strategy.size()); ++ ++ storage.compact(this.data.palette(), compactedPalette, array); ++ ++ // If the palette didn't change during compaction, do a simple copy of the data array ++ if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == strategy.calculateBitsForSerialization(idMap, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279 ++ data = this.asOptional(storage.getRaw().clone()); ++ elements = hashPalette.getElements(); ++ } else { ++ int bits = strategy.calculateBitsForSerialization(idMap, compactedPalette.getSize()); ++ if (bits != 0) { ++ // Re-pack the integer array as the palette has changed size ++ SimpleBitStorage copy = new SimpleBitStorage(bits, array.length); ++ for (int i = 0; i < array.length; ++i) { ++ copy.set(i, array[i]); ++ } ++ ++ // We don't need to clone the data array as we are the sole owner of it ++ data = this.asOptional(copy.getRaw()); ++ } ++ ++ elements = compactedPalette.getElements(); ++ } ++ } + } finally { + this.release(); + } + +- return var12; ++ return new PalettedContainerRO.PackedData<>(elements, data); ++ // JettPack end + } + + private static void swapPalette(int[] is, IntUnaryOperator intUnaryOperator) { +@@ -361,17 +400,37 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + + @Override + public void count(PalettedContainer.CountConsumer counter) { +- if (this.data.palette.getSize() == 1) { +- counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); +- } else { +- Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap(); +- this.data.storage.getAll((key) -> { +- int2IntOpenHashMap.addTo(key, 1); +- }); +- int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> { +- counter.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue()); +- }); ++ // JettPack start - lithium: chunk.serialization ++ int len = this.data.palette().getSize(); ++ ++ // Do not allocate huge arrays if we're using a large palette ++ if (len > 4096) { ++ // VanillaCopy ++ if (this.data.palette.getSize() == 1) { ++ counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); ++ } else { ++ Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap(); ++ this.data.storage.getAll((key) -> { ++ int2IntOpenHashMap.addTo(key, 1); ++ }); ++ int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> { ++ counter.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue()); ++ }); ++ } ++ } ++ ++ short[] counts = new short[len]; ++ ++ this.data.storage().getAll(i -> counts[i]++); ++ ++ for (int i = 0; i < counts.length; i++) { ++ T obj = this.data.palette().valueFor(i); ++ ++ if (obj != null) { ++ counter.accept(obj, counts[i]); ++ } + } ++ // JettPack end + } + + static record Configuration(Palette.Factory factory, int bits) { diff --git a/patches/server/0071-Configurable-criterion-triggers.patch b/patches/server/0072-Configurable-criterion-triggers.patch similarity index 100% rename from patches/server/0071-Configurable-criterion-triggers.patch rename to patches/server/0072-Configurable-criterion-triggers.patch diff --git a/patches/server/0072-Set-item-stuck-sleep-to-15-ticks.patch b/patches/server/0073-Set-item-stuck-sleep-to-15-ticks.patch similarity index 100% rename from patches/server/0072-Set-item-stuck-sleep-to-15-ticks.patch rename to patches/server/0073-Set-item-stuck-sleep-to-15-ticks.patch diff --git a/patches/server/0073-Smarter-statistics-ticking.patch b/patches/server/0074-Smarter-statistics-ticking.patch similarity index 100% rename from patches/server/0073-Smarter-statistics-ticking.patch rename to patches/server/0074-Smarter-statistics-ticking.patch diff --git a/patches/server/0074-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch b/patches/server/0075-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch similarity index 100% rename from patches/server/0074-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch rename to patches/server/0075-lithium-ai.nearby_entity_tracking-and-ai.nearby_enti.patch diff --git a/patches/server/0075-some-entity-micro-opts.patch b/patches/server/0076-some-entity-micro-opts.patch similarity index 100% rename from patches/server/0075-some-entity-micro-opts.patch rename to patches/server/0076-some-entity-micro-opts.patch diff --git a/patches/server/0076-Dont-eat-blocks-in-non-ticking-chunks.patch b/patches/server/0077-Dont-eat-blocks-in-non-ticking-chunks.patch similarity index 100% rename from patches/server/0076-Dont-eat-blocks-in-non-ticking-chunks.patch rename to patches/server/0077-Dont-eat-blocks-in-non-ticking-chunks.patch diff --git a/patches/server/0077-Fast-speed-check.patch b/patches/server/0078-Fast-speed-check.patch similarity index 100% rename from patches/server/0077-Fast-speed-check.patch rename to patches/server/0078-Fast-speed-check.patch diff --git a/patches/server/0079-lithium-cache-iterate-outwards.patch b/patches/server/0079-lithium-cache-iterate-outwards.patch new file mode 100644 index 0000000..8664b26 --- /dev/null +++ b/patches/server/0079-lithium-cache-iterate-outwards.patch @@ -0,0 +1,175 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: 2No2Name <2No2Name@web.de> +Date: Thu, 13 Jan 2022 15:38:29 -0500 +Subject: [PATCH] lithium: cache iterate outwards + +Original code by the PR below, licensed under GNU Lesser General Public License v3.0 +You can find the original code on https://github.com/CaffeineMC/lithium-fabric/pull/123 (Yarn mappings) + +diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a5d3aa309d3fdaab9e0fea2dfb91a080a3ac1193 +--- /dev/null ++++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java +@@ -0,0 +1,71 @@ ++package me.jellysquid.mods.lithium.common.cached_blockpos_iteration; ++ ++import it.unimi.dsi.fastutil.longs.LongArrayList; ++import it.unimi.dsi.fastutil.longs.LongList; ++import java.util.Iterator; ++import java.util.Random; ++import java.util.concurrent.ConcurrentHashMap; ++import net.minecraft.core.BlockPos; ++ ++/** ++ * @author 2No2Name, original implemenation by SuperCoder7979 and Gegy1000 ++ */ ++public class IterateOutwardsCache { ++ //POS_ZERO must not be replaced with BlockPos.ORIGIN, otherwise iterateOutwards at BlockPos.ORIGIN will not use the cache ++ public static final BlockPos POS_ZERO = new BlockPos(0,0,0); ++ ++ ++ private final ConcurrentHashMap table; ++ private final int capacity; ++ private final Random random; ++ ++ public IterateOutwardsCache(int capacity) { ++ this.capacity = capacity; ++ this.table = new ConcurrentHashMap<>(31); ++ this.random = new Random(); ++ } ++ ++ private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) { ++ // Add all positions to the cached list ++ for (BlockPos pos : BlockPos.withinManhattan(POS_ZERO, xRange, yRange, zRange)) { ++ entry.add(pos.asLong()); ++ } ++ } ++ ++ public LongList getOrCompute(int xRange, int yRange, int zRange) { ++ long key = BlockPos.asLong(xRange, yRange, zRange); ++ ++ LongArrayList entry = this.table.get(key); ++ if (entry != null) { ++ return entry; ++ } ++ ++ // Cache miss: compute and store ++ entry = new LongArrayList(128); ++ ++ this.fillPositionsWithIterateOutwards(entry, xRange, yRange, zRange); ++ ++ //decrease the array size, as of now it won't be modified anymore anyways ++ entry.trim(); ++ ++ //this might overwrite an entry as the same entry could have been computed and added during this thread's computation ++ //we do not use computeIfAbsent, as it can delay other threads for too long ++ Object previousEntry = this.table.put(key, entry); ++ ++ ++ if (previousEntry == null && this.table.size() > this.capacity) { ++ //prevent a memory leak by randomly removing about 1/8th of the elements when the exceed the desired capacity is exceeded ++ final Iterator iterator = this.table.keySet().iterator(); ++ //prevent an unlikely infinite loop caused by another thread filling the table concurrently using counting ++ for (int i = -this.capacity; iterator.hasNext() && i < 5; i++) { ++ Long key2 = iterator.next(); ++ //random is not threadsafe, but it doesn't matter here, because we don't need quality random numbers ++ if (this.random.nextInt(8) == 0 && key2 != key) { ++ iterator.remove(); ++ } ++ } ++ } ++ ++ return entry; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java +new file mode 100644 +index 0000000000000000000000000000000000000000..493661ff3ac7247b68b7b02784b09b0eaf88fc52 +--- /dev/null ++++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java +@@ -0,0 +1,46 @@ ++package me.jellysquid.mods.lithium.common.cached_blockpos_iteration; ++ ++import it.unimi.dsi.fastutil.longs.LongIterator; ++import it.unimi.dsi.fastutil.longs.LongList; ++import java.util.Iterator; ++import net.minecraft.core.BlockPos; ++ ++/** ++ * @author 2No2Name ++ */ ++public class LongList2BlockPosMutableIterable implements Iterable { ++ ++ private final LongList positions; ++ private final int xOffset, yOffset, zOffset; ++ ++ public LongList2BlockPosMutableIterable(BlockPos offset, LongList posList) { ++ this.xOffset = offset.getX(); ++ this.yOffset = offset.getY(); ++ this.zOffset = offset.getZ(); ++ this.positions = posList; ++ } ++ ++ @Override ++ public Iterator iterator() { ++ return new Iterator() { ++ ++ private final LongIterator it = LongList2BlockPosMutableIterable.this.positions.iterator(); ++ private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); ++ ++ @Override ++ public boolean hasNext() { ++ return it.hasNext(); ++ } ++ ++ @Override ++ public net.minecraft.core.BlockPos next() { ++ long nextPos = this.it.nextLong(); ++ return this.pos.set( ++ LongList2BlockPosMutableIterable.this.xOffset + BlockPos.getX(nextPos), ++ LongList2BlockPosMutableIterable.this.yOffset + BlockPos.getY(nextPos), ++ LongList2BlockPosMutableIterable.this.zOffset + BlockPos.getZ(nextPos)); ++ } ++ }; ++ } ++ ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java +index 153451ecd5b3c8e8ecb2d5ec91ccd582d4300899..4487752469f9ab95e9d2aeb76a9627dc02095d76 100644 +--- a/src/main/java/net/minecraft/core/BlockPos.java ++++ b/src/main/java/net/minecraft/core/BlockPos.java +@@ -18,6 +18,12 @@ import net.minecraft.world.phys.AABB; + import net.minecraft.world.phys.Vec3; + import org.apache.commons.lang3.Validate; + import org.slf4j.Logger; ++// JettPack start ++import it.unimi.dsi.fastutil.longs.LongList; ++import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache; ++import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.LongList2BlockPosMutableIterable; ++import static me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache.POS_ZERO; ++// JettPack end + + @Immutable + public class BlockPos extends Vec3i { +@@ -284,7 +290,18 @@ public class BlockPos extends Vec3i { + }; + } + ++ // JettPack start - lithium: cached iterate outwards ++ private static final IterateOutwardsCache ITERATE_OUTWARDS_CACHE = new IterateOutwardsCache(50); ++ private static final LongList HOGLIN_PIGLIN_CACHE = ITERATE_OUTWARDS_CACHE.getOrCompute(8, 4, 8); ++ // JettPack end ++ + public static Iterable withinManhattan(BlockPos center, int rangeX, int rangeY, int rangeZ) { ++ // JettPack start - lithium: cached iterate outwards ++ if (center != POS_ZERO) { ++ final LongList positions = rangeX == 8 && rangeY == 4 && rangeZ == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(rangeX, rangeY, rangeZ); ++ return new LongList2BlockPosMutableIterable(center, positions); ++ } ++ // JettPack end + int i = rangeX + rangeY + rangeZ; + // Paper start - rename variables to fix conflict with anonymous class (remap fix) + int centerX = center.getX(); diff --git a/patches/server/0080-lithium-ai.raid.patch b/patches/server/0080-lithium-ai.raid.patch new file mode 100644 index 0000000..fa3c7ac --- /dev/null +++ b/patches/server/0080-lithium-ai.raid.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: jellysquid3 +Date: Tue, 18 Jan 2022 10:37:18 -0500 +Subject: [PATCH] lithium: ai.raid + +Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0 +You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings) + +diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java +index 6a0a1731fd6804eb69d3641213712d31bce085b2..5f4bb589474ce7d4f214e32ab0bc4b9cb71638d0 100644 +--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java ++++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java +@@ -269,7 +269,16 @@ public class Raid { + this.status = Raid.RaidStatus.STOPPED; + } + ++ private boolean isBarDirty; // JettPack + public void tick() { ++ // JettPack start - lithium: ai.raid ++ if (this.isBarDirty) { ++ this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F)); ++ ++ this.isBarDirty = false; ++ } ++ // JettPack end ++ + if (!this.isStopped()) { + if (this.status == Raid.RaidStatus.ONGOING) { + boolean flag = this.active; +@@ -626,7 +635,7 @@ public class Raid { + } + + public void updateBossbar() { +- this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F)); ++ this.isBarDirty = true; // JettPack - lithium: ai.raid + } + + public float getHealthOfLivingRaiders() { +diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java +index 4bb9730b6a42702e91467f980b9f045585039db3..7ba9c7f995c2bacc8f9a86a78747ea30f45eb59a 100644 +--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java ++++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java +@@ -46,8 +46,9 @@ import net.minecraft.world.phys.Vec3; + public abstract class Raider extends PatrollingMonster { + + protected static final EntityDataAccessor IS_CELEBRATING = SynchedEntityData.defineId(Raider.class, EntityDataSerializers.BOOLEAN); ++ public static final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // JettPack - lithium: ai.raid + static final Predicate ALLOWED_ITEMS = (entityitem) -> { +- return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), Raid.getLeaderBannerInstance()); ++ return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), CACHED_OMINOUS_BANNER); // JettPack - lithium: ai.raid + }; + @Nullable + protected Raid raid; +@@ -149,7 +150,7 @@ public abstract class Raider extends PatrollingMonster { + } + } + +- if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance()) && entityhuman != null) { ++ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, CACHED_OMINOUS_BANNER) && entityhuman != null) { // JettPack - lithium: ai.raid + MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); + byte b0 = 1; + int i; +@@ -304,6 +305,7 @@ public abstract class Raider extends PatrollingMonster { + public class ObtainRaidLeaderBannerGoal extends Goal { + + private final T mob; ++ private static final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // JettPack + + public ObtainRaidLeaderBannerGoal(T entityraider) { // CraftBukkit - decompile error + this.mob = entityraider; +@@ -315,7 +317,7 @@ public abstract class Raider extends PatrollingMonster { + if (!this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items + Raid raid = this.mob.getCurrentRaid(); + +- if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance())) { ++ if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), CACHED_OMINOUS_BANNER)) { // JettPack - lithium: ai.raid + Raider entityraider = raid.getLeader(this.mob.getWave()); + + if (entityraider == null || !entityraider.isAlive()) { diff --git a/patches/server/0080-lithium-gen.cached_generator_settings.patch b/patches/server/0080-lithium-gen.cached_generator_settings.patch deleted file mode 100644 index e0d247c..0000000 --- a/patches/server/0080-lithium-gen.cached_generator_settings.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: SuperCoder7979 <25208576+SuperCoder7979@users.noreply.github.com> -Date: Fri, 22 Jan 2021 16:38:19 -0500 -Subject: [PATCH] lithium: gen.cached_generator_settings - -Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0 -You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings) - -diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -index df1db87d2dd5076fccea6a1ac9271a9d786729bb..47e611d674865f4c6e36032df61bb9bf284f5286 100644 ---- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java -@@ -67,6 +67,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - public final Registry noises; - public final Holder settings; - private final Aquifer.FluidPicker globalFluidPicker; -+ private final int cachedSeaLevel; // Mirai - lithium: gen.cached_generator_settings - - public NoiseBasedChunkGenerator(Registry structureSetRegistry, Registry noiseRegistry, BiomeSource populationSource, Holder holder) { - super(structureSetRegistry, Optional.empty(), populationSource); -@@ -83,6 +84,8 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - this.globalFluidPicker = (j, k, l) -> { - return k < Math.min(-54, i) ? aquifer_b : aquifer_b1; - }; -+ -+ this.cachedSeaLevel = ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); // Mirai - lithium: gen.cached_generator_settings - } - - @Override -@@ -400,7 +403,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { - - @Override - public int getSeaLevel() { -- return ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); -+ return this.cachedSeaLevel; // Mirai - lithium: gen.cached_generator_settings - } - - @Override diff --git a/patches/server/0078-lithium-block.moving_block_shapes.patch b/patches/server/0081-lithium-block.moving_block_shapes.patch similarity index 100% rename from patches/server/0078-lithium-block.moving_block_shapes.patch rename to patches/server/0081-lithium-block.moving_block_shapes.patch diff --git a/patches/server/0079-lithium-shapes.blockstate_cache.patch b/patches/server/0082-lithium-shapes.blockstate_cache.patch similarity index 100% rename from patches/server/0079-lithium-shapes.blockstate_cache.patch rename to patches/server/0082-lithium-shapes.blockstate_cache.patch diff --git a/patches/server/0083-lithium-gen.patch b/patches/server/0083-lithium-gen.patch new file mode 100644 index 0000000..d1e4ca3 --- /dev/null +++ b/patches/server/0083-lithium-gen.patch @@ -0,0 +1,243 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SuperCoder7979 <25208576+SuperCoder7979@users.noreply.github.com> +Date: Fri, 22 Jan 2021 16:38:19 -0500 +Subject: [PATCH] lithium: gen + +Original code by CaffeineMC, licensed under GNU Lesser General Public License v3.0 +You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings) + +diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c99eff34c1be07508c88fe9525c3ae1a087fdef7 +--- /dev/null ++++ b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java +@@ -0,0 +1,92 @@ ++package me.jellysquid.mods.lithium.common.util; ++ ++import net.minecraft.core.SectionPos; ++import net.minecraft.world.level.LevelHeightAccessor; ++ ++public class Pos { ++ ++ public static class BlockCoord { ++ public static int getYSize(LevelHeightAccessor view) { ++ return view.getHeight(); ++ } ++ public static int getMinY(LevelHeightAccessor view) { ++ return view.getMinBuildHeight(); ++ } ++ public static int getMaxYInclusive(LevelHeightAccessor view) { ++ return view.getMaxBuildHeight() - 1; ++ } ++ public static int getMaxYExclusive(LevelHeightAccessor view) { ++ return view.getMaxBuildHeight(); ++ } ++ ++ public static int getMaxInSectionCoord(int sectionCoord) { ++ return 15 + getMinInSectionCoord(sectionCoord); ++ } ++ ++ public static int getMaxYInSectionIndex(LevelHeightAccessor view, int sectionIndex){ ++ return getMaxInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex)); ++ } ++ ++ public static int getMinInSectionCoord(int sectionCoord) { ++ return SectionPos.sectionToBlockCoord(sectionCoord); ++ } ++ ++ public static int getMinYInSectionIndex(LevelHeightAccessor view, int sectionIndex) { ++ return getMinInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex)); ++ } ++ } ++ ++ public static class ChunkCoord { ++ public static int fromBlockCoord(int blockCoord) { ++ return SectionPos.blockToSectionCoord(blockCoord); ++ } ++ ++ public static int fromBlockSize(int i) { ++ return i >> 4; //same method as fromBlockCoord, just be clear about coord/size semantic difference ++ } ++ } ++ ++ public static class SectionYCoord { ++ public static int getNumYSections(LevelHeightAccessor view) { ++ return view.getSectionsCount(); ++ } ++ public static int getMinYSection(LevelHeightAccessor view) { ++ return view.getMinSection(); ++ } ++ public static int getMaxYSectionInclusive(LevelHeightAccessor view) { ++ return view.getMaxSection() - 1; ++ } ++ public static int getMaxYSectionExclusive(LevelHeightAccessor view) { ++ return view.getMaxSection(); ++ } ++ ++ public static int fromSectionIndex(LevelHeightAccessor view, int sectionCoord) { ++ return sectionCoord + SectionYCoord.getMinYSection(view); ++ } ++ public static int fromBlockCoord(int blockCoord) { ++ return SectionPos.blockToSectionCoord(blockCoord); ++ } ++ } ++ ++ public static class SectionYIndex { ++ public static int getNumYSections(LevelHeightAccessor view) { ++ return view.getSectionsCount(); ++ } ++ public static int getMinYSectionIndex(LevelHeightAccessor view) { ++ return 0; ++ } ++ public static int getMaxYSectionIndexInclusive(LevelHeightAccessor view) { ++ return view.getSectionsCount() - 1; ++ } ++ public static int getMaxYSectionIndexExclusive(LevelHeightAccessor view) { ++ return view.getSectionsCount(); ++ } ++ ++ public static int fromSectionCoord(LevelHeightAccessor view, int sectionCoord) { ++ return sectionCoord - SectionYCoord.getMinYSection(view); ++ } ++ public static int fromBlockCoord(LevelHeightAccessor view, int blockCoord) { ++ return fromSectionCoord(view, SectionPos.blockToSectionCoord(blockCoord)); ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java +index d37ba3fec0e4011629a5fbc88d377d52267ad395..4967605f46a58ad9888c6a997f950f50d1bd5d1e 100644 +--- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java ++++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java +@@ -53,6 +53,7 @@ import net.minecraft.world.phys.Vec3; + import net.minecraft.world.ticks.LevelTickAccess; + import net.minecraft.world.ticks.WorldGenTickAccess; + import org.slf4j.Logger; ++import me.jellysquid.mods.lithium.common.util.Pos; // Mirai - lithium: gen + + public class WorldGenRegion implements WorldGenLevel { + +@@ -81,6 +82,8 @@ public class WorldGenRegion implements WorldGenLevel { + private Supplier currentlyGenerating; + private final AtomicLong subTickCount = new AtomicLong(); + private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random"); ++ private ChunkAccess[] chunksArr; // Mirai - lithium: gen ++ private int minChunkX, minChunkZ; // Mirai - lithium: gen + + public WorldGenRegion(ServerLevel world, List chunks, ChunkStatus status, int placementRadius) { + this.generatingStatus = status; +@@ -103,6 +106,12 @@ public class WorldGenRegion implements WorldGenLevel { + this.lastPos = ((ChunkAccess) chunks.get(chunks.size() - 1)).getPos(); + this.structureManager = world.structureManager().forWorldGenRegion(this); + } ++ // Mirai start - lithium: gen ++ this.minChunkX = this.firstPos.x; ++ this.minChunkZ = this.firstPos.z; ++ ++ this.chunksArr = chunks.toArray(new ChunkAccess[0]); ++ // Mirai end + } + + public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) { +@@ -118,11 +127,33 @@ public class WorldGenRegion implements WorldGenLevel { + this.currentlyGenerating = structureName; + } + ++ // Mirai start - lithium: gen ++ /** ++ * @reason Use the chunk array for faster access ++ * @author SuperCoder7979, 2No2Name ++ */ + @Override + public ChunkAccess getChunk(int chunkX, int chunkZ) { +- return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY); ++ int x = chunkX - this.minChunkX; ++ int z = chunkZ - this.minChunkZ; ++ int w = this.size; ++ ++ if (x >= 0 && z >= 0 && x < w && z < w) { ++ return this.chunksArr[x + z * w]; ++ } else { ++ throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ)); ++ } + } + ++ /** ++ * Use our chunk fetch function ++ */ ++ public ChunkAccess getChunk(BlockPos pos) { ++ // Skip checking chunk.getStatus().isAtLeast(ChunkStatus.EMPTY) here, because it is always true ++ return this.getChunk(Pos.ChunkCoord.fromBlockCoord(pos.getX()), Pos.ChunkCoord.fromBlockCoord(pos.getZ())); ++ } ++ // Mirai end ++ + @Nullable + @Override + public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { +@@ -178,10 +209,24 @@ public class WorldGenRegion implements WorldGenLevel { + } + // Paper end + ++ // Mirai start - lithium: gen ++ /** ++ * @reason Avoid pointer de-referencing, make method easier to inline ++ * @author JellySquid ++ */ + @Override + public BlockState getBlockState(BlockPos pos) { +- return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); ++ int x = (Pos.ChunkCoord.fromBlockCoord(pos.getX())) - this.minChunkX; ++ int z = (Pos.ChunkCoord.fromBlockCoord(pos.getZ())) - this.minChunkZ; ++ int w = this.size; ++ ++ if (x >= 0 && z >= 0 && x < w && z < w) { ++ return this.chunksArr[x + z * w].getBlockState(pos); ++ } else { ++ throw new NullPointerException("No chunk exists at " + new ChunkPos(pos)); ++ } + } ++ // Mirai end + + @Override + public FluidState getFluidState(BlockPos pos) { +diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +index df1db87d2dd5076fccea6a1ac9271a9d786729bb..a9be97c61714597dd68fbe196c90b214a4cd9647 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +@@ -67,6 +67,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + public final Registry noises; + public final Holder settings; + private final Aquifer.FluidPicker globalFluidPicker; ++ private int cachedSeaLevel; // Mirai - lithium: gen + + public NoiseBasedChunkGenerator(Registry structureSetRegistry, Registry noiseRegistry, BiomeSource populationSource, Holder holder) { + super(structureSetRegistry, Optional.empty(), populationSource); +@@ -83,6 +84,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + this.globalFluidPicker = (j, k, l) -> { + return k < Math.min(-54, i) ? aquifer_b : aquifer_b1; + }; ++ this.cachedSeaLevel = ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); // Mirai - lithium: gen + } + + @Override +@@ -398,10 +400,19 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { + return ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().height(); + } + ++ // Mirai start - lithium: gen ++ /** ++ * Use cached sea level instead of retrieving from the registry every time. ++ * This method is called for every block in the chunk so this will save a lot of registry lookups. ++ * ++ * @author SuperCoder79 ++ * @reason avoid registry lookup ++ */ + @Override + public int getSeaLevel() { +- return ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); ++ return this.cachedSeaLevel; + } ++ // Mirai end + + @Override + public int getMinY() { diff --git a/patches/server/0081-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch b/patches/server/0084-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch similarity index 100% rename from patches/server/0081-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch rename to patches/server/0084-PaperPR-Stop-large-look-changes-from-crashing-the-se.patch diff --git a/patches/server/0082-PaperPR-Add-more-collision-code-skipping-logic.patch b/patches/server/0085-PaperPR-Add-more-collision-code-skipping-logic.patch similarity index 100% rename from patches/server/0082-PaperPR-Add-more-collision-code-skipping-logic.patch rename to patches/server/0085-PaperPR-Add-more-collision-code-skipping-logic.patch diff --git a/patches/server/0083-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch b/patches/server/0086-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch similarity index 100% rename from patches/server/0083-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch rename to patches/server/0086-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch diff --git a/patches/server/0087-c2me-reduce_allocs.patch b/patches/server/0087-c2me-reduce_allocs.patch new file mode 100644 index 0000000..9899efe --- /dev/null +++ b/patches/server/0087-c2me-reduce_allocs.patch @@ -0,0 +1,258 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: ishland +Date: Mon, 24 Jan 2022 10:56:10 -0500 +Subject: [PATCH] c2me: reduce_allocs + +Copyright (c) 2021-2022 ishland + +Original code by RelativityMC, licensed under MIT +You can find the original code on https://github.com/RelativityMC/C2ME-fabric (Yarn mappings) + +diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b1229bae2e74d22065c723c6d3eaf9a97d572b04 +--- /dev/null ++++ b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java +@@ -0,0 +1,23 @@ ++package com.ishland.c2me.opts.allocs.common; ++ ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++import java.util.BitSet; ++import java.util.function.IntFunction; ++ ++public class ObjectCachingUtils { ++ ++ private static final IntFunction bitSetConstructor = BitSet::new; ++ ++ public static ThreadLocal> BITSETS = ThreadLocal.withInitial(Int2ObjectOpenHashMap::new); ++ ++ private ObjectCachingUtils() { ++ } ++ ++ public static BitSet getCachedOrNewBitSet(int bits) { ++ final BitSet bitSet = BITSETS.get().computeIfAbsent(bits, bitSetConstructor); ++ bitSet.clear(); ++ return bitSet; ++ } ++ ++} +diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4c84006c90bda4849b27879d5218f98e6d98f1dc +--- /dev/null ++++ b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java +@@ -0,0 +1,68 @@ ++package com.ishland.c2me.opts.allocs.common; ++ ++import java.util.Optional; ++import net.minecraft.core.BlockPos; ++import net.minecraft.util.RandomSource; ++import net.minecraft.world.level.WorldGenLevel; ++import net.minecraft.world.level.chunk.ChunkGenerator; ++import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; ++import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; ++import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; ++ ++public class PooledFeatureContext extends FeaturePlaceContext { ++ ++ public static final ThreadLocal>> POOL = ThreadLocal.withInitial(() -> new SimpleObjectPool<>(unused -> new PooledFeatureContext<>(), unused -> {}, 2048)); ++ ++ private Optional> feature; ++ private WorldGenLevel world; ++ private ChunkGenerator generator; ++ private RandomSource random; ++ private BlockPos origin; ++ private FC config; ++ ++ public PooledFeatureContext() { ++ super(null, null, null, null, null, null); ++ } ++ ++ public void reInit(Optional> feature, WorldGenLevel world, ChunkGenerator generator, RandomSource random, BlockPos origin, FC config) { ++ this.feature = feature; ++ this.world = world; ++ this.generator = generator; ++ this.random = random; ++ this.origin = origin; ++ this.config = config; ++ } ++ ++ public void reInit() { ++ this.feature = null; ++ this.world = null; ++ this.generator = null; ++ this.random = null; ++ this.origin = null; ++ this.config = null; ++ } ++ ++ public WorldGenLevel level() { ++ return this.world; ++ } ++ ++ public ChunkGenerator chunkGenerator() { ++ return this.generator; ++ } ++ ++ public RandomSource random() { ++ return this.random; ++ } ++ ++ public BlockPos origin() { ++ return this.origin; ++ } ++ ++ public FC config() { ++ return this.config; ++ } ++ ++ public Optional> topFeature() { ++ return this.feature; ++ } ++} +diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b989019847f73ba3af57f7428699c9c869d6332f +--- /dev/null ++++ b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java +@@ -0,0 +1,57 @@ ++package com.ishland.c2me.opts.allocs.common; ++ ++import com.google.common.base.Preconditions; ++ ++import java.util.Objects; ++import java.util.function.Consumer; ++import java.util.function.Function; ++ ++public class SimpleObjectPool { ++ ++ private final Function, T> constructor; ++ private final Consumer initializer; ++ private final int size; ++ ++ private final Object[] cachedObjects; ++ private int allocatedCount = 0; ++ ++ public SimpleObjectPool(Function, T> constructor, Consumer initializer, int size) { ++ this.constructor = Objects.requireNonNull(constructor); ++ this.initializer = Objects.requireNonNull(initializer); ++ Preconditions.checkArgument(size > 0); ++ this.cachedObjects = new Object[size]; ++ this.size = size; ++ ++ for (int i = 0; i < size; i++) { ++ final T object = constructor.apply(this); ++ this.cachedObjects[i] = object; ++ } ++ } ++ ++ public T alloc() { ++ final T object; ++ synchronized (this) { ++ if (this.allocatedCount >= this.size) { // oversized, falling back to normal alloc ++ object = this.constructor.apply(this); ++ return object; ++ } ++ ++ // get an object from the array ++ final int ordinal = this.allocatedCount++; ++ object = (T) this.cachedObjects[ordinal]; ++ this.cachedObjects[ordinal] = null; ++ } ++ ++ this.initializer.accept(object); // initialize the object ++ ++ return object; ++ } ++ ++ public void release(T object) { ++ synchronized (this) { ++ if (this.allocatedCount == 0) return; // pool is full ++ this.cachedObjects[--this.allocatedCount] = object; // store the object into the pool ++ } ++ } ++ ++} +diff --git a/src/main/java/net/minecraft/resources/ResourceLocation.java b/src/main/java/net/minecraft/resources/ResourceLocation.java +index 7017dd42f832d928f1008a05f01701667d951644..4e767dd8f9594e8a8f5d71e2bfd8c976c0032f98 100644 +--- a/src/main/java/net/minecraft/resources/ResourceLocation.java ++++ b/src/main/java/net/minecraft/resources/ResourceLocation.java +@@ -27,6 +27,7 @@ public class ResourceLocation implements Comparable { + public static final String REALMS_NAMESPACE = "realms"; + protected final String namespace; + protected final String path; ++ private String cachedString = null; // Mirai - c2me: opts allocs + + protected ResourceLocation(String[] id) { + this.namespace = StringUtils.isEmpty(id[0]) ? "minecraft" : id[0]; +@@ -99,7 +100,16 @@ public class ResourceLocation implements Comparable { + + @Override + public String toString() { +- return this.namespace + ":" + this.path; ++ // Mirai start - c2me: opts allocs ++ /** ++ * @author ishland ++ * @reason cache toString ++ */ ++ if (this.cachedString != null) return this.cachedString; ++ final String s = this.namespace + ":" + this.path; ++ this.cachedString = s; ++ return s; ++ // Mirai end + } + + @Override +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java +index 2f67705132df06ae6231dd1b89a4f61a90616ef5..1013df19df55316200169f6c3deec8876ea4686a 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ConfiguredFeature.java +@@ -12,6 +12,10 @@ import net.minecraft.util.RandomSource; + import net.minecraft.world.level.WorldGenLevel; + import net.minecraft.world.level.chunk.ChunkGenerator; + import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; ++// Mirai start - c2me: opts allocs ++import com.ishland.c2me.opts.allocs.common.PooledFeatureContext; ++import com.ishland.c2me.opts.allocs.common.SimpleObjectPool; ++// Mirai end + + public record ConfiguredFeature>(F feature, FC config) { + public static final Codec> DIRECT_CODEC = Registry.FEATURE.byNameCodec().dispatch((configuredFeature) -> { +@@ -21,7 +25,22 @@ public record ConfiguredFeature>> LIST_CODEC = RegistryCodecs.homogeneousList(Registry.CONFIGURED_FEATURE_REGISTRY, DIRECT_CODEC); + + public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, RandomSource random, BlockPos origin) { +- return this.feature.place(this.config, world, chunkGenerator, random, origin); ++ // Mirai start - c2me: opts allocs ++ /** ++ * @author ishland ++ * @reason pool FeatureContext ++ */ ++ if (!world.ensureCanWrite(origin)) return false; ++ final SimpleObjectPool> pool = PooledFeatureContext.POOL.get(); ++ final PooledFeatureContext context = (PooledFeatureContext) pool.alloc(); ++ try { ++ context.reInit(java.util.Optional.empty(), world, chunkGenerator, random, origin, this.config); ++ return this.feature.place(context); ++ } finally { ++ context.reInit(); ++ pool.release(context); ++ } ++ // Mirai end + } + + public Stream> getFeatures() { +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java +index b2f36a998437e2a63a3cbc6c3aa95b1402bff2f1..d69a57f67eeb99f3db4f80d13b9f0276ce4603af 100644 +--- a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java +@@ -54,7 +54,7 @@ public class OreFeature extends Feature { + + protected boolean doPlace(WorldGenLevel world, RandomSource randomSource, OreConfiguration config, double startX, double endX, double startZ, double endZ, double startY, double endY, int x, int y, int z, int horizontalSize, int verticalSize) { + int i = 0; +- BitSet bitSet = new BitSet(horizontalSize * verticalSize * horizontalSize); ++ BitSet bitSet = com.ishland.c2me.opts.allocs.common.ObjectCachingUtils.getCachedOrNewBitSet(horizontalSize * verticalSize * horizontalSize); // Mirai - c2me: opts allocs + BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); + int j = config.size; + double[] ds = new double[j * 4]; diff --git a/patches/server/0084-lithium-ai.sensor.secondary_poi.patch b/patches/server/0088-lithium-ai.sensor.secondary_poi.patch similarity index 100% rename from patches/server/0084-lithium-ai.sensor.secondary_poi.patch rename to patches/server/0088-lithium-ai.sensor.secondary_poi.patch diff --git a/patches/server/0085-Fix-tick-function-tag-running-before-load.patch b/patches/server/0089-Fix-tick-function-tag-running-before-load.patch similarity index 100% rename from patches/server/0085-Fix-tick-function-tag-running-before-load.patch rename to patches/server/0089-Fix-tick-function-tag-running-before-load.patch diff --git a/patches/server/0086-lithium-suffocation.patch b/patches/server/0090-lithium-suffocation.patch similarity index 100% rename from patches/server/0086-lithium-suffocation.patch rename to patches/server/0090-lithium-suffocation.patch diff --git a/patches/server/0087-Optimize-default-values-for-configs.patch b/patches/server/0091-Optimize-default-values-for-configs.patch similarity index 100% rename from patches/server/0087-Optimize-default-values-for-configs.patch rename to patches/server/0091-Optimize-default-values-for-configs.patch diff --git a/patches/server/0088-Configurable-map-update-interval.patch b/patches/server/0092-Configurable-map-update-interval.patch similarity index 100% rename from patches/server/0088-Configurable-map-update-interval.patch rename to patches/server/0092-Configurable-map-update-interval.patch diff --git a/patches/server/0089-Fix-hunger-saturation-depleting-on-peaceful.patch b/patches/server/0093-Fix-hunger-saturation-depleting-on-peaceful.patch similarity index 100% rename from patches/server/0089-Fix-hunger-saturation-depleting-on-peaceful.patch rename to patches/server/0093-Fix-hunger-saturation-depleting-on-peaceful.patch diff --git a/patches/server/0090-Fix-mobs-attacking-themselves.patch b/patches/server/0094-Fix-mobs-attacking-themselves.patch similarity index 100% rename from patches/server/0090-Fix-mobs-attacking-themselves.patch rename to patches/server/0094-Fix-mobs-attacking-themselves.patch diff --git a/patches/server/0091-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch b/patches/server/0095-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch similarity index 100% rename from patches/server/0091-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch rename to patches/server/0095-Fix-brewing-stands-resetting-their-brewTime-when-bei.patch diff --git a/patches/server/0092-lithium-world.tick_scheduler.patch b/patches/server/0096-lithium-world.tick_scheduler.patch similarity index 100% rename from patches/server/0092-lithium-world.tick_scheduler.patch rename to patches/server/0096-lithium-world.tick_scheduler.patch diff --git a/patches/server/0093-Save-Json-list-asynchronously.patch b/patches/server/0097-Save-Json-list-asynchronously.patch similarity index 100% rename from patches/server/0093-Save-Json-list-asynchronously.patch rename to patches/server/0097-Save-Json-list-asynchronously.patch diff --git a/patches/server/0094-Swaps-the-predicate-order-of-collision.patch b/patches/server/0098-Swaps-the-predicate-order-of-collision.patch similarity index 100% rename from patches/server/0094-Swaps-the-predicate-order-of-collision.patch rename to patches/server/0098-Swaps-the-predicate-order-of-collision.patch diff --git a/patches/server/0095-Fix-head-rotation-packet-spam.patch b/patches/server/0099-Fix-head-rotation-packet-spam.patch similarity index 100% rename from patches/server/0095-Fix-head-rotation-packet-spam.patch rename to patches/server/0099-Fix-head-rotation-packet-spam.patch diff --git a/patches/server/0096-Cache-block-break-animation-packet.patch b/patches/server/0100-Cache-block-break-animation-packet.patch similarity index 100% rename from patches/server/0096-Cache-block-break-animation-packet.patch rename to patches/server/0100-Cache-block-break-animation-packet.patch diff --git a/patches/server/0097-Use-more-fastutil-data-structures.patch b/patches/server/0101-Use-more-fastutil-data-structures.patch similarity index 100% rename from patches/server/0097-Use-more-fastutil-data-structures.patch rename to patches/server/0101-Use-more-fastutil-data-structures.patch