diff --git a/patches/server/0009-MC-Utils.patch b/patches/server/0009-MC-Utils.patch index 653f48c157..44889e7585 100644 --- a/patches/server/0009-MC-Utils.patch +++ b/patches/server/0009-MC-Utils.patch @@ -12,147 +12,13 @@ public net.minecraft.server.level.ServerChunkCache mainThreadProcessor public net.minecraft.server.level.ServerChunkCache$MainThreadExecutor public net.minecraft.world.level.chunk.LevelChunkSection states -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java new file mode 100644 -index 0000000000000000000000000000000000000000..554f4d4e63c1431721989e6f502a32ccc53a8807 +index 0000000000000000000000000000000000000000..ba68998f6ef57b24c72fd833bd7de440de9501cc --- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -@@ -0,0 +1,128 @@ -+package com.destroystokyo.paper.util.maplist; -+ -+import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.NoSuchElementException; -+import net.minecraft.world.level.chunk.LevelChunk; -+ -+// list with O(1) remove & contains -+/** -+ * @author Spottedleaf -+ */ -+public final class ChunkList implements Iterable { -+ -+ protected final Long2IntOpenHashMap chunkToIndex = new Long2IntOpenHashMap(2, 0.8f); -+ { -+ this.chunkToIndex.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ protected static final LevelChunk[] EMPTY_LIST = new LevelChunk[0]; -+ -+ protected LevelChunk[] chunks = EMPTY_LIST; -+ protected int count; -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public boolean contains(final LevelChunk chunk) { -+ return this.chunkToIndex.containsKey(chunk.coordinateKey); -+ } -+ -+ public boolean remove(final LevelChunk chunk) { -+ final int index = this.chunkToIndex.remove(chunk.coordinateKey); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entity at the end to this index -+ final int endIndex = --this.count; -+ final LevelChunk end = this.chunks[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.chunkToIndex.put(end.coordinateKey, index); // update index -+ } -+ this.chunks[index] = end; -+ this.chunks[endIndex] = null; -+ -+ return true; -+ } -+ -+ public boolean add(final LevelChunk chunk) { -+ final int count = this.count; -+ final int currIndex = this.chunkToIndex.putIfAbsent(chunk.coordinateKey, count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ LevelChunk[] list = this.chunks; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.chunks = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = chunk; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public LevelChunk getChecked(final int index) { -+ if (index < 0 || index >= this.count) { -+ throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); -+ } -+ return this.chunks[index]; -+ } -+ -+ public LevelChunk getUnchecked(final int index) { -+ return this.chunks[index]; -+ } -+ -+ public LevelChunk[] getRawData() { -+ return this.chunks; -+ } -+ -+ public void clear() { -+ this.chunkToIndex.clear(); -+ Arrays.fill(this.chunks, 0, this.count, null); -+ this.count = 0; -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new Iterator() { -+ -+ LevelChunk lastRet; -+ int current; -+ -+ @Override -+ public boolean hasNext() { -+ return this.current < ChunkList.this.count; -+ } -+ -+ @Override -+ public LevelChunk next() { -+ if (this.current >= ChunkList.this.count) { -+ throw new NoSuchElementException(); -+ } -+ return this.lastRet = ChunkList.this.chunks[this.current++]; -+ } -+ -+ @Override -+ public void remove() { -+ final LevelChunk lastRet = this.lastRet; -+ -+ if (lastRet == null) { -+ throw new IllegalStateException(); -+ } -+ this.lastRet = null; -+ -+ ChunkList.this.remove(lastRet); -+ --this.current; -+ } -+ }; -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0133ea6feb1ab88f021f66855669f58367e7420b ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/EntityList.java -@@ -0,0 +1,128 @@ -+package com.destroystokyo.paper.util.maplist; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +@@ -0,0 +1,129 @@ ++package ca.spottedleaf.moonrise.common.list; + +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import net.minecraft.world.entity.Entity; @@ -161,6 +27,7 @@ index 0000000000000000000000000000000000000000..0133ea6feb1ab88f021f66855669f583 +import java.util.NoSuchElementException; + +// list with O(1) remove & contains ++ +/** + * @author Spottedleaf + */ @@ -280,13 +147,13 @@ index 0000000000000000000000000000000000000000..0133ea6feb1ab88f021f66855669f583 + }; + } +} -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java new file mode 100644 -index 0000000000000000000000000000000000000000..277cfd9d1e8fff5d9b5e534b75c3c5162d58b0b7 +index 0000000000000000000000000000000000000000..fcfbca333234c09f7c056bbfcd9ac8860b20a8db --- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/IBlockDataList.java -@@ -0,0 +1,128 @@ -+package com.destroystokyo.paper.util.maplist; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java +@@ -0,0 +1,125 @@ ++package ca.spottedleaf.moonrise.common.list; + +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; @@ -295,12 +162,9 @@ index 0000000000000000000000000000000000000000..277cfd9d1e8fff5d9b5e534b75c3c516 +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.GlobalPalette; + -+/** -+ * @author Spottedleaf -+ */ +public final class IBlockDataList { + -+ static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); ++ private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); + + // map of location -> (index | (location << 16) | (palette id << 32)) + private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); @@ -414,33 +278,365 @@ index 0000000000000000000000000000000000000000..277cfd9d1e8fff5d9b5e534b75c3c516 + return this.map.values().iterator(); + } +} -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java new file mode 100644 -index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb3498ddffe1 +index 0000000000000000000000000000000000000000..c21e00812f1aaa1279834a0562d360d6b89e146c --- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/ReferenceList.java -@@ -0,0 +1,125 @@ -+package com.destroystokyo.paper.util.maplist; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java +@@ -0,0 +1,312 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2IntMap; ++import java.util.Arrays; ++import java.util.NoSuchElementException; ++ ++public final class IteratorSafeOrderedReferenceSet { ++ ++ public static final int ITERATOR_FLAG_SEE_ADDITIONS = 1 << 0; ++ ++ private final Reference2IntLinkedOpenHashMap indexMap; ++ private int firstInvalidIndex = -1; ++ ++ /* list impl */ ++ private E[] listElements; ++ private int listSize; ++ ++ private final double maxFragFactor; ++ ++ private int iteratorCount; ++ ++ public IteratorSafeOrderedReferenceSet() { ++ this(16, 0.75f, 16, 0.2); ++ } ++ ++ public IteratorSafeOrderedReferenceSet(final int setCapacity, final float setLoadFactor, final int arrayCapacity, ++ final double maxFragFactor) { ++ this.indexMap = new Reference2IntLinkedOpenHashMap<>(setCapacity, setLoadFactor); ++ this.indexMap.defaultReturnValue(-1); ++ this.maxFragFactor = maxFragFactor; ++ this.listElements = (E[])new Object[arrayCapacity]; ++ } ++ ++ /* ++ public void check() { ++ int iterated = 0; ++ ReferenceOpenHashSet check = new ReferenceOpenHashSet<>(); ++ if (this.listElements != null) { ++ for (int i = 0; i < this.listSize; ++i) { ++ Object obj = this.listElements[i]; ++ if (obj != null) { ++ iterated++; ++ if (!check.add((E)obj)) { ++ throw new IllegalStateException("contains duplicate"); ++ } ++ if (!this.contains((E)obj)) { ++ throw new IllegalStateException("desync"); ++ } ++ } ++ } ++ } ++ ++ if (iterated != this.size()) { ++ throw new IllegalStateException("Size is mismatched! Got " + iterated + ", expected " + this.size()); ++ } ++ ++ check.clear(); ++ iterated = 0; ++ for (final java.util.Iterator iterator = this.unsafeIterator(IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS); iterator.hasNext();) { ++ final E element = iterator.next(); ++ iterated++; ++ if (!check.add(element)) { ++ throw new IllegalStateException("contains duplicate (iterator is wrong)"); ++ } ++ if (!this.contains(element)) { ++ throw new IllegalStateException("desync (iterator is wrong)"); ++ } ++ } ++ ++ if (iterated != this.size()) { ++ throw new IllegalStateException("Size is mismatched! (iterator is wrong) Got " + iterated + ", expected " + this.size()); ++ } ++ } ++ */ ++ ++ private double getFragFactor() { ++ return 1.0 - ((double)this.indexMap.size() / (double)this.listSize); ++ } ++ ++ public int createRawIterator() { ++ ++this.iteratorCount; ++ if (this.indexMap.isEmpty()) { ++ return -1; ++ } else { ++ return this.firstInvalidIndex == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0; ++ } ++ } ++ ++ public int advanceRawIterator(final int index) { ++ final E[] elements = this.listElements; ++ int ret = index + 1; ++ for (int len = this.listSize; ret < len; ++ret) { ++ if (elements[ret] != null) { ++ return ret; ++ } ++ } ++ ++ return -1; ++ } ++ ++ public void finishRawIterator() { ++ if (--this.iteratorCount == 0) { ++ if (this.getFragFactor() >= this.maxFragFactor) { ++ this.defrag(); ++ } ++ } ++ } ++ ++ public boolean remove(final E element) { ++ final int index = this.indexMap.removeInt(element); ++ if (index >= 0) { ++ if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) { ++ this.firstInvalidIndex = index; ++ } ++ if (this.listElements[index] != element) { ++ throw new IllegalStateException(); ++ } ++ this.listElements[index] = null; ++ if (this.iteratorCount == 0 && this.getFragFactor() >= this.maxFragFactor) { ++ this.defrag(); ++ } ++ //this.check(); ++ return true; ++ } ++ return false; ++ } ++ ++ public boolean contains(final E element) { ++ return this.indexMap.containsKey(element); ++ } ++ ++ public boolean add(final E element) { ++ final int listSize = this.listSize; ++ ++ final int previous = this.indexMap.putIfAbsent(element, listSize); ++ if (previous != -1) { ++ return false; ++ } ++ ++ if (listSize >= this.listElements.length) { ++ this.listElements = Arrays.copyOf(this.listElements, listSize * 2); ++ } ++ this.listElements[listSize] = element; ++ this.listSize = listSize + 1; ++ ++ //this.check(); ++ return true; ++ } ++ ++ private void defrag() { ++ if (this.firstInvalidIndex < 0) { ++ return; // nothing to do ++ } ++ ++ if (this.indexMap.isEmpty()) { ++ Arrays.fill(this.listElements, 0, this.listSize, null); ++ this.listSize = 0; ++ this.firstInvalidIndex = -1; ++ //this.check(); ++ return; ++ } ++ ++ final E[] backingArray = this.listElements; ++ ++ int lastValidIndex; ++ java.util.Iterator> iterator; ++ ++ if (this.firstInvalidIndex == 0) { ++ iterator = this.indexMap.reference2IntEntrySet().fastIterator(); ++ lastValidIndex = 0; ++ } else { ++ lastValidIndex = this.firstInvalidIndex; ++ final E key = backingArray[lastValidIndex - 1]; ++ iterator = this.indexMap.reference2IntEntrySet().fastIterator(new Reference2IntMap.Entry() { ++ @Override ++ public int getIntValue() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int setValue(int i) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public E getKey() { ++ return key; ++ } ++ }); ++ } ++ ++ while (iterator.hasNext()) { ++ final Reference2IntMap.Entry entry = iterator.next(); ++ ++ final int newIndex = lastValidIndex++; ++ backingArray[newIndex] = entry.getKey(); ++ entry.setValue(newIndex); ++ } ++ ++ // cleanup end ++ Arrays.fill(backingArray, lastValidIndex, this.listSize, null); ++ this.listSize = lastValidIndex; ++ this.firstInvalidIndex = -1; ++ //this.check(); ++ } ++ ++ public E rawGet(final int index) { ++ return this.listElements[index]; ++ } ++ ++ public int size() { ++ // always returns the correct amount - listSize can be different ++ return this.indexMap.size(); ++ } ++ ++ public IteratorSafeOrderedReferenceSet.Iterator iterator() { ++ return this.iterator(0); ++ } ++ ++ public IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { ++ ++this.iteratorCount; ++ return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); ++ } ++ ++ public java.util.Iterator unsafeIterator() { ++ return this.unsafeIterator(0); ++ } ++ public java.util.Iterator unsafeIterator(final int flags) { ++ return new BaseIterator<>(this, false, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); ++ } ++ ++ public static interface Iterator extends java.util.Iterator { ++ ++ public void finishedIterating(); ++ ++ } ++ ++ private static final class BaseIterator implements IteratorSafeOrderedReferenceSet.Iterator { ++ ++ private final IteratorSafeOrderedReferenceSet set; ++ private final boolean canFinish; ++ private final int maxIndex; ++ private int nextIndex; ++ private E pendingValue; ++ private boolean finished; ++ private E lastReturned; ++ ++ private BaseIterator(final IteratorSafeOrderedReferenceSet set, final boolean canFinish, final int maxIndex) { ++ this.set = set; ++ this.canFinish = canFinish; ++ this.maxIndex = maxIndex; ++ } ++ ++ @Override ++ public boolean hasNext() { ++ if (this.finished) { ++ return false; ++ } ++ if (this.pendingValue != null) { ++ return true; ++ } ++ ++ final E[] elements = this.set.listElements; ++ int index, len; ++ for (index = this.nextIndex, len = Math.min(this.maxIndex, this.set.listSize); index < len; ++index) { ++ final E element = elements[index]; ++ if (element != null) { ++ this.pendingValue = element; ++ this.nextIndex = index + 1; ++ return true; ++ } ++ } ++ ++ this.nextIndex = index; ++ return false; ++ } ++ ++ @Override ++ public E next() { ++ if (!this.hasNext()) { ++ throw new NoSuchElementException(); ++ } ++ final E ret = this.pendingValue; ++ ++ this.pendingValue = null; ++ this.lastReturned = ret; ++ ++ return ret; ++ } ++ ++ @Override ++ public void remove() { ++ final E lastReturned = this.lastReturned; ++ if (lastReturned == null) { ++ throw new IllegalStateException(); ++ } ++ this.lastReturned = null; ++ this.set.remove(lastReturned); ++ } ++ ++ @Override ++ public void finishedIterating() { ++ if (this.finished || !this.canFinish) { ++ throw new IllegalStateException(); ++ } ++ this.lastReturned = null; ++ this.finished = true; ++ this.set.finishRawIterator(); ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2e876b918672e8ef3b5197b7e6b1597247fdeaa1 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java +@@ -0,0 +1,142 @@ ++package ca.spottedleaf.moonrise.common.list; + +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import java.util.Arrays; +import java.util.Iterator; +import java.util.NoSuchElementException; + -+/** -+ * @author Spottedleaf -+ */ +public final class ReferenceList implements Iterable { + -+ protected final Reference2IntOpenHashMap referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f); -+ { ++ private static final Object[] EMPTY_LIST = new Object[0]; ++ ++ private final Reference2IntOpenHashMap referenceToIndex; ++ private E[] references; ++ private int count; ++ ++ public ReferenceList() { ++ this((E[])EMPTY_LIST); ++ } ++ ++ public ReferenceList(final E[] referenceArray) { ++ this.references = referenceArray; ++ this.referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f); + this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE); + } + -+ protected static final Object[] EMPTY_LIST = new Object[0]; ++ private ReferenceList(final E[] references, final int count, final Reference2IntOpenHashMap referenceToIndex) { ++ this.references = references; ++ this.count = count; ++ this.referenceToIndex = referenceToIndex; ++ } + -+ protected Object[] references = EMPTY_LIST; -+ protected int count; ++ public ReferenceList copy() { ++ return new ReferenceList<>(this.references.clone(), this.count, this.referenceToIndex.clone()); ++ } + + public int size() { + return this.count; @@ -477,7 +673,7 @@ index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb34 + return false; // already in this list + } + -+ Object[] list = this.references; ++ E[] list = this.references; + + if (list.length == count) { + // resize required @@ -494,17 +690,21 @@ index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb34 + if (index < 0 || index >= this.count) { + throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); + } -+ return (E)this.references[index]; ++ return this.references[index]; + } + + public E getUnchecked(final int index) { -+ return (E)this.references[index]; ++ return this.references[index]; + } + + public Object[] getRawData() { + return this.references; + } + ++ public E[] getRawDataUnchecked() { ++ return this.references; ++ } ++ + public void clear() { + this.referenceToIndex.clear(); + Arrays.fill(this.references, 0, this.count, null); @@ -527,7 +727,7 @@ index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb34 + if (this.current >= ReferenceList.this.count) { + throw new NoSuchElementException(); + } -+ return this.lastRet = (E)ReferenceList.this.references[this.current++]; ++ return this.lastRet = ReferenceList.this.references[this.current++]; + } + + @Override @@ -545,305 +745,2028 @@ index 0000000000000000000000000000000000000000..190c5f0b02a3d99054704ae1afbffb34 + }; + } +} -diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java new file mode 100644 -index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9690e967d +index 0000000000000000000000000000000000000000..db92261a6cb3758391108361096417c61bc82cdc --- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java -@@ -0,0 +1,453 @@ -+package com.destroystokyo.paper.util.misc; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java +@@ -0,0 +1,117 @@ ++package ca.spottedleaf.moonrise.common.list; ++ ++import java.lang.reflect.Array; ++import java.util.Arrays; ++import java.util.Comparator; ++ ++public final class SortedList { ++ ++ private static final Object[] EMPTY_LIST = new Object[0]; ++ ++ private Comparator comparator; ++ private E[] elements; ++ private int count; ++ ++ public SortedList(final Comparator comparator) { ++ this((E[])EMPTY_LIST, comparator); ++ } ++ ++ public SortedList(final E[] elements, final Comparator comparator) { ++ this.elements = elements; ++ this.comparator = comparator; ++ } ++ ++ // start, end are inclusive ++ private static int insertIdx(final E[] elements, final E element, final Comparator comparator, ++ int start, int end) { ++ while (start <= end) { ++ final int middle = (start + end) >>> 1; ++ ++ final E middleVal = elements[middle]; ++ ++ final int cmp = comparator.compare(element, middleVal); ++ ++ if (cmp < 0) { ++ end = middle - 1; ++ } else { ++ start = middle + 1; ++ } ++ } ++ ++ return start; ++ } ++ ++ public int size() { ++ return this.count; ++ } ++ ++ public boolean isEmpty() { ++ return this.count == 0; ++ } ++ ++ public int add(final E element) { ++ E[] elements = this.elements; ++ final int count = this.count; ++ this.count = count + 1; ++ final Comparator comparator = this.comparator; ++ ++ final int idx = insertIdx(elements, element, comparator, 0, count - 1); ++ ++ if (count >= elements.length) { ++ // copy and insert at the same time ++ if (idx == count) { ++ this.elements = elements = Arrays.copyOf(elements, (int)Math.max(4L, count * 2L)); // overflow results in negative ++ elements[count] = element; ++ return idx; ++ } else { ++ final E[] newElements = (E[])Array.newInstance(elements.getClass().getComponentType(), (int)Math.max(4L, count * 2L)); ++ System.arraycopy(elements, 0, newElements, 0, idx); ++ newElements[idx] = element; ++ System.arraycopy(elements, idx, newElements, idx + 1, count - idx); ++ this.elements = newElements; ++ return idx; ++ } ++ } else { ++ if (idx == count) { ++ // no copy needed ++ elements[idx] = element; ++ return idx; ++ } else { ++ // shift elements down ++ System.arraycopy(elements, idx, elements, idx + 1, count - idx); ++ elements[idx] = element; ++ return idx; ++ } ++ } ++ } ++ ++ public E get(final int idx) { ++ if (idx < 0 || idx >= this.count) { ++ throw new IndexOutOfBoundsException(idx); ++ } ++ return this.elements[idx]; ++ } ++ ++ ++ public E remove(final E element) { ++ E[] elements = this.elements; ++ final int count = this.count; ++ final Comparator comparator = this.comparator; ++ ++ final int idx = Arrays.binarySearch(elements, 0, count, element, comparator); ++ if (idx < 0) { ++ return null; ++ } ++ ++ final int last = this.count - 1; ++ this.count = last; ++ ++ final E ret = elements[idx]; ++ ++ System.arraycopy(elements, idx + 1, elements, idx, last - idx); ++ ++ elements[last] = null; ++ ++ return ret; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..62caf61a4b0b7ebc764006ea8bbd0274594d9f4a +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.map; ++ ++import it.unimi.dsi.fastutil.ints.Int2IntFunction; ++ ++import java.util.Arrays; ++ ++public class Int2IntArraySortedMap { ++ ++ protected int[] key; ++ protected int[] val; ++ protected int size; ++ ++ public Int2IntArraySortedMap() { ++ this.key = new int[8]; ++ this.val = new int[8]; ++ } ++ ++ public int put(final int key, final int value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final int current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return 0; ++ } ++ ++ public int computeIfAbsent(final int key, final Int2IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public int get(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return 0; ++ } ++ return this.val[index]; ++ } ++ ++ public int getFloor(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? 0 : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fea9e8ba7caaf6259614090d4f872619470d32f9 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java +@@ -0,0 +1,74 @@ ++package ca.spottedleaf.moonrise.common.map; ++ ++import java.util.Arrays; ++import java.util.function.IntFunction; ++ ++public class Int2ObjectArraySortedMap { ++ ++ protected int[] key; ++ protected V[] val; ++ protected int size; ++ ++ public Int2ObjectArraySortedMap() { ++ this.key = new int[8]; ++ this.val = (V[])new Object[8]; ++ } ++ ++ public V put(final int key, final V value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final V current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return null; ++ } ++ ++ public V computeIfAbsent(final int key, final IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public V get(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return null; ++ } ++ return this.val[index]; ++ } ++ ++ public V getFloor(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1); ++ return this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c077ca606934e9f13da3a8e2a194f82a99fe9ae9 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.moonrise.common.map; ++ ++import it.unimi.dsi.fastutil.longs.Long2IntFunction; ++ ++import java.util.Arrays; ++ ++public class Long2IntArraySortedMap { ++ ++ protected long[] key; ++ protected int[] val; ++ protected int size; ++ ++ public Long2IntArraySortedMap() { ++ this.key = new long[8]; ++ this.val = new int[8]; ++ } ++ ++ public int put(final long key, final int value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final int current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return 0; ++ } ++ ++ public int computeIfAbsent(final long key, final Long2IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public int get(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return 0; ++ } ++ return this.val[index]; ++ } ++ ++ public int getFloor(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? 0 : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b24d037af5709196b66c79c692e1814cd5b20e49 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java +@@ -0,0 +1,76 @@ ++package ca.spottedleaf.moonrise.common.map; ++ ++import java.util.Arrays; ++import java.util.function.LongFunction; ++ ++public class Long2ObjectArraySortedMap { ++ ++ protected long[] key; ++ protected V[] val; ++ protected int size; ++ ++ public Long2ObjectArraySortedMap() { ++ this.key = new long[8]; ++ this.val = (V[])new Object[8]; ++ } ++ ++ public V put(final long key, final V value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final V current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return null; ++ } ++ ++ public V computeIfAbsent(final long key, final LongFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public V get(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return null; ++ } ++ return this.val[index]; ++ } ++ ++ public V getFloor(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? null : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..aa86882bb7b0712f29d7344009093c0e7a81be84 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java +@@ -0,0 +1,48 @@ ++package ca.spottedleaf.moonrise.common.map; ++ ++import it.unimi.dsi.fastutil.longs.Long2BooleanFunction; ++import it.unimi.dsi.fastutil.longs.Long2BooleanLinkedOpenHashMap; ++ ++public final class SynchronisedLong2BooleanMap { ++ private final Long2BooleanLinkedOpenHashMap map = new Long2BooleanLinkedOpenHashMap(); ++ private final int limit; ++ ++ public SynchronisedLong2BooleanMap(final int limit) { ++ this.limit = limit; ++ } ++ ++ // must hold lock on map ++ private void purgeEntries() { ++ while (this.map.size() > this.limit) { ++ this.map.removeLastBoolean(); ++ } ++ } ++ ++ public boolean remove(final long key) { ++ synchronized (this.map) { ++ return this.map.remove(key); ++ } ++ } ++ ++ // note: ++ public boolean getOrCompute(final long key, final Long2BooleanFunction ifAbsent) { ++ synchronized (this.map) { ++ if (this.map.containsKey(key)) { ++ return this.map.getAndMoveToFirst(key); ++ } ++ } ++ ++ final boolean put = ifAbsent.get(key); ++ ++ synchronized (this.map) { ++ if (this.map.containsKey(key)) { ++ return this.map.getAndMoveToFirst(key); ++ } ++ this.map.putAndMoveToFirst(key, put); ++ ++ this.purgeEntries(); ++ ++ return put; ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dbb51afc6cefe0071fe3ddcd2c1109f2755c3b4d +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java +@@ -0,0 +1,47 @@ ++package ca.spottedleaf.moonrise.common.map; + -+import io.papermc.paper.util.IntegerUtil; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -+import io.papermc.paper.util.MCUtil; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.world.level.ChunkPos; -+import javax.annotation.Nullable; -+import java.util.Iterator; ++import java.util.function.BiFunction; + -+/** @author Spottedleaf */ -+public abstract class AreaMap { ++public final class SynchronisedLong2ObjectMap { ++ private final Long2ObjectLinkedOpenHashMap map = new Long2ObjectLinkedOpenHashMap<>(); ++ private final int limit; + -+ /* Tested via https://gist.github.com/Spottedleaf/520419c6f41ef348fe9926ce674b7217 */ ++ public SynchronisedLong2ObjectMap(final int limit) { ++ this.limit = limit; ++ } + -+ protected final Object2LongOpenHashMap objectToLastCoordinate = new Object2LongOpenHashMap<>(); -+ protected final Object2IntOpenHashMap objectToViewDistance = new Object2IntOpenHashMap<>(); ++ // must hold lock on map ++ private void purgeEntries() { ++ while (this.map.size() > this.limit) { ++ this.map.removeLast(); ++ } ++ } + ++ public V get(final long key) { ++ synchronized (this.map) { ++ return this.map.getAndMoveToFirst(key); ++ } ++ } ++ ++ public V put(final long key, final V value) { ++ synchronized (this.map) { ++ final V ret = this.map.putAndMoveToFirst(key, value); ++ this.purgeEntries(); ++ return ret; ++ } ++ } ++ ++ public V compute(final long key, final BiFunction remappingFunction) { ++ synchronized (this.map) { ++ // first, compute the value - if one is added, it will be at the last entry ++ this.map.compute(key, remappingFunction); ++ // move the entry to first, just in case it was added at last ++ final V ret = this.map.getAndMoveToFirst(key); ++ // now purge the last entries ++ this.purgeEntries(); ++ ++ return ret; ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9c0eff9017b24bb65b1029cefb5d0bfcb9beff01 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java +@@ -0,0 +1,75 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++public final class AllocatingRateLimiter { ++ ++ // max difference granularity in ns ++ private final long maxGranularity; ++ ++ private double allocation = 0.0; ++ private long lastAllocationUpdate; ++ // the carry is used to store the remainder of the last take, so that the take amount remains the same (minus floating point error) ++ // over any time period using take regardless of the number of take calls or the intervals between the take calls ++ // i.e. take obtains 3.5 elements, stores 0.5 to this field for the next take() call to use and returns 3 ++ private double takeCarry = 0.0; ++ private long lastTakeUpdate; ++ ++ public AllocatingRateLimiter(final long maxGranularity) { ++ this.maxGranularity = maxGranularity; ++ } ++ ++ public void reset(final long time) { ++ this.allocation = 0.0; ++ this.lastAllocationUpdate = time; ++ this.takeCarry = 0.0; ++ this.lastTakeUpdate = time; ++ } ++ ++ // rate in units/s, and time in ns ++ public void tickAllocation(final long time, final double rate, final double maxAllocation) { ++ final long diff = Math.min(this.maxGranularity, time - this.lastAllocationUpdate); ++ this.lastAllocationUpdate = time; ++ ++ this.allocation = Math.min(maxAllocation - this.takeCarry, this.allocation + rate * (diff*1.0E-9D)); ++ } ++ ++ public long previewAllocation(final long time, final double rate, final long maxTake) { ++ if (maxTake < 1L) { ++ return 0L; ++ } ++ ++ final long diff = Math.min(this.maxGranularity, time - this.lastTakeUpdate); ++ ++ // note: abs(takeCarry) <= 1.0 ++ final double take = Math.min( ++ Math.min((double)maxTake - this.takeCarry, this.allocation), ++ rate * (diff*1.0E-9) ++ ); ++ ++ return (long)Math.floor(this.takeCarry + take); ++ } ++ ++ // rate in units/s, and time in ns ++ public long takeAllocation(final long time, final double rate, final long maxTake) { ++ if (maxTake < 1L) { ++ return 0L; ++ } ++ ++ double ret = this.takeCarry; ++ final long diff = Math.min(this.maxGranularity, time - this.lastTakeUpdate); ++ this.lastTakeUpdate = time; ++ ++ // note: abs(takeCarry) <= 1.0 ++ final double take = Math.min( ++ Math.min((double)maxTake - this.takeCarry, this.allocation), ++ rate * (diff*1.0E-9) ++ ); ++ ++ ret += take; ++ this.allocation -= take; ++ ++ final long retInteger = (long)Math.floor(ret); ++ this.takeCarry = ret - (double)retInteger; ++ ++ return retInteger; ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java +new file mode 100644 +index 0000000000000000000000000000000000000000..460e27ab0506c83a28934800ee74ee886d4b025e +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java +@@ -0,0 +1,297 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; ++import it.unimi.dsi.fastutil.longs.LongIterator; ++import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; ++ ++public final class Delayed26WayDistancePropagator3D { ++ ++ // this map is considered "stale" unless updates are propagated. ++ protected final Delayed8WayDistancePropagator2D.LevelMap levels = new Delayed8WayDistancePropagator2D.LevelMap(8192*2, 0.6f); ++ ++ // this map is never stale ++ protected final Long2ByteOpenHashMap sources = new Long2ByteOpenHashMap(4096, 0.6f); ++ ++ // Generally updates to positions are made close to other updates, so we link to decrease cache misses when ++ // propagating updates ++ protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet(); ++ ++ @FunctionalInterface ++ public static interface LevelChangeCallback { ++ ++ /** ++ * This can be called for intermediate updates. So do not rely on newLevel being close to or ++ * the exact level that is expected after a full propagation has occured. ++ */ ++ public void onLevelUpdate(final long coordinate, final byte oldLevel, final byte newLevel); ++ ++ } ++ ++ protected final LevelChangeCallback changeCallback; ++ ++ public Delayed26WayDistancePropagator3D() { ++ this(null); ++ } ++ ++ public Delayed26WayDistancePropagator3D(final LevelChangeCallback changeCallback) { ++ this.changeCallback = changeCallback; ++ } ++ ++ public int getLevel(final long pos) { ++ return this.levels.get(pos); ++ } ++ ++ public int getLevel(final int x, final int y, final int z) { ++ return this.levels.get(CoordinateUtils.getChunkSectionKey(x, y, z)); ++ } ++ ++ public void setSource(final int x, final int y, final int z, final int level) { ++ this.setSource(CoordinateUtils.getChunkSectionKey(x, y, z), level); ++ } ++ ++ public void setSource(final long coordinate, final int level) { ++ if ((level & 63) != level || level == 0) { ++ throw new IllegalArgumentException("Level must be in (0, 63], not " + level); ++ } ++ ++ final byte byteLevel = (byte)level; ++ final byte oldLevel = this.sources.put(coordinate, byteLevel); ++ ++ if (oldLevel == byteLevel) { ++ return; // nothing to do ++ } ++ ++ // queue to update later ++ this.updatedSources.add(coordinate); ++ } ++ ++ public void removeSource(final int x, final int y, final int z) { ++ this.removeSource(CoordinateUtils.getChunkSectionKey(x, y, z)); ++ } ++ ++ public void removeSource(final long coordinate) { ++ if (this.sources.remove(coordinate) != 0) { ++ this.updatedSources.add(coordinate); ++ } ++ } ++ ++ // queues used for BFS propagating levels ++ protected final Delayed8WayDistancePropagator2D.WorkQueue[] levelIncreaseWorkQueues = new Delayed8WayDistancePropagator2D.WorkQueue[64]; + { -+ this.objectToViewDistance.defaultReturnValue(-1); -+ this.objectToLastCoordinate.defaultReturnValue(Long.MIN_VALUE); -+ } -+ -+ // we use linked for better iteration. -+ // map of: coordinate to set of objects in coordinate -+ protected final Long2ObjectOpenHashMap> areaMap = new Long2ObjectOpenHashMap<>(1024, 0.7f); -+ protected final PooledLinkedHashSets pooledHashSets; -+ -+ protected final ChangeCallback addCallback; -+ protected final ChangeCallback removeCallback; -+ protected final ChangeSourceCallback changeSourceCallback; -+ -+ public AreaMap() { -+ this(new PooledLinkedHashSets<>()); -+ } -+ -+ // let users define a "global" or "shared" pooled sets if they wish -+ public AreaMap(final PooledLinkedHashSets pooledHashSets) { -+ this(pooledHashSets, null, null); -+ } -+ -+ public AreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, final ChangeCallback removeCallback) { -+ this(pooledHashSets, addCallback, removeCallback, null); -+ } -+ public AreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, final ChangeCallback removeCallback, final ChangeSourceCallback changeSourceCallback) { -+ this.pooledHashSets = pooledHashSets; -+ this.addCallback = addCallback; -+ this.removeCallback = removeCallback; -+ this.changeSourceCallback = changeSourceCallback; -+ } -+ -+ @Nullable -+ public final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getObjectsInRange(final long key) { -+ return this.areaMap.get(key); -+ } -+ -+ @Nullable -+ public final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getObjectsInRange(final ChunkPos chunkPos) { -+ return this.areaMap.get(MCUtil.getCoordinateKey(chunkPos)); -+ } -+ -+ @Nullable -+ public final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getObjectsInRange(final int chunkX, final int chunkZ) { -+ return this.areaMap.get(MCUtil.getCoordinateKey(chunkX, chunkZ)); -+ } -+ -+ // Long.MIN_VALUE indicates the object is not mapped -+ public final long getLastCoordinate(final E object) { -+ return this.objectToLastCoordinate.getOrDefault(object, Long.MIN_VALUE); -+ } -+ -+ // -1 indicates the object is not mapped -+ public final int getLastViewDistance(final E object) { -+ return this.objectToViewDistance.getOrDefault(object, -1); -+ } -+ -+ // returns the total number of mapped chunks -+ public final int size() { -+ return this.areaMap.size(); -+ } -+ -+ public final void addOrUpdate(final E object, final int chunkX, final int chunkZ, final int viewDistance) { -+ final int oldViewDistance = this.objectToViewDistance.put(object, viewDistance); -+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ final long oldPos = this.objectToLastCoordinate.put(object, newPos); -+ -+ if (oldViewDistance == -1) { -+ this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance); -+ this.addObjectCallback(object, chunkX, chunkZ, viewDistance); -+ } else { -+ this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance); -+ this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance); -+ } -+ //this.validate(object, viewDistance); -+ } -+ -+ public final boolean update(final E object, final int chunkX, final int chunkZ, final int viewDistance) { -+ final int oldViewDistance = this.objectToViewDistance.replace(object, viewDistance); -+ if (oldViewDistance == -1) { -+ return false; -+ } else { -+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ final long oldPos = this.objectToLastCoordinate.put(object, newPos); -+ this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance); -+ this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance); -+ } -+ //this.validate(object, viewDistance); -+ return true; -+ } -+ -+ // called after the distance map updates -+ protected void updateObjectCallback(final E Object, final long oldPosition, final long newPosition, final int oldViewDistance, final int newViewDistance) { -+ if (newPosition != oldPosition && this.changeSourceCallback != null) { -+ this.changeSourceCallback.accept(Object, oldPosition, newPosition); ++ for (int i = 0; i < this.levelIncreaseWorkQueues.length; ++i) { ++ this.levelIncreaseWorkQueues[i] = new Delayed8WayDistancePropagator2D.WorkQueue(); + } + } ++ protected final Delayed8WayDistancePropagator2D.WorkQueue[] levelRemoveWorkQueues = new Delayed8WayDistancePropagator2D.WorkQueue[64]; ++ { ++ for (int i = 0; i < this.levelRemoveWorkQueues.length; ++i) { ++ this.levelRemoveWorkQueues[i] = new Delayed8WayDistancePropagator2D.WorkQueue(); ++ } ++ } ++ protected long levelIncreaseWorkQueueBitset; ++ protected long levelRemoveWorkQueueBitset; + -+ public final boolean add(final E object, final int chunkX, final int chunkZ, final int viewDistance) { -+ final int oldViewDistance = this.objectToViewDistance.putIfAbsent(object, viewDistance); -+ if (oldViewDistance != -1) { ++ protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { ++ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[level]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelIncreaseWorkQueueBitset |= (1L << level); ++ } ++ ++ protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { ++ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[index]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelIncreaseWorkQueueBitset |= (1L << index); ++ } ++ ++ protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { ++ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[level]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelRemoveWorkQueueBitset |= (1L << level); ++ } ++ ++ public boolean propagateUpdates() { ++ if (this.updatedSources.isEmpty()) { + return false; + } + -+ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ this.objectToLastCoordinate.put(object, newPos); -+ this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance); -+ this.addObjectCallback(object, chunkX, chunkZ, viewDistance); ++ boolean ret = false; + -+ //this.validate(object, viewDistance); ++ for (final LongIterator iterator = this.updatedSources.iterator(); iterator.hasNext();) { ++ final long coordinate = iterator.nextLong(); + -+ return true; -+ } ++ final byte currentLevel = this.levels.get(coordinate); ++ final byte updatedSource = this.sources.get(coordinate); + -+ // called after the distance map updates -+ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {} -+ -+ public final boolean remove(final E object) { -+ final long position = this.objectToLastCoordinate.removeLong(object); -+ final int viewDistance = this.objectToViewDistance.removeInt(object); -+ -+ if (viewDistance == -1) { -+ return false; -+ } -+ -+ final int currentX = MCUtil.getCoordinateX(position); -+ final int currentZ = MCUtil.getCoordinateZ(position); -+ -+ this.removeObject(object, currentX, currentZ, currentX, currentZ, viewDistance); -+ this.removeObjectCallback(object, currentX, currentZ, viewDistance); -+ //this.validate(object, -1); -+ return true; -+ } -+ -+ // called after the distance map updates -+ protected void removeObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {} -+ -+ protected abstract PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getEmptySetFor(final E object); -+ -+ // expensive op, only for debug -+ protected void validate(final E object, final int viewDistance) { -+ int entiesGot = 0; -+ int expectedEntries = (2 * viewDistance + 1); -+ expectedEntries *= expectedEntries; -+ if (viewDistance < 0) { -+ expectedEntries = 0; -+ } -+ -+ final long currPosition = this.objectToLastCoordinate.getLong(object); -+ -+ final int centerX = MCUtil.getCoordinateX(currPosition); -+ final int centerZ = MCUtil.getCoordinateZ(currPosition); -+ -+ for (Iterator>> iterator = this.areaMap.long2ObjectEntrySet().fastIterator(); -+ iterator.hasNext();) { -+ -+ final Long2ObjectLinkedOpenHashMap.Entry> entry = iterator.next(); -+ final long key = entry.getLongKey(); -+ final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet map = entry.getValue(); -+ -+ if (map.referenceCount == 0) { -+ throw new IllegalStateException("Invalid map"); ++ if (currentLevel == updatedSource) { ++ continue; + } ++ ret = true; + -+ if (map.contains(object)) { -+ ++entiesGot; ++ if (updatedSource > currentLevel) { ++ // level increase ++ this.addToIncreaseWorkQueue(coordinate, updatedSource); ++ } else { ++ // level decrease ++ this.addToRemoveWorkQueue(coordinate, currentLevel); ++ // if the current coordinate is a source, then the decrease propagation will detect that and queue ++ // the source propagation ++ } ++ } + -+ final int chunkX = MCUtil.getCoordinateX(key); -+ final int chunkZ = MCUtil.getCoordinateZ(key); ++ this.updatedSources.clear(); + -+ final int dist = Math.max(IntegerUtil.branchlessAbs(chunkX - centerX), IntegerUtil.branchlessAbs(chunkZ - centerZ)); ++ // propagate source level increases first for performance reasons (in crowded areas hopefully the additions ++ // make the removes remove less) ++ this.propagateIncreases(); + -+ if (dist > viewDistance) { -+ throw new IllegalStateException("Expected view distance " + viewDistance + ", got " + dist); ++ // now we propagate the decreases (which will then re-propagate clobbered sources) ++ this.propagateDecreases(); ++ ++ return ret; ++ } ++ ++ protected void propagateIncreases() { ++ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset); ++ this.levelIncreaseWorkQueueBitset != 0L; ++ this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) { ++ ++ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; ++ while (!queue.queuedLevels.isEmpty()) { ++ final long coordinate = queue.queuedCoordinates.removeFirstLong(); ++ byte level = queue.queuedLevels.removeFirstByte(); ++ ++ final boolean neighbourCheck = level < 0; ++ ++ final byte currentLevel; ++ if (neighbourCheck) { ++ level = (byte)-level; ++ currentLevel = this.levels.get(coordinate); ++ } else { ++ currentLevel = this.levels.putIfGreater(coordinate, level); ++ } ++ ++ if (neighbourCheck) { ++ // used when propagating from decrease to indicate that this level needs to check its neighbours ++ // this means the level at coordinate could be equal, but would still need neighbours checked ++ ++ if (currentLevel != level) { ++ // something caused the level to change, which means something propagated to it (which means ++ // us propagating here is redundant), or something removed the level (which means we ++ // cannot propagate further) ++ continue; ++ } ++ } else if (currentLevel >= level) { ++ // something higher/equal propagated ++ continue; ++ } ++ if (this.changeCallback != null) { ++ this.changeCallback.onLevelUpdate(coordinate, currentLevel, level); ++ } ++ ++ if (level == 1) { ++ // can't propagate 0 to neighbours ++ continue; ++ } ++ ++ // propagate to neighbours ++ final byte neighbourLevel = (byte)(level - 1); ++ final int x = CoordinateUtils.getChunkSectionX(coordinate); ++ final int y = CoordinateUtils.getChunkSectionY(coordinate); ++ final int z = CoordinateUtils.getChunkSectionZ(coordinate); ++ ++ for (int dy = -1; dy <= 1; ++dy) { ++ for (int dz = -1; dz <= 1; ++dz) { ++ for (int dx = -1; dx <= 1; ++dx) { ++ if ((dy | dz | dx) == 0) { ++ // already propagated to coordinate ++ continue; ++ } ++ ++ // sure we can check the neighbour level in the map right now and avoid a propagation, ++ // but then we would still have to recheck it when popping the value off of the queue! ++ // so just avoid the double lookup ++ final long neighbourCoordinate = CoordinateUtils.getChunkSectionKey(dx + x, dy + y, dz + z); ++ this.addToIncreaseWorkQueue(neighbourCoordinate, neighbourLevel); ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ protected void propagateDecreases() { ++ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset); ++ this.levelRemoveWorkQueueBitset != 0L; ++ this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) { ++ ++ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; ++ while (!queue.queuedLevels.isEmpty()) { ++ final long coordinate = queue.queuedCoordinates.removeFirstLong(); ++ final byte level = queue.queuedLevels.removeFirstByte(); ++ ++ final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); ++ if (currentLevel == 0) { ++ // something else removed ++ continue; ++ } ++ ++ if (currentLevel > level) { ++ // something higher propagated here or we hit the propagation of another source ++ // in the second case we need to re-propagate because we could have just clobbered another source's ++ // propagation ++ this.addToIncreaseWorkQueue(coordinate, currentLevel, (byte)-currentLevel); // indicate to the increase code that the level's neighbours need checking ++ continue; ++ } ++ ++ if (this.changeCallback != null) { ++ this.changeCallback.onLevelUpdate(coordinate, currentLevel, (byte)0); ++ } ++ ++ final byte source = this.sources.get(coordinate); ++ if (source != 0) { ++ // must re-propagate source later ++ this.addToIncreaseWorkQueue(coordinate, source); ++ } ++ ++ if (level == 0) { ++ // can't propagate -1 to neighbours ++ // we have to check neighbours for removing 1 just in case the neighbour is 2 ++ continue; ++ } ++ ++ // propagate to neighbours ++ final byte neighbourLevel = (byte)(level - 1); ++ final int x = CoordinateUtils.getChunkSectionX(coordinate); ++ final int y = CoordinateUtils.getChunkSectionY(coordinate); ++ final int z = CoordinateUtils.getChunkSectionZ(coordinate); ++ ++ for (int dy = -1; dy <= 1; ++dy) { ++ for (int dz = -1; dz <= 1; ++dz) { ++ for (int dx = -1; dx <= 1; ++dx) { ++ if ((dy | dz | dx) == 0) { ++ // already propagated to coordinate ++ continue; ++ } ++ ++ // sure we can check the neighbour level in the map right now and avoid a propagation, ++ // but then we would still have to recheck it when popping the value off of the queue! ++ // so just avoid the double lookup ++ final long neighbourCoordinate = CoordinateUtils.getChunkSectionKey(dx + x, dy + y, dz + z); ++ this.addToRemoveWorkQueue(neighbourCoordinate, neighbourLevel); ++ } ++ } + } + } + } + -+ if (entiesGot != expectedEntries) { -+ throw new IllegalStateException("Expected " + expectedEntries + ", got " + entiesGot); -+ } ++ // propagate sources we clobbered in the process ++ this.propagateIncreases(); + } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ab2fa1563d5e32a5313dfcc1da411cab45fb5ca0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java +@@ -0,0 +1,718 @@ ++package ca.spottedleaf.moonrise.common.misc; + -+ private void addObjectTo(final E object, final int chunkX, final int chunkZ, final int currChunkX, -+ final int currChunkZ, final int prevChunkX, final int prevChunkZ) { -+ final long key = MCUtil.getCoordinateKey(chunkX, chunkZ); ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import it.unimi.dsi.fastutil.HashCommon; ++import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue; ++import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; ++import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; ++import it.unimi.dsi.fastutil.longs.LongIterator; ++import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; + -+ PooledLinkedHashSets.PooledObjectLinkedOpenHashSet empty = this.getEmptySetFor(object); -+ PooledLinkedHashSets.PooledObjectLinkedOpenHashSet current = this.areaMap.putIfAbsent(key, empty); ++public final class Delayed8WayDistancePropagator2D { + -+ if (current != null) { -+ PooledLinkedHashSets.PooledObjectLinkedOpenHashSet next = this.pooledHashSets.findMapWith(current, object); -+ if (next == current) { -+ throw new IllegalStateException("Expected different map: got " + next.toString()); -+ } -+ this.areaMap.put(key, next); ++ // Test ++ /* ++ protected static void test(int x, int z, com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap reference, Delayed8WayDistancePropagator2D test) { ++ int got = test.getLevel(x, z); + -+ current = next; -+ // fall through to callback -+ } else { -+ current = empty; -+ } -+ -+ if (this.addCallback != null) { -+ try { -+ this.addCallback.accept(object, chunkX, chunkZ, currChunkX, currChunkZ, prevChunkX, prevChunkZ, current); -+ } catch (final Throwable ex) { -+ if (ex instanceof ThreadDeath) { -+ throw (ThreadDeath)ex; ++ int expect = 0; ++ Object[] nearest = reference.getObjectsInRange(x, z) == null ? null : reference.getObjectsInRange(x, z).getBackingSet(); ++ if (nearest != null) { ++ for (Object _obj : nearest) { ++ if (_obj instanceof Ticket) { ++ Ticket ticket = (Ticket)_obj; ++ long ticketCoord = reference.getLastCoordinate(ticket); ++ int viewDistance = reference.getLastViewDistance(ticket); ++ int distance = Math.max(com.destroystokyo.paper.util.math.IntegerUtil.branchlessAbs(MCUtil.getCoordinateX(ticketCoord) - x), ++ com.destroystokyo.paper.util.math.IntegerUtil.branchlessAbs(MCUtil.getCoordinateZ(ticketCoord) - z)); ++ int level = viewDistance - distance; ++ if (level > expect) { ++ expect = level; ++ } + } -+ MinecraftServer.LOGGER.error("Add callback for map threw exception ", ex); + } + } ++ ++ if (expect != got) { ++ throw new IllegalStateException("Expected " + expect + " at pos (" + x + "," + z + ") but got " + got); ++ } + } + -+ private void removeObjectFrom(final E object, final int chunkX, final int chunkZ, final int currChunkX, -+ final int currChunkZ, final int prevChunkX, final int prevChunkZ) { -+ final long key = MCUtil.getCoordinateKey(chunkX, chunkZ); ++ static class Ticket { + -+ PooledLinkedHashSets.PooledObjectLinkedOpenHashSet current = this.areaMap.get(key); ++ int x; ++ int z; + -+ if (current == null) { -+ throw new IllegalStateException("Current map may not be null for " + object + ", (" + chunkX + "," + chunkZ + ")"); -+ } ++ final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet empty ++ = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); + -+ PooledLinkedHashSets.PooledObjectLinkedOpenHashSet next = this.pooledHashSets.findMapWithout(current, object); ++ } + -+ if (next == current) { -+ throw new IllegalStateException("Current map [" + next.toString() + "] should have contained " + object + ", (" + chunkX + "," + chunkZ + ")"); -+ } ++ public static void main(final String[] args) { ++ com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap reference = new com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap() { ++ @Override ++ protected com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getEmptySetFor(Ticket object) { ++ return object.empty; ++ } ++ }; ++ Delayed8WayDistancePropagator2D test = new Delayed8WayDistancePropagator2D(); + -+ if (next != null) { -+ this.areaMap.put(key, next); -+ } else { -+ this.areaMap.remove(key); -+ } -+ -+ if (this.removeCallback != null) { -+ try { -+ this.removeCallback.accept(object, chunkX, chunkZ, currChunkX, currChunkZ, prevChunkX, prevChunkZ, next); -+ } catch (final Throwable ex) { -+ if (ex instanceof ThreadDeath) { -+ throw (ThreadDeath)ex; ++ final int maxDistance = 64; ++ // test origin ++ { ++ Ticket originTicket = new Ticket(); ++ int originDistance = 31; ++ // test single source ++ reference.add(originTicket, 0, 0, originDistance); ++ test.setSource(0, 0, originDistance); test.propagateUpdates(); // set and propagate ++ for (int dx = -originDistance; dx <= originDistance; ++dx) { ++ for (int dz = -originDistance; dz <= originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ // test single source decrease ++ reference.update(originTicket, 0, 0, originDistance/2); ++ test.setSource(0, 0, originDistance/2); test.propagateUpdates(); // set and propagate ++ for (int dx = -originDistance; dx <= originDistance; ++dx) { ++ for (int dz = -originDistance; dz <= originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ // test source increase ++ originDistance = 2*originDistance; ++ reference.update(originTicket, 0, 0, originDistance); ++ test.setSource(0, 0, originDistance); test.propagateUpdates(); // set and propagate ++ for (int dx = -4*originDistance; dx <= 4*originDistance; ++dx) { ++ for (int dz = -4*originDistance; dz <= 4*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ reference.remove(originTicket); ++ test.removeSource(0, 0); test.propagateUpdates(); ++ } ++ ++ // test multiple sources at origin ++ { ++ int originDistance = 31; ++ java.util.List list = new java.util.ArrayList<>(); ++ for (int i = 0; i < 10; ++i) { ++ Ticket a = new Ticket(); ++ list.add(a); ++ a.x = (i & 1) == 1 ? -i : i; ++ a.z = (i & 1) == 1 ? -i : i; ++ } ++ for (Ticket ticket : list) { ++ reference.add(ticket, ticket.x, ticket.z, originDistance); ++ test.setSource(ticket.x, ticket.z, originDistance); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { ++ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket level decrease ++ ++ for (Ticket ticket : list) { ++ reference.update(ticket, ticket.x, ticket.z, originDistance/2); ++ test.setSource(ticket.x, ticket.z, originDistance/2); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { ++ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket level increase ++ ++ for (Ticket ticket : list) { ++ reference.update(ticket, ticket.x, ticket.z, originDistance*2); ++ test.setSource(ticket.x, ticket.z, originDistance*2); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { ++ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket remove ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ if ((i & 3) != 0) { ++ continue; ++ } ++ Ticket ticket = list.get(i); ++ reference.remove(ticket); ++ test.removeSource(ticket.x, ticket.z); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { ++ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ } ++ ++ // now test at coordinate offsets ++ // test offset ++ { ++ Ticket originTicket = new Ticket(); ++ int originDistance = 31; ++ int offX = 54432; ++ int offZ = -134567; ++ // test single source ++ reference.add(originTicket, offX, offZ, originDistance); ++ test.setSource(offX, offZ, originDistance); test.propagateUpdates(); // set and propagate ++ for (int dx = -originDistance; dx <= originDistance; ++dx) { ++ for (int dz = -originDistance; dz <= originDistance; ++dz) { ++ test(dx + offX, dz + offZ, reference, test); ++ } ++ } ++ // test single source decrease ++ reference.update(originTicket, offX, offZ, originDistance/2); ++ test.setSource(offX, offZ, originDistance/2); test.propagateUpdates(); // set and propagate ++ for (int dx = -originDistance; dx <= originDistance; ++dx) { ++ for (int dz = -originDistance; dz <= originDistance; ++dz) { ++ test(dx + offX, dz + offZ, reference, test); ++ } ++ } ++ // test source increase ++ originDistance = 2*originDistance; ++ reference.update(originTicket, offX, offZ, originDistance); ++ test.setSource(offX, offZ, originDistance); test.propagateUpdates(); // set and propagate ++ for (int dx = -4*originDistance; dx <= 4*originDistance; ++dx) { ++ for (int dz = -4*originDistance; dz <= 4*originDistance; ++dz) { ++ test(dx + offX, dz + offZ, reference, test); ++ } ++ } ++ ++ reference.remove(originTicket); ++ test.removeSource(offX, offZ); test.propagateUpdates(); ++ } ++ ++ // test multiple sources at origin ++ { ++ int originDistance = 31; ++ int offX = 54432; ++ int offZ = -134567; ++ java.util.List list = new java.util.ArrayList<>(); ++ for (int i = 0; i < 10; ++i) { ++ Ticket a = new Ticket(); ++ list.add(a); ++ a.x = offX + ((i & 1) == 1 ? -i : i); ++ a.z = offZ + ((i & 1) == 1 ? -i : i); ++ } ++ for (Ticket ticket : list) { ++ reference.add(ticket, ticket.x, ticket.z, originDistance); ++ test.setSource(ticket.x, ticket.z, originDistance); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { ++ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket level decrease ++ ++ for (Ticket ticket : list) { ++ reference.update(ticket, ticket.x, ticket.z, originDistance/2); ++ test.setSource(ticket.x, ticket.z, originDistance/2); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { ++ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket level increase ++ ++ for (Ticket ticket : list) { ++ reference.update(ticket, ticket.x, ticket.z, originDistance*2); ++ test.setSource(ticket.x, ticket.z, originDistance*2); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { ++ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ ++ // test ticket remove ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ if ((i & 3) != 0) { ++ continue; ++ } ++ Ticket ticket = list.get(i); ++ reference.remove(ticket); ++ test.removeSource(ticket.x, ticket.z); ++ } ++ test.propagateUpdates(); ++ ++ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { ++ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { ++ test(dx, dz, reference, test); ++ } ++ } ++ } ++ } ++ */ ++ ++ // this map is considered "stale" unless updates are propagated. ++ protected final LevelMap levels = new LevelMap(8192*2, 0.6f); ++ ++ // this map is never stale ++ protected final Long2ByteOpenHashMap sources = new Long2ByteOpenHashMap(4096, 0.6f); ++ ++ // Generally updates to positions are made close to other updates, so we link to decrease cache misses when ++ // propagating updates ++ protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet(); ++ ++ @FunctionalInterface ++ public static interface LevelChangeCallback { ++ ++ /** ++ * This can be called for intermediate updates. So do not rely on newLevel being close to or ++ * the exact level that is expected after a full propagation has occured. ++ */ ++ public void onLevelUpdate(final long coordinate, final byte oldLevel, final byte newLevel); ++ ++ } ++ ++ protected final LevelChangeCallback changeCallback; ++ ++ public Delayed8WayDistancePropagator2D() { ++ this(null); ++ } ++ ++ public Delayed8WayDistancePropagator2D(final LevelChangeCallback changeCallback) { ++ this.changeCallback = changeCallback; ++ } ++ ++ public int getLevel(final long pos) { ++ return this.levels.get(pos); ++ } ++ ++ public int getLevel(final int x, final int z) { ++ return this.levels.get(CoordinateUtils.getChunkKey(x, z)); ++ } ++ ++ public void setSource(final int x, final int z, final int level) { ++ this.setSource(CoordinateUtils.getChunkKey(x, z), level); ++ } ++ ++ public void setSource(final long coordinate, final int level) { ++ if ((level & 63) != level || level == 0) { ++ throw new IllegalArgumentException("Level must be in (0, 63], not " + level); ++ } ++ ++ final byte byteLevel = (byte)level; ++ final byte oldLevel = this.sources.put(coordinate, byteLevel); ++ ++ if (oldLevel == byteLevel) { ++ return; // nothing to do ++ } ++ ++ // queue to update later ++ this.updatedSources.add(coordinate); ++ } ++ ++ public void removeSource(final int x, final int z) { ++ this.removeSource(CoordinateUtils.getChunkKey(x, z)); ++ } ++ ++ public void removeSource(final long coordinate) { ++ if (this.sources.remove(coordinate) != 0) { ++ this.updatedSources.add(coordinate); ++ } ++ } ++ ++ // queues used for BFS propagating levels ++ protected final WorkQueue[] levelIncreaseWorkQueues = new WorkQueue[64]; ++ { ++ for (int i = 0; i < this.levelIncreaseWorkQueues.length; ++i) { ++ this.levelIncreaseWorkQueues[i] = new WorkQueue(); ++ } ++ } ++ protected final WorkQueue[] levelRemoveWorkQueues = new WorkQueue[64]; ++ { ++ for (int i = 0; i < this.levelRemoveWorkQueues.length; ++i) { ++ this.levelRemoveWorkQueues[i] = new WorkQueue(); ++ } ++ } ++ protected long levelIncreaseWorkQueueBitset; ++ protected long levelRemoveWorkQueueBitset; ++ ++ protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { ++ final WorkQueue queue = this.levelIncreaseWorkQueues[level]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelIncreaseWorkQueueBitset |= (1L << level); ++ } ++ ++ protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { ++ final WorkQueue queue = this.levelIncreaseWorkQueues[index]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelIncreaseWorkQueueBitset |= (1L << index); ++ } ++ ++ protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { ++ final WorkQueue queue = this.levelRemoveWorkQueues[level]; ++ queue.queuedCoordinates.enqueue(coordinate); ++ queue.queuedLevels.enqueue(level); ++ ++ this.levelRemoveWorkQueueBitset |= (1L << level); ++ } ++ ++ public boolean propagateUpdates() { ++ if (this.updatedSources.isEmpty()) { ++ return false; ++ } ++ ++ boolean ret = false; ++ ++ for (final LongIterator iterator = this.updatedSources.iterator(); iterator.hasNext();) { ++ final long coordinate = iterator.nextLong(); ++ ++ final byte currentLevel = this.levels.get(coordinate); ++ final byte updatedSource = this.sources.get(coordinate); ++ ++ if (currentLevel == updatedSource) { ++ continue; ++ } ++ ret = true; ++ ++ if (updatedSource > currentLevel) { ++ // level increase ++ this.addToIncreaseWorkQueue(coordinate, updatedSource); ++ } else { ++ // level decrease ++ this.addToRemoveWorkQueue(coordinate, currentLevel); ++ // if the current coordinate is a source, then the decrease propagation will detect that and queue ++ // the source propagation ++ } ++ } ++ ++ this.updatedSources.clear(); ++ ++ // propagate source level increases first for performance reasons (in crowded areas hopefully the additions ++ // make the removes remove less) ++ this.propagateIncreases(); ++ ++ // now we propagate the decreases (which will then re-propagate clobbered sources) ++ this.propagateDecreases(); ++ ++ return ret; ++ } ++ ++ protected void propagateIncreases() { ++ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset); ++ this.levelIncreaseWorkQueueBitset != 0L; ++ this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) { ++ ++ final WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; ++ while (!queue.queuedLevels.isEmpty()) { ++ final long coordinate = queue.queuedCoordinates.removeFirstLong(); ++ byte level = queue.queuedLevels.removeFirstByte(); ++ ++ final boolean neighbourCheck = level < 0; ++ ++ final byte currentLevel; ++ if (neighbourCheck) { ++ level = (byte)-level; ++ currentLevel = this.levels.get(coordinate); ++ } else { ++ currentLevel = this.levels.putIfGreater(coordinate, level); ++ } ++ ++ if (neighbourCheck) { ++ // used when propagating from decrease to indicate that this level needs to check its neighbours ++ // this means the level at coordinate could be equal, but would still need neighbours checked ++ ++ if (currentLevel != level) { ++ // something caused the level to change, which means something propagated to it (which means ++ // us propagating here is redundant), or something removed the level (which means we ++ // cannot propagate further) ++ continue; ++ } ++ } else if (currentLevel >= level) { ++ // something higher/equal propagated ++ continue; ++ } ++ if (this.changeCallback != null) { ++ this.changeCallback.onLevelUpdate(coordinate, currentLevel, level); ++ } ++ ++ if (level == 1) { ++ // can't propagate 0 to neighbours ++ continue; ++ } ++ ++ // propagate to neighbours ++ final byte neighbourLevel = (byte)(level - 1); ++ final int x = (int)coordinate; ++ final int z = (int)(coordinate >>> 32); ++ ++ for (int dx = -1; dx <= 1; ++dx) { ++ for (int dz = -1; dz <= 1; ++dz) { ++ if ((dx | dz) == 0) { ++ // already propagated to coordinate ++ continue; ++ } ++ ++ // sure we can check the neighbour level in the map right now and avoid a propagation, ++ // but then we would still have to recheck it when popping the value off of the queue! ++ // so just avoid the double lookup ++ final long neighbourCoordinate = CoordinateUtils.getChunkKey(x + dx, z + dz); ++ this.addToIncreaseWorkQueue(neighbourCoordinate, neighbourLevel); ++ } + } -+ MinecraftServer.LOGGER.error("Remove callback for map threw exception ", ex); + } + } + } + -+ private void addObject(final E object, final int chunkX, final int chunkZ, final int prevChunkX, final int prevChunkZ, final int viewDistance) { -+ final int maxX = chunkX + viewDistance; -+ final int maxZ = chunkZ + viewDistance; -+ final int minX = chunkX - viewDistance; -+ final int minZ = chunkZ - viewDistance; -+ for (int x = minX; x <= maxX; ++x) { -+ for (int z = minZ; z <= maxZ; ++z) { -+ this.addObjectTo(object, x, z, chunkX, chunkZ, prevChunkX, prevChunkZ); ++ protected void propagateDecreases() { ++ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset); ++ this.levelRemoveWorkQueueBitset != 0L; ++ this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) { ++ ++ final WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; ++ while (!queue.queuedLevels.isEmpty()) { ++ final long coordinate = queue.queuedCoordinates.removeFirstLong(); ++ final byte level = queue.queuedLevels.removeFirstByte(); ++ ++ final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); ++ if (currentLevel == 0) { ++ // something else removed ++ continue; ++ } ++ ++ if (currentLevel > level) { ++ // something higher propagated here or we hit the propagation of another source ++ // in the second case we need to re-propagate because we could have just clobbered another source's ++ // propagation ++ this.addToIncreaseWorkQueue(coordinate, currentLevel, (byte)-currentLevel); // indicate to the increase code that the level's neighbours need checking ++ continue; ++ } ++ ++ if (this.changeCallback != null) { ++ this.changeCallback.onLevelUpdate(coordinate, currentLevel, (byte)0); ++ } ++ ++ final byte source = this.sources.get(coordinate); ++ if (source != 0) { ++ // must re-propagate source later ++ this.addToIncreaseWorkQueue(coordinate, source); ++ } ++ ++ if (level == 0) { ++ // can't propagate -1 to neighbours ++ // we have to check neighbours for removing 1 just in case the neighbour is 2 ++ continue; ++ } ++ ++ // propagate to neighbours ++ final byte neighbourLevel = (byte)(level - 1); ++ final int x = (int)coordinate; ++ final int z = (int)(coordinate >>> 32); ++ ++ for (int dx = -1; dx <= 1; ++dx) { ++ for (int dz = -1; dz <= 1; ++dz) { ++ if ((dx | dz) == 0) { ++ // already propagated to coordinate ++ continue; ++ } ++ ++ // sure we can check the neighbour level in the map right now and avoid a propagation, ++ // but then we would still have to recheck it when popping the value off of the queue! ++ // so just avoid the double lookup ++ final long neighbourCoordinate = CoordinateUtils.getChunkKey(x + dx, z + dz); ++ this.addToRemoveWorkQueue(neighbourCoordinate, neighbourLevel); ++ } ++ } ++ } ++ } ++ ++ // propagate sources we clobbered in the process ++ this.propagateIncreases(); ++ } ++ ++ protected static final class LevelMap extends Long2ByteOpenHashMap { ++ public LevelMap() { ++ super(); ++ } ++ ++ public LevelMap(final int expected, final float loadFactor) { ++ super(expected, loadFactor); ++ } ++ ++ // copied from superclass ++ private int find(final long k) { ++ if (k == 0L) { ++ return this.containsNullKey ? this.n : -(this.n + 1); ++ } else { ++ final long[] key = this.key; ++ long curr; ++ int pos; ++ if ((curr = key[pos = (int)HashCommon.mix(k) & this.mask]) == 0L) { ++ return -(pos + 1); ++ } else if (k == curr) { ++ return pos; ++ } else { ++ while((curr = key[pos = pos + 1 & this.mask]) != 0L) { ++ if (k == curr) { ++ return pos; ++ } ++ } ++ ++ return -(pos + 1); ++ } ++ } ++ } ++ ++ // copied from superclass ++ private void insert(final int pos, final long k, final byte v) { ++ if (pos == this.n) { ++ this.containsNullKey = true; ++ } ++ ++ this.key[pos] = k; ++ this.value[pos] = v; ++ if (this.size++ >= this.maxFill) { ++ this.rehash(HashCommon.arraySize(this.size + 1, this.f)); ++ } ++ } ++ ++ // copied from superclass ++ public byte putIfGreater(final long key, final byte value) { ++ final int pos = this.find(key); ++ if (pos < 0) { ++ if (this.defRetValue < value) { ++ this.insert(-pos - 1, key, value); ++ } ++ return this.defRetValue; ++ } else { ++ final byte curr = this.value[pos]; ++ if (value > curr) { ++ this.value[pos] = value; ++ return curr; ++ } ++ return curr; ++ } ++ } ++ ++ // copied from superclass ++ private void removeEntry(final int pos) { ++ --this.size; ++ this.shiftKeys(pos); ++ if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { ++ this.rehash(this.n / 2); ++ } ++ } ++ ++ // copied from superclass ++ private void removeNullEntry() { ++ this.containsNullKey = false; ++ --this.size; ++ if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { ++ this.rehash(this.n / 2); ++ } ++ } ++ ++ // copied from superclass ++ public byte removeIfGreaterOrEqual(final long key, final byte value) { ++ if (key == 0L) { ++ if (!this.containsNullKey) { ++ return this.defRetValue; ++ } ++ final byte current = this.value[this.n]; ++ if (value >= current) { ++ this.removeNullEntry(); ++ return current; ++ } ++ return current; ++ } else { ++ long[] keys = this.key; ++ byte[] values = this.value; ++ long curr; ++ int pos; ++ if ((curr = keys[pos = (int)HashCommon.mix(key) & this.mask]) == 0L) { ++ return this.defRetValue; ++ } else if (key == curr) { ++ final byte current = values[pos]; ++ if (value >= current) { ++ this.removeEntry(pos); ++ return current; ++ } ++ return current; ++ } else { ++ while((curr = keys[pos = pos + 1 & this.mask]) != 0L) { ++ if (key == curr) { ++ final byte current = values[pos]; ++ if (value >= current) { ++ this.removeEntry(pos); ++ return current; ++ } ++ return current; ++ } ++ } ++ ++ return this.defRetValue; ++ } + } + } + } + -+ private void removeObject(final E object, final int chunkX, final int chunkZ, final int currentChunkX, final int currentChunkZ, final int viewDistance) { -+ final int maxX = chunkX + viewDistance; -+ final int maxZ = chunkZ + viewDistance; -+ final int minX = chunkX - viewDistance; -+ final int minZ = chunkZ - viewDistance; -+ for (int x = minX; x <= maxX; ++x) { -+ for (int z = minZ; z <= maxZ; ++z) { -+ this.removeObjectFrom(object, x, z, currentChunkX, currentChunkZ, chunkX, chunkZ); ++ protected static final class WorkQueue { ++ ++ public final NoResizeLongArrayFIFODeque queuedCoordinates = new NoResizeLongArrayFIFODeque(); ++ public final NoResizeByteArrayFIFODeque queuedLevels = new NoResizeByteArrayFIFODeque(); ++ ++ } ++ ++ protected static final class NoResizeLongArrayFIFODeque extends LongArrayFIFOQueue { ++ ++ /** ++ * Assumes non-empty. If empty, undefined behaviour. ++ */ ++ public long removeFirstLong() { ++ // copied from superclass ++ long t = this.array[this.start]; ++ if (++this.start == this.length) { ++ this.start = 0; ++ } ++ ++ return t; ++ } ++ } ++ ++ protected static final class NoResizeByteArrayFIFODeque extends ByteArrayFIFOQueue { ++ ++ /** ++ * Assumes non-empty. If empty, undefined behaviour. ++ */ ++ public byte removeFirstByte() { ++ // copied from superclass ++ byte t = this.array[this.start]; ++ if (++this.start == this.length) { ++ this.start = 0; ++ } ++ ++ return t; ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ab093b0e8ac6f762921eb1d15f5217345c4eba05 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java +@@ -0,0 +1,211 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.MoonriseConstants; ++import ca.spottedleaf.moonrise.common.util.ChunkSystem; ++import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants; ++import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; ++import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.level.ChunkPos; ++ ++public final class NearbyPlayers { ++ ++ public static enum NearbyMapType { ++ GENERAL, ++ GENERAL_SMALL, ++ GENERAL_REALLY_SMALL, ++ TICK_VIEW_DISTANCE, ++ VIEW_DISTANCE, ++ SPAWN_RANGE, // Moonrise - chunk tick iteration ++ } ++ ++ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); ++ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length; ++ ++ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1; ++ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; ++ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; ++ ++ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); ++ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); ++ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); ++ ++ private final ServerLevel world; ++ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); ++ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); ++ ++ public NearbyPlayers(final ServerLevel world) { ++ this.world = world; ++ } ++ ++ public void addPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; ++ if (this.players.putIfAbsent(player, newTrackers) != null) { ++ throw new IllegalStateException("Already have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { ++ // use 0 for default, will be updated by tickPlayer ++ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0); ++ } ++ ++ // update view distances ++ this.tickPlayer(player); ++ } ++ ++ public void removePlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.remove(player); ++ if (players == null) { ++ return; // May be called during teleportation before the player is actually placed ++ } ++ ++ for (final TrackedPlayer tracker : players) { ++ tracker.remove(); ++ } ++ } ++ ++ public void tickPlayer(final ServerPlayer player) { ++ final TrackedPlayer[] players = this.players.get(player); ++ if (players == null) { ++ throw new IllegalStateException("Don't have player " + player); ++ } ++ ++ final ChunkPos chunk = player.chunkPosition(); ++ ++ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); ++ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); ++ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getLoadViewDistance(player)); ++ players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration ++ } ++ ++ public TrackedChunk getChunk(final ChunkPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public TrackedChunk getChunk(final BlockPos pos) { ++ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ } ++ ++ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); ++ ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ ++ public static final class TrackedChunk { ++ ++ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; ++ ++ private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; ++ private int nonEmptyLists; ++ private long updateCount; ++ ++ public boolean isEmpty() { ++ return this.nonEmptyLists == 0; ++ } ++ ++ public long getUpdateCount() { ++ return this.updateCount; ++ } ++ ++ public ReferenceList getPlayers(final NearbyMapType type) { ++ return this.players[type.ordinal()]; ++ } ++ ++ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ ++this.nonEmptyLists; ++ (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player); ++ return; ++ } ++ ++ if (!list.add(player)) { ++ throw new IllegalStateException("Already contains player " + player); + } + } ++ ++ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { ++ ++this.updateCount; ++ ++ final int idx = type.ordinal(); ++ final ReferenceList list = this.players[idx]; ++ if (list == null) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (!list.remove(player)) { ++ throw new IllegalStateException("Does not contain player " + player); ++ } ++ ++ if (list.size() == 0) { ++ this.players[idx] = null; ++ --this.nonEmptyLists; ++ } ++ } ++ } ++ ++ private final class TrackedPlayer extends SingleUserAreaMap { ++ ++ private final NearbyMapType type; ++ ++ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { ++ super(player); ++ this.type = type; ++ } ++ ++ @Override ++ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { ++ return new TrackedChunk(); ++ }).addPlayer(parameter, this.type); ++ } ++ ++ @Override ++ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { ++ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); ++ ++ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); ++ if (chunk == null) { ++ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); ++ } ++ ++ chunk.removePlayer(parameter, this.type); ++ ++ if (chunk.isEmpty()) { ++ NearbyPlayers.this.byChunk.remove(chunkKey); ++ } ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..efefd94b652228d877db5dbca8b28354ad42529f +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java +@@ -0,0 +1,94 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.IntPairUtil; ++import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; ++import it.unimi.dsi.fastutil.objects.ReferenceSet; ++ ++public final class PositionCountingAreaMap { ++ ++ private final Reference2ReferenceOpenHashMap counters = new Reference2ReferenceOpenHashMap<>(); ++ private final Long2IntOpenHashMap positions = new Long2IntOpenHashMap(); ++ ++ public ReferenceSet getObjects() { ++ return this.counters.keySet(); ++ } ++ ++ public int getTotalPositions() { ++ return this.positions.size(); ++ } ++ ++ public boolean hasObjectsNear(final int toX, final int toZ) { ++ return this.positions.containsKey(IntPairUtil.key(toX, toZ)); ++ } ++ ++ public int getObjectsNear(final int toX, final int toZ) { ++ return this.positions.get(IntPairUtil.key(toX, toZ)); ++ } ++ ++ public boolean add(final T parameter, final int toX, final int toZ, final int distance) { ++ final PositionCounter existing = this.counters.get(parameter); ++ if (existing != null) { ++ return false; ++ } ++ ++ final PositionCounter counter = new PositionCounter(parameter); ++ ++ this.counters.put(parameter, counter); ++ ++ return counter.add(toX, toZ, distance); ++ } ++ ++ public boolean addOrUpdate(final T parameter, final int toX, final int toZ, final int distance) { ++ final PositionCounter existing = this.counters.get(parameter); ++ if (existing != null) { ++ return existing.update(toX, toZ, distance); ++ } ++ ++ final PositionCounter counter = new PositionCounter(parameter); ++ ++ this.counters.put(parameter, counter); ++ ++ return counter.add(toX, toZ, distance); ++ } ++ ++ public boolean remove(final T parameter) { ++ final PositionCounter counter = this.counters.remove(parameter); ++ if (counter == null) { ++ return false; ++ } ++ ++ counter.remove(); ++ ++ return true; ++ } ++ ++ public boolean update(final T parameter, final int toX, final int toZ, final int distance) { ++ final PositionCounter counter = this.counters.get(parameter); ++ if (counter == null) { ++ return false; ++ } ++ ++ return counter.update(toX, toZ, distance); ++ } ++ ++ private final class PositionCounter extends SingleUserAreaMap { ++ ++ public PositionCounter(final T parameter) { ++ super(parameter); ++ } ++ ++ @Override ++ protected void addCallback(final T parameter, final int toX, final int toZ) { ++ PositionCountingAreaMap.this.positions.addTo(IntPairUtil.key(toX, toZ), 1); ++ } ++ ++ @Override ++ protected void removeCallback(final T parameter, final int toX, final int toZ) { ++ final long key = IntPairUtil.key(toX, toZ); ++ if (PositionCountingAreaMap.this.positions.addTo(key, -1) == 1) { ++ PositionCountingAreaMap.this.positions.remove(key); ++ } ++ } ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..94689e0342cf95dbedec955d67c95fa07a219678 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java +@@ -0,0 +1,248 @@ ++package ca.spottedleaf.moonrise.common.misc; ++ ++import ca.spottedleaf.concurrentutil.util.IntegerUtil; ++ ++public abstract class SingleUserAreaMap { ++ ++ public static final int NOT_SET = Integer.MIN_VALUE; ++ ++ private final T parameter; ++ private int lastChunkX = NOT_SET; ++ private int lastChunkZ = NOT_SET; ++ private int distance = NOT_SET; ++ ++ public SingleUserAreaMap(final T parameter) { ++ this.parameter = parameter; ++ } ++ ++ public final T getParameter() { ++ return this.parameter; ++ } ++ ++ public final int getLastChunkX() { ++ return this.lastChunkX; ++ } ++ ++ public final int getLastChunkZ() { ++ return this.lastChunkZ; ++ } ++ ++ public final int getLastDistance() { ++ return this.distance; + } + + /* math sign function except 0 returns 1 */ @@ -851,11 +2774,65 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + return 1 | (val >> (Integer.SIZE - 1)); + } + -+ private void updateObject(final E object, final long oldPosition, final long newPosition, final int oldViewDistance, final int newViewDistance) { -+ final int toX = MCUtil.getCoordinateX(newPosition); -+ final int toZ = MCUtil.getCoordinateZ(newPosition); -+ final int fromX = MCUtil.getCoordinateX(oldPosition); -+ final int fromZ = MCUtil.getCoordinateZ(oldPosition); ++ protected abstract void addCallback(final T parameter, final int chunkX, final int chunkZ); ++ ++ protected abstract void removeCallback(final T parameter, final int chunkX, final int chunkZ); ++ ++ private void addToNew(final T parameter, final int chunkX, final int chunkZ, final int distance) { ++ final int maxX = chunkX + distance; ++ final int maxZ = chunkZ + distance; ++ ++ for (int cx = chunkX - distance; cx <= maxX; ++cx) { ++ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { ++ this.addCallback(parameter, cx, cz); ++ } ++ } ++ } ++ ++ private void removeFromOld(final T parameter, final int chunkX, final int chunkZ, final int distance) { ++ final int maxX = chunkX + distance; ++ final int maxZ = chunkZ + distance; ++ ++ for (int cx = chunkX - distance; cx <= maxX; ++cx) { ++ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { ++ this.removeCallback(parameter, cx, cz); ++ } ++ } ++ } ++ ++ public final boolean add(final int chunkX, final int chunkZ, final int distance) { ++ if (distance < 0) { ++ throw new IllegalArgumentException(Integer.toString(distance)); ++ } ++ if (this.lastChunkX != NOT_SET) { ++ return false; ++ } ++ this.lastChunkX = chunkX; ++ this.lastChunkZ = chunkZ; ++ this.distance = distance; ++ ++ this.addToNew(this.parameter, chunkX, chunkZ, distance); ++ ++ return true; ++ } ++ ++ public final boolean update(final int toX, final int toZ, final int newViewDistance) { ++ if (newViewDistance < 0) { ++ throw new IllegalArgumentException(Integer.toString(newViewDistance)); ++ } ++ final int fromX = this.lastChunkX; ++ final int fromZ = this.lastChunkZ; ++ final int oldViewDistance = this.distance; ++ if (fromX == NOT_SET) { ++ return false; ++ } ++ ++ this.lastChunkX = toX; ++ this.lastChunkZ = toZ; ++ this.distance = newViewDistance; ++ ++ final T parameter = this.parameter; ++ + + final int dx = toX - fromX; + final int dz = toZ - fromZ; @@ -864,10 +2841,10 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + final int totalZ = IntegerUtil.branchlessAbs(fromZ - toZ); + + if (Math.max(totalX, totalZ) > (2 * Math.max(newViewDistance, oldViewDistance))) { -+ // teleported? -+ this.removeObject(object, fromX, fromZ, fromX, fromZ, oldViewDistance); -+ this.addObject(object, toX, toZ, fromX, fromZ, newViewDistance); -+ return; ++ // teleported ++ this.removeFromOld(parameter, fromX, fromZ, oldViewDistance); ++ this.addToNew(parameter, toX, toZ, newViewDistance); ++ return true; + } + + if (oldViewDistance != newViewDistance) { @@ -882,7 +2859,7 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + // only remove if we're outside the new view distance... + if (Math.max(IntegerUtil.branchlessAbs(currX - toX), IntegerUtil.branchlessAbs(currZ - toZ)) > newViewDistance) { -+ this.removeObjectFrom(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.removeCallback(parameter, currX, currZ); + } + } + } @@ -898,12 +2875,12 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + // only add if we're outside the old view distance... + if (Math.max(IntegerUtil.branchlessAbs(currX - fromX), IntegerUtil.branchlessAbs(currZ - fromZ)) > oldViewDistance) { -+ this.addObjectTo(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.addCallback(parameter, currX, currZ); + } + } + } + -+ return; ++ return true; + } + + // x axis is width @@ -939,7 +2916,7 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addObjectTo(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.addCallback(parameter, currX, currZ); + } + } + } @@ -954,7 +2931,7 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addObjectTo(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.addCallback(parameter, currX, currZ); + } + } + } @@ -969,7 +2946,7 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeObjectFrom(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.removeCallback(parameter, currX, currZ); + } + } + } @@ -984,672 +2961,39 @@ index 0000000000000000000000000000000000000000..41b9405d6759d865e0d14dd4f95163e9 + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeObjectFrom(object, currX, currZ, toX, toZ, fromX, fromZ); ++ this.removeCallback(parameter, currX, currZ); + } + } + } ++ ++ return true; + } + -+ @FunctionalInterface -+ public static interface ChangeCallback { ++ public final boolean remove() { ++ final int chunkX = this.lastChunkX; ++ final int chunkZ = this.lastChunkZ; ++ final int distance = this.distance; ++ if (chunkX == NOT_SET) { ++ return false; ++ } + -+ // if there is no previous position, then prevPos = Integer.MIN_VALUE -+ void accept(final E object, final int rangeX, final int rangeZ, final int currPosX, final int currPosZ, final int prevPosX, final int prevPosZ, -+ final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState); ++ this.lastChunkX = this.lastChunkZ = this.distance = NOT_SET; + -+ } ++ this.removeFromOld(this.parameter, chunkX, chunkZ, distance); + -+ @FunctionalInterface -+ public static interface ChangeSourceCallback { -+ void accept(final E object, final long prevPos, final long newPos); ++ return true; + } +} -diff --git a/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java b/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java new file mode 100644 -index 0000000000000000000000000000000000000000..896c3ff7ddb07f1f6f05f90e1e3fe7fb615071d4 +index 0000000000000000000000000000000000000000..4123edddc556c47f3f8d83523c125fd2e46b30e2 --- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/misc/DistanceTrackingAreaMap.java -@@ -0,0 +1,175 @@ -+package com.destroystokyo.paper.util.misc; -+ -+import io.papermc.paper.util.IntegerUtil; -+import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -+import io.papermc.paper.util.MCUtil; -+import net.minecraft.world.level.ChunkPos; -+ -+/** @author Spottedleaf */ -+public abstract class DistanceTrackingAreaMap extends AreaMap { -+ -+ // use this map only if you need distance tracking, the tracking here is obviously going to hit harder. -+ -+ protected final Long2IntOpenHashMap chunkToNearestDistance = new Long2IntOpenHashMap(1024, 0.7f); -+ { -+ this.chunkToNearestDistance.defaultReturnValue(-1); -+ } -+ -+ protected final DistanceChangeCallback distanceChangeCallback; -+ -+ public DistanceTrackingAreaMap() { -+ this(new PooledLinkedHashSets<>()); -+ } -+ -+ // let users define a "global" or "shared" pooled sets if they wish -+ public DistanceTrackingAreaMap(final PooledLinkedHashSets pooledHashSets) { -+ this(pooledHashSets, null, null, null); -+ } -+ -+ public DistanceTrackingAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, final ChangeCallback removeCallback, -+ final DistanceChangeCallback distanceChangeCallback) { -+ super(pooledHashSets, addCallback, removeCallback); -+ this.distanceChangeCallback = distanceChangeCallback; -+ } -+ -+ // ret -1 if there is nothing mapped -+ public final int getNearestObjectDistance(final long key) { -+ return this.chunkToNearestDistance.get(key); -+ } -+ -+ // ret -1 if there is nothing mapped -+ public final int getNearestObjectDistance(final ChunkPos chunkPos) { -+ return this.chunkToNearestDistance.get(MCUtil.getCoordinateKey(chunkPos)); -+ } -+ -+ // ret -1 if there is nothing mapped -+ public final int getNearestObjectDistance(final int chunkX, final int chunkZ) { -+ return this.chunkToNearestDistance.get(MCUtil.getCoordinateKey(chunkX, chunkZ)); -+ } -+ -+ protected final void recalculateDistance(final int chunkX, final int chunkZ) { -+ final long key = MCUtil.getCoordinateKey(chunkX, chunkZ); -+ final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet state = this.areaMap.get(key); -+ if (state == null) { -+ final int oldDistance = this.chunkToNearestDistance.remove(key); -+ // nothing here. -+ if (oldDistance == -1) { -+ // nothing was here previously -+ return; -+ } -+ if (this.distanceChangeCallback != null) { -+ this.distanceChangeCallback.accept(chunkX, chunkZ, oldDistance, -1, null); -+ } -+ return; -+ } -+ -+ int newDistance = Integer.MAX_VALUE; -+ -+ final Object[] rawData = state.getBackingSet(); -+ for (int i = 0, len = rawData.length; i < len; ++i) { -+ final Object raw = rawData[i]; -+ -+ if (raw == null) { -+ continue; -+ } -+ -+ final E object = (E)raw; -+ final long location = this.objectToLastCoordinate.getLong(object); -+ -+ final int distance = Math.max(IntegerUtil.branchlessAbs(chunkX - MCUtil.getCoordinateX(location)), IntegerUtil.branchlessAbs(chunkZ - MCUtil.getCoordinateZ(location))); -+ -+ if (distance < newDistance) { -+ newDistance = distance; -+ } -+ } -+ -+ final int oldDistance = this.chunkToNearestDistance.put(key, newDistance); -+ -+ if (oldDistance != newDistance) { -+ if (this.distanceChangeCallback != null) { -+ this.distanceChangeCallback.accept(chunkX, chunkZ, oldDistance, newDistance, state); -+ } -+ } -+ } -+ -+ @Override -+ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) { -+ final int maxX = chunkX + viewDistance; -+ final int maxZ = chunkZ + viewDistance; -+ final int minX = chunkX - viewDistance; -+ final int minZ = chunkZ - viewDistance; -+ for (int x = minX; x <= maxX; ++x) { -+ for (int z = minZ; z <= maxZ; ++z) { -+ this.recalculateDistance(x, z); -+ } -+ } -+ } -+ -+ @Override -+ protected void removeObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) { -+ final int maxX = chunkX + viewDistance; -+ final int maxZ = chunkZ + viewDistance; -+ final int minX = chunkX - viewDistance; -+ final int minZ = chunkZ - viewDistance; -+ for (int x = minX; x <= maxX; ++x) { -+ for (int z = minZ; z <= maxZ; ++z) { -+ this.recalculateDistance(x, z); -+ } -+ } -+ } -+ -+ @Override -+ protected void updateObjectCallback(final E object, final long oldPosition, final long newPosition, final int oldViewDistance, final int newViewDistance) { -+ if (oldPosition == newPosition && newViewDistance == oldViewDistance) { -+ return; -+ } -+ -+ final int toX = MCUtil.getCoordinateX(newPosition); -+ final int toZ = MCUtil.getCoordinateZ(newPosition); -+ final int fromX = MCUtil.getCoordinateX(oldPosition); -+ final int fromZ = MCUtil.getCoordinateZ(oldPosition); -+ -+ final int totalX = IntegerUtil.branchlessAbs(fromX - toX); -+ final int totalZ = IntegerUtil.branchlessAbs(fromZ - toZ); -+ -+ if (Math.max(totalX, totalZ) > (2 * Math.max(newViewDistance, oldViewDistance))) { -+ // teleported? -+ this.removeObjectCallback(object, fromX, fromZ, oldViewDistance); -+ this.addObjectCallback(object, toX, toZ, newViewDistance); -+ return; -+ } -+ -+ final int minX = Math.min(fromX - oldViewDistance, toX - newViewDistance); -+ final int maxX = Math.max(fromX + oldViewDistance, toX + newViewDistance); -+ final int minZ = Math.min(fromZ - oldViewDistance, toZ - newViewDistance); -+ final int maxZ = Math.max(fromZ + oldViewDistance, toZ + newViewDistance); -+ -+ for (int x = minX; x <= maxX; ++x) { -+ for (int z = minZ; z <= maxZ; ++z) { -+ final int distXOld = IntegerUtil.branchlessAbs(x - fromX); -+ final int distZOld = IntegerUtil.branchlessAbs(z - fromZ); -+ -+ if (Math.max(distXOld, distZOld) <= oldViewDistance) { -+ this.recalculateDistance(x, z); -+ continue; -+ } -+ -+ final int distXNew = IntegerUtil.branchlessAbs(x - toX); -+ final int distZNew = IntegerUtil.branchlessAbs(z - toZ); -+ -+ if (Math.max(distXNew, distZNew) <= newViewDistance) { -+ this.recalculateDistance(x, z); -+ continue; -+ } -+ } -+ } -+ } -+ -+ @FunctionalInterface -+ public static interface DistanceChangeCallback { -+ -+ void accept(final int posX, final int posZ, final int oldNearestDistance, final int newNearestDistance, -+ final PooledLinkedHashSets.PooledObjectLinkedOpenHashSet state); -+ -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..46954db7ecd35ac4018fdf476df7c8020d7ce6c8 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/misc/PlayerAreaMap.java -@@ -0,0 +1,32 @@ -+package com.destroystokyo.paper.util.misc; -+ -+import net.minecraft.server.level.ServerPlayer; -+ -+/** -+ * @author Spottedleaf -+ */ -+public final class PlayerAreaMap extends AreaMap { -+ -+ public PlayerAreaMap() { -+ super(); -+ } -+ -+ public PlayerAreaMap(final PooledLinkedHashSets pooledHashSets) { -+ super(pooledHashSets); -+ } -+ -+ public PlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, -+ final ChangeCallback removeCallback) { -+ this(pooledHashSets, addCallback, removeCallback, null); -+ } -+ -+ public PlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, -+ final ChangeCallback removeCallback, final ChangeSourceCallback changeSourceCallback) { -+ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback); -+ } -+ -+ @Override -+ protected PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getEmptySetFor(final ServerPlayer player) { -+ return player.cachedSingleHashSet; -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PlayerDistanceTrackingAreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/PlayerDistanceTrackingAreaMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d05dcea15f7047b58736c7c0e07920a04d6c5abe ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/misc/PlayerDistanceTrackingAreaMap.java -@@ -0,0 +1,24 @@ -+package com.destroystokyo.paper.util.misc; -+ -+import net.minecraft.server.level.ServerPlayer; -+ -+public class PlayerDistanceTrackingAreaMap extends DistanceTrackingAreaMap { -+ -+ public PlayerDistanceTrackingAreaMap() { -+ super(); -+ } -+ -+ public PlayerDistanceTrackingAreaMap(final PooledLinkedHashSets pooledHashSets) { -+ super(pooledHashSets); -+ } -+ -+ public PlayerDistanceTrackingAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, -+ final ChangeCallback removeCallback, final DistanceChangeCallback distanceChangeCallback) { -+ super(pooledHashSets, addCallback, removeCallback, distanceChangeCallback); -+ } -+ -+ @Override -+ protected PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getEmptySetFor(final ServerPlayer player) { -+ return player.cachedSingleHashSet; -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java b/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e51104e65a07b6ea7bbbcbb6afb066ef6401cc5b ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/misc/PooledLinkedHashSets.java -@@ -0,0 +1,287 @@ -+package com.destroystokyo.paper.util.misc; -+ -+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -+import java.lang.ref.WeakReference; -+ -+/** @author Spottedleaf */ -+public class PooledLinkedHashSets { -+ -+ /* Tested via https://gist.github.com/Spottedleaf/a93bb7a8993d6ce142d3efc5932bf573 */ -+ -+ // we really want to avoid that equals() check as much as possible... -+ protected final Object2ObjectOpenHashMap, PooledObjectLinkedOpenHashSet> mapPool = new Object2ObjectOpenHashMap<>(128, 0.25f); -+ -+ protected void decrementReferenceCount(final PooledObjectLinkedOpenHashSet current) { -+ if (current.referenceCount == 0) { -+ throw new IllegalStateException("Cannot decrement reference count for " + current); -+ } -+ if (current.referenceCount == -1 || --current.referenceCount > 0) { -+ return; -+ } -+ -+ this.mapPool.remove(current); -+ return; -+ } -+ -+ public PooledObjectLinkedOpenHashSet findMapWith(final PooledObjectLinkedOpenHashSet current, final E object) { -+ final PooledObjectLinkedOpenHashSet cached = current.getAddCache(object); -+ -+ if (cached != null) { -+ decrementReferenceCount(current); -+ -+ if (cached.referenceCount == 0) { -+ // bring the map back from the dead -+ PooledObjectLinkedOpenHashSet contending = this.mapPool.putIfAbsent(cached, cached); -+ if (contending != null) { -+ // a map already exists with the elements we want -+ if (contending.referenceCount != -1) { -+ ++contending.referenceCount; -+ } -+ current.updateAddCache(object, contending); -+ return contending; -+ } -+ -+ cached.referenceCount = 1; -+ } else if (cached.referenceCount != -1) { -+ ++cached.referenceCount; -+ } -+ -+ return cached; -+ } -+ -+ if (!current.add(object)) { -+ return current; -+ } -+ -+ // we use get/put since we use a different key on put -+ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); -+ -+ if (ret == null) { -+ ret = new PooledObjectLinkedOpenHashSet<>(current); -+ current.remove(object); -+ this.mapPool.put(ret, ret); -+ ret.referenceCount = 1; -+ } else { -+ if (ret.referenceCount != -1) { -+ ++ret.referenceCount; -+ } -+ current.remove(object); -+ } -+ -+ current.updateAddCache(object, ret); -+ -+ decrementReferenceCount(current); -+ return ret; -+ } -+ -+ // rets null if current.size() == 1 -+ public PooledObjectLinkedOpenHashSet findMapWithout(final PooledObjectLinkedOpenHashSet current, final E object) { -+ if (current.set.size() == 1) { -+ decrementReferenceCount(current); -+ return null; -+ } -+ -+ final PooledObjectLinkedOpenHashSet cached = current.getRemoveCache(object); -+ -+ if (cached != null) { -+ decrementReferenceCount(current); -+ -+ if (cached.referenceCount == 0) { -+ // bring the map back from the dead -+ PooledObjectLinkedOpenHashSet contending = this.mapPool.putIfAbsent(cached, cached); -+ if (contending != null) { -+ // a map already exists with the elements we want -+ if (contending.referenceCount != -1) { -+ ++contending.referenceCount; -+ } -+ current.updateRemoveCache(object, contending); -+ return contending; -+ } -+ -+ cached.referenceCount = 1; -+ } else if (cached.referenceCount != -1) { -+ ++cached.referenceCount; -+ } -+ -+ return cached; -+ } -+ -+ if (!current.remove(object)) { -+ return current; -+ } -+ -+ // we use get/put since we use a different key on put -+ PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); -+ -+ if (ret == null) { -+ ret = new PooledObjectLinkedOpenHashSet<>(current); -+ current.add(object); -+ this.mapPool.put(ret, ret); -+ ret.referenceCount = 1; -+ } else { -+ if (ret.referenceCount != -1) { -+ ++ret.referenceCount; -+ } -+ current.add(object); -+ } -+ -+ current.updateRemoveCache(object, ret); -+ -+ decrementReferenceCount(current); -+ return ret; -+ } -+ -+ static final class RawSetObjectLinkedOpenHashSet extends ObjectOpenHashSet { -+ -+ public RawSetObjectLinkedOpenHashSet() { -+ super(); -+ } -+ -+ public RawSetObjectLinkedOpenHashSet(final int capacity) { -+ super(capacity); -+ } -+ -+ public RawSetObjectLinkedOpenHashSet(final int capacity, final float loadFactor) { -+ super(capacity, loadFactor); -+ } -+ -+ @Override -+ public RawSetObjectLinkedOpenHashSet clone() { -+ return (RawSetObjectLinkedOpenHashSet)super.clone(); -+ } -+ -+ public E[] getRawSet() { -+ return this.key; -+ } -+ } -+ -+ public static final class PooledObjectLinkedOpenHashSet { -+ -+ private static final WeakReference NULL_REFERENCE = new WeakReference<>(null); -+ -+ final RawSetObjectLinkedOpenHashSet set; -+ int referenceCount; // -1 if special -+ int hash; // optimize hashcode -+ -+ // add cache -+ WeakReference lastAddObject = NULL_REFERENCE; -+ WeakReference> lastAddMap = NULL_REFERENCE; -+ -+ // remove cache -+ WeakReference lastRemoveObject = NULL_REFERENCE; -+ WeakReference> lastRemoveMap = NULL_REFERENCE; -+ -+ public PooledObjectLinkedOpenHashSet(final PooledLinkedHashSets pooledSets) { -+ this.set = new RawSetObjectLinkedOpenHashSet<>(2, 0.8f); -+ } -+ -+ public PooledObjectLinkedOpenHashSet(final E single) { -+ this((PooledLinkedHashSets)null); -+ this.referenceCount = -1; -+ this.add(single); -+ } -+ -+ public PooledObjectLinkedOpenHashSet(final PooledObjectLinkedOpenHashSet other) { -+ this.set = other.set.clone(); -+ this.hash = other.hash; -+ } -+ -+ // from https://github.com/Spottedleaf/ConcurrentUtil/blob/master/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java -+ // generated by https://github.com/skeeto/hash-prospector -+ private static int hash0(int x) { -+ x *= 0x36935555; -+ x ^= x >>> 16; -+ return x; -+ } -+ -+ PooledObjectLinkedOpenHashSet getAddCache(final E element) { -+ final E currentAdd = this.lastAddObject.get(); -+ -+ if (currentAdd == null || !(currentAdd == element || currentAdd.equals(element))) { -+ return null; -+ } -+ -+ return this.lastAddMap.get(); -+ } -+ -+ PooledObjectLinkedOpenHashSet getRemoveCache(final E element) { -+ final E currentRemove = this.lastRemoveObject.get(); -+ -+ if (currentRemove == null || !(currentRemove == element || currentRemove.equals(element))) { -+ return null; -+ } -+ -+ return this.lastRemoveMap.get(); -+ } -+ -+ void updateAddCache(final E element, final PooledObjectLinkedOpenHashSet map) { -+ this.lastAddObject = new WeakReference<>(element); -+ this.lastAddMap = new WeakReference<>(map); -+ } -+ -+ void updateRemoveCache(final E element, final PooledObjectLinkedOpenHashSet map) { -+ this.lastRemoveObject = new WeakReference<>(element); -+ this.lastRemoveMap = new WeakReference<>(map); -+ } -+ -+ boolean add(final E element) { -+ boolean added = this.set.add(element); -+ -+ if (added) { -+ this.hash += hash0(element.hashCode()); -+ } -+ -+ return added; -+ } -+ -+ boolean remove(Object element) { -+ boolean removed = this.set.remove(element); -+ -+ if (removed) { -+ this.hash -= hash0(element.hashCode()); -+ } -+ -+ return removed; -+ } -+ -+ public boolean contains(final Object element) { -+ return this.set.contains(element); -+ } -+ -+ public E[] getBackingSet() { -+ return this.set.getRawSet(); -+ } -+ -+ public int size() { -+ return this.set.size(); -+ } -+ -+ @Override -+ public int hashCode() { -+ return this.hash; -+ } -+ -+ @Override -+ public boolean equals(final Object other) { -+ if (!(other instanceof PooledObjectLinkedOpenHashSet)) { -+ return false; -+ } -+ if (this.referenceCount == 0) { -+ return other == this; -+ } else { -+ if (other == this) { -+ // Unfortunately we are never equal to our own instance while in use! -+ return false; -+ } -+ return this.hash == ((PooledObjectLinkedOpenHashSet)other).hash && this.set.equals(((PooledObjectLinkedOpenHashSet)other).set); -+ } -+ } -+ -+ @Override -+ public String toString() { -+ return "PooledHashSet: size: " + this.set.size() + ", reference count: " + this.referenceCount + ", hash: " + -+ this.hashCode() + ", identity: " + System.identityHashCode(this) + " map: " + this.set.toString(); -+ } -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a743703502cea333bd4231b6557de50e8eaf81eb ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java -@@ -0,0 +1,85 @@ -+package com.destroystokyo.paper.util.pooled; -+ -+import io.papermc.paper.util.MCUtil; -+import org.apache.commons.lang3.mutable.MutableInt; -+ -+import java.util.ArrayDeque; -+import java.util.function.Consumer; -+import java.util.function.Supplier; -+ -+public final class PooledObjects { -+ -+ /** -+ * Wrapper for an object that will be have a cleaner registered for it, and may be automatically returned to pool. -+ */ -+ public class AutoReleased { -+ private final E object; -+ private final Runnable cleaner; -+ -+ public AutoReleased(E object, Runnable cleaner) { -+ this.object = object; -+ this.cleaner = cleaner; -+ } -+ -+ public final E getObject() { -+ return object; -+ } -+ -+ public final Runnable getCleaner() { -+ return cleaner; -+ } -+ } -+ -+ public static final PooledObjects POOLED_MUTABLE_INTEGERS = new PooledObjects<>(MutableInt::new, 1024); -+ -+ private final Supplier creator; -+ private final Consumer releaser; -+ private final int maxPoolSize; -+ private final ArrayDeque queue; -+ -+ public PooledObjects(final Supplier creator, int maxPoolSize) { -+ this(creator, maxPoolSize, null); -+ } -+ public PooledObjects(final Supplier creator, int maxPoolSize, Consumer releaser) { -+ if (creator == null) { -+ throw new NullPointerException("Creator must not be null"); -+ } -+ if (maxPoolSize <= 0) { -+ throw new IllegalArgumentException("Max pool size must be greater-than 0"); -+ } -+ -+ this.queue = new ArrayDeque<>(maxPoolSize); -+ this.maxPoolSize = maxPoolSize; -+ this.creator = creator; -+ this.releaser = releaser; -+ } -+ -+ public AutoReleased acquireCleaner(Object holder) { -+ return acquireCleaner(holder, this::release); -+ } -+ -+ public AutoReleased acquireCleaner(Object holder, Consumer releaser) { -+ E resource = acquire(); -+ Runnable cleaner = MCUtil.registerCleaner(holder, resource, releaser); -+ return new AutoReleased(resource, cleaner); -+ } -+ -+ public final E acquire() { -+ E value; -+ synchronized (queue) { -+ value = this.queue.pollLast(); -+ } -+ return value != null ? value : this.creator.get(); -+ } -+ -+ public final void release(final E value) { -+ if (this.releaser != null) { -+ this.releaser.accept(value); -+ } -+ synchronized (this.queue) { -+ if (queue.size() < this.maxPoolSize) { -+ this.queue.addLast(value); -+ } -+ } -+ } -+} -diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8066e27ff88454cb4bc8075d936e58a067dbe9b4 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java -@@ -0,0 +1,71 @@ -+package com.destroystokyo.paper.util.set; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java +@@ -0,0 +1,68 @@ ++package ca.spottedleaf.moonrise.common.set; + +import java.util.Collection; + -+/** -+ * @author Spottedleaf <Spottedleaf@users.noreply.github.com> -+ */ +public final class OptimizedSmallEnumSet> { + + private final Class enumClass; @@ -1665,7 +3009,7 @@ index 0000000000000000000000000000000000000000..8066e27ff88454cb4bc8075d936e58a0 + this.enumClass = clazz; + } + -+ public boolean add(final E element) { ++ public boolean addUnchecked(final E element) { + final int ordinal = element.ordinal(); + final long key = 1L << ordinal; + @@ -1675,7 +3019,7 @@ index 0000000000000000000000000000000000000000..8066e27ff88454cb4bc8075d936e58a0 + return (prev & key) == 0; + } + -+ public boolean remove(final E element) { ++ public boolean removeUnchecked(final E element) { + final int ordinal = element.ordinal(); + final long key = 1L << ordinal; + @@ -1693,7 +3037,7 @@ index 0000000000000000000000000000000000000000..8066e27ff88454cb4bc8075d936e58a0 + return Long.bitCount(this.backingSet); + } + -+ public void addAll(final Collection enums) { ++ public void addAllUnchecked(final Collection enums) { + for (final E element : enums) { + if (element == null) { + throw new NullPointerException("Null element"); @@ -1710,63 +3054,38 @@ index 0000000000000000000000000000000000000000..8066e27ff88454cb4bc8075d936e58a0 + return (other.backingSet & this.backingSet) != 0; + } + -+ public boolean contains(final E element) { ++ public boolean hasElement(final E element) { + return (this.backingSet & (1L << element.ordinal())) != 0; + } +} -diff --git a/src/main/java/com/mojang/logging/LogUtils.java b/src/main/java/com/mojang/logging/LogUtils.java -index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a5c896f85 100644 ---- a/src/main/java/com/mojang/logging/LogUtils.java -+++ b/src/main/java/com/mojang/logging/LogUtils.java -@@ -61,4 +61,9 @@ public class LogUtils { - public static Logger getLogger() { - return LoggerFactory.getLogger(STACK_WALKER.getCallerClass()); - } -+ // Paper start -+ public static Logger getClassLogger() { -+ return LoggerFactory.getLogger(STACK_WALKER.getCallerClass().getSimpleName()); -+ } -+ // Paper end - } -diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java new file mode 100644 -index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783075ae17a +index 0000000000000000000000000000000000000000..da323a1105347d5cf4b946df10ded78a953236f2 --- /dev/null -+++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -@@ -0,0 +1,297 @@ -+package io.papermc.paper.chunk.system; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +@@ -0,0 +1,284 @@ ++package ca.spottedleaf.moonrise.common.util; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.destroystokyo.paper.util.SneakyThrow; +import com.mojang.logging.LogUtils; -+import io.papermc.paper.util.CoordinateUtils; +import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.ChunkMap; -+import net.minecraft.server.level.ChunkResult; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.server.level.TicketType; +import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.status.ChunkPyramid; -+import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.status.ChunkStep; -+import org.bukkit.Bukkit; ++import net.minecraft.world.level.chunk.status.ChunkStatus; +import org.slf4j.Logger; -+import java.util.ArrayList; +import java.util.List; -+import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +public final class ChunkSystem { + + private static final Logger LOGGER = LogUtils.getLogger(); -+ private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL); ++ private static final net.minecraft.world.level.chunk.status.ChunkStep FULL_CHUNK_STEP = net.minecraft.world.level.chunk.status.ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL); + -+ public static int getDistance(final ChunkStatus status) { ++ private static int getDistance(final ChunkStatus status) { + return FULL_CHUNK_STEP.getAccumulatedRadiusOf(status); + } + @@ -1802,21 +3121,21 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + }); + } + -+ static final TicketType CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); ++ static final net.minecraft.server.level.TicketType CHUNK_LOAD = net.minecraft.server.level.TicketType.create("chunk_load", Long::compareTo); + + private static long chunkLoadCounter = 0L; + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, + final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ if (!Bukkit.isPrimaryThread()) { ++ if (!org.bukkit.Bukkit.isPrimaryThread()) { + scheduleChunkTask(level, chunkX, chunkZ, () -> { + scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + }, priority); + return; + } + -+ final int minLevel = 33 + ChunkSystem.getDistance(toStatus); ++ final int minLevel = 33 + getDistance(toStatus); + final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); + + if (addTicket) { + level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); @@ -1830,10 +3149,10 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + } + } catch (final Throwable thr) { + LOGGER.error("Exception handling chunk load callback", thr); -+ SneakyThrow.sneaky(thr); ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr); + } finally { + if (addTicket) { -+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); ++ level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); + level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } + } @@ -1846,14 +3165,14 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + return; + } + -+ final CompletableFuture> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap); ++ final java.util.concurrent.CompletableFuture> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap); + + if (loadFuture.isDone()) { + loadCallback.accept(loadFuture.join().orElse(null)); + return; + } + -+ loadFuture.whenCompleteAsync((final ChunkResult result, final Throwable thr) -> { ++ loadFuture.whenCompleteAsync((final net.minecraft.server.level.ChunkResult result, final Throwable thr) -> { + if (thr != null) { + loadCallback.accept(null); + return; @@ -1872,7 +3191,7 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); + } + -+ if (!Bukkit.isPrimaryThread()) { ++ if (!org.bukkit.Bukkit.isPrimaryThread()) { + scheduleChunkTask(level, chunkX, chunkZ, () -> { + scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + }, priority); @@ -1882,7 +3201,7 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + final int minLevel = 33 - (toStatus.ordinal() - 1); + final int radius = toStatus.ordinal() - 1; + final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); ++ final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); + + if (addTicket) { + level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); @@ -1896,10 +3215,10 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + } + } catch (final Throwable thr) { + LOGGER.error("Exception handling chunk load callback", thr); -+ SneakyThrow.sneaky(thr); ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(thr); + } finally { + if (addTicket) { -+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); ++ level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); + level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); + } + } @@ -1912,7 +3231,7 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + return; + } + -+ final CompletableFuture> tickingState; ++ final java.util.concurrent.CompletableFuture> tickingState; + switch (toStatus) { + case FULL: { + tickingState = holder.getFullChunkFuture(); @@ -1936,7 +3255,7 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + return; + } + -+ tickingState.whenCompleteAsync((final ChunkResult result, final Throwable thr) -> { ++ tickingState.whenCompleteAsync((final net.minecraft.server.level.ChunkResult result, final Throwable thr) -> { + if (thr != null) { + loadCallback.accept(null); + return; @@ -1948,11 +3267,11 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + } + + public static List getVisibleChunkHolders(final ServerLevel level) { -+ return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); ++ return new java.util.ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); + } + + public static List getUpdatingChunkHolders(final ServerLevel level) { -+ return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); ++ return new java.util.ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); + } + + public static int getVisibleChunkHolderCount(final ServerLevel level) { @@ -1967,8 +3286,8 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + return getUpdatingChunkHolderCount(level) != 0; + } + -+ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) { -+ ++ public static boolean screenEntity(final ServerLevel level, final Entity entity) { ++ return true; + } + + public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) { @@ -1988,19 +3307,19 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + } + + public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().tickingChunks.add(chunk); ++ + } + + public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().tickingChunks.remove(chunk); ++ + } + + public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().entityTickingChunks.add(chunk); ++ + } + + public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ chunk.level.getChunkSource().entityTickingChunks.remove(chunk); ++ + } + + public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { @@ -2014,7 +3333,7 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + public static int getLoadViewDistance(final ServerPlayer player) { + final ServerLevel level = player.serverLevel(); + if (level == null) { -+ return Bukkit.getViewDistance(); ++ return org.bukkit.Bukkit.getViewDistance(); + } + return level.chunkSource.chunkMap.getPlayerViewDistance(player); + } @@ -2022,51 +3341,30 @@ index 0000000000000000000000000000000000000000..a79abe9b26f68d573812e91554124783 + public static int getTickViewDistance(final ServerPlayer player) { + final ServerLevel level = player.serverLevel(); + if (level == null) { -+ return Bukkit.getSimulationDistance(); ++ return org.bukkit.Bukkit.getSimulationDistance(); + } + return level.chunkSource.chunkMap.distanceManager.simulationDistance; + } + -+ private ChunkSystem() { -+ throw new RuntimeException(); -+ } ++ private ChunkSystem() {} +} -diff --git a/src/main/java/io/papermc/paper/util/CachedLists.java b/src/main/java/io/papermc/paper/util/CachedLists.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java new file mode 100644 -index 0000000000000000000000000000000000000000..be668387f65a633c6ac497fca632a4767a1bf3a2 +index 0000000000000000000000000000000000000000..31b92bd48828cbea25b44a9f0f96886347aa1ae6 --- /dev/null -+++ b/src/main/java/io/papermc/paper/util/CachedLists.java -@@ -0,0 +1,8 @@ -+package io.papermc.paper.util; -+ -+public final class CachedLists { -+ -+ public static void reset() { -+ -+ } -+} -diff --git a/src/main/java/io/papermc/paper/util/CoordinateUtils.java b/src/main/java/io/papermc/paper/util/CoordinateUtils.java -new file mode 100644 -index 0000000000000000000000000000000000000000..413e4b6da027876dbbe8eb78f2568a440f431547 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/CoordinateUtils.java -@@ -0,0 +1,128 @@ -+package io.papermc.paper.util; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java +@@ -0,0 +1,129 @@ ++package ca.spottedleaf.moonrise.common.util; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.phys.Vec3; + +public final class CoordinateUtils { + -+ // dx, dz are relative to the target chunk -+ // dx, dz in [-radius, radius] -+ public static int getNeighbourMappedIndex(final int dx, final int dz, final int radius) { -+ return (dx + radius) + (2 * radius + 1)*(dz + radius); -+ } -+ + // the chunk keys are compatible with vanilla + + public static long getChunkKey(final BlockPos pos) { @@ -2157,282 +3455,497 @@ index 0000000000000000000000000000000000000000..413e4b6da027876dbbe8eb78f2568a44 + return (int)(key << (Long.SIZE - (SECTION_Z_SHIFT + SECTION_Z_BITS)) >> (Long.SIZE - SECTION_Z_BITS)); + } + -+ // the block coordinates are not necessarily compatible with vanilla's -+ -+ public static int getBlockCoordinate(final double blockCoordinate) { -+ return Mth.floor(blockCoordinate); ++ public static int getBlockX(final Vec3 pos) { ++ return Mth.floor(pos.x); + } + -+ public static long getBlockKey(final int x, final int y, final int z) { -+ return ((long)x & 0x7FFFFFF) | (((long)z & 0x7FFFFFF) << 27) | ((long)y << 54); ++ public static int getBlockY(final Vec3 pos) { ++ return Mth.floor(pos.y); + } + -+ public static long getBlockKey(final BlockPos pos) { -+ return ((long)pos.getX() & 0x7FFFFFF) | (((long)pos.getZ() & 0x7FFFFFF) << 27) | ((long)pos.getY() << 54); ++ public static int getBlockZ(final Vec3 pos) { ++ return Mth.floor(pos.z); + } + -+ public static long getBlockKey(final Entity entity) { -+ return ((long)entity.getX() & 0x7FFFFFF) | (((long)entity.getZ() & 0x7FFFFFF) << 27) | ((long)entity.getY() << 54); ++ public static int getChunkX(final Vec3 pos) { ++ return Mth.floor(pos.x) >> 4; ++ } ++ ++ public static int getChunkY(final Vec3 pos) { ++ return Mth.floor(pos.y) >> 4; ++ } ++ ++ public static int getChunkZ(final Vec3 pos) { ++ return Mth.floor(pos.z) >> 4; + } + + private CoordinateUtils() { + throw new RuntimeException(); + } +} -diff --git a/src/main/java/io/papermc/paper/util/IntegerUtil.java b/src/main/java/io/papermc/paper/util/IntegerUtil.java +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..16785bd5c0524f6bad0691ca7ecd4514608d2eab +index 0000000000000000000000000000000000000000..0531f25aaad162386a029d33e68d7c8336b9d5d1 --- /dev/null -+++ b/src/main/java/io/papermc/paper/util/IntegerUtil.java -@@ -0,0 +1,242 @@ -+package io.papermc.paper.util; ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java +@@ -0,0 +1,109 @@ ++package ca.spottedleaf.moonrise.common.util; + -+public final class IntegerUtil { ++import java.util.Objects; + -+ public static final int HIGH_BIT_U32 = Integer.MIN_VALUE; -+ public static final long HIGH_BIT_U64 = Long.MIN_VALUE; ++public final class FlatBitsetUtil { + -+ public static int ceilLog2(final int value) { -+ return Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros -+ } ++ private static final int LOG2_LONG = 6; ++ private static final long ALL_SET = -1L; ++ private static final int BITS_PER_LONG = Long.SIZE; + -+ public static long ceilLog2(final long value) { -+ return Long.SIZE - Long.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int floorLog2(final int value) { -+ // xor is optimized subtract for 2^n -1 -+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) -+ return (Integer.SIZE - 1) ^ Integer.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int floorLog2(final long value) { -+ // xor is optimized subtract for 2^n -1 -+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) -+ return (Long.SIZE - 1) ^ Long.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros -+ } -+ -+ public static int roundCeilLog2(final int value) { -+ // optimized variant of 1 << (32 - leading(val - 1)) -+ // given -+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) -+ // 1 << (32 - leading(val - 1)) = HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) -+ // HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) -+ // HIGH_BIT_32 >>> (31 - 32 + leading(val - 1)) -+ // HIGH_BIT_32 >>> (-1 + leading(val - 1)) -+ return HIGH_BIT_U32 >>> (Integer.numberOfLeadingZeros(value - 1) - 1); -+ } -+ -+ public static long roundCeilLog2(final long value) { -+ // see logic documented above -+ return HIGH_BIT_U64 >>> (Long.numberOfLeadingZeros(value - 1) - 1); -+ } -+ -+ public static int roundFloorLog2(final int value) { -+ // optimized variant of 1 << (31 - leading(val)) -+ // given -+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) -+ // 1 << (31 - leading(val)) = HIGH_BIT_32 >> (31 - (31 - leading(val))) -+ // HIGH_BIT_32 >> (31 - (31 - leading(val))) -+ // HIGH_BIT_32 >> (31 - 31 + leading(val)) -+ return HIGH_BIT_U32 >>> Integer.numberOfLeadingZeros(value); -+ } -+ -+ public static long roundFloorLog2(final long value) { -+ // see logic documented above -+ return HIGH_BIT_U64 >>> Long.numberOfLeadingZeros(value); -+ } -+ -+ public static boolean isPowerOfTwo(final int n) { -+ // 2^n has one bit -+ // note: this rets true for 0 still -+ return IntegerUtil.getTrailingBit(n) == n; -+ } -+ -+ public static boolean isPowerOfTwo(final long n) { -+ // 2^n has one bit -+ // note: this rets true for 0 still -+ return IntegerUtil.getTrailingBit(n) == n; -+ } -+ -+ public static int getTrailingBit(final int n) { -+ return -n & n; -+ } -+ -+ public static long getTrailingBit(final long n) { -+ return -n & n; -+ } -+ -+ public static int trailingZeros(final int n) { -+ return Integer.numberOfTrailingZeros(n); -+ } -+ -+ public static int trailingZeros(final long n) { -+ return Long.numberOfTrailingZeros(n); -+ } -+ -+ // from hacker's delight (signed division magic value) -+ public static int getDivisorMultiple(final long numbers) { -+ return (int)(numbers >>> 32); -+ } -+ -+ // from hacker's delight (signed division magic value) -+ public static int getDivisorShift(final long numbers) { -+ return (int)numbers; -+ } -+ -+ // copied from hacker's delight (signed division magic value) -+ // http://www.hackersdelight.org/hdcodetxt/magic.c.txt -+ public static long getDivisorNumbers(final int d) { -+ final int ad = branchlessAbs(d); -+ -+ if (ad < 2) { -+ throw new IllegalArgumentException("|number| must be in [2, 2^31 -1], not: " + d); ++ // from inclusive ++ // to exclusive ++ public static int firstSet(final long[] bitset, final int from, final int to) { ++ if ((from | to | (to - from)) < 0) { ++ throw new IndexOutOfBoundsException(); + } + -+ final int two31 = 0x80000000; -+ final long mask = 0xFFFFFFFFL; // mask for enforcing unsigned behaviour ++ int bitsetIdx = from >>> LOG2_LONG; ++ int bitIdx = from & ~(BITS_PER_LONG - 1); + -+ /* -+ Signed usage: -+ int number; -+ long magic = getDivisorNumbers(div); -+ long mul = magic >>> 32; -+ int sign = number >> 31; -+ int result = (int)(((long)number * mul) >>> magic) - sign; -+ */ -+ /* -+ Unsigned usage: -+ int number; -+ long magic = getDivisorNumbers(div); -+ long mul = magic >>> 32; -+ int result = (int)(((long)number * mul) >>> magic); -+ */ -+ -+ int p = 31; -+ -+ // all these variables are UNSIGNED! -+ int t = two31 + (d >>> 31); -+ int anc = t - 1 - (int)((t & mask)%ad); -+ int q1 = (int)((two31 & mask)/(anc & mask)); -+ int r1 = two31 - q1*anc; -+ int q2 = (int)((two31 & mask)/(ad & mask)); -+ int r2 = two31 - q2*ad; -+ int delta; -+ -+ do { -+ p = p + 1; -+ q1 = 2*q1; // Update q1 = 2**p/|nc|. -+ r1 = 2*r1; // Update r1 = rem(2**p, |nc|). -+ if ((r1 & mask) >= (anc & mask)) {// (Must be an unsigned comparison here) -+ q1 = q1 + 1; -+ r1 = r1 - anc; ++ long tmp = bitset[bitsetIdx] & (ALL_SET << from); ++ for (;;) { ++ if (tmp != 0L) { ++ final int ret = bitIdx | Long.numberOfTrailingZeros(tmp); ++ return ret >= to ? -1 : ret; + } -+ q2 = 2*q2; // Update q2 = 2**p/|d|. -+ r2 = 2*r2; // Update r2 = rem(2**p, |d|). -+ if ((r2 & mask) >= (ad & mask)) {// (Must be an unsigned comparison here) -+ q2 = q2 + 1; -+ r2 = r2 - ad; -+ } -+ delta = ad - r2; -+ } while ((q1 & mask) < (delta & mask) || (q1 == delta && r1 == 0)); + -+ int magicNum = q2 + 1; -+ if (d < 0) { -+ magicNum = -magicNum; ++ bitIdx += BITS_PER_LONG; ++ ++ if (bitIdx >= to) { ++ return -1; ++ } ++ ++ tmp = bitset[++bitsetIdx]; + } -+ int shift = p; -+ return ((long)magicNum << 32) | shift; + } + -+ public static int branchlessAbs(final int val) { -+ // -n = -1 ^ n + 1 -+ final int mask = val >> (Integer.SIZE - 1); // -1 if < 0, 0 if >= 0 -+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 ++ // from inclusive ++ // to exclusive ++ public static int firstClear(final long[] bitset, final int from, final int to) { ++ if ((from | to | (to - from)) < 0) { ++ throw new IndexOutOfBoundsException(); ++ } ++ // like firstSet, but invert the bitset ++ ++ int bitsetIdx = from >>> LOG2_LONG; ++ int bitIdx = from & ~(BITS_PER_LONG - 1); ++ ++ long tmp = (~bitset[bitsetIdx]) & (ALL_SET << from); ++ for (;;) { ++ if (tmp != 0L) { ++ final int ret = bitIdx | Long.numberOfTrailingZeros(tmp); ++ return ret >= to ? -1 : ret; ++ } ++ ++ bitIdx += BITS_PER_LONG; ++ ++ if (bitIdx >= to) { ++ return -1; ++ } ++ ++ tmp = ~bitset[++bitsetIdx]; ++ } + } + -+ public static long branchlessAbs(final long val) { -+ // -n = -1 ^ n + 1 -+ final long mask = val >> (Long.SIZE - 1); // -1 if < 0, 0 if >= 0 -+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 ++ // from inclusive ++ // to exclusive ++ public static void clearRange(final long[] bitset, final int from, int to) { ++ if ((from | to | (to - from)) < 0) { ++ throw new IndexOutOfBoundsException(); ++ } ++ ++ if (from == to) { ++ return; ++ } ++ ++ --to; ++ ++ final int fromBitsetIdx = from >>> LOG2_LONG; ++ final int toBitsetIdx = to >>> LOG2_LONG; ++ ++ final long keepFirst = ~(ALL_SET << from); ++ final long keepLast = ~(ALL_SET >>> ((BITS_PER_LONG - 1) ^ to)); ++ ++ Objects.checkFromToIndex(fromBitsetIdx, toBitsetIdx, bitset.length); ++ ++ if (fromBitsetIdx == toBitsetIdx) { ++ // special case: need to keep both first and last ++ bitset[fromBitsetIdx] &= (keepFirst | keepLast); ++ } else { ++ bitset[fromBitsetIdx] &= keepFirst; ++ ++ for (int i = fromBitsetIdx + 1; i < toBitsetIdx; ++i) { ++ bitset[i] = 0L; ++ } ++ ++ bitset[toBitsetIdx] &= keepLast; ++ } + } + -+ //https://github.com/skeeto/hash-prospector for hash functions -+ -+ //score = ~590.47984224483832 -+ public static int hash0(int x) { -+ x *= 0x36935555; -+ x ^= x >>> 16; -+ return x; ++ // from inclusive ++ // to exclusive ++ public static boolean isRangeSet(final long[] bitset, final int from, final int to) { ++ return firstClear(bitset, from, to) == -1; + } + -+ //score = ~310.01596637036749 -+ public static int hash1(int x) { -+ x ^= x >>> 15; -+ x *= 0x356aaaad; -+ x ^= x >>> 17; -+ return x; ++ ++ private FlatBitsetUtil() {} ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..91efda726b87a8a8f28dee84e31b6a7063752ebd +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import com.google.gson.JsonElement; ++import com.google.gson.internal.Streams; ++import com.google.gson.stream.JsonWriter; ++import java.io.File; ++import java.io.FileOutputStream; ++import java.io.IOException; ++import java.io.PrintStream; ++import java.io.StringWriter; ++import java.nio.charset.StandardCharsets; ++ ++public final class JsonUtil { ++ ++ public static void writeJson(final JsonElement element, final File file) throws IOException { ++ final StringWriter stringWriter = new StringWriter(); ++ final JsonWriter jsonWriter = new JsonWriter(stringWriter); ++ jsonWriter.setIndent(" "); ++ jsonWriter.setLenient(false); ++ Streams.write(element, jsonWriter); ++ ++ final String jsonString = stringWriter.toString(); ++ ++ final File parent = file.getParentFile(); ++ if (parent != null) { ++ parent.mkdirs(); ++ } ++ file.createNewFile(); ++ try (final PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) { ++ out.print(jsonString); ++ } + } + -+ public static int hash2(int x) { -+ x ^= x >>> 16; -+ x *= 0x7feb352d; -+ x ^= x >>> 15; -+ x *= 0x846ca68b; -+ x ^= x >>> 16; -+ return x; ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ac6f284ee4469d16c5655328b2488d7612832353 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java +@@ -0,0 +1,10 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++public final class MixinWorkarounds { ++ ++ // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs ++ public static long[] clone(final long[] values) { ++ return values.clone(); + } + -+ public static int hash3(int x) { -+ x ^= x >>> 17; -+ x *= 0xed5ad4bb; -+ x ^= x >>> 11; -+ x *= 0xac4c1b51; -+ x ^= x >>> 15; -+ x *= 0x31848bab; -+ x ^= x >>> 14; -+ return x; ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3abe0bd2a820352b85306d554bf14a4cf6123091 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import java.io.File; ++ ++public final class MoonriseCommon { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); ++ ++ // Paper start ++ public static PrioritisedThreadPool WORKER_POOL; ++ public static int WORKER_THREADS; ++ public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { ++ // Paper end ++ int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; ++ if (defaultWorkerThreads <= 4) { ++ defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; ++ } else { ++ defaultWorkerThreads = defaultWorkerThreads / 2; ++ } ++ defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper ++ ++ int workerThreads = chunkSystem.workerThreads; // Paper ++ ++ if (workerThreads <= 0) { ++ workerThreads = defaultWorkerThreads; ++ } ++ ++ WORKER_POOL = new PrioritisedThreadPool( ++ "Paper Worker Pool", workerThreads, // Paper ++ (final Thread thread, final Integer id) -> { ++ thread.setName("Paper Common Worker #" + id.intValue()); // Paper ++ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { ++ @Override ++ public void uncaughtException(final Thread thread, final Throwable throwable) { ++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); ++ } ++ }); ++ }, (long)(20.0e6)); // 20ms ++ WORKER_THREADS = workerThreads; + } + -+ //score = ~365.79959673201887 -+ public static long hash1(long x) { -+ x ^= x >>> 27; -+ x *= 0xb24924b71d2d354bL; -+ x ^= x >>> 28; -+ return x; ++ private MoonriseCommon() {} ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++public final class MoonriseConstants { ++ ++ public static final int MAX_VIEW_DISTANCE = 32; ++ ++ private MoonriseConstants() {} ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7deb341b7e2b4592ae3f88733d6cacf6e58764e4 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +@@ -0,0 +1,139 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.ChunkPos; ++import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.Vec3; ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++ ++import java.util.concurrent.atomic.AtomicInteger; ++ ++public class TickThread extends Thread { ++ ++ private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class); ++ ++ /** ++ * @deprecated ++ */ ++ @Deprecated ++ public static void ensureTickThread(final String reason) { ++ if (!isTickThread()) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } + } + -+ //h2 hash -+ public static long hash2(long x) { -+ x ^= x >>> 32; -+ x *= 0xd6e8feb86659fd93L; -+ x ^= x >>> 32; -+ x *= 0xd6e8feb86659fd93L; -+ x ^= x >>> 32; -+ return x; ++ public static void ensureTickThread(final ServerLevel world, final BlockPos pos, final String reason) { ++ if (!isTickThreadFor(world, pos)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } + } + -+ public static long hash3(long x) { -+ x ^= x >>> 45; -+ x *= 0xc161abe5704b6c79L; -+ x ^= x >>> 41; -+ x *= 0xe3e5389aedbc90f7L; -+ x ^= x >>> 56; -+ x *= 0x1f9aba75a52db073L; -+ x ^= x >>> 53; -+ return x; ++ public static void ensureTickThread(final ServerLevel world, final ChunkPos pos, final String reason) { ++ if (!isTickThreadFor(world, pos)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } + } + -+ private IntegerUtil() { ++ public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) { ++ if (!isTickThreadFor(world, chunkX, chunkZ)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } ++ } ++ ++ public static void ensureTickThread(final Entity entity, final String reason) { ++ if (!isTickThreadFor(entity)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } ++ } ++ ++ public static void ensureTickThread(final ServerLevel world, final AABB aabb, final String reason) { ++ if (!isTickThreadFor(world, aabb)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } ++ } ++ ++ public static void ensureTickThread(final ServerLevel world, final double blockX, final double blockZ, final String reason) { ++ if (!isTickThreadFor(world, blockX, blockZ)) { ++ LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); ++ throw new IllegalStateException(reason); ++ } ++ } ++ ++ public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ ++ ++ private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); ++ ++ public TickThread(final String name) { ++ this(null, name); ++ } ++ ++ public TickThread(final Runnable run, final String name) { ++ this(run, name, ID_GENERATOR.incrementAndGet()); ++ } ++ ++ private TickThread(final Runnable run, final String name, final int id) { ++ super(run, name); ++ this.id = id; ++ } ++ ++ public static TickThread getCurrentTickThread() { ++ return (TickThread)Thread.currentThread(); ++ } ++ ++ public static boolean isTickThread() { ++ return org.bukkit.Bukkit.isPrimaryThread(); // Paper ++ } ++ ++ public static boolean isShutdownThread() { ++ return false; ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final BlockPos pos) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final ChunkPos pos) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final Vec3 pos) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final AABB aabb) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final double blockX, final double blockZ) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final Vec3 position, final Vec3 deltaMovement, final int buffer) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) { ++ return isTickThread(); ++ } ++ ++ public static boolean isTickThreadFor(final Entity entity) { ++ return isTickThread(); ++ } ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..af9623240ff2d389aa7090623f507720e7dbab7d +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java +@@ -0,0 +1,54 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.LevelHeightAccessor; ++ ++public final class WorldUtil { ++ ++ // min, max are inclusive ++ ++ public static int getMaxSection(final LevelHeightAccessor world) { ++ return world.getMaxSection() - 1; // getMaxSection() is exclusive ++ } ++ ++ public static int getMinSection(final LevelHeightAccessor world) { ++ return world.getMinSection(); ++ } ++ ++ public static int getMaxLightSection(final LevelHeightAccessor world) { ++ return getMaxSection(world) + 1; ++ } ++ ++ public static int getMinLightSection(final LevelHeightAccessor world) { ++ return getMinSection(world) - 1; ++ } ++ ++ ++ ++ public static int getTotalSections(final LevelHeightAccessor world) { ++ return getMaxSection(world) - getMinSection(world) + 1; ++ } ++ ++ public static int getTotalLightSections(final LevelHeightAccessor world) { ++ return getMaxLightSection(world) - getMinLightSection(world) + 1; ++ } ++ ++ public static int getMinBlockY(final LevelHeightAccessor world) { ++ return getMinSection(world) << 4; ++ } ++ ++ public static int getMaxBlockY(final LevelHeightAccessor world) { ++ return (getMaxSection(world) << 4) | 15; ++ } ++ ++ public static String getWorldName(final Level world) { ++ if (world == null) { ++ return "null world"; ++ } ++ return world.getWorld().getName(); // Paper ++ } ++ ++ private WorldUtil() { + throw new RuntimeException(); + } +} +diff --git a/src/main/java/com/mojang/logging/LogUtils.java b/src/main/java/com/mojang/logging/LogUtils.java +index 46cab7a8c7b87ab01b26074b04f5a02b3907cfc4..49019b4a9bc4e634d54a9b0acaf9229a5c896f85 100644 +--- a/src/main/java/com/mojang/logging/LogUtils.java ++++ b/src/main/java/com/mojang/logging/LogUtils.java +@@ -61,4 +61,9 @@ public class LogUtils { + public static Logger getLogger() { + return LoggerFactory.getLogger(STACK_WALKER.getCallerClass()); + } ++ // Paper start ++ public static Logger getClassLogger() { ++ return LoggerFactory.getLogger(STACK_WALKER.getCallerClass().getSimpleName()); ++ } ++ // Paper end + } diff --git a/src/main/java/io/papermc/paper/util/IntervalledCounter.java b/src/main/java/io/papermc/paper/util/IntervalledCounter.java new file mode 100644 -index 0000000000000000000000000000000000000000..c90acc3bde887b9c8f8d49fcc3195657c721bc14 +index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65f2288d7f --- /dev/null +++ b/src/main/java/io/papermc/paper/util/IntervalledCounter.java -@@ -0,0 +1,128 @@ +@@ -0,0 +1,129 @@ +package io.papermc.paper.util; + +public final class IntervalledCounter { @@ -2536,6 +4049,7 @@ index 0000000000000000000000000000000000000000..c90acc3bde887b9c8f8d49fcc3195657 + } else { + // ordered from [head, length) + // then followed by [0, tail) ++ + System.arraycopy(oldElements, head, newElements, 0, oldElements.length - head); + System.arraycopy(oldElements, 0, newElements, oldElements.length - head, tail); + @@ -3147,845 +4661,6 @@ index 0000000000000000000000000000000000000000..f7114d5b8f2f93f62883e24da29afaf9 + return foundFrame.orElse(null); + } +} -diff --git a/src/main/java/io/papermc/paper/util/WorldUtil.java b/src/main/java/io/papermc/paper/util/WorldUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..67bb91fcfb532a919954cd9d7733d09a6c3fec35 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/WorldUtil.java -@@ -0,0 +1,46 @@ -+package io.papermc.paper.util; -+ -+import net.minecraft.world.level.LevelHeightAccessor; -+ -+public final class WorldUtil { -+ -+ // min, max are inclusive -+ -+ public static int getMaxSection(final LevelHeightAccessor world) { -+ return world.getMaxSection() - 1; // getMaxSection() is exclusive -+ } -+ -+ public static int getMinSection(final LevelHeightAccessor world) { -+ return world.getMinSection(); -+ } -+ -+ public static int getMaxLightSection(final LevelHeightAccessor world) { -+ return getMaxSection(world) + 1; -+ } -+ -+ public static int getMinLightSection(final LevelHeightAccessor world) { -+ return getMinSection(world) - 1; -+ } -+ -+ -+ -+ public static int getTotalSections(final LevelHeightAccessor world) { -+ return getMaxSection(world) - getMinSection(world) + 1; -+ } -+ -+ public static int getTotalLightSections(final LevelHeightAccessor world) { -+ return getMaxLightSection(world) - getMinLightSection(world) + 1; -+ } -+ -+ public static int getMinBlockY(final LevelHeightAccessor world) { -+ return getMinSection(world) << 4; -+ } -+ -+ public static int getMaxBlockY(final LevelHeightAccessor world) { -+ return (getMaxSection(world) << 4) | 15; -+ } -+ -+ private WorldUtil() { -+ throw new RuntimeException(); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0fd814f1d65c111266a2b20f86561839a4cef755 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java -@@ -0,0 +1,334 @@ -+package io.papermc.paper.util.maplist; -+ -+import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2IntMap; -+import org.bukkit.Bukkit; -+import java.util.Arrays; -+import java.util.NoSuchElementException; -+ -+public final class IteratorSafeOrderedReferenceSet { -+ -+ public static final int ITERATOR_FLAG_SEE_ADDITIONS = 1 << 0; -+ -+ protected final Reference2IntLinkedOpenHashMap indexMap; -+ protected int firstInvalidIndex = -1; -+ -+ /* list impl */ -+ protected E[] listElements; -+ protected int listSize; -+ -+ protected final double maxFragFactor; -+ -+ protected int iteratorCount; -+ -+ private final boolean threadRestricted; -+ -+ public IteratorSafeOrderedReferenceSet() { -+ this(16, 0.75f, 16, 0.2); -+ } -+ -+ public IteratorSafeOrderedReferenceSet(final boolean threadRestricted) { -+ this(16, 0.75f, 16, 0.2, threadRestricted); -+ } -+ -+ public IteratorSafeOrderedReferenceSet(final int setCapacity, final float setLoadFactor, final int arrayCapacity, -+ final double maxFragFactor) { -+ this(setCapacity, setLoadFactor, arrayCapacity, maxFragFactor, false); -+ } -+ public IteratorSafeOrderedReferenceSet(final int setCapacity, final float setLoadFactor, final int arrayCapacity, -+ final double maxFragFactor, final boolean threadRestricted) { -+ this.indexMap = new Reference2IntLinkedOpenHashMap<>(setCapacity, setLoadFactor); -+ this.indexMap.defaultReturnValue(-1); -+ this.maxFragFactor = maxFragFactor; -+ this.listElements = (E[])new Object[arrayCapacity]; -+ this.threadRestricted = threadRestricted; -+ } -+ -+ /* -+ public void check() { -+ int iterated = 0; -+ ReferenceOpenHashSet check = new ReferenceOpenHashSet<>(); -+ if (this.listElements != null) { -+ for (int i = 0; i < this.listSize; ++i) { -+ Object obj = this.listElements[i]; -+ if (obj != null) { -+ iterated++; -+ if (!check.add((E)obj)) { -+ throw new IllegalStateException("contains duplicate"); -+ } -+ if (!this.contains((E)obj)) { -+ throw new IllegalStateException("desync"); -+ } -+ } -+ } -+ } -+ -+ if (iterated != this.size()) { -+ throw new IllegalStateException("Size is mismatched! Got " + iterated + ", expected " + this.size()); -+ } -+ -+ check.clear(); -+ iterated = 0; -+ for (final java.util.Iterator iterator = this.unsafeIterator(IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS); iterator.hasNext();) { -+ final E element = iterator.next(); -+ iterated++; -+ if (!check.add(element)) { -+ throw new IllegalStateException("contains duplicate (iterator is wrong)"); -+ } -+ if (!this.contains(element)) { -+ throw new IllegalStateException("desync (iterator is wrong)"); -+ } -+ } -+ -+ if (iterated != this.size()) { -+ throw new IllegalStateException("Size is mismatched! (iterator is wrong) Got " + iterated + ", expected " + this.size()); -+ } -+ } -+ */ -+ -+ protected final boolean allowSafeIteration() { -+ return !this.threadRestricted || Bukkit.isPrimaryThread(); -+ } -+ -+ protected final double getFragFactor() { -+ return 1.0 - ((double)this.indexMap.size() / (double)this.listSize); -+ } -+ -+ public int createRawIterator() { -+ if (this.allowSafeIteration()) { -+ ++this.iteratorCount; -+ } -+ if (this.indexMap.isEmpty()) { -+ return -1; -+ } else { -+ return this.firstInvalidIndex == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0; -+ } -+ } -+ -+ public int advanceRawIterator(final int index) { -+ final E[] elements = this.listElements; -+ int ret = index + 1; -+ for (int len = this.listSize; ret < len; ++ret) { -+ if (elements[ret] != null) { -+ return ret; -+ } -+ } -+ -+ return -1; -+ } -+ -+ public void finishRawIterator() { -+ if (this.allowSafeIteration() && --this.iteratorCount == 0) { -+ if (this.getFragFactor() >= this.maxFragFactor) { -+ this.defrag(); -+ } -+ } -+ } -+ -+ public boolean remove(final E element) { -+ final int index = this.indexMap.removeInt(element); -+ if (index >= 0) { -+ if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) { -+ this.firstInvalidIndex = index; -+ } -+ if (this.listElements[index] != element) { -+ throw new IllegalStateException(); -+ } -+ this.listElements[index] = null; -+ if (this.allowSafeIteration() && this.iteratorCount == 0 && this.getFragFactor() >= this.maxFragFactor) { -+ this.defrag(); -+ } -+ //this.check(); -+ return true; -+ } -+ return false; -+ } -+ -+ public boolean contains(final E element) { -+ return this.indexMap.containsKey(element); -+ } -+ -+ public boolean add(final E element) { -+ final int listSize = this.listSize; -+ -+ final int previous = this.indexMap.putIfAbsent(element, listSize); -+ if (previous != -1) { -+ return false; -+ } -+ -+ if (listSize >= this.listElements.length) { -+ this.listElements = Arrays.copyOf(this.listElements, listSize * 2); -+ } -+ this.listElements[listSize] = element; -+ this.listSize = listSize + 1; -+ -+ //this.check(); -+ return true; -+ } -+ -+ protected void defrag() { -+ if (this.firstInvalidIndex < 0) { -+ return; // nothing to do -+ } -+ -+ if (this.indexMap.isEmpty()) { -+ Arrays.fill(this.listElements, 0, this.listSize, null); -+ this.listSize = 0; -+ this.firstInvalidIndex = -1; -+ //this.check(); -+ return; -+ } -+ -+ final E[] backingArray = this.listElements; -+ -+ int lastValidIndex; -+ java.util.Iterator> iterator; -+ -+ if (this.firstInvalidIndex == 0) { -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(); -+ lastValidIndex = 0; -+ } else { -+ lastValidIndex = this.firstInvalidIndex; -+ final E key = backingArray[lastValidIndex - 1]; -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(new Reference2IntMap.Entry() { -+ @Override -+ public int getIntValue() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public int setValue(int i) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public E getKey() { -+ return key; -+ } -+ }); -+ } -+ -+ while (iterator.hasNext()) { -+ final Reference2IntMap.Entry entry = iterator.next(); -+ -+ final int newIndex = lastValidIndex++; -+ backingArray[newIndex] = entry.getKey(); -+ entry.setValue(newIndex); -+ } -+ -+ // cleanup end -+ Arrays.fill(backingArray, lastValidIndex, this.listSize, null); -+ this.listSize = lastValidIndex; -+ this.firstInvalidIndex = -1; -+ //this.check(); -+ } -+ -+ public E rawGet(final int index) { -+ return this.listElements[index]; -+ } -+ -+ public int size() { -+ // always returns the correct amount - listSize can be different -+ return this.indexMap.size(); -+ } -+ -+ public IteratorSafeOrderedReferenceSet.Iterator iterator() { -+ return this.iterator(0); -+ } -+ -+ public IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { -+ if (this.allowSafeIteration()) { -+ ++this.iteratorCount; -+ } -+ return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); -+ } -+ -+ public java.util.Iterator unsafeIterator() { -+ return this.unsafeIterator(0); -+ } -+ public java.util.Iterator unsafeIterator(final int flags) { -+ return new BaseIterator<>(this, false, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); -+ } -+ -+ public static interface Iterator extends java.util.Iterator { -+ -+ public void finishedIterating(); -+ -+ } -+ -+ protected static final class BaseIterator implements IteratorSafeOrderedReferenceSet.Iterator { -+ -+ protected final IteratorSafeOrderedReferenceSet set; -+ protected final boolean canFinish; -+ protected final int maxIndex; -+ protected int nextIndex; -+ protected E pendingValue; -+ protected boolean finished; -+ protected E lastReturned; -+ -+ protected BaseIterator(final IteratorSafeOrderedReferenceSet set, final boolean canFinish, final int maxIndex) { -+ this.set = set; -+ this.canFinish = canFinish; -+ this.maxIndex = maxIndex; -+ } -+ -+ @Override -+ public boolean hasNext() { -+ if (this.finished) { -+ return false; -+ } -+ if (this.pendingValue != null) { -+ return true; -+ } -+ -+ final E[] elements = this.set.listElements; -+ int index, len; -+ for (index = this.nextIndex, len = Math.min(this.maxIndex, this.set.listSize); index < len; ++index) { -+ final E element = elements[index]; -+ if (element != null) { -+ this.pendingValue = element; -+ this.nextIndex = index + 1; -+ return true; -+ } -+ } -+ -+ this.nextIndex = index; -+ return false; -+ } -+ -+ @Override -+ public E next() { -+ if (!this.hasNext()) { -+ throw new NoSuchElementException(); -+ } -+ final E ret = this.pendingValue; -+ -+ this.pendingValue = null; -+ this.lastReturned = ret; -+ -+ return ret; -+ } -+ -+ @Override -+ public void remove() { -+ final E lastReturned = this.lastReturned; -+ if (lastReturned == null) { -+ throw new IllegalStateException(); -+ } -+ this.lastReturned = null; -+ this.set.remove(lastReturned); -+ } -+ -+ @Override -+ public void finishedIterating() { -+ if (this.finished || !this.canFinish) { -+ throw new IllegalStateException(); -+ } -+ this.lastReturned = null; -+ this.finished = true; -+ if (this.set.allowSafeIteration()) { -+ this.set.finishRawIterator(); -+ } -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c3ce8a42dddd76b7189ad5685b23f9d9f8ccadb3 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java -@@ -0,0 +1,203 @@ -+package io.papermc.paper.util.player; -+ -+import com.destroystokyo.paper.util.maplist.ReferenceList; -+import io.papermc.paper.chunk.system.ChunkSystem; -+import io.papermc.paper.util.CoordinateUtils; -+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -+import net.minecraft.core.BlockPos; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.level.ChunkPos; -+ -+public final class NearbyPlayers { -+ -+ public static enum NearbyMapType { -+ GENERAL, -+ GENERAL_SMALL, -+ GENERAL_REALLY_SMALL, -+ TICK_VIEW_DISTANCE, -+ VIEW_DISTANCE; -+ } -+ -+ private static final NearbyMapType[] MOB_TYPES = NearbyMapType.values(); -+ public static final int TOTAL_MAP_TYPES = MOB_TYPES.length; -+ -+ private static final int GENERAL_AREA_VIEW_DISTANCE = 33; -+ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; -+ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; -+ -+ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); -+ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); -+ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); -+ -+ private final ServerLevel world; -+ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ -+ public NearbyPlayers(final ServerLevel world) { -+ this.world = world; -+ } -+ -+ public void addPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; -+ if (this.players.putIfAbsent(player, newTrackers) != null) { -+ throw new IllegalStateException("Already have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { -+ // use 0 for default, will be updated by tickPlayer -+ (newTrackers[i] = new TrackedPlayer(player, MOB_TYPES[i])).add(chunk.x, chunk.z, 0); -+ } -+ -+ // update view distances -+ this.tickPlayer(player); -+ } -+ -+ public void removePlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.remove(player); -+ if (players == null) { -+ return; // May be called during teleportation before the player is actually placed -+ } -+ -+ for (final TrackedPlayer tracker : players) { -+ tracker.remove(); -+ } -+ } -+ -+ public void tickPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.get(player); -+ if (players == null) { -+ throw new IllegalStateException("Don't have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); -+ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getLoadViewDistance(player)); -+ } -+ -+ public TrackedChunk getChunk(final ChunkPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public TrackedChunk getChunk(final BlockPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public static final class TrackedChunk { -+ -+ public final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; -+ private int nonEmptyLists; -+ private int updateCount; -+ -+ public boolean isEmpty() { -+ return this.nonEmptyLists == 0; -+ } -+ -+ public int getUpdateCount() { -+ return this.updateCount; -+ } -+ -+ public ReferenceList getPlayers(final NearbyMapType type) { -+ return this.players[type.ordinal()]; -+ } -+ -+ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ ++this.nonEmptyLists; -+ (this.players[idx] = new ReferenceList<>()).add(player); -+ return; -+ } -+ -+ if (!list.add(player)) { -+ throw new IllegalStateException("Already contains player " + player); -+ } -+ } -+ -+ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (!list.remove(player)) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (list.size() == 0) { -+ this.players[idx] = null; -+ --this.nonEmptyLists; -+ } -+ } -+ } -+ -+ private final class TrackedPlayer extends SingleUserAreaMap { -+ -+ final NearbyMapType type; -+ -+ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { -+ super(player); -+ this.type = type; -+ } -+ -+ @Override -+ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -+ return new TrackedChunk(); -+ }).addPlayer(parameter, this.type); -+ } -+ -+ @Override -+ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ if (chunk == null) { -+ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); -+ } -+ -+ chunk.removePlayer(parameter, this.type); -+ -+ if (chunk.isEmpty()) { -+ NearbyPlayers.this.byChunk.remove(chunkKey); -+ } -+ } -+ } -+} -diff --git a/src/main/java/io/papermc/paper/util/player/SingleUserAreaMap.java b/src/main/java/io/papermc/paper/util/player/SingleUserAreaMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d603887f4d0464f4463172fd79bcd5298d54983e ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/player/SingleUserAreaMap.java -@@ -0,0 +1,232 @@ -+package io.papermc.paper.util.player; -+ -+import io.papermc.paper.util.IntegerUtil; -+ -+public abstract class SingleUserAreaMap { -+ -+ private static final int NOT_SET = Integer.MIN_VALUE; -+ -+ private final T parameter; -+ private int lastChunkX = NOT_SET; -+ private int lastChunkZ = NOT_SET; -+ private int distance = NOT_SET; -+ -+ public SingleUserAreaMap(final T parameter) { -+ this.parameter = parameter; -+ } -+ -+ /* math sign function except 0 returns 1 */ -+ protected static int sign(int val) { -+ return 1 | (val >> (Integer.SIZE - 1)); -+ } -+ -+ protected abstract void addCallback(final T parameter, final int chunkX, final int chunkZ); -+ -+ protected abstract void removeCallback(final T parameter, final int chunkX, final int chunkZ); -+ -+ private void addToNew(final T parameter, final int chunkX, final int chunkZ, final int distance) { -+ final int maxX = chunkX + distance; -+ final int maxZ = chunkZ + distance; -+ -+ for (int cx = chunkX - distance; cx <= maxX; ++cx) { -+ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { -+ this.addCallback(parameter, cx, cz); -+ } -+ } -+ } -+ -+ private void removeFromOld(final T parameter, final int chunkX, final int chunkZ, final int distance) { -+ final int maxX = chunkX + distance; -+ final int maxZ = chunkZ + distance; -+ -+ for (int cx = chunkX - distance; cx <= maxX; ++cx) { -+ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { -+ this.removeCallback(parameter, cx, cz); -+ } -+ } -+ } -+ -+ public final boolean add(final int chunkX, final int chunkZ, final int distance) { -+ if (distance < 0) { -+ throw new IllegalArgumentException(Integer.toString(distance)); -+ } -+ if (this.lastChunkX != NOT_SET) { -+ return false; -+ } -+ this.lastChunkX = chunkX; -+ this.lastChunkZ = chunkZ; -+ this.distance = distance; -+ -+ this.addToNew(this.parameter, chunkX, chunkZ, distance); -+ -+ return true; -+ } -+ -+ public final boolean update(final int toX, final int toZ, final int newViewDistance) { -+ if (newViewDistance < 0) { -+ throw new IllegalArgumentException(Integer.toString(newViewDistance)); -+ } -+ final int fromX = this.lastChunkX; -+ final int fromZ = this.lastChunkZ; -+ final int oldViewDistance = this.distance; -+ if (fromX == NOT_SET) { -+ return false; -+ } -+ -+ this.lastChunkX = toX; -+ this.lastChunkZ = toZ; -+ this.distance = newViewDistance; -+ -+ final T parameter = this.parameter; -+ -+ -+ final int dx = toX - fromX; -+ final int dz = toZ - fromZ; -+ -+ final int totalX = IntegerUtil.branchlessAbs(fromX - toX); -+ final int totalZ = IntegerUtil.branchlessAbs(fromZ - toZ); -+ -+ if (Math.max(totalX, totalZ) > (2 * Math.max(newViewDistance, oldViewDistance))) { -+ // teleported? -+ this.removeFromOld(parameter, fromX, fromZ, oldViewDistance); -+ this.addToNew(parameter, toX, toZ, newViewDistance); -+ return true; -+ } -+ -+ if (oldViewDistance != newViewDistance) { -+ // remove loop -+ -+ final int oldMinX = fromX - oldViewDistance; -+ final int oldMinZ = fromZ - oldViewDistance; -+ final int oldMaxX = fromX + oldViewDistance; -+ final int oldMaxZ = fromZ + oldViewDistance; -+ for (int currX = oldMinX; currX <= oldMaxX; ++currX) { -+ for (int currZ = oldMinZ; currZ <= oldMaxZ; ++currZ) { -+ -+ // only remove if we're outside the new view distance... -+ if (Math.max(IntegerUtil.branchlessAbs(currX - toX), IntegerUtil.branchlessAbs(currZ - toZ)) > newViewDistance) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ // add loop -+ -+ final int newMinX = toX - newViewDistance; -+ final int newMinZ = toZ - newViewDistance; -+ final int newMaxX = toX + newViewDistance; -+ final int newMaxZ = toZ + newViewDistance; -+ for (int currX = newMinX; currX <= newMaxX; ++currX) { -+ for (int currZ = newMinZ; currZ <= newMaxZ; ++currZ) { -+ -+ // only add if we're outside the old view distance... -+ if (Math.max(IntegerUtil.branchlessAbs(currX - fromX), IntegerUtil.branchlessAbs(currZ - fromZ)) > oldViewDistance) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ // x axis is width -+ // z axis is height -+ // right refers to the x axis of where we moved -+ // top refers to the z axis of where we moved -+ -+ // same view distance -+ -+ // used for relative positioning -+ final int up = sign(dz); // 1 if dz >= 0, -1 otherwise -+ final int right = sign(dx); // 1 if dx >= 0, -1 otherwise -+ -+ // The area excluded by overlapping the two view distance squares creates four rectangles: -+ // Two on the left, and two on the right. The ones on the left we consider the "removed" section -+ // and on the right the "added" section. -+ // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually -+ // exclusive to the regions they surround. -+ -+ // 4 points of the rectangle -+ int maxX; // exclusive -+ int minX; // inclusive -+ int maxZ; // exclusive -+ int minZ; // inclusive -+ -+ if (dx != 0) { -+ // handle right addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX + (oldViewDistance * right) + right; // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle up addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = toX - (oldViewDistance * right); // inclusive -+ maxZ = toZ + (oldViewDistance * up) + up; // exclusive -+ minZ = fromZ + (oldViewDistance * up) + up; // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dx != 0) { -+ // handle left removal -+ -+ maxX = toX - (oldViewDistance * right); // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle down removal -+ -+ maxX = fromX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = toZ - (oldViewDistance * up); // exclusive -+ minZ = fromZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ public final boolean remove() { -+ final int chunkX = this.lastChunkX; -+ final int chunkZ = this.lastChunkZ; -+ final int distance = this.distance; -+ if (chunkX == NOT_SET) { -+ return false; -+ } -+ -+ this.lastChunkX = this.lastChunkZ = this.distance = NOT_SET; -+ -+ this.removeFromOld(this.parameter, chunkX, chunkZ, distance); -+ -+ return true; -+ } -+} diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java index 5135cd504ec5864a4603c004e748947a7d88d2b4..396f368a7e21a7c7b1630b4e20cdbc452c4b0f84 100644 --- a/src/main/java/net/minecraft/Util.java @@ -4124,7 +4799,7 @@ index 3e5a85a7ad6149b04622c254fbc2e174896a4128..3f662692ed4846e026a9d48595e7b3b2 + } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 40adb6117b9e0d5f70103113202a07715e403e2a..9eb987f9d86396d6b7e9d4f3834bea3326640ac7 100644 +index 40adb6117b9e0d5f70103113202a07715e403e2a..cef1761cdaf3e456695f2de61f4295fb99361914 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -310,6 +310,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + if (ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { + ChunkHolder.this.isFullChunkReady = true; -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(chunk, this); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkBorder(chunk, this); + } + }); + }); @@ -4299,7 +4973,7 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd if (flag && !flag1) { + // Paper start + if (this.isFullChunkReady) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper + } + // Paper end this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); @@ -4314,7 +4988,7 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd + chunkResult.ifSuccess(chunk -> { + // note: Here is a very good place to add callbacks to logic waiting on this. + ChunkHolder.this.isTickingReady = true; -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, this); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkTicking(chunk, this); + }); + }); + // Paper end @@ -4325,7 +4999,7 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd - this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); + // Paper start + if (this.isTickingReady) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper + } + // Paper end + this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage @@ -4340,7 +5014,7 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd + this.entityTickingChunkFuture.thenAccept(chunkResult -> { + chunkResult.ifSuccess(chunk -> { + ChunkHolder.this.isEntityTickingReady = true; -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, this); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkEntityTicking(chunk, this); + }); + }); + // Paper end @@ -4351,7 +5025,7 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd - this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); + // Paper start + if (this.isEntityTickingReady) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); + } + // Paper end + this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage @@ -4378,62 +5052,27 @@ index f40a2f348c45a29168ca3d4eef07b5b628060bee..c643bb0daa5cd264fd6ebab7acf0a2bd + // Paper end } diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd6629ac4b49 100644 +index 5b920beb39dad8d392b4e5e12a89880720e41942..6751e403595170b22abf100a27f97251edcb2125 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -170,6 +170,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -170,6 +170,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }; // CraftBukkit end -+ // Paper start - distance maps -+ private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); -+ -+ void addPlayerToDistanceMaps(ServerPlayer player) { -+ int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); -+ int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); -+ // Note: players need to be explicitly added to distance maps before they can be updated -+ this.nearbyPlayers.addPlayer(player); -+ } -+ -+ void removePlayerFromDistanceMaps(ServerPlayer player) { -+ int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); -+ int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); -+ // Note: players need to be explicitly added to distance maps before they can be updated -+ this.nearbyPlayers.removePlayer(player); -+ } -+ -+ void updateMaps(ServerPlayer player) { -+ int chunkX = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getX()); -+ int chunkZ = io.papermc.paper.util.MCUtil.getChunkCoordinate(player.getZ()); -+ // Note: players need to be explicitly added to distance maps before they can be updated -+ this.nearbyPlayers.tickPlayer(player); -+ } -+ // Paper end + // Paper start + public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { -+ return this.pendingUnloads.get(io.papermc.paper.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); ++ return this.pendingUnloads.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); + } -+ public final io.papermc.paper.util.player.NearbyPlayers nearbyPlayers; + // Paper end + public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); this.visibleChunkMap = this.updatingChunkMap.clone(); -@@ -221,8 +252,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.poiManager = new PoiManager(new RegionStorageInfo(session.getLevelId(), world.dimension(), "poi"), path.resolve("poi"), dataFixer, dsync, iregistrycustom, world.getServer(), world); - this.setServerViewDistance(viewDistance); +@@ -223,6 +229,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, this.mainThreadMailbox); -+ // Paper start -+ this.nearbyPlayers = new io.papermc.paper.util.player.NearbyPlayers(this.level); -+ // Paper end -+ } -+ -+ // Paper start -+ // always use accessor, so folia can override -+ public final io.papermc.paper.util.player.NearbyPlayers getNearbyPlayers() { -+ return this.nearbyPlayers; } ++ // Paper start + public int getMobCountNear(final ServerPlayer player, final net.minecraft.world.entity.MobCategory mobCategory) { + return -1; + } @@ -4442,24 +5081,24 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 protected ChunkGenerator generator() { return this.worldGenContext.generator(); } -@@ -378,9 +423,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -378,9 +390,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }; stringbuilder.append("Updating:").append(System.lineSeparator()); - this.updatingChunkMap.values().forEach(consumer); -+ io.papermc.paper.chunk.system.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper stringbuilder.append("Visible:").append(System.lineSeparator()); - this.visibleChunkMap.values().forEach(consumer); -+ io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading"); -@@ -422,8 +467,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -422,8 +434,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider holder.setTicketLevel(level); } else { holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); + // Paper start -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(this.level, holder); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderCreate(this.level, holder); + // Paper end } @@ -4469,34 +5108,34 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 this.updatingChunkMap.put(pos, holder); this.modified = true; } -@@ -445,7 +496,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -445,7 +463,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider protected void saveAllChunks(boolean flush) { if (flush) { - List list = this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); -+ List list = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper ++ List list = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper MutableBoolean mutableboolean = new MutableBoolean(); do { -@@ -468,7 +519,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -468,7 +486,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }); this.flushWorker(); } else { - this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded); -+ io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); } } -@@ -487,7 +538,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -487,7 +505,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public boolean hasWork() { - return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); -+ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || io.papermc.paper.chunk.system.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper ++ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper } private void processUnloads(BooleanSupplier shouldKeepTicking) { -@@ -504,6 +555,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -504,6 +522,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } this.updatingChunkMap.remove(j); @@ -4504,16 +5143,16 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 this.pendingUnloads.put(j, playerchunk); this.modified = true; ++i; -@@ -523,7 +575,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -523,7 +542,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } int l = 0; - ObjectIterator objectiterator = this.visibleChunkMap.values().iterator(); -+ Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper ++ Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { -@@ -541,7 +593,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -541,7 +560,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } else { ChunkAccess ichunkaccess = holder.getLatestChunk(); @@ -4521,23 +5160,23 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 + // Paper start + boolean removed; + if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); + // Paper end LevelChunk chunk; if (ichunkaccess instanceof LevelChunk) { -@@ -559,7 +615,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -559,7 +582,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.lightEngine.tryScheduleUpdate(); this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); - } + } else if (removed) { // Paper start -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); + } // Paper end } }; -@@ -896,7 +954,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -896,7 +921,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -4546,7 +5185,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 int j = Mth.clamp(watchDistance, 2, 32); if (j != this.serverViewDistance) { -@@ -913,7 +971,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -913,7 +938,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } @@ -4555,28 +5194,28 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance); } -@@ -942,7 +1000,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -942,7 +967,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public int size() { - return this.visibleChunkMap.size(); -+ return io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper ++ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper } public DistanceManager getDistanceManager() { -@@ -950,19 +1008,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -950,19 +975,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } protected Iterable getChunks() { - return Iterables.unmodifiableIterable(this.visibleChunkMap.values()); -+ return Iterables.unmodifiableIterable(io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper ++ return Iterables.unmodifiableIterable(ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper } void dumpChunks(Writer writer) throws IOException { CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer); TickingTracker tickingtracker = this.distanceManager.tickingTracker(); - ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator(); -+ Iterator objectbidirectionaliterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper ++ Iterator objectbidirectionaliterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper while (objectbidirectionaliterator.hasNext()) { - Entry entry = (Entry) objectbidirectionaliterator.next(); @@ -4589,31 +5228,7 @@ index 5b920beb39dad8d392b4e5e12a89880720e41942..d3caadb3e884d7d0468daf5eff9abd66 Optional optional = Optional.ofNullable(playerchunk.getLatestChunk()); Optional optional1 = optional.flatMap((ichunkaccess) -> { return ichunkaccess instanceof LevelChunk ? Optional.of((LevelChunk) ichunkaccess) : Optional.empty(); -@@ -1083,6 +1141,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - - player.setChunkTrackingView(ChunkTrackingView.EMPTY); - this.updateChunkTracking(player); -+ this.addPlayerToDistanceMaps(player); // Paper - distance maps - } else { - SectionPos sectionposition = player.getLastSectionPos(); - -@@ -1091,6 +1150,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.distanceManager.removePlayer(sectionposition, player); - } - -+ this.removePlayerFromDistanceMaps(player); // Paper - distance maps - this.applyChunkTrackingView(player, ChunkTrackingView.EMPTY); - } - -@@ -1142,6 +1202,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.updateChunkTracking(player); - } - -+ this.updateMaps(player); // Paper - distance maps - } - - private void updateChunkTracking(ServerPlayer player) { -@@ -1385,10 +1446,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1385,10 +1410,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }); } @@ -4659,7 +5274,7 @@ index b6cc33943fe7e4667944f3e6f868b3033ea9ca18..27065ffc5473c518acee3a3096b83fac while (objectiterator.hasNext()) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index d39268911ed7c4d60ee6a82178be23245aae58c4..e9f53f57c363a32106880ea9aad0ccf5a7342509 100644 +index d39268911ed7c4d60ee6a82178be23245aae58c4..cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -48,6 +48,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; @@ -4670,20 +5285,18 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..e9f53f57c363a32106880ea9aad0ccf5 private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); private final DistanceManager distanceManager; final ServerLevel level; -@@ -66,6 +67,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -66,6 +67,10 @@ public class ServerChunkCache extends ChunkSource { @Nullable @VisibleForDebug private NaturalSpawner.SpawnState lastSpawnState; + // Paper start -+ public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet tickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true); -+ public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true); + private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); + long chunkFutureAwaitCounter; + // Paper end public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { this.level = world; -@@ -91,6 +98,54 @@ public class ServerChunkCache extends ChunkSource { +@@ -91,6 +96,54 @@ public class ServerChunkCache extends ChunkSource { return chunk.getFullChunkNow() != null; } // CraftBukkit end @@ -4738,7 +5351,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..e9f53f57c363a32106880ea9aad0ccf5 @Override public ThreadedLevelLightEngine getLightEngine() { -@@ -286,7 +341,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -286,7 +339,7 @@ public class ServerChunkCache extends ChunkSource { return this.mainThreadProcessor.pollTask(); } @@ -4747,7 +5360,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..e9f53f57c363a32106880ea9aad0ccf5 boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag1 = this.chunkMap.promoteChunkMap(); -@@ -299,6 +354,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -299,6 +352,12 @@ public class ServerChunkCache extends ChunkSource { } } @@ -4761,7 +5374,7 @@ index d39268911ed7c4d60ee6a82178be23245aae58c4..e9f53f57c363a32106880ea9aad0ccf5 ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9d11fcb3df12182ae00ce73f7e30091fd199a341..eea8bafd98e3a8d82b3216488537ab898cc4ae7a 100644 +index 9d11fcb3df12182ae00ce73f7e30091fd199a341..4c39d9e0466240b5cd459ee649a22fe3a72bf9f0 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -236,6 +236,98 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -4852,7 +5465,7 @@ index 9d11fcb3df12182ae00ce73f7e30091fd199a341..eea8bafd98e3a8d82b3216488537ab89 + + for (int cx = minChunkX; cx <= maxChunkX; ++cx) { + for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) { -+ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad( ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad( + this, cx, cz, net.minecraft.world.level.chunk.status.ChunkStatus.FULL, true, priority, consumer + ); + } @@ -4864,27 +5477,17 @@ index 9d11fcb3df12182ae00ce73f7e30091fd199a341..eea8bafd98e3a8d82b3216488537ab89 public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { // IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index defe0b30964613cbae5195485aafff21d73ff18e..684dfbcdd4d000ac918c0f77a60c9abf9b30d3a4 100644 +index defe0b30964613cbae5195485aafff21d73ff18e..8d535d96252068fd2a1608600ce29d5d16690fec 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -280,6 +280,8 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -280,6 +280,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public boolean sentListPacket = false; public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end + public boolean isRealPlayer; // Paper -+ public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); -@@ -349,6 +351,8 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { - this.updateOptions(clientOptions); - this.object = null; - -+ this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper -+ - // CraftBukkit start - this.displayName = this.getScoreboardName(); - this.bukkitPickUpLoot = true; diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java index 045b754b5b70bbd1e7732ad2142dfadd6cc2305c..f56e5c0f53f9b52a9247b9be9265b949494fc924 100644 --- a/src/main/java/net/minecraft/server/level/TicketType.java @@ -5517,7 +6120,7 @@ index ae16b014abd52ee10d523fb003cce166b846b222..7f302405a88766c2112539d24d3dd2e5 public BlockState getBlockState(BlockPos pos) { int i = pos.getY(); diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -index 34933c5324126f9afdc5cba9dea997ace8f01806..219062cff8a05c765b092f1525043d9d9a1153ae 100644 +index 34933c5324126f9afdc5cba9dea997ace8f01806..1cfc906317f07a44f06a4adf021c44e34a2f1d07 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java @@ -91,6 +91,18 @@ public class PersistentEntitySectionManager implements A @@ -5529,8 +6132,8 @@ index 34933c5324126f9afdc5cba9dea997ace8f01806..219062cff8a05c765b092f1525043d9d + // I don't want to know why this is a generic type. + Entity entityCasted = (Entity)entity; + boolean wasRemoved = entityCasted.isRemoved(); -+ io.papermc.paper.chunk.system.ChunkSystem.onEntityPreAdd((net.minecraft.server.level.ServerLevel) entityCasted.level(), entityCasted); -+ if (!wasRemoved && entityCasted.isRemoved()) { ++ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted); ++ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) { + // removed by callback + return false; + } @@ -5554,7 +6157,7 @@ index fe0f57dbeecc4b5a0c81863f33e41d11eb60943a..9babfd8e6c847ea26863be6243f17fc2 + } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 508419378c88ba8688edbd5142d9d8ba52396507..a59eebb89d11788b999d1e5cb4fd2f4e55e023ab 100644 +index 508419378c88ba8688edbd5142d9d8ba52396507..69c62699e3412f2730e3db65f196099d77698980 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -252,8 +252,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -5563,7 +6166,7 @@ index 508419378c88ba8688edbd5142d9d8ba52396507..a59eebb89d11788b999d1e5cb4fd2f4e public Chunk[] getLoadedChunks() { - Long2ObjectLinkedOpenHashMap chunks = this.world.getChunkSource().chunkMap.visibleChunkMap; - return chunks.values().stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new); -+ List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world); // Paper ++ List chunks = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.world); // Paper + return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new); } @@ -5599,7 +6202,7 @@ index 508419378c88ba8688edbd5142d9d8ba52396507..a59eebb89d11788b999d1e5cb4fd2f4e + + java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); + -+ io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { + net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { + net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; + ret.complete(chunk == null ? null : new CraftChunk(chunk)); @@ -5634,7 +6237,7 @@ index 508419378c88ba8688edbd5142d9d8ba52396507..a59eebb89d11788b999d1e5cb4fd2f4e + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e130d0aa64d0caaa7760d8de4b1f989523f9de20..45108559bb2e4ae9d33aed5d92b72cbe5c17f553 100644 +index e130d0aa64d0caaa7760d8de4b1f989523f9de20..9ca244b69995552df63fb5d4e3d6961b585bcc47 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2420,4 +2420,34 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -5644,7 +6247,7 @@ index e130d0aa64d0caaa7760d8de4b1f989523f9de20..45108559bb2e4ae9d33aed5d92b72cbe + + @Override + public int getViewDistance() { -+ return io.papermc.paper.chunk.system.ChunkSystem.getLoadViewDistance(this.getHandle()); ++ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getLoadViewDistance(this.getHandle()) - 1; + } + + @Override @@ -5654,7 +6257,7 @@ index e130d0aa64d0caaa7760d8de4b1f989523f9de20..45108559bb2e4ae9d33aed5d92b72cbe + + @Override + public int getSimulationDistance() { -+ return io.papermc.paper.chunk.system.ChunkSystem.getTickViewDistance(this.getHandle()); ++ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getTickViewDistance(this.getHandle()); + } + + @Override @@ -5664,7 +6267,7 @@ index e130d0aa64d0caaa7760d8de4b1f989523f9de20..45108559bb2e4ae9d33aed5d92b72cbe + + @Override + public int getSendViewDistance() { -+ return io.papermc.paper.chunk.system.ChunkSystem.getSendViewDistance(this.getHandle()); ++ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getSendViewDistance(this.getHandle()); + } + + @Override diff --git a/patches/server/0010-Adventure.patch b/patches/server/0010-Adventure.patch index fff8643fbd..d636c142bd 100644 --- a/patches/server/0010-Adventure.patch +++ b/patches/server/0010-Adventure.patch @@ -2606,7 +2606,7 @@ index bb97fdb9aa6167083442a928276ebe4225a586ef..5d1758086ed4fce5b36a5b31df44ccea @Override diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 9eb987f9d86396d6b7e9d4f3834bea3326640ac7..25d6be308be03815301cfbefdc4199c898f7b9c0 100644 +index cef1761cdaf3e456695f2de61f4295fb99361914..e0b2d474e8d6f2d573d2c1f63e68ba931ecf4eb6 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -201,6 +201,7 @@ import org.bukkit.craftbukkit.SpigotTimings; // Spigot @@ -2627,7 +2627,7 @@ index 9eb987f9d86396d6b7e9d4f3834bea3326640ac7..25d6be308be03815301cfbefdc4199c8 private int playerIdleTimeout; private final long[] tickTimesNanos; private long aggregatedTickTimesNanos; -@@ -1397,7 +1397,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { boolean flag1 = true; -@@ -2027,8 +2026,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2024,8 +2023,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public void sendChatMessage(OutgoingChatMessage message, boolean filterMaskEnabled, ChatType.Bound params) { @@ -2776,7 +2776,7 @@ index 684dfbcdd4d000ac918c0f77a60c9abf9b30d3a4..200993e8c482442a2c7ae4d9551d0470 } } -@@ -2055,6 +2059,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2052,6 +2056,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } // CraftBukkit end this.language = clientOptions.language(); @@ -3553,7 +3553,7 @@ index cbdb1a56a97150c164515a4ce6d3ba06428bf321..b214e7b302abbfe1641485a05f1371ac public URI getUrl() { return this.handle.link(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index a59eebb89d11788b999d1e5cb4fd2f4e55e023ab..1e8d93d81b7a391bbd1e9926ff35a68d4c563f0f 100644 +index 69c62699e3412f2730e3db65f196099d77698980..4878a1b085a83dd4a8ffdc86250b8fb4fbac5192 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -162,6 +162,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -4147,7 +4147,7 @@ index 55945b83a5426b352bad9507cc9e94afb1278032..9ea1537408ff2d790747b6e5a681d917 public boolean isOp() { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 45108559bb2e4ae9d33aed5d92b72cbe5c17f553..859f3eb2d616156b0efaa70ee03e357e6f0760f3 100644 +index 834b2a3ab2cccbd50686a1a0ca999685638b2a95..2b6912514ab39c26338c6ac580a8d1f33f3df61f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -388,14 +388,40 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch index 35237b2e07..2b8cd780b7 100644 --- a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch +++ b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch @@ -260,7 +260,7 @@ index 8323f135d6bf2e1f12525e05094ffa3f2420e7e1..a143ea1e58464a3122fbd8ccafe417bd } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 25d6be308be03815301cfbefdc4199c898f7b9c0..b67cb9b027c33494f0ed3c6c6ac354a5c79fbf47 100644 +index e0b2d474e8d6f2d573d2c1f63e68ba931ecf4eb6..91800791427e9362baf68ca3cffda5bfa58de2b8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -154,7 +154,7 @@ import com.mojang.serialization.Dynamic; @@ -308,7 +308,7 @@ index 25d6be308be03815301cfbefdc4199c898f7b9c0..b67cb9b027c33494f0ed3c6c6ac354a5 } catch (Exception ignored) { } // CraftBukkit end -@@ -1659,7 +1662,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && this.ticksUntilAutosave <= 0) { this.ticksUntilAutosave = this.autosavePeriod; // CraftBukkit end @@ -799,7 +799,6 @@ index cde2e181bf1aaf92f1e96b00e03b7b001a06e6b3..a720743149f9d1f90eda3b7b928b9d25 MinecraftServer.LOGGER.debug("Autosave finished"); - SpigotTimings.worldSaveTimer.stopTiming(); // Spigot } - io.papermc.paper.util.CachedLists.reset(); // Paper + // Paper start - move executeAll() into full server tick timing + try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { + this.runAllTasks(); @@ -808,7 +807,7 @@ index cde2e181bf1aaf92f1e96b00e03b7b001a06e6b3..a720743149f9d1f90eda3b7b928b9d25 this.profiler.push("tallying"); long j = Util.getNanos() - i; int k = this.tickCount % 100; -@@ -1359,8 +1383,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { entityplayer.connection.suspendFlushing(); }); @@ -852,7 +851,7 @@ index cde2e181bf1aaf92f1e96b00e03b7b001a06e6b3..a720743149f9d1f90eda3b7b928b9d25 // Send time updates to everyone, it will get the right time from the world the player is in. if (this.tickCount % 20 == 0) { for (int i = 0; i < this.getPlayerList().players.size(); ++i) { -@@ -1458,7 +1481,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = Lists.newArrayList(); List list1 = this.level.players(); ObjectIterator objectiterator = this.entityMap.values().iterator(); @@ -1000,7 +999,7 @@ index d3caadb3e884d7d0468daf5eff9abd6629ac4b49..a7de9d6bbbd0b3d60b1d49e116c388b1 ChunkMap.TrackedEntity playerchunkmap_entitytracker; -@@ -1360,14 +1363,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1324,14 +1327,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker.serverEntity.sendChanges(); } } @@ -1019,10 +1018,10 @@ index d3caadb3e884d7d0468daf5eff9abd6629ac4b49..a7de9d6bbbd0b3d60b1d49e116c388b1 } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f6454f8b7c3 100644 +index cf94dd9ddcc1eabcf3fd336e70720f4ed3e52175..e0c8b89767087cba34fc3c3809db4c386dacb193 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -197,13 +197,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -195,13 +195,15 @@ public class ServerChunkCache extends ChunkSource { } gameprofilerfiller.incrementCounter("getChunkCacheMiss"); @@ -1040,7 +1039,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 ChunkResult chunkresult = (ChunkResult) completablefuture.join(); ChunkAccess ichunkaccess1 = (ChunkAccess) chunkresult.orElse(null); // CraftBukkit - decompile error -@@ -368,7 +370,9 @@ public class ServerChunkCache extends ChunkSource { +@@ -366,7 +368,9 @@ public class ServerChunkCache extends ChunkSource { public void save(boolean flush) { this.runDistanceManagerUpdates(); @@ -1050,7 +1049,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 } @Override -@@ -410,10 +414,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -408,10 +412,10 @@ public class ServerChunkCache extends ChunkSource { this.level.timings.doChunkMap.stopTiming(); // Spigot this.level.getProfiler().popPush("chunks"); if (tickChunks) { @@ -1063,7 +1062,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 } this.level.timings.doChunkUnload.startTiming(); // Spigot -@@ -436,6 +440,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -434,6 +438,7 @@ public class ServerChunkCache extends ChunkSource { gameprofilerfiller.push("filteringLoadedChunks"); List list = Lists.newArrayListWithCapacity(this.chunkMap.size()); Iterator iterator = this.chunkMap.getChunks().iterator(); @@ -1071,7 +1070,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 while (iterator.hasNext()) { ChunkHolder playerchunk = (ChunkHolder) iterator.next(); -@@ -448,8 +453,10 @@ public class ServerChunkCache extends ChunkSource { +@@ -446,8 +451,10 @@ public class ServerChunkCache extends ChunkSource { if (this.level.tickRateManager().runsNormally()) { gameprofilerfiller.popPush("naturalSpawnCount"); @@ -1082,7 +1081,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 this.lastSpawnState = spawnercreature_d; gameprofilerfiller.popPush("spawnAndTick"); -@@ -472,22 +479,25 @@ public class ServerChunkCache extends ChunkSource { +@@ -470,22 +477,25 @@ public class ServerChunkCache extends ChunkSource { } if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { @@ -1111,7 +1110,7 @@ index e9f53f57c363a32106880ea9aad0ccf5a7342509..0ff45d4ce6ae0b7feac53c7a9f361f64 gameprofilerfiller.pop(); gameprofilerfiller.pop(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index eea8bafd98e3a8d82b3216488537ab898cc4ae7a..9675d91e4e7ed46147c3f7a11dd65122fe998dc2 100644 +index 4c39d9e0466240b5cd459ee649a22fe3a72bf9f0..eb98bb1bd76869fd76b34885223c8e57a04e0c51 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1,6 +1,8 @@ @@ -1805,7 +1804,7 @@ index b0ffa23faf62629043dfd613315eaf9c5fcc2cfe..00000000000000000000000000000000 - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 859f3eb2d616156b0efaa70ee03e357e6f0760f3..a02e5c967d9dfcd507e1019d28ed3735945f9613 100644 +index 2b6912514ab39c26338c6ac580a8d1f33f3df61f..eb633256f353ddaee5098d11f0e5f50d7e5a26cd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2782,6 +2782,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0024-Add-TickThread.patch b/patches/server/0024-Add-TickThread.patch deleted file mode 100644 index bf8c922243..0000000000 --- a/patches/server/0024-Add-TickThread.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sun, 3 Mar 2019 20:53:18 -0800 -Subject: [PATCH] Add TickThread - -Placeholder patch, to be used by chunksystem rewrite - -diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java -new file mode 100644 -index 0000000000000000000000000000000000000000..73e83d56a340f0c7dcb8ff737d621003e72c6de4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/util/TickThread.java -@@ -0,0 +1,83 @@ -+package io.papermc.paper.util; -+ -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.entity.Entity; -+import org.bukkit.Bukkit; -+import java.util.concurrent.atomic.AtomicInteger; -+ -+public final class TickThread extends Thread { -+ -+ public static final boolean STRICT_THREAD_CHECKS = Boolean.getBoolean("paper.strict-thread-checks"); -+ -+ static { -+ if (STRICT_THREAD_CHECKS) { -+ MinecraftServer.LOGGER.warn("Strict thread checks enabled - performance may suffer"); -+ } -+ } -+ -+ public static void softEnsureTickThread(final String reason) { -+ if (!STRICT_THREAD_CHECKS) { -+ return; -+ } -+ ensureTickThread(reason); -+ } -+ -+ public static void ensureTickThread(final String reason) { -+ if (!isTickThread()) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) { -+ if (!isTickThreadFor(world, chunkX, chunkZ)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final Entity entity, final String reason) { -+ if (!isTickThreadFor(entity)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ -+ -+ private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); -+ -+ public TickThread(final String name) { -+ this(null, name); -+ } -+ -+ public TickThread(final Runnable run, final String name) { -+ this(run, name, ID_GENERATOR.incrementAndGet()); -+ } -+ -+ private TickThread(final Runnable run, final String name, final int id) { -+ super(run, name); -+ this.id = id; -+ } -+ -+ public static TickThread getCurrentTickThread() { -+ return (TickThread) Thread.currentThread(); -+ } -+ -+ public static boolean isTickThread() { -+ return Bukkit.isPrimaryThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final Entity entity) { -+ return isTickThread(); -+ } -+} -diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java -index bbf0d9d9c44fe8d7add2f978994ec129420814c7..78669fa035b7537ff7e533cf32aaf2995625424f 100644 ---- a/src/main/java/org/spigotmc/AsyncCatcher.java -+++ b/src/main/java/org/spigotmc/AsyncCatcher.java -@@ -9,7 +9,7 @@ public class AsyncCatcher - - public static void catchOp(String reason) - { -- if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) -+ if ( (AsyncCatcher.enabled || io.papermc.paper.util.TickThread.STRICT_THREAD_CHECKS) && Thread.currentThread() != MinecraftServer.getServer().serverThread ) // Paper - { - throw new IllegalStateException( "Asynchronous " + reason + "!" ); - } diff --git a/patches/server/0025-Further-improve-server-tick-loop.patch b/patches/server/0024-Further-improve-server-tick-loop.patch similarity index 99% rename from patches/server/0025-Further-improve-server-tick-loop.patch rename to patches/server/0024-Further-improve-server-tick-loop.patch index 0fc8d093bf..5b2ddf7282 100644 --- a/patches/server/0025-Further-improve-server-tick-loop.patch +++ b/patches/server/0024-Further-improve-server-tick-loop.patch @@ -12,7 +12,7 @@ Previous implementation did not calculate TPS correctly. Switch to a realistic rolling average and factor in std deviation as an extra reporting variable diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index a720743149f9d1f90eda3b7b928b9d25d8c8f553..c09f3dc29c86fef9edfe7831776a77fc73e52210 100644 +index d76dae9ce9022308b316080ac48b7030d674cc6b..e9d56d75b7c648f04d3a56942b2866090c570129 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -296,7 +296,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index df60bfc7555326f079082199b940b0c4b4248cfc..35bcdbfd7f17c4e2260c199e9848c4d361b61944 100644 +index de1708e5d39561115d2825eea4a5f6e1f1f4e5b8..1e5b42fc3903b14537d232c8adbbaf79078d8d8e 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -227,6 +227,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0079-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch similarity index 93% rename from patches/server/0079-Entity-AddTo-RemoveFrom-World-Events.patch rename to patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch index 9a833e6f86..83aad502c3 100644 --- a/patches/server/0079-Entity-AddTo-RemoveFrom-World-Events.patch +++ b/patches/server/0078-Entity-AddTo-RemoveFrom-World-Events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 35bcdbfd7f17c4e2260c199e9848c4d361b61944..43dbcfb5900b301950be68db48487af2a95748a3 100644 +index 1e5b42fc3903b14537d232c8adbbaf79078d8d8e..e6cf145fa7a2968c70e9e467e3927fd38e199e06 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2153,6 +2153,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0080-Configurable-Chunk-Inhabited-Time.patch b/patches/server/0079-Configurable-Chunk-Inhabited-Time.patch similarity index 100% rename from patches/server/0080-Configurable-Chunk-Inhabited-Time.patch rename to patches/server/0079-Configurable-Chunk-Inhabited-Time.patch diff --git a/patches/server/0081-EntityPathfindEvent.patch b/patches/server/0080-EntityPathfindEvent.patch similarity index 100% rename from patches/server/0081-EntityPathfindEvent.patch rename to patches/server/0080-EntityPathfindEvent.patch diff --git a/patches/server/0082-Sanitise-RegionFileCache-and-make-configurable.patch b/patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch similarity index 100% rename from patches/server/0082-Sanitise-RegionFileCache-and-make-configurable.patch rename to patches/server/0081-Sanitise-RegionFileCache-and-make-configurable.patch diff --git a/patches/server/0083-Do-not-load-chunks-for-Pathfinding.patch b/patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch similarity index 100% rename from patches/server/0083-Do-not-load-chunks-for-Pathfinding.patch rename to patches/server/0082-Do-not-load-chunks-for-Pathfinding.patch diff --git a/patches/server/0084-Add-PlayerUseUnknownEntityEvent.patch b/patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch similarity index 100% rename from patches/server/0084-Add-PlayerUseUnknownEntityEvent.patch rename to patches/server/0083-Add-PlayerUseUnknownEntityEvent.patch diff --git a/patches/server/0085-Configurable-random-tick-rates-for-blocks.patch b/patches/server/0084-Configurable-random-tick-rates-for-blocks.patch similarity index 100% rename from patches/server/0085-Configurable-random-tick-rates-for-blocks.patch rename to patches/server/0084-Configurable-random-tick-rates-for-blocks.patch diff --git a/patches/server/0086-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch similarity index 89% rename from patches/server/0086-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch rename to patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch index dd26a7381c..ab40c40da1 100644 --- a/patches/server/0086-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch +++ b/patches/server/0085-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix Cancelling BlockPlaceEvent triggering physics diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 43dbcfb5900b301950be68db48487af2a95748a3..2d27b92b02611d883a84a694280364d3a7ddcb09 100644 +index e6cf145fa7a2968c70e9e467e3927fd38e199e06..223f8d9be5d73e296f5815db7123b95c3b345162 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1389,6 +1389,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0087-Optimize-DataBits.patch b/patches/server/0086-Optimize-DataBits.patch similarity index 100% rename from patches/server/0087-Optimize-DataBits.patch rename to patches/server/0086-Optimize-DataBits.patch diff --git a/patches/server/0088-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch similarity index 100% rename from patches/server/0088-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch rename to patches/server/0087-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch diff --git a/patches/server/0089-Configurable-Player-Collision.patch b/patches/server/0088-Configurable-Player-Collision.patch similarity index 98% rename from patches/server/0089-Configurable-Player-Collision.patch rename to patches/server/0088-Configurable-Player-Collision.patch index f64375d8bd..719e6bb654 100644 --- a/patches/server/0089-Configurable-Player-Collision.patch +++ b/patches/server/0088-Configurable-Player-Collision.patch @@ -18,7 +18,7 @@ index 9a1a961eabd4362c171da78c6be82c867f3696a4..1d0c473442b5c72245c356054440323e ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerPrefix); ComponentSerialization.TRUSTED_STREAM_CODEC.encode(buf, this.playerSuffix); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c38f932fe1c22dbe9b2583aab43ae879e4e5d4ad..785e033064ac8067baba2b471797ca34cf323825 100644 +index a37f11633663e07652274707b29a849e518511c5..6dec7884fdd15eb8f32e8831ed0f3a92af710472 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -640,6 +640,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -@@ -2549,9 +2551,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Co-authored-by: Aikar diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2d27b92b02611d883a84a694280364d3a7ddcb09..7c835a9328b1ba8426663ed3e9575fcd35a0f748 100644 +index 223f8d9be5d73e296f5815db7123b95c3b345162..d728afbe1d6882f1ace4ead9d87f4b7d2af43ba2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1322,7 +1322,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0103-Avoid-blocking-on-Network-Manager-creation.patch b/patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch similarity index 100% rename from patches/server/0103-Avoid-blocking-on-Network-Manager-creation.patch rename to patches/server/0102-Avoid-blocking-on-Network-Manager-creation.patch diff --git a/patches/server/0104-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch b/patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch similarity index 100% rename from patches/server/0104-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch rename to patches/server/0103-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch diff --git a/patches/server/0105-Add-setting-for-proxy-online-mode-status.patch b/patches/server/0104-Add-setting-for-proxy-online-mode-status.patch similarity index 100% rename from patches/server/0105-Add-setting-for-proxy-online-mode-status.patch rename to patches/server/0104-Add-setting-for-proxy-online-mode-status.patch diff --git a/patches/server/0106-Optimise-BlockState-s-hashCode-equals.patch b/patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch similarity index 100% rename from patches/server/0106-Optimise-BlockState-s-hashCode-equals.patch rename to patches/server/0105-Optimise-BlockState-s-hashCode-equals.patch diff --git a/patches/server/0107-Configurable-packet-in-spam-threshold.patch b/patches/server/0106-Configurable-packet-in-spam-threshold.patch similarity index 100% rename from patches/server/0107-Configurable-packet-in-spam-threshold.patch rename to patches/server/0106-Configurable-packet-in-spam-threshold.patch diff --git a/patches/server/0108-Configurable-flying-kick-messages.patch b/patches/server/0107-Configurable-flying-kick-messages.patch similarity index 100% rename from patches/server/0108-Configurable-flying-kick-messages.patch rename to patches/server/0107-Configurable-flying-kick-messages.patch diff --git a/patches/server/0109-Add-EntityZapEvent.patch b/patches/server/0108-Add-EntityZapEvent.patch similarity index 100% rename from patches/server/0109-Add-EntityZapEvent.patch rename to patches/server/0108-Add-EntityZapEvent.patch diff --git a/patches/server/0110-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch b/patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch similarity index 100% rename from patches/server/0110-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch rename to patches/server/0109-Filter-bad-block-entity-nbt-data-from-falling-blocks.patch diff --git a/patches/server/0111-Cache-user-authenticator-threads.patch b/patches/server/0110-Cache-user-authenticator-threads.patch similarity index 100% rename from patches/server/0111-Cache-user-authenticator-threads.patch rename to patches/server/0110-Cache-user-authenticator-threads.patch diff --git a/patches/server/0112-Allow-Reloading-of-Command-Aliases.patch b/patches/server/0111-Allow-Reloading-of-Command-Aliases.patch similarity index 100% rename from patches/server/0112-Allow-Reloading-of-Command-Aliases.patch rename to patches/server/0111-Allow-Reloading-of-Command-Aliases.patch diff --git a/patches/server/0113-Add-source-to-PlayerExpChangeEvent.patch b/patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch similarity index 100% rename from patches/server/0113-Add-source-to-PlayerExpChangeEvent.patch rename to patches/server/0112-Add-source-to-PlayerExpChangeEvent.patch diff --git a/patches/server/0114-Add-ProjectileCollideEvent.patch b/patches/server/0113-Add-ProjectileCollideEvent.patch similarity index 100% rename from patches/server/0114-Add-ProjectileCollideEvent.patch rename to patches/server/0113-Add-ProjectileCollideEvent.patch diff --git a/patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch b/patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch similarity index 100% rename from patches/server/0115-Prevent-Pathfinding-out-of-World-Border.patch rename to patches/server/0114-Prevent-Pathfinding-out-of-World-Border.patch diff --git a/patches/server/0116-Optimize-Level.hasChunkAt-BlockPosition-Z.patch b/patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch similarity index 100% rename from patches/server/0116-Optimize-Level.hasChunkAt-BlockPosition-Z.patch rename to patches/server/0115-Optimize-Level.hasChunkAt-BlockPosition-Z.patch diff --git a/patches/server/0117-Bound-Treasure-Maps-to-World-Border.patch b/patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch similarity index 100% rename from patches/server/0117-Bound-Treasure-Maps-to-World-Border.patch rename to patches/server/0116-Bound-Treasure-Maps-to-World-Border.patch diff --git a/patches/server/0118-Configurable-Cartographer-Treasure-Maps.patch b/patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch similarity index 100% rename from patches/server/0118-Configurable-Cartographer-Treasure-Maps.patch rename to patches/server/0117-Configurable-Cartographer-Treasure-Maps.patch diff --git a/patches/server/0119-Add-API-methods-to-control-if-armor-stands-can-move.patch b/patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch similarity index 100% rename from patches/server/0119-Add-API-methods-to-control-if-armor-stands-can-move.patch rename to patches/server/0118-Add-API-methods-to-control-if-armor-stands-can-move.patch diff --git a/patches/server/0120-String-based-Action-Bar-API.patch b/patches/server/0119-String-based-Action-Bar-API.patch similarity index 94% rename from patches/server/0120-String-based-Action-Bar-API.patch rename to patches/server/0119-String-based-Action-Bar-API.patch index e77bad7174..b4a1ec6598 100644 --- a/patches/server/0120-String-based-Action-Bar-API.patch +++ b/patches/server/0119-String-based-Action-Bar-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] String based Action Bar API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a2c09546434ef8b8d8e304b83d902efd5fc36a70..935815a532725e391465baf6764224dec8d0bc9b 100644 +index c399264ccffe646be10b3f13ebe0c0103d97f62c..d471e9370fdbcbce5357e52e8ea2a10c196cd33d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -388,6 +388,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0121-Properly-fix-item-duplication-bug.patch b/patches/server/0120-Properly-fix-item-duplication-bug.patch similarity index 91% rename from patches/server/0121-Properly-fix-item-duplication-bug.patch rename to patches/server/0120-Properly-fix-item-duplication-bug.patch index 86782af8c7..7a9b41d7f1 100644 --- a/patches/server/0121-Properly-fix-item-duplication-bug.patch +++ b/patches/server/0120-Properly-fix-item-duplication-bug.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Properly fix item duplication bug Credit to prplz for figuring out the real issue diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ac4b66a4aa9e2f186ed5ff3c7d41a01152a9d283..e7b39f06707a62d26af7e183413e0301501d2ce0 100644 +index e9fe09f77aacc0b7b13e95d4d04d94fdfa2181c3..269cfe7aa87cf4a73ee2faca142c83e4d10a98c7 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2630,7 +2630,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2627,7 +2627,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public boolean isImmobile() { diff --git a/patches/server/0122-Firework-API-s.patch b/patches/server/0121-Firework-API-s.patch similarity index 100% rename from patches/server/0122-Firework-API-s.patch rename to patches/server/0121-Firework-API-s.patch diff --git a/patches/server/0123-PlayerTeleportEndGatewayEvent.patch b/patches/server/0122-PlayerTeleportEndGatewayEvent.patch similarity index 93% rename from patches/server/0123-PlayerTeleportEndGatewayEvent.patch rename to patches/server/0122-PlayerTeleportEndGatewayEvent.patch index 6b7a9ec94f..3a00fbf930 100644 --- a/patches/server/0123-PlayerTeleportEndGatewayEvent.patch +++ b/patches/server/0122-PlayerTeleportEndGatewayEvent.patch @@ -7,10 +7,10 @@ Allows you to access the Gateway being used in a teleport event Fix the offset used for player teleportation diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index dae729c39e5d3fefc8188069e81f33066746c4a6..3ae34c67fe3dd8b30d24f1a31102f0a071c1703d 100644 +index 269cfe7aa87cf4a73ee2faca142c83e4d10a98c7..dd2a359eda0ab3aaf5a94e00a1675bae424bd860 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1195,11 +1195,22 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1192,11 +1192,22 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { ResourceKey resourcekey = worldserver1.getTypeKey(); if (worldserver != null && worldserver.dimension() == worldserver1.dimension()) { // CraftBukkit diff --git a/patches/server/0124-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch similarity index 90% rename from patches/server/0124-Provide-E-TE-Chunk-count-stat-methods.patch rename to patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch index afc98a061a..f1025e5537 100644 --- a/patches/server/0124-Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/0123-Provide-E-TE-Chunk-count-stat-methods.patch @@ -20,7 +20,7 @@ index 03b0720c6ebf1a876d56d18a941e0a06ed26dbf0..4fcbea7b8b12be10157da0c1f35c06e4 private final List pendingBlockEntityTickers = Lists.newArrayList(); private boolean tickingBlockEntities; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 1e8d93d81b7a391bbd1e9926ff35a68d4c563f0f..2794a7996147fce5533877a47cd1e7b6f7e7576f 100644 +index 4878a1b085a83dd4a8ffdc86250b8fb4fbac5192..1b7660a2d003bfb19ef80ba8066b6417f85328ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -164,6 +164,56 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -43,7 +43,7 @@ index 1e8d93d81b7a391bbd1e9926ff35a68d4c563f0f..2794a7996147fce5533877a47cd1e7b6 + public int getTileEntityCount() { + // We don't use the full world tile entity list, so we must iterate chunks + int size = 0; -+ for (ChunkHolder playerchunk : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) { ++ for (ChunkHolder playerchunk : ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.world)) { + net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk(); + if (chunk == null) { + continue; @@ -62,7 +62,7 @@ index 1e8d93d81b7a391bbd1e9926ff35a68d4c563f0f..2794a7996147fce5533877a47cd1e7b6 + public int getChunkCount() { + int ret = 0; + -+ for (ChunkHolder chunkHolder : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) { ++ for (ChunkHolder chunkHolder : ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.world)) { + if (chunkHolder.getTickingChunk() != null) { + ++ret; + } diff --git a/patches/server/0125-Enforce-Sync-Player-Saves.patch b/patches/server/0124-Enforce-Sync-Player-Saves.patch similarity index 100% rename from patches/server/0125-Enforce-Sync-Player-Saves.patch rename to patches/server/0124-Enforce-Sync-Player-Saves.patch diff --git a/patches/server/0126-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch similarity index 100% rename from patches/server/0126-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch rename to patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch diff --git a/patches/server/0127-Cap-Entity-Collisions.patch b/patches/server/0126-Cap-Entity-Collisions.patch similarity index 100% rename from patches/server/0127-Cap-Entity-Collisions.patch rename to patches/server/0126-Cap-Entity-Collisions.patch diff --git a/patches/server/0128-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch similarity index 100% rename from patches/server/0128-Remove-CraftScheduler-Async-Task-Debugger.patch rename to patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch diff --git a/patches/server/0129-Properly-handle-async-calls-to-restart-the-server.patch b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch similarity index 99% rename from patches/server/0129-Properly-handle-async-calls-to-restart-the-server.patch rename to patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch index 37a92c3e71..602cf5d4bb 100644 --- a/patches/server/0129-Properly-handle-async-calls-to-restart-the-server.patch +++ b/patches/server/0128-Properly-handle-async-calls-to-restart-the-server.patch @@ -30,7 +30,7 @@ will have plugins and worlds saving to the disk has a high potential to result in corruption/dataloss. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 451b6fef2c13a35eb00370fccd92581c97810137..6c46ce47d1460dcd9b387f02a09d85048a45b049 100644 +index d566d64c6c3bd97ac4b4f80bdf1b1bd5a381ef55..e464349a46eab23eb5b8d4d31f577d78532b3ce1 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -242,6 +242,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop this.level.spigotConfig.viewDistance) ? (byte) this.level.spigotConfig.viewDistance : chunkRange; chunkRange = (chunkRange > 8) ? 8 : chunkRange; @@ -23,7 +23,7 @@ index a7de9d6bbbd0b3d60b1d49e116c388b1846f33e4..767e3aed729b630d67a702d5e5bda02e // Spigot end if (!this.distanceManager.hasPlayersNearby(chunkcoordintpair.toLong())) { return false; -@@ -1089,6 +1091,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1056,6 +1058,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } entityplayer = (ServerPlayer) iterator.next(); @@ -40,10 +40,10 @@ index a7de9d6bbbd0b3d60b1d49e116c388b1846f33e4..767e3aed729b630d67a702d5e5bda02e return true; diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 0ff45d4ce6ae0b7feac53c7a9f361f6454f8b7c3..035c33b1e1be4f41e5cbe09bf6c3abd617258cad 100644 +index e0c8b89767087cba34fc3c3809db4c386dacb193..a939bad7da9c852827a2d67d9ace5d0df4911a31 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -463,6 +463,15 @@ public class ServerChunkCache extends ChunkSource { +@@ -461,6 +461,15 @@ public class ServerChunkCache extends ChunkSource { boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit Util.shuffle(list, this.level.random); @@ -60,13 +60,13 @@ index 0ff45d4ce6ae0b7feac53c7a9f361f6454f8b7c3..035c33b1e1be4f41e5cbe09bf6c3abd6 boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit Iterator iterator1 = list.iterator(); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 3ae34c67fe3dd8b30d24f1a31102f0a071c1703d..809a4f403695240b507528fb8fa3f7d390f86349 100644 +index dd2a359eda0ab3aaf5a94e00a1675bae424bd860..db3f5a774daa0750cdcc0c2c47d1bd4fd2900dd9 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -286,6 +286,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -285,6 +285,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end public boolean isRealPlayer; // Paper - public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { diff --git a/patches/server/0166-Add-setPlayerProfile-API-for-Skulls.patch b/patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch similarity index 97% rename from patches/server/0166-Add-setPlayerProfile-API-for-Skulls.patch rename to patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch index 108aa16286..d8b7b10015 100644 --- a/patches/server/0166-Add-setPlayerProfile-API-for-Skulls.patch +++ b/patches/server/0165-Add-setPlayerProfile-API-for-Skulls.patch @@ -7,7 +7,7 @@ This allows you to create already filled textures on Skulls to avoid texture loo which commonly cause rate limit issues with Mojang API diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java -index aa965ea05fb364e9cfc4bbf4241a47c3400355b0..45ac1d9193c3a0dc397d6e7ccfccec896fa78a13 100644 +index 08838e17979b59555adc242ccdd7af7cbf11f9d6..23374a104510025fd8f882361a29825d0bec6ee0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -98,7 +98,22 @@ public class CraftSkull extends CraftBlockEntityState implemen diff --git a/patches/server/0167-PreCreatureSpawnEvent.patch b/patches/server/0166-PreCreatureSpawnEvent.patch similarity index 100% rename from patches/server/0167-PreCreatureSpawnEvent.patch rename to patches/server/0166-PreCreatureSpawnEvent.patch diff --git a/patches/server/0168-Fill-Profile-Property-Events.patch b/patches/server/0167-Fill-Profile-Property-Events.patch similarity index 100% rename from patches/server/0168-Fill-Profile-Property-Events.patch rename to patches/server/0167-Fill-Profile-Property-Events.patch diff --git a/patches/server/0169-Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch similarity index 100% rename from patches/server/0169-Add-PlayerAdvancementCriterionGrantEvent.patch rename to patches/server/0168-Add-PlayerAdvancementCriterionGrantEvent.patch diff --git a/patches/server/0170-Add-ArmorStand-Item-Meta.patch b/patches/server/0169-Add-ArmorStand-Item-Meta.patch similarity index 100% rename from patches/server/0170-Add-ArmorStand-Item-Meta.patch rename to patches/server/0169-Add-ArmorStand-Item-Meta.patch diff --git a/patches/server/0171-Extend-Player-Interact-cancellation.patch b/patches/server/0170-Extend-Player-Interact-cancellation.patch similarity index 100% rename from patches/server/0171-Extend-Player-Interact-cancellation.patch rename to patches/server/0170-Extend-Player-Interact-cancellation.patch diff --git a/patches/server/0172-Tameable-getOwnerUniqueId-API.patch b/patches/server/0171-Tameable-getOwnerUniqueId-API.patch similarity index 100% rename from patches/server/0172-Tameable-getOwnerUniqueId-API.patch rename to patches/server/0171-Tameable-getOwnerUniqueId-API.patch diff --git a/patches/server/0173-Toggleable-player-crits.patch b/patches/server/0172-Toggleable-player-crits.patch similarity index 100% rename from patches/server/0173-Toggleable-player-crits.patch rename to patches/server/0172-Toggleable-player-crits.patch diff --git a/patches/server/0174-Disable-Explicit-Network-Manager-Flushing.patch b/patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch similarity index 100% rename from patches/server/0174-Disable-Explicit-Network-Manager-Flushing.patch rename to patches/server/0173-Disable-Explicit-Network-Manager-Flushing.patch diff --git a/patches/server/0175-Implement-extended-PaperServerListPingEvent.patch b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch similarity index 97% rename from patches/server/0175-Implement-extended-PaperServerListPingEvent.patch rename to patches/server/0174-Implement-extended-PaperServerListPingEvent.patch index 4ca3384be1..f39816c85d 100644 --- a/patches/server/0175-Implement-extended-PaperServerListPingEvent.patch +++ b/patches/server/0174-Implement-extended-PaperServerListPingEvent.patch @@ -162,7 +162,7 @@ index 0000000000000000000000000000000000000000..874dcbefea469440a9028ddc399a37c9 + +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6c46ce47d1460dcd9b387f02a09d85048a45b049..f71b1c2497594b592bcc51be9fa6a6d8fe8e819b 100644 +index e464349a46eab23eb5b8d4d31f577d78532b3ce1..7f4c9ba88c2d33c2cc23e406a616f9eb35d738ce 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -3,6 +3,9 @@ package net.minecraft.server; @@ -175,7 +175,7 @@ index 6c46ce47d1460dcd9b387f02a09d85048a45b049..f71b1c2497594b592bcc51be9fa6a6d8 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -1518,7 +1521,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 5bf3f2faac0af6bddfd2ecb423a13cdf0dd1af1b..2fd93f715bd69fb0217939c87f7872720a9adb7c 100644 +index 0706dd82cfdb6808ef61149b2a8d8be971f19be9..ae9d058e9450f59bb6a03ebc6fffed8a0b3ebee8 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2185,6 +2185,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2182,6 +2182,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.camera = (Entity) (entity == null ? this : entity); if (entity1 != this.camera) { diff --git a/patches/server/0258-Add-more-Witch-API.patch b/patches/server/0257-Add-more-Witch-API.patch similarity index 100% rename from patches/server/0258-Add-more-Witch-API.patch rename to patches/server/0257-Add-more-Witch-API.patch diff --git a/patches/server/0259-Check-Drowned-for-Villager-Aggression-Config.patch b/patches/server/0258-Check-Drowned-for-Villager-Aggression-Config.patch similarity index 100% rename from patches/server/0259-Check-Drowned-for-Villager-Aggression-Config.patch rename to patches/server/0258-Check-Drowned-for-Villager-Aggression-Config.patch diff --git a/patches/server/0260-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0259-Add-option-to-prevent-players-from-moving-into-unloa.patch similarity index 100% rename from patches/server/0260-Add-option-to-prevent-players-from-moving-into-unloa.patch rename to patches/server/0259-Add-option-to-prevent-players-from-moving-into-unloa.patch diff --git a/patches/server/0261-Reset-players-airTicks-on-respawn.patch b/patches/server/0260-Reset-players-airTicks-on-respawn.patch similarity index 84% rename from patches/server/0261-Reset-players-airTicks-on-respawn.patch rename to patches/server/0260-Reset-players-airTicks-on-respawn.patch index c7bda44c48..c14f0e7188 100644 --- a/patches/server/0261-Reset-players-airTicks-on-respawn.patch +++ b/patches/server/0260-Reset-players-airTicks-on-respawn.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Reset players airTicks on respawn diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 099e740df4966be29a52ea1398bfc7f531d4fb9d..1056286007e1c16c6fce3df7918a082a545f92b5 100644 +index ae9d058e9450f59bb6a03ebc6fffed8a0b3ebee8..dad9d89d77001d2c84fbae7a8a4a4312cc5953dc 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2706,6 +2706,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2703,6 +2703,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.setHealth(this.getMaxHealth()); this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset diff --git a/patches/server/0262-Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/server/0261-Don-t-sleep-after-profile-lookups-if-not-needed.patch similarity index 100% rename from patches/server/0262-Don-t-sleep-after-profile-lookups-if-not-needed.patch rename to patches/server/0261-Don-t-sleep-after-profile-lookups-if-not-needed.patch diff --git a/patches/server/0263-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0262-Improve-Server-Thread-Pool-and-Thread-Priorities.patch similarity index 98% rename from patches/server/0263-Improve-Server-Thread-Pool-and-Thread-Priorities.patch rename to patches/server/0262-Improve-Server-Thread-Pool-and-Thread-Priorities.patch index 9ea7802386..278b5c5f14 100644 --- a/patches/server/0263-Improve-Server-Thread-Pool-and-Thread-Priorities.patch +++ b/patches/server/0262-Improve-Server-Thread-Pool-and-Thread-Priorities.patch @@ -92,7 +92,7 @@ index 54562fa04d14a937451ea7aa9d80194f2c31b471..4cf88f6d815d60cfbf8e4ecf9d96d0cf return executorService; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6a97ab5e8a435e67df77b1d0480ccb397314ee05..c8b5714ad87b501fdf820ae2ad8e6a4bdef82651 100644 +index 5d429b707383e6620a0d83f23d7a8694ecc70735..995ee6b2af01a14d61a031008dd05518668a98ae 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -323,6 +323,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index faa228698c7dd60bde0f3767cc27957ece04b8be..f3bce016e729d553aaa6185470bbf4317f94352b 100644 +index 8245b38d37b4cee6f4e7b61d7af40a18e54a3f43..e226eda5efc0e45e59cb5f6251ed008b67d5299a 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -203,23 +203,27 @@ public class Main { diff --git a/patches/server/0318-Add-ThrownEggHatchEvent.patch b/patches/server/0317-Add-ThrownEggHatchEvent.patch similarity index 100% rename from patches/server/0318-Add-ThrownEggHatchEvent.patch rename to patches/server/0317-Add-ThrownEggHatchEvent.patch diff --git a/patches/server/0319-Entity-Jump-API.patch b/patches/server/0318-Entity-Jump-API.patch similarity index 100% rename from patches/server/0319-Entity-Jump-API.patch rename to patches/server/0318-Entity-Jump-API.patch diff --git a/patches/server/0320-Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/server/0319-Add-option-to-nerf-pigmen-from-nether-portals.patch similarity index 100% rename from patches/server/0320-Add-option-to-nerf-pigmen-from-nether-portals.patch rename to patches/server/0319-Add-option-to-nerf-pigmen-from-nether-portals.patch diff --git a/patches/server/0321-Make-the-GUI-graph-fancier.patch b/patches/server/0320-Make-the-GUI-graph-fancier.patch similarity index 100% rename from patches/server/0321-Make-the-GUI-graph-fancier.patch rename to patches/server/0320-Make-the-GUI-graph-fancier.patch diff --git a/patches/server/0322-add-hand-to-BlockMultiPlaceEvent.patch b/patches/server/0321-add-hand-to-BlockMultiPlaceEvent.patch similarity index 100% rename from patches/server/0322-add-hand-to-BlockMultiPlaceEvent.patch rename to patches/server/0321-add-hand-to-BlockMultiPlaceEvent.patch diff --git a/patches/server/0323-Validate-tripwire-hook-placement-before-update.patch b/patches/server/0322-Validate-tripwire-hook-placement-before-update.patch similarity index 100% rename from patches/server/0323-Validate-tripwire-hook-placement-before-update.patch rename to patches/server/0322-Validate-tripwire-hook-placement-before-update.patch diff --git a/patches/server/0324-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/patches/server/0323-Add-option-to-allow-iron-golems-to-spawn-in-air.patch similarity index 100% rename from patches/server/0324-Add-option-to-allow-iron-golems-to-spawn-in-air.patch rename to patches/server/0323-Add-option-to-allow-iron-golems-to-spawn-in-air.patch diff --git a/patches/server/0325-Configurable-chance-of-villager-zombie-infection.patch b/patches/server/0324-Configurable-chance-of-villager-zombie-infection.patch similarity index 100% rename from patches/server/0325-Configurable-chance-of-villager-zombie-infection.patch rename to patches/server/0324-Configurable-chance-of-villager-zombie-infection.patch diff --git a/patches/server/0326-Optimise-Chunk-getFluid.patch b/patches/server/0325-Optimise-Chunk-getFluid.patch similarity index 100% rename from patches/server/0326-Optimise-Chunk-getFluid.patch rename to patches/server/0325-Optimise-Chunk-getFluid.patch diff --git a/patches/server/0327-Set-spigots-verbose-world-setting-to-false-by-def.patch b/patches/server/0326-Set-spigots-verbose-world-setting-to-false-by-def.patch similarity index 100% rename from patches/server/0327-Set-spigots-verbose-world-setting-to-false-by-def.patch rename to patches/server/0326-Set-spigots-verbose-world-setting-to-false-by-def.patch diff --git a/patches/server/0328-Add-tick-times-API-and-mspt-command.patch b/patches/server/0327-Add-tick-times-API-and-mspt-command.patch similarity index 97% rename from patches/server/0328-Add-tick-times-API-and-mspt-command.patch rename to patches/server/0327-Add-tick-times-API-and-mspt-command.patch index 53ce864287..e076e69dde 100644 --- a/patches/server/0328-Add-tick-times-API-and-mspt-command.patch +++ b/patches/server/0327-Add-tick-times-API-and-mspt-command.patch @@ -125,7 +125,7 @@ index 72f2e81b9905a0d57ed8e2a88578f62d5235c456..7b58b2d6297800c2dcdbf7539e5ab8e7 public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ee86f2cb71b2c8dc85c27635efca3666de7a3cbe..1e6546637c5c2ddf4aacc7a3ea8623ce55059203 100644 +index 3ffb330a16797c04694f73b0cd9f5b38a07641b4..ff73167bfe210305491e35f18adc2755d3651a85 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -258,6 +258,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entitytypes = entity.getType(); int i = entitytypes.clientTrackingRange() * 16; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 33cb58e7298e7900dbcd37dbdb21de83bfca6a26..a87782c3cb0a751f532feda0b827d7c7eac163e1 100644 +index f1fa4cb11f69e248dd55b8aa69f5d07268f182a1..89e05d9316b012a5c8103682ff9dbeae757f4f57 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2149,7 +2149,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0335-Don-t-tick-dead-players.patch b/patches/server/0334-Don-t-tick-dead-players.patch similarity index 85% rename from patches/server/0335-Don-t-tick-dead-players.patch rename to patches/server/0334-Don-t-tick-dead-players.patch index 27ce527eee..ea38303ab0 100644 --- a/patches/server/0335-Don-t-tick-dead-players.patch +++ b/patches/server/0334-Don-t-tick-dead-players.patch @@ -7,10 +7,10 @@ Causes sync chunk loads and who knows what all else. This is safe because Spectators are skipped in unloaded chunks too in vanilla. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 6a385b5cb5baf94b1340e0029df7dcd908e5f702..588fcfb614299eeebef081d2dd005f1a8a00153b 100644 +index 7e60da3249e44b333ea3d22ddee706b270dd9c61..6075e536f09875e577cea7caff70d6a417470254 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -767,7 +767,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -764,7 +764,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public void doTick() { try { diff --git a/patches/server/0336-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/server/0335-Dead-Player-s-shouldn-t-be-able-to-move.patch similarity index 100% rename from patches/server/0336-Dead-Player-s-shouldn-t-be-able-to-move.patch rename to patches/server/0335-Dead-Player-s-shouldn-t-be-able-to-move.patch diff --git a/patches/server/0337-Don-t-move-existing-players-to-world-spawn.patch b/patches/server/0336-Don-t-move-existing-players-to-world-spawn.patch similarity index 92% rename from patches/server/0337-Don-t-move-existing-players-to-world-spawn.patch rename to patches/server/0336-Don-t-move-existing-players-to-world-spawn.patch index e8fef02c0f..a557384e1c 100644 --- a/patches/server/0337-Don-t-move-existing-players-to-world-spawn.patch +++ b/patches/server/0336-Don-t-move-existing-players-to-world-spawn.patch @@ -13,10 +13,10 @@ By skipping this, we avoid potential for a large spike on server start. public net.minecraft.server.level.ServerPlayer fudgeSpawnLocation(Lnet/minecraft/server/level/ServerLevel;)V diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 588fcfb614299eeebef081d2dd005f1a8a00153b..8dff4fb382639e4db9c80bbdfbc69167aa7996a1 100644 +index 6075e536f09875e577cea7caff70d6a417470254..a9c1aa9e382b0864386030a66158b53d12026a00 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -358,7 +358,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -357,7 +357,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.server = server; this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); @@ -25,7 +25,7 @@ index 588fcfb614299eeebef081d2dd005f1a8a00153b..8dff4fb382639e4db9c80bbdfbc69167 this.updateOptions(clientOptions); this.object = null; -@@ -630,7 +630,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -627,7 +627,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { position = Vec3.atCenterOf(world.getSharedSpawnPos()); } this.setLevel(world); diff --git a/patches/server/0338-Optimize-Pathfinding.patch b/patches/server/0337-Optimize-Pathfinding.patch similarity index 100% rename from patches/server/0338-Optimize-Pathfinding.patch rename to patches/server/0337-Optimize-Pathfinding.patch diff --git a/patches/server/0339-Reduce-Either-Optional-allocation.patch b/patches/server/0338-Reduce-Either-Optional-allocation.patch similarity index 100% rename from patches/server/0339-Reduce-Either-Optional-allocation.patch rename to patches/server/0338-Reduce-Either-Optional-allocation.patch diff --git a/patches/server/0340-Reduce-memory-footprint-of-CompoundTag.patch b/patches/server/0339-Reduce-memory-footprint-of-CompoundTag.patch similarity index 100% rename from patches/server/0340-Reduce-memory-footprint-of-CompoundTag.patch rename to patches/server/0339-Reduce-memory-footprint-of-CompoundTag.patch diff --git a/patches/server/0341-Prevent-opening-inventories-when-frozen.patch b/patches/server/0340-Prevent-opening-inventories-when-frozen.patch similarity index 94% rename from patches/server/0341-Prevent-opening-inventories-when-frozen.patch rename to patches/server/0340-Prevent-opening-inventories-when-frozen.patch index 5969f96e51..133a70b2d7 100644 --- a/patches/server/0341-Prevent-opening-inventories-when-frozen.patch +++ b/patches/server/0340-Prevent-opening-inventories-when-frozen.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent opening inventories when frozen diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index fb72ce049aeb49ee59cd07e074e61bb31591c252..b4089878f7f8cd32cea7741b72be5bb5218f3032 100644 +index a9c1aa9e382b0864386030a66158b53d12026a00..2d31cd0924ad44534418ec084507c19f49d95f24 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -712,7 +712,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -709,7 +709,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate; } // Paper end - Configurable container update tick rate @@ -17,7 +17,7 @@ index fb72ce049aeb49ee59cd07e074e61bb31591c252..b4089878f7f8cd32cea7741b72be5bb5 this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason this.containerMenu = this.inventoryMenu; } -@@ -1637,7 +1637,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1634,7 +1634,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else { // CraftBukkit start this.containerMenu = container; diff --git a/patches/server/0342-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0341-Don-t-run-entity-collision-code-if-not-needed.patch similarity index 100% rename from patches/server/0342-Don-t-run-entity-collision-code-if-not-needed.patch rename to patches/server/0341-Don-t-run-entity-collision-code-if-not-needed.patch diff --git a/patches/server/0343-Implement-Player-Client-Options-API.patch b/patches/server/0342-Implement-Player-Client-Options-API.patch similarity index 94% rename from patches/server/0343-Implement-Player-Client-Options-API.patch rename to patches/server/0342-Implement-Player-Client-Options-API.patch index 1778c7d21e..6470ba2e4a 100644 --- a/patches/server/0343-Implement-Player-Client-Options-API.patch +++ b/patches/server/0342-Implement-Player-Client-Options-API.patch @@ -87,10 +87,10 @@ index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabb + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 1e780b73fac4d686444ff3a009cf33318068d8d1..8554ee1636416d9fb1aee2051e4a4d08b0c6d636 100644 +index 2d31cd0924ad44534418ec084507c19f49d95f24..15df50a36138f29ae278cf1f1f531ad949f4a93e 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -359,7 +359,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -358,7 +358,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); // this.moveTo(this.adjustSpawnLocation(world, world.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn @@ -98,8 +98,8 @@ index 1e780b73fac4d686444ff3a009cf33318068d8d1..8554ee1636416d9fb1aee2051e4a4d08 + this.updateOptionsNoEvents(clientOptions); // Paper - don't call options events on login this.object = null; - this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper -@@ -2149,7 +2149,23 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + // CraftBukkit start +@@ -2146,7 +2146,23 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } @@ -123,7 +123,7 @@ index 1e780b73fac4d686444ff3a009cf33318068d8d1..8554ee1636416d9fb1aee2051e4a4d08 // CraftBukkit start if (this.getMainArm() != clientOptions.mainHand()) { PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), this.getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT); -@@ -2160,6 +2176,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2157,6 +2173,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.server.server.getPluginManager().callEvent(event); } // CraftBukkit end @@ -136,7 +136,7 @@ index 1e780b73fac4d686444ff3a009cf33318068d8d1..8554ee1636416d9fb1aee2051e4a4d08 this.adventure$locale = java.util.Objects.requireNonNullElse(net.kyori.adventure.translation.Translator.parseLocale(this.language), java.util.Locale.US); // Paper this.requestedViewDistance = clientOptions.viewDistance(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index a32a3e8aa5108f28f7bda637c50627afb59f7598..8865dabc729af78fcc306d48e754c54f80dfb2e4 100644 +index 80a9a4df9b1114f932badd847238c7a0a1a00941..a0835efca3bef35c434b716ceccd05c801d2f240 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -653,6 +653,28 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0344-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/0343-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch similarity index 100% rename from patches/server/0344-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch rename to patches/server/0343-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch diff --git a/patches/server/0345-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch b/patches/server/0344-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch similarity index 96% rename from patches/server/0345-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch rename to patches/server/0344-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch index 08456c3e37..0c65900b36 100644 --- a/patches/server/0345-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch +++ b/patches/server/0344-Fire-PlayerJoinEvent-when-Player-is-actually-ready.patch @@ -31,10 +31,10 @@ delays anymore. public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 02ea2b2d5463909663bb599b6ca57198b8513456..37bfe3d315210462ed69bb1cb161604e9eb85c36 100644 +index fd50b43197bf3a92e838023de31b7acd8a257b8e..161792d0226dbb50e9f5ab5c0fe42cc73f44c2a8 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1288,6 +1288,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1252,6 +1252,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider return; } // Paper end - ignore and warn about illegal addEntity calls instead of crashing server @@ -43,7 +43,7 @@ index 02ea2b2d5463909663bb599b6ca57198b8513456..37bfe3d315210462ed69bb1cb161604e EntityType entitytypes = entity.getType(); int i = entitytypes.clientTrackingRange() * 16; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 8554ee1636416d9fb1aee2051e4a4d08b0c6d636..9cba3ac95318f1a4b680b541ce5d825fc5c4ad02 100644 +index 15df50a36138f29ae278cf1f1f531ad949f4a93e..b43a32989bd9c05f26da97634149350b311ad820 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -288,6 +288,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { diff --git a/patches/server/0346-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch similarity index 100% rename from patches/server/0346-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch rename to patches/server/0345-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch diff --git a/patches/server/0347-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0346-Add-PlayerAttackEntityCooldownResetEvent.patch similarity index 100% rename from patches/server/0347-Add-PlayerAttackEntityCooldownResetEvent.patch rename to patches/server/0346-Add-PlayerAttackEntityCooldownResetEvent.patch diff --git a/patches/server/0348-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/0347-Don-t-fire-BlockFade-on-worldgen-threads.patch similarity index 100% rename from patches/server/0348-Don-t-fire-BlockFade-on-worldgen-threads.patch rename to patches/server/0347-Don-t-fire-BlockFade-on-worldgen-threads.patch diff --git a/patches/server/0349-Add-phantom-creative-and-insomniac-controls.patch b/patches/server/0348-Add-phantom-creative-and-insomniac-controls.patch similarity index 100% rename from patches/server/0349-Add-phantom-creative-and-insomniac-controls.patch rename to patches/server/0348-Add-phantom-creative-and-insomniac-controls.patch diff --git a/patches/server/0350-Fix-item-duplication-and-teleport-issues.patch b/patches/server/0349-Fix-item-duplication-and-teleport-issues.patch similarity index 100% rename from patches/server/0350-Fix-item-duplication-and-teleport-issues.patch rename to patches/server/0349-Fix-item-duplication-and-teleport-issues.patch diff --git a/patches/server/0351-Villager-Restocks-API.patch b/patches/server/0350-Villager-Restocks-API.patch similarity index 100% rename from patches/server/0351-Villager-Restocks-API.patch rename to patches/server/0350-Villager-Restocks-API.patch diff --git a/patches/server/0352-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0351-Validate-PickItem-Packet-and-kick-for-invalid.patch similarity index 100% rename from patches/server/0352-Validate-PickItem-Packet-and-kick-for-invalid.patch rename to patches/server/0351-Validate-PickItem-Packet-and-kick-for-invalid.patch diff --git a/patches/server/0353-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/server/0352-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch similarity index 93% rename from patches/server/0353-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch rename to patches/server/0352-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch index 44bd324f68..a52cf1acdb 100644 --- a/patches/server/0353-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch +++ b/patches/server/0352-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch @@ -17,7 +17,7 @@ keeping long lived large direct buffers in cache. Set system properly at server startup if not set already to help protect from this. diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index f3bce016e729d553aaa6185470bbf4317f94352b..02243b69cca7255588b43dab57e1c9ca4c3ca87f 100644 +index e226eda5efc0e45e59cb5f6251ed008b67d5299a..b9b93a4e20eed028b76eab4dcb9610ae05f22faf 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -27,6 +27,7 @@ public class Main { diff --git a/patches/server/0354-misc-debugging-dumps.patch b/patches/server/0353-misc-debugging-dumps.patch similarity index 98% rename from patches/server/0354-misc-debugging-dumps.patch rename to patches/server/0353-misc-debugging-dumps.patch index 5959f30078..55771587f6 100644 --- a/patches/server/0354-misc-debugging-dumps.patch +++ b/patches/server/0353-misc-debugging-dumps.patch @@ -49,7 +49,7 @@ index e25fc35716aff1d1805884b18f67b0eb33d8c05c..8ca9ac8eff9d605baa878ca24e165ac5 StackTraceElement[] astacktraceelement = exception.getStackTrace(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 1e6546637c5c2ddf4aacc7a3ea8623ce55059203..af83b1c762239fe7c8c11d3904f30504b0a1ca67 100644 +index ff73167bfe210305491e35f18adc2755d3651a85..1088a91ee131d1c303961557d8fb90101c2d8d3b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -916,6 +916,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop vanillaToPaper(Goal goal) { + EnumSet goals = EnumSet.noneOf(GoalType.class); + for (GoalType type : GoalType.values()) { -+ if (goal.getFlags().contains(paperToVanilla(type))) { ++ if (goal.getFlags().hasElement(paperToVanilla(type))) { + goals.add(type); + } + } @@ -402,7 +401,7 @@ index 0000000000000000000000000000000000000000..3f8cca8027051694cb0440373e75f418 +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java new file mode 100644 -index 0000000000000000000000000000000000000000..b5f75ad725f5933db8f0688b2c0b27d620919241 +index 0000000000000000000000000000000000000000..26c745dd9ccdfdd5c5039f2acc5201b9b91fb274 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java @@ -0,0 +1,53 @@ @@ -422,7 +421,7 @@ index 0000000000000000000000000000000000000000..b5f75ad725f5933db8f0688b2c0b27d6 + + this.setFlags(MobGoalHelper.paperToVanilla(handle.getTypes())); + if (this.getFlags().size() == 0) { -+ this.getFlags().add(Flag.UNKNOWN_BEHAVIOR); ++ this.getFlags().addUnchecked(Flag.UNKNOWN_BEHAVIOR); + } + } + @@ -461,7 +460,7 @@ index 0000000000000000000000000000000000000000..b5f75ad725f5933db8f0688b2c0b27d6 +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java new file mode 100644 -index 0000000000000000000000000000000000000000..30ed9ffd6a65914d7545636150a09327aba047c3 +index 0000000000000000000000000000000000000000..24c30e8a462c59829ab2bd9ee52a1b248550d8ab --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java @@ -0,0 +1,224 @@ @@ -584,7 +583,7 @@ index 0000000000000000000000000000000000000000..30ed9ffd6a65914d7545636150a09327 + CraftMob craftMob = (CraftMob) mob; + Set> goals = new HashSet<>(); + for (WrappedGoal item : getHandle(craftMob, type).getAvailableGoals()) { -+ if (!item.getGoal().getFlags().contains(MobGoalHelper.paperToVanilla(type))) { ++ if (!item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) { + continue; + } + @@ -607,7 +606,7 @@ index 0000000000000000000000000000000000000000..30ed9ffd6a65914d7545636150a09327 + continue; + } + for (WrappedGoal item : getHandle(craftMob, internalType).getAvailableGoals()) { -+ if (item.getGoal().getFlags().contains(MobGoalHelper.paperToVanilla(type))) { ++ if (item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) { + continue; + } + @@ -637,7 +636,7 @@ index 0000000000000000000000000000000000000000..30ed9ffd6a65914d7545636150a09327 + Set> goals = new HashSet<>(); + getHandle(craftMob, type).getAvailableGoals() + .stream().filter(WrappedGoal::isRunning) -+ .filter(item -> item.getGoal().getFlags().contains(MobGoalHelper.paperToVanilla(type))) ++ .filter(item -> item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) + .forEach(item -> { + if (item.getGoal() instanceof PaperCustomGoal) { + //noinspection unchecked @@ -660,7 +659,7 @@ index 0000000000000000000000000000000000000000..30ed9ffd6a65914d7545636150a09327 + getHandle(craftMob, internalType).getAvailableGoals() + .stream() + .filter(WrappedGoal::isRunning) -+ .filter(item -> !item.getGoal().getFlags().contains(MobGoalHelper.paperToVanilla(type))) ++ .filter(item -> !item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) + .forEach(item -> { + if (item.getGoal() instanceof PaperCustomGoal) { + //noinspection unchecked diff --git a/patches/server/0357-Add-villager-reputation-API.patch b/patches/server/0356-Add-villager-reputation-API.patch similarity index 100% rename from patches/server/0357-Add-villager-reputation-API.patch rename to patches/server/0356-Add-villager-reputation-API.patch diff --git a/patches/server/0358-ExperienceOrb-merging-stacking-API-and-fixes.patch b/patches/server/0357-ExperienceOrb-merging-stacking-API-and-fixes.patch similarity index 100% rename from patches/server/0358-ExperienceOrb-merging-stacking-API-and-fixes.patch rename to patches/server/0357-ExperienceOrb-merging-stacking-API-and-fixes.patch diff --git a/patches/server/0359-Fix-PotionEffect-ignores-icon-flag.patch b/patches/server/0358-Fix-PotionEffect-ignores-icon-flag.patch similarity index 100% rename from patches/server/0359-Fix-PotionEffect-ignores-icon-flag.patch rename to patches/server/0358-Fix-PotionEffect-ignores-icon-flag.patch diff --git a/patches/server/0360-Potential-bed-API.patch b/patches/server/0359-Potential-bed-API.patch similarity index 95% rename from patches/server/0360-Potential-bed-API.patch rename to patches/server/0359-Potential-bed-API.patch index 34470bcfc1..9b500674e0 100644 --- a/patches/server/0360-Potential-bed-API.patch +++ b/patches/server/0359-Potential-bed-API.patch @@ -8,7 +8,7 @@ Adds a new method to fetch the location of a player's bed without generating any getPotentialBedLocation - Gets the last known location of a player's bed. This does not preform any check if the bed is still valid and does not load any chunks. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index eb2d39d408e7f46a8f047a2b0d76981f24e1320a..bbd3f0981eb95348ef12c9af8fa1712c022ed869 100644 +index b55919a0e61a36697c95599dba17dbe2b788fd2a..084938fa2ffa7ee462766bf03f8e2b4c0fd4bf6b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -12,6 +12,7 @@ import net.minecraft.nbt.CompoundTag; diff --git a/patches/server/0361-Wait-for-Async-Tasks-during-shutdown.patch b/patches/server/0360-Wait-for-Async-Tasks-during-shutdown.patch similarity index 97% rename from patches/server/0361-Wait-for-Async-Tasks-during-shutdown.patch rename to patches/server/0360-Wait-for-Async-Tasks-during-shutdown.patch index e7c0b4c6b0..f978f93066 100644 --- a/patches/server/0361-Wait-for-Async-Tasks-during-shutdown.patch +++ b/patches/server/0360-Wait-for-Async-Tasks-during-shutdown.patch @@ -10,7 +10,7 @@ Adds a 5 second grace period for any async tasks to finish and warns if any are still running after that delay just as reload does. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index af83b1c762239fe7c8c11d3904f30504b0a1ca67..badd42d84b6367f6926bcff0ec8426fb6402ae80 100644 +index 1088a91ee131d1c303961557d8fb90101c2d8d3b..2d25ba18d3db4b3eea8bd30812656f1ade4c2a67 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -943,6 +943,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { + ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> { net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c; + if (chunk != null) this.addTicket(x, z); // Paper diff --git a/patches/server/0380-Add-BlockStateMeta-clearBlockState.patch b/patches/server/0379-Add-BlockStateMeta-clearBlockState.patch similarity index 100% rename from patches/server/0380-Add-BlockStateMeta-clearBlockState.patch rename to patches/server/0379-Add-BlockStateMeta-clearBlockState.patch diff --git a/patches/server/0381-Convert-legacy-attributes-in-Item-Meta.patch b/patches/server/0380-Convert-legacy-attributes-in-Item-Meta.patch similarity index 97% rename from patches/server/0381-Convert-legacy-attributes-in-Item-Meta.patch rename to patches/server/0380-Convert-legacy-attributes-in-Item-Meta.patch index 94ddf33189..b929596c4e 100644 --- a/patches/server/0381-Convert-legacy-attributes-in-Item-Meta.patch +++ b/patches/server/0380-Convert-legacy-attributes-in-Item-Meta.patch @@ -30,7 +30,7 @@ index de40e522960469b98f987bd688489740446d9f85..5678d2007d5adf45dec0638c5dd848b6 public CraftAttributeMap(AttributeMap handle) { this.handle = handle; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java -index 38596695282157e3ff0a53a1185d211268854c15..24ebc5841ed16129c0e9305da6cf1d8fb67d42ec 100644 +index 69be26f8f47854f39cfed0559d944ef4f983c0f3..0b87cfbdf039ee5bc017d2b1783c7c4853047952 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -695,7 +695,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { diff --git a/patches/server/0382-Do-not-accept-invalid-client-settings.patch b/patches/server/0381-Do-not-accept-invalid-client-settings.patch similarity index 100% rename from patches/server/0382-Do-not-accept-invalid-client-settings.patch rename to patches/server/0381-Do-not-accept-invalid-client-settings.patch diff --git a/patches/server/0383-Improve-fix-EntityTargetLivingEntityEvent.patch b/patches/server/0382-Improve-fix-EntityTargetLivingEntityEvent.patch similarity index 100% rename from patches/server/0383-Improve-fix-EntityTargetLivingEntityEvent.patch rename to patches/server/0382-Improve-fix-EntityTargetLivingEntityEvent.patch diff --git a/patches/server/0384-Add-entity-liquid-API.patch b/patches/server/0383-Add-entity-liquid-API.patch similarity index 100% rename from patches/server/0384-Add-entity-liquid-API.patch rename to patches/server/0383-Add-entity-liquid-API.patch diff --git a/patches/server/0385-Add-PrepareResultEvent.patch b/patches/server/0384-Add-PrepareResultEvent.patch similarity index 100% rename from patches/server/0385-Add-PrepareResultEvent.patch rename to patches/server/0384-Add-PrepareResultEvent.patch diff --git a/patches/server/0386-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/server/0385-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch similarity index 100% rename from patches/server/0386-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch rename to patches/server/0385-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch diff --git a/patches/server/0387-Fix-arrows-never-despawning-MC-125757.patch b/patches/server/0386-Fix-arrows-never-despawning-MC-125757.patch similarity index 100% rename from patches/server/0387-Fix-arrows-never-despawning-MC-125757.patch rename to patches/server/0386-Fix-arrows-never-despawning-MC-125757.patch diff --git a/patches/server/0388-Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/server/0387-Thread-Safe-Vanilla-Command-permission-checking.patch similarity index 100% rename from patches/server/0388-Thread-Safe-Vanilla-Command-permission-checking.patch rename to patches/server/0387-Thread-Safe-Vanilla-Command-permission-checking.patch diff --git a/patches/server/0389-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch b/patches/server/0388-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch similarity index 100% rename from patches/server/0389-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch rename to patches/server/0388-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch diff --git a/patches/server/0390-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch b/patches/server/0389-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch similarity index 100% rename from patches/server/0390-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch rename to patches/server/0389-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch diff --git a/patches/server/0391-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch b/patches/server/0390-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch similarity index 100% rename from patches/server/0391-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch rename to patches/server/0390-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch diff --git a/patches/server/0392-Optimize-NetworkManager-Exception-Handling.patch b/patches/server/0391-Optimize-NetworkManager-Exception-Handling.patch similarity index 100% rename from patches/server/0392-Optimize-NetworkManager-Exception-Handling.patch rename to patches/server/0391-Optimize-NetworkManager-Exception-Handling.patch diff --git a/patches/server/0393-Fix-some-rails-connecting-improperly.patch b/patches/server/0392-Fix-some-rails-connecting-improperly.patch similarity index 100% rename from patches/server/0393-Fix-some-rails-connecting-improperly.patch rename to patches/server/0392-Fix-some-rails-connecting-improperly.patch diff --git a/patches/server/0394-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch b/patches/server/0393-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch similarity index 100% rename from patches/server/0394-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch rename to patches/server/0393-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch diff --git a/patches/server/0395-Brand-support.patch b/patches/server/0394-Brand-support.patch similarity index 91% rename from patches/server/0395-Brand-support.patch rename to patches/server/0394-Brand-support.patch index 24c2290fe4..b5c888a819 100644 --- a/patches/server/0395-Brand-support.patch +++ b/patches/server/0394-Brand-support.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Brand support diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index d4e933b8d0f2352ac035b99fc386e6fe6d7f6651..4e76d4cacf688bce9d00eaff5ea601dbf16493e9 100644 +index b43a32989bd9c05f26da97634149350b311ad820..16dca5bcb7b1cbecec9be88c60240f3abe43ffdb 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -294,6 +294,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -293,6 +293,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + // CraftBukkit end public boolean isRealPlayer; // Paper - public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent + public @Nullable String clientBrandName = null; // Paper - Brand support @@ -57,7 +57,7 @@ index 2d1fad00ee084841618f0da8113c7aac8c0e2b0d..a3c67bdc2c08b3550534f37d15b0db90 } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index aa549021a1676d0aa0aa7c9f1b0bf0bb800385a4..1febe581fbbc3accbf8fdbf086fba427cefdd3e9 100644 +index a0835efca3bef35c434b716ceccd05c801d2f240..99799563942693ae36188092d76054fdff97d4ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3139,6 +3139,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0396-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/server/0395-Add-playPickupItemAnimation-to-LivingEntity.patch similarity index 100% rename from patches/server/0396-Add-playPickupItemAnimation-to-LivingEntity.patch rename to patches/server/0395-Add-playPickupItemAnimation-to-LivingEntity.patch diff --git a/patches/server/0397-Don-t-require-FACING-data.patch b/patches/server/0396-Don-t-require-FACING-data.patch similarity index 100% rename from patches/server/0397-Don-t-require-FACING-data.patch rename to patches/server/0396-Don-t-require-FACING-data.patch diff --git a/patches/server/0398-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/server/0397-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch similarity index 92% rename from patches/server/0398-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch rename to patches/server/0397-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch index 48ef428173..37342b6ffe 100644 --- a/patches/server/0398-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch +++ b/patches/server/0397-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix SpawnChangeEvent not firing for all use-cases diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a87782c3cb0a751f532feda0b827d7c7eac163e1..2c70df4d6ba8188ef7e1ab30b70bcfaa1a660eca 100644 +index 89e05d9316b012a5c8103682ff9dbeae757f4f57..9114ba1742a4fc8683848d431fa92046a85fe871 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1666,7 +1666,9 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -19,7 +19,7 @@ index a87782c3cb0a751f532feda0b827d7c7eac163e1..2c70df4d6ba8188ef7e1ab30b70bcfaa } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e085fd750aa8823ca6a3bab9b6e5c5b8338021bb..009be0baf925245ff8fa3d849f4233fb952f881e 100644 +index 6e01013228798f9682624e912618500f0d4fa485..5ae307f9343ffea39c286992459a6c8069d9fb86 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -246,12 +246,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0399-Add-moon-phase-API.patch b/patches/server/0398-Add-moon-phase-API.patch similarity index 100% rename from patches/server/0399-Add-moon-phase-API.patch rename to patches/server/0398-Add-moon-phase-API.patch diff --git a/patches/server/0400-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/server/0399-Do-not-let-the-server-load-chunks-from-newer-version.patch similarity index 100% rename from patches/server/0400-Do-not-let-the-server-load-chunks-from-newer-version.patch rename to patches/server/0399-Do-not-let-the-server-load-chunks-from-newer-version.patch diff --git a/patches/server/0401-Prevent-headless-pistons-from-being-created.patch b/patches/server/0400-Prevent-headless-pistons-from-being-created.patch similarity index 100% rename from patches/server/0401-Prevent-headless-pistons-from-being-created.patch rename to patches/server/0400-Prevent-headless-pistons-from-being-created.patch diff --git a/patches/server/0402-Add-BellRingEvent.patch b/patches/server/0401-Add-BellRingEvent.patch similarity index 100% rename from patches/server/0402-Add-BellRingEvent.patch rename to patches/server/0401-Add-BellRingEvent.patch diff --git a/patches/server/0403-Add-zombie-targets-turtle-egg-config.patch b/patches/server/0402-Add-zombie-targets-turtle-egg-config.patch similarity index 100% rename from patches/server/0403-Add-zombie-targets-turtle-egg-config.patch rename to patches/server/0402-Add-zombie-targets-turtle-egg-config.patch diff --git a/patches/server/0404-Buffer-joins-to-world.patch b/patches/server/0403-Buffer-joins-to-world.patch similarity index 100% rename from patches/server/0404-Buffer-joins-to-world.patch rename to patches/server/0403-Buffer-joins-to-world.patch diff --git a/patches/server/0405-Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/server/0404-Fix-hex-colors-not-working-in-some-kick-messages.patch similarity index 100% rename from patches/server/0405-Fix-hex-colors-not-working-in-some-kick-messages.patch rename to patches/server/0404-Fix-hex-colors-not-working-in-some-kick-messages.patch diff --git a/patches/server/0406-PortalCreateEvent-needs-to-know-its-entity.patch b/patches/server/0405-PortalCreateEvent-needs-to-know-its-entity.patch similarity index 100% rename from patches/server/0406-PortalCreateEvent-needs-to-know-its-entity.patch rename to patches/server/0405-PortalCreateEvent-needs-to-know-its-entity.patch diff --git a/patches/server/0407-Add-more-Evoker-API.patch b/patches/server/0406-Add-more-Evoker-API.patch similarity index 100% rename from patches/server/0407-Add-more-Evoker-API.patch rename to patches/server/0406-Add-more-Evoker-API.patch diff --git a/patches/server/0408-Add-methods-to-get-translation-keys.patch b/patches/server/0407-Add-methods-to-get-translation-keys.patch similarity index 100% rename from patches/server/0408-Add-methods-to-get-translation-keys.patch rename to patches/server/0407-Add-methods-to-get-translation-keys.patch diff --git a/patches/server/0409-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/server/0408-Create-HoverEvent-from-ItemStack-Entity.patch similarity index 100% rename from patches/server/0409-Create-HoverEvent-from-ItemStack-Entity.patch rename to patches/server/0408-Create-HoverEvent-from-ItemStack-Entity.patch diff --git a/patches/server/0410-Cache-block-data-strings.patch b/patches/server/0409-Cache-block-data-strings.patch similarity index 95% rename from patches/server/0410-Cache-block-data-strings.patch rename to patches/server/0409-Cache-block-data-strings.patch index c73022bfec..28a1635b20 100644 --- a/patches/server/0410-Cache-block-data-strings.patch +++ b/patches/server/0409-Cache-block-data-strings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Cache block data strings diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 331ed639496a73dbfdde795b6d6154a9c8ea78b4..5b7f2b2993844cbcc13742f69b0521832d1970da 100644 +index 6c9026cf224cf9dc75a5f61f1c051e640d1887ed..b9ba0033542bae48678e0321fbe0633a711291a5 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2148,6 +2148,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop cachedSingleHashSet; // Paper +@@ -294,6 +294,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { + public boolean isRealPlayer; // Paper public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support + public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event diff --git a/patches/server/0435-Add-Wandering-Trader-spawn-rate-config-options.patch b/patches/server/0434-Add-Wandering-Trader-spawn-rate-config-options.patch similarity index 100% rename from patches/server/0435-Add-Wandering-Trader-spawn-rate-config-options.patch rename to patches/server/0434-Add-Wandering-Trader-spawn-rate-config-options.patch diff --git a/patches/server/0436-Add-Destroy-Speed-API.patch b/patches/server/0435-Add-Destroy-Speed-API.patch similarity index 100% rename from patches/server/0436-Add-Destroy-Speed-API.patch rename to patches/server/0435-Add-Destroy-Speed-API.patch diff --git a/patches/server/0437-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0436-Fix-Player-spawnParticle-x-y-z-precision-loss.patch similarity index 93% rename from patches/server/0437-Fix-Player-spawnParticle-x-y-z-precision-loss.patch rename to patches/server/0436-Fix-Player-spawnParticle-x-y-z-precision-loss.patch index 83724b282d..60ac65b823 100644 --- a/patches/server/0437-Fix-Player-spawnParticle-x-y-z-precision-loss.patch +++ b/patches/server/0436-Fix-Player-spawnParticle-x-y-z-precision-loss.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix Player spawnParticle x/y/z precision loss diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 1febe581fbbc3accbf8fdbf086fba427cefdd3e9..533bb2da5ed226a31f0534f17048afa2d99e36ee 100644 +index 99799563942693ae36188092d76054fdff97d4ca..766242aa6930b37630be77e421b4b5675c5feb0d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2707,7 +2707,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0438-Add-LivingEntity-clearActiveItem.patch b/patches/server/0437-Add-LivingEntity-clearActiveItem.patch similarity index 100% rename from patches/server/0438-Add-LivingEntity-clearActiveItem.patch rename to patches/server/0437-Add-LivingEntity-clearActiveItem.patch diff --git a/patches/server/0439-Add-PlayerItemCooldownEvent.patch b/patches/server/0438-Add-PlayerItemCooldownEvent.patch similarity index 100% rename from patches/server/0439-Add-PlayerItemCooldownEvent.patch rename to patches/server/0438-Add-PlayerItemCooldownEvent.patch diff --git a/patches/server/0440-Significantly-improve-performance-of-the-end-generat.patch b/patches/server/0439-Significantly-improve-performance-of-the-end-generat.patch similarity index 100% rename from patches/server/0440-Significantly-improve-performance-of-the-end-generat.patch rename to patches/server/0439-Significantly-improve-performance-of-the-end-generat.patch diff --git a/patches/server/0441-More-lightning-API.patch b/patches/server/0440-More-lightning-API.patch similarity index 100% rename from patches/server/0441-More-lightning-API.patch rename to patches/server/0440-More-lightning-API.patch diff --git a/patches/server/0442-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0441-Climbing-should-not-bypass-cramming-gamerule.patch similarity index 100% rename from patches/server/0442-Climbing-should-not-bypass-cramming-gamerule.patch rename to patches/server/0441-Climbing-should-not-bypass-cramming-gamerule.patch diff --git a/patches/server/0443-Add-missing-default-perms-for-commands.patch b/patches/server/0442-Add-missing-default-perms-for-commands.patch similarity index 100% rename from patches/server/0443-Add-missing-default-perms-for-commands.patch rename to patches/server/0442-Add-missing-default-perms-for-commands.patch diff --git a/patches/server/0444-Add-PlayerShearBlockEvent.patch b/patches/server/0443-Add-PlayerShearBlockEvent.patch similarity index 100% rename from patches/server/0444-Add-PlayerShearBlockEvent.patch rename to patches/server/0443-Add-PlayerShearBlockEvent.patch diff --git a/patches/server/0445-Limit-recipe-packets.patch b/patches/server/0444-Limit-recipe-packets.patch similarity index 100% rename from patches/server/0445-Limit-recipe-packets.patch rename to patches/server/0444-Limit-recipe-packets.patch diff --git a/patches/server/0446-Fix-CraftSound-backwards-compatibility.patch b/patches/server/0445-Fix-CraftSound-backwards-compatibility.patch similarity index 100% rename from patches/server/0446-Fix-CraftSound-backwards-compatibility.patch rename to patches/server/0445-Fix-CraftSound-backwards-compatibility.patch diff --git a/patches/server/0447-Player-Chunk-Load-Unload-Events.patch b/patches/server/0446-Player-Chunk-Load-Unload-Events.patch similarity index 100% rename from patches/server/0447-Player-Chunk-Load-Unload-Events.patch rename to patches/server/0446-Player-Chunk-Load-Unload-Events.patch diff --git a/patches/server/0448-Optimize-Dynamic-get-Missing-Keys.patch b/patches/server/0447-Optimize-Dynamic-get-Missing-Keys.patch similarity index 100% rename from patches/server/0448-Optimize-Dynamic-get-Missing-Keys.patch rename to patches/server/0447-Optimize-Dynamic-get-Missing-Keys.patch diff --git a/patches/server/0449-Expose-LivingEntity-hurt-direction.patch b/patches/server/0448-Expose-LivingEntity-hurt-direction.patch similarity index 100% rename from patches/server/0449-Expose-LivingEntity-hurt-direction.patch rename to patches/server/0448-Expose-LivingEntity-hurt-direction.patch diff --git a/patches/server/0450-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/server/0449-Add-OBSTRUCTED-reason-to-BedEnterResult.patch similarity index 100% rename from patches/server/0450-Add-OBSTRUCTED-reason-to-BedEnterResult.patch rename to patches/server/0449-Add-OBSTRUCTED-reason-to-BedEnterResult.patch diff --git a/patches/server/0451-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch b/patches/server/0450-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch similarity index 100% rename from patches/server/0451-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch rename to patches/server/0450-Fix-crash-from-invalid-ingredient-lists-in-VillagerA.patch diff --git a/patches/server/0452-Add-TargetHitEvent.patch b/patches/server/0451-Add-TargetHitEvent.patch similarity index 100% rename from patches/server/0452-Add-TargetHitEvent.patch rename to patches/server/0451-Add-TargetHitEvent.patch diff --git a/patches/server/0453-MC-4-Fix-item-position-desync.patch b/patches/server/0452-MC-4-Fix-item-position-desync.patch similarity index 100% rename from patches/server/0453-MC-4-Fix-item-position-desync.patch rename to patches/server/0452-MC-4-Fix-item-position-desync.patch diff --git a/patches/server/0454-Additional-Block-Material-API.patch b/patches/server/0453-Additional-Block-Material-API.patch similarity index 100% rename from patches/server/0454-Additional-Block-Material-API.patch rename to patches/server/0453-Additional-Block-Material-API.patch diff --git a/patches/server/0455-Fix-harming-potion-dupe.patch b/patches/server/0454-Fix-harming-potion-dupe.patch similarity index 100% rename from patches/server/0455-Fix-harming-potion-dupe.patch rename to patches/server/0454-Fix-harming-potion-dupe.patch diff --git a/patches/server/0456-API-to-get-Material-from-Boats-and-Minecarts.patch b/patches/server/0455-API-to-get-Material-from-Boats-and-Minecarts.patch similarity index 100% rename from patches/server/0456-API-to-get-Material-from-Boats-and-Minecarts.patch rename to patches/server/0455-API-to-get-Material-from-Boats-and-Minecarts.patch diff --git a/patches/server/0457-Allow-disabling-mob-spawner-spawn-egg-transformation.patch b/patches/server/0456-Allow-disabling-mob-spawner-spawn-egg-transformation.patch similarity index 100% rename from patches/server/0457-Allow-disabling-mob-spawner-spawn-egg-transformation.patch rename to patches/server/0456-Allow-disabling-mob-spawner-spawn-egg-transformation.patch diff --git a/patches/server/0458-Fix-Not-a-string-Map-Conversion-spam.patch b/patches/server/0457-Fix-Not-a-string-Map-Conversion-spam.patch similarity index 100% rename from patches/server/0458-Fix-Not-a-string-Map-Conversion-spam.patch rename to patches/server/0457-Fix-Not-a-string-Map-Conversion-spam.patch diff --git a/patches/server/0459-Add-PlayerFlowerPotManipulateEvent.patch b/patches/server/0458-Add-PlayerFlowerPotManipulateEvent.patch similarity index 100% rename from patches/server/0459-Add-PlayerFlowerPotManipulateEvent.patch rename to patches/server/0458-Add-PlayerFlowerPotManipulateEvent.patch diff --git a/patches/server/0460-Fix-interact-event-not-being-called-sometimes.patch b/patches/server/0459-Fix-interact-event-not-being-called-sometimes.patch similarity index 100% rename from patches/server/0460-Fix-interact-event-not-being-called-sometimes.patch rename to patches/server/0459-Fix-interact-event-not-being-called-sometimes.patch diff --git a/patches/server/0461-Zombie-API-breaking-doors.patch b/patches/server/0460-Zombie-API-breaking-doors.patch similarity index 100% rename from patches/server/0461-Zombie-API-breaking-doors.patch rename to patches/server/0460-Zombie-API-breaking-doors.patch diff --git a/patches/server/0462-Fix-nerfed-slime-when-splitting.patch b/patches/server/0461-Fix-nerfed-slime-when-splitting.patch similarity index 100% rename from patches/server/0462-Fix-nerfed-slime-when-splitting.patch rename to patches/server/0461-Fix-nerfed-slime-when-splitting.patch diff --git a/patches/server/0463-Add-EntityLoadCrossbowEvent.patch b/patches/server/0462-Add-EntityLoadCrossbowEvent.patch similarity index 100% rename from patches/server/0463-Add-EntityLoadCrossbowEvent.patch rename to patches/server/0462-Add-EntityLoadCrossbowEvent.patch diff --git a/patches/server/0464-Add-WorldGameRuleChangeEvent.patch b/patches/server/0463-Add-WorldGameRuleChangeEvent.patch similarity index 98% rename from patches/server/0464-Add-WorldGameRuleChangeEvent.patch rename to patches/server/0463-Add-WorldGameRuleChangeEvent.patch index 40dab3d535..737b50a1b8 100644 --- a/patches/server/0464-Add-WorldGameRuleChangeEvent.patch +++ b/patches/server/0463-Add-WorldGameRuleChangeEvent.patch @@ -64,7 +64,7 @@ index 0b46ad360be919e4aeb0ffc0eebae9fe712fb861..51e560d7856f230c5aa2dc32706c3a49 public int get() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 009be0baf925245ff8fa3d849f4233fb952f881e..c1125b0db7449a6d61e7b0a4e7c5d30917744b5d 100644 +index 5ae307f9343ffea39c286992459a6c8069d9fb86..08124dd65d1f950bdec8fcb55d2553c601b30a66 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1885,8 +1885,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0465-Add-ServerResourcesReloadedEvent.patch b/patches/server/0464-Add-ServerResourcesReloadedEvent.patch similarity index 94% rename from patches/server/0465-Add-ServerResourcesReloadedEvent.patch rename to patches/server/0464-Add-ServerResourcesReloadedEvent.patch index bfc98bc7e5..8996d46e70 100644 --- a/patches/server/0465-Add-ServerResourcesReloadedEvent.patch +++ b/patches/server/0464-Add-ServerResourcesReloadedEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add ServerResourcesReloadedEvent diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index e39cfc9750bf1d3f20abb3a2e9d46fa51ccdc248..3511b578f137c94ed562690901952e81e6f90ee5 100644 +index 055172644d6a3c30b512262fcba940610161b8d7..84028b8ad189407f89fbdd63d3e185c86335b596 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2117,7 +2117,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop completablefuture = CompletableFuture.supplyAsync(() -> { Stream stream = dataPacks.stream(); // CraftBukkit - decompile error PackRepository resourcepackrepository = this.packRepository; -@@ -2149,6 +2155,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent @@ -17,7 +17,7 @@ index 3511b578f137c94ed562690901952e81e6f90ee5..93c92146c2c7961a5de970e1c18eb7a1 this.profiler.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index deabbf30a550ff1835530257177b8f47e4710414..6b2d00878a373680bc3d59e19ae11a2d545146cc 100644 +index 373560fc82e491e6c8b755fecfe78d49a2fc3e2f..644341b8bc3079c6f092226acd11667f64bd55a1 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -228,6 +228,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0490-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/server/0489-added-option-to-disable-pathfinding-updates-on-block.patch similarity index 92% rename from patches/server/0490-added-option-to-disable-pathfinding-updates-on-block.patch rename to patches/server/0489-added-option-to-disable-pathfinding-updates-on-block.patch index dd30ec31b5..e40ef31e16 100644 --- a/patches/server/0490-added-option-to-disable-pathfinding-updates-on-block.patch +++ b/patches/server/0489-added-option-to-disable-pathfinding-updates-on-block.patch @@ -5,7 +5,7 @@ Subject: [PATCH] added option to disable pathfinding updates on block changes diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 6b2d00878a373680bc3d59e19ae11a2d545146cc..58c56636f324f1073bbb03d94f51cd69600a80c4 100644 +index 644341b8bc3079c6f092226acd11667f64bd55a1..1fe013b94cf1b5332f1e4645dd35df01e11fe0d9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1374,6 +1374,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0491-Inline-shift-direction-fields.patch b/patches/server/0490-Inline-shift-direction-fields.patch similarity index 100% rename from patches/server/0491-Inline-shift-direction-fields.patch rename to patches/server/0490-Inline-shift-direction-fields.patch diff --git a/patches/server/0492-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/server/0491-Allow-adding-items-to-BlockDropItemEvent.patch similarity index 100% rename from patches/server/0492-Allow-adding-items-to-BlockDropItemEvent.patch rename to patches/server/0491-Allow-adding-items-to-BlockDropItemEvent.patch diff --git a/patches/server/0493-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/server/0492-Add-getMainThreadExecutor-to-BukkitScheduler.patch similarity index 100% rename from patches/server/0493-Add-getMainThreadExecutor-to-BukkitScheduler.patch rename to patches/server/0492-Add-getMainThreadExecutor-to-BukkitScheduler.patch diff --git a/patches/server/0494-living-entity-allow-attribute-registration.patch b/patches/server/0493-living-entity-allow-attribute-registration.patch similarity index 100% rename from patches/server/0494-living-entity-allow-attribute-registration.patch rename to patches/server/0493-living-entity-allow-attribute-registration.patch diff --git a/patches/server/0495-fix-dead-slime-setSize-invincibility.patch b/patches/server/0494-fix-dead-slime-setSize-invincibility.patch similarity index 100% rename from patches/server/0495-fix-dead-slime-setSize-invincibility.patch rename to patches/server/0494-fix-dead-slime-setSize-invincibility.patch diff --git a/patches/server/0496-Merchant-getRecipes-should-return-an-immutable-list.patch b/patches/server/0495-Merchant-getRecipes-should-return-an-immutable-list.patch similarity index 100% rename from patches/server/0496-Merchant-getRecipes-should-return-an-immutable-list.patch rename to patches/server/0495-Merchant-getRecipes-should-return-an-immutable-list.patch diff --git a/patches/server/0497-Expose-Tracked-Players.patch b/patches/server/0496-Expose-Tracked-Players.patch similarity index 100% rename from patches/server/0497-Expose-Tracked-Players.patch rename to patches/server/0496-Expose-Tracked-Players.patch diff --git a/patches/server/0498-Improve-ServerGUI.patch b/patches/server/0497-Improve-ServerGUI.patch similarity index 100% rename from patches/server/0498-Improve-ServerGUI.patch rename to patches/server/0497-Improve-ServerGUI.patch diff --git a/patches/server/0499-fix-converting-txt-to-json-file.patch b/patches/server/0498-fix-converting-txt-to-json-file.patch similarity index 100% rename from patches/server/0499-fix-converting-txt-to-json-file.patch rename to patches/server/0498-fix-converting-txt-to-json-file.patch diff --git a/patches/server/0500-Add-worldborder-events.patch b/patches/server/0499-Add-worldborder-events.patch similarity index 100% rename from patches/server/0500-Add-worldborder-events.patch rename to patches/server/0499-Add-worldborder-events.patch diff --git a/patches/server/0501-Add-PlayerNameEntityEvent.patch b/patches/server/0500-Add-PlayerNameEntityEvent.patch similarity index 100% rename from patches/server/0501-Add-PlayerNameEntityEvent.patch rename to patches/server/0500-Add-PlayerNameEntityEvent.patch diff --git a/patches/server/0502-Add-recipe-to-cook-events.patch b/patches/server/0501-Add-recipe-to-cook-events.patch similarity index 100% rename from patches/server/0502-Add-recipe-to-cook-events.patch rename to patches/server/0501-Add-recipe-to-cook-events.patch diff --git a/patches/server/0503-Add-Block-isValidTool.patch b/patches/server/0502-Add-Block-isValidTool.patch similarity index 100% rename from patches/server/0503-Add-Block-isValidTool.patch rename to patches/server/0502-Add-Block-isValidTool.patch diff --git a/patches/server/0504-Allow-using-signs-inside-spawn-protection.patch b/patches/server/0503-Allow-using-signs-inside-spawn-protection.patch similarity index 100% rename from patches/server/0504-Allow-using-signs-inside-spawn-protection.patch rename to patches/server/0503-Allow-using-signs-inside-spawn-protection.patch diff --git a/patches/server/0505-Expand-world-key-API.patch b/patches/server/0504-Expand-world-key-API.patch similarity index 100% rename from patches/server/0505-Expand-world-key-API.patch rename to patches/server/0504-Expand-world-key-API.patch diff --git a/patches/server/0506-Add-fast-alternative-constructor-for-Rotations.patch b/patches/server/0505-Add-fast-alternative-constructor-for-Rotations.patch similarity index 100% rename from patches/server/0506-Add-fast-alternative-constructor-for-Rotations.patch rename to patches/server/0505-Add-fast-alternative-constructor-for-Rotations.patch diff --git a/patches/server/0507-Drop-carried-item-when-player-has-disconnected.patch b/patches/server/0506-Drop-carried-item-when-player-has-disconnected.patch similarity index 100% rename from patches/server/0507-Drop-carried-item-when-player-has-disconnected.patch rename to patches/server/0506-Drop-carried-item-when-player-has-disconnected.patch diff --git a/patches/server/0508-forced-whitelist-use-configurable-kick-message.patch b/patches/server/0507-forced-whitelist-use-configurable-kick-message.patch similarity index 87% rename from patches/server/0508-forced-whitelist-use-configurable-kick-message.patch rename to patches/server/0507-forced-whitelist-use-configurable-kick-message.patch index a4cd1362fc..4ec0ee6b72 100644 --- a/patches/server/0508-forced-whitelist-use-configurable-kick-message.patch +++ b/patches/server/0507-forced-whitelist-use-configurable-kick-message.patch @@ -5,10 +5,10 @@ Subject: [PATCH] forced whitelist: use configurable kick message diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 93c92146c2c7961a5de970e1c18eb7a1907c551b..84bc3fac67c8db28a7102f99bffe762cf34a4a7a 100644 +index d38cc3e642eb33759175227fbf86ed250cf0b9f3..e02e57d243bc8bccddcf3e3c40887fb774f5e460 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2289,7 +2289,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 0f5c34ad7b983b9ea4e994145142457033a8c997..bd1abd4ad5dc129df4c844571c9a91e7cc1748d9 100644 +index 685601f7ae8396524be6acc1b1394a2403ac6163..3e2a623bda0a65b78cdd725feb4581ded6ec07fe 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1197,7 +1197,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1194,7 +1194,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { Player respawnPlayer = this.getBukkitEntity(); Location location = CraftLocation.toBukkit(dimensionTransition.pos(), dimensionTransition.newLevel().getWorld(), dimensionTransition.yRot(), dimensionTransition.xRot()); diff --git a/patches/server/0525-Introduce-beacon-activation-deactivation-events.patch b/patches/server/0524-Introduce-beacon-activation-deactivation-events.patch similarity index 100% rename from patches/server/0525-Introduce-beacon-activation-deactivation-events.patch rename to patches/server/0524-Introduce-beacon-activation-deactivation-events.patch diff --git a/patches/server/0526-Add-Channel-initialization-listeners.patch b/patches/server/0525-Add-Channel-initialization-listeners.patch similarity index 100% rename from patches/server/0526-Add-Channel-initialization-listeners.patch rename to patches/server/0525-Add-Channel-initialization-listeners.patch diff --git a/patches/server/0527-Send-empty-commands-if-tab-completion-is-disabled.patch b/patches/server/0526-Send-empty-commands-if-tab-completion-is-disabled.patch similarity index 100% rename from patches/server/0527-Send-empty-commands-if-tab-completion-is-disabled.patch rename to patches/server/0526-Send-empty-commands-if-tab-completion-is-disabled.patch diff --git a/patches/server/0528-Add-more-WanderingTrader-API.patch b/patches/server/0527-Add-more-WanderingTrader-API.patch similarity index 100% rename from patches/server/0528-Add-more-WanderingTrader-API.patch rename to patches/server/0527-Add-more-WanderingTrader-API.patch diff --git a/patches/server/0529-Add-EntityBlockStorage-clearEntities.patch b/patches/server/0528-Add-EntityBlockStorage-clearEntities.patch similarity index 94% rename from patches/server/0529-Add-EntityBlockStorage-clearEntities.patch rename to patches/server/0528-Add-EntityBlockStorage-clearEntities.patch index e52d1c5e1c..b19812d989 100644 --- a/patches/server/0529-Add-EntityBlockStorage-clearEntities.patch +++ b/patches/server/0528-Add-EntityBlockStorage-clearEntities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add EntityBlockStorage#clearEntities() diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index 344b18127d3e8c7408a162cc85287382bdfdda9a..b18494d2a83473e9bc4197f86ff599de59043217 100644 +index b345403cdf5b2828f99708fef65136594a3331c3..ef8a0236ab4fb648c4bb2a8cfc90e3cefe8f9f1d 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java @@ -151,6 +151,11 @@ public class BeehiveBlockEntity extends BlockEntity { diff --git a/patches/server/0530-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch b/patches/server/0529-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch similarity index 100% rename from patches/server/0530-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch rename to patches/server/0529-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch diff --git a/patches/server/0531-Add-HiddenPotionEffect-API.patch b/patches/server/0530-Add-HiddenPotionEffect-API.patch similarity index 100% rename from patches/server/0531-Add-HiddenPotionEffect-API.patch rename to patches/server/0530-Add-HiddenPotionEffect-API.patch diff --git a/patches/server/0532-Inventory-close.patch b/patches/server/0531-Inventory-close.patch similarity index 100% rename from patches/server/0532-Inventory-close.patch rename to patches/server/0531-Inventory-close.patch diff --git a/patches/server/0533-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch b/patches/server/0532-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch similarity index 100% rename from patches/server/0533-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch rename to patches/server/0532-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch diff --git a/patches/server/0534-Add-basic-Datapack-API.patch b/patches/server/0533-Add-basic-Datapack-API.patch similarity index 100% rename from patches/server/0534-Add-basic-Datapack-API.patch rename to patches/server/0533-Add-basic-Datapack-API.patch diff --git a/patches/server/0535-Add-environment-variable-to-disable-server-gui.patch b/patches/server/0534-Add-environment-variable-to-disable-server-gui.patch similarity index 100% rename from patches/server/0535-Add-environment-variable-to-disable-server-gui.patch rename to patches/server/0534-Add-environment-variable-to-disable-server-gui.patch diff --git a/patches/server/0536-Expand-PlayerGameModeChangeEvent.patch b/patches/server/0535-Expand-PlayerGameModeChangeEvent.patch similarity index 96% rename from patches/server/0536-Expand-PlayerGameModeChangeEvent.patch rename to patches/server/0535-Expand-PlayerGameModeChangeEvent.patch index 98696ab8cc..67e3856a2e 100644 --- a/patches/server/0536-Expand-PlayerGameModeChangeEvent.patch +++ b/patches/server/0535-Expand-PlayerGameModeChangeEvent.patch @@ -45,10 +45,10 @@ index 7f09119bc7d661e08a960dd2bd46006efe752d3e..d1da3600dc07107309b20ebe6e7c0c4d } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 47259d580460fd00c6c7a4e798e28667f333ca9c..205d0f5bc3da737f960fb0e795b959e611e48422 100644 +index 3e2a623bda0a65b78cdd725feb4581ded6ec07fe..9e9ef3c8e7316fc9d35672ff2a4eb1795c333279 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -2087,10 +2087,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2084,10 +2084,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public boolean setGameMode(GameType gameMode) { @@ -69,7 +69,7 @@ index 47259d580460fd00c6c7a4e798e28667f333ca9c..205d0f5bc3da737f960fb0e795b959e6 } else { this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId())); if (gameMode == GameType.SPECTATOR) { -@@ -2106,7 +2114,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2103,7 +2111,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.onUpdateAbilities(); this.updateEffectVisibility(); @@ -78,7 +78,7 @@ index 47259d580460fd00c6c7a4e798e28667f333ca9c..205d0f5bc3da737f960fb0e795b959e6 } } -@@ -2512,6 +2520,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2509,6 +2517,16 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } public void loadGameTypes(@Nullable CompoundTag nbt) { @@ -147,7 +147,7 @@ index 699658bd80eb88907041efb01d31e4051edb91de..58e5acbd00c4f8c0fcafa4f2c21b6a9f } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index b2e5bf420d0d8e3f635632d91faf15e10f1988f6..00ccb9ae0d41ba87db2617853206d714a4225563 100644 +index 7652da85170cd5a64d1b443430b85c388e2939a9..6aa9a31b2bba086265c0e83c4ea9181540a0a5f6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1654,7 +1654,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0537-ItemStack-repair-check-API.patch b/patches/server/0536-ItemStack-repair-check-API.patch similarity index 100% rename from patches/server/0537-ItemStack-repair-check-API.patch rename to patches/server/0536-ItemStack-repair-check-API.patch diff --git a/patches/server/0538-More-Enchantment-API.patch b/patches/server/0537-More-Enchantment-API.patch similarity index 100% rename from patches/server/0538-More-Enchantment-API.patch rename to patches/server/0537-More-Enchantment-API.patch diff --git a/patches/server/0539-Move-range-check-for-block-placing-up.patch b/patches/server/0538-Move-range-check-for-block-placing-up.patch similarity index 100% rename from patches/server/0539-Move-range-check-for-block-placing-up.patch rename to patches/server/0538-Move-range-check-for-block-placing-up.patch diff --git a/patches/server/0540-Add-Mob-lookAt-API.patch b/patches/server/0539-Add-Mob-lookAt-API.patch similarity index 100% rename from patches/server/0540-Add-Mob-lookAt-API.patch rename to patches/server/0539-Add-Mob-lookAt-API.patch diff --git a/patches/server/0541-Correctly-check-if-bucket-dispenses-will-succeed-for.patch b/patches/server/0540-Correctly-check-if-bucket-dispenses-will-succeed-for.patch similarity index 100% rename from patches/server/0541-Correctly-check-if-bucket-dispenses-will-succeed-for.patch rename to patches/server/0540-Correctly-check-if-bucket-dispenses-will-succeed-for.patch diff --git a/patches/server/0542-Add-Unix-domain-socket-support.patch b/patches/server/0541-Add-Unix-domain-socket-support.patch similarity index 100% rename from patches/server/0542-Add-Unix-domain-socket-support.patch rename to patches/server/0541-Add-Unix-domain-socket-support.patch diff --git a/patches/server/0543-Add-EntityInsideBlockEvent.patch b/patches/server/0542-Add-EntityInsideBlockEvent.patch similarity index 99% rename from patches/server/0543-Add-EntityInsideBlockEvent.patch rename to patches/server/0542-Add-EntityInsideBlockEvent.patch index 912a0dbe33..5080baf21f 100644 --- a/patches/server/0543-Add-EntityInsideBlockEvent.patch +++ b/patches/server/0542-Add-EntityInsideBlockEvent.patch @@ -137,7 +137,7 @@ index e2d6693da4abe6204c0ecb5e924a3903fa80ab7d..cff3e9869340f1ffb7093431cbe1ac5e // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ())); diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -index 211b7809f099678bc3bd64bd29fd9c4d19e3ab0d..6e7595193275e88c69b82ebbc9f9df636879a03e 100644 +index b968129b9a93fdf771caba5f768456070543ba6a..669234bca9fa50548447f77dc5f314df8d9dd7c9 100644 --- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java @@ -79,6 +79,7 @@ public class FrogspawnBlock extends Block { diff --git a/patches/server/0544-Improve-item-default-attribute-API.patch b/patches/server/0543-Improve-item-default-attribute-API.patch similarity index 100% rename from patches/server/0544-Improve-item-default-attribute-API.patch rename to patches/server/0543-Improve-item-default-attribute-API.patch diff --git a/patches/server/0545-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/0544-Add-cause-to-Weather-ThunderChangeEvents.patch similarity index 97% rename from patches/server/0545-Add-cause-to-Weather-ThunderChangeEvents.patch rename to patches/server/0544-Add-cause-to-Weather-ThunderChangeEvents.patch index 6fddf161d3..2807ad861f 100644 --- a/patches/server/0545-Add-cause-to-Weather-ThunderChangeEvents.patch +++ b/patches/server/0544-Add-cause-to-Weather-ThunderChangeEvents.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add cause to Weather/ThunderChangeEvents diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 58c56636f324f1073bbb03d94f51cd69600a80c4..9a09946b6b178837c44daae894555000668aeb72 100644 +index 1fe013b94cf1b5332f1e4645dd35df01e11fe0d9..055650b315d53b56798ded7af2054c3e8e3ee319 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -441,8 +441,8 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -95,7 +95,7 @@ index e50ad48658193f889d65d37c57b1e30ce46758b7..efd0bcfebb3b4f63018d4e20a6a89f79 if (weather.isCancelled()) { return; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index a197e6993842a1e43311ad9c1fae2f18f799e44b..862a83b421b77b7126efa455e5f7ba9c744f59f5 100644 +index c3581aa9a2d708e410c7eae1b7abe6c6f3427ad6..dc16ed952719a5203b1b9a61e0ad2bd39021e8f1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1208,7 +1208,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0546-More-Lidded-Block-API.patch b/patches/server/0545-More-Lidded-Block-API.patch similarity index 100% rename from patches/server/0546-More-Lidded-Block-API.patch rename to patches/server/0545-More-Lidded-Block-API.patch diff --git a/patches/server/0547-Limit-item-frame-cursors-on-maps.patch b/patches/server/0546-Limit-item-frame-cursors-on-maps.patch similarity index 100% rename from patches/server/0547-Limit-item-frame-cursors-on-maps.patch rename to patches/server/0546-Limit-item-frame-cursors-on-maps.patch diff --git a/patches/server/0548-Add-PlayerKickEvent-causes.patch b/patches/server/0547-Add-PlayerKickEvent-causes.patch similarity index 99% rename from patches/server/0548-Add-PlayerKickEvent-causes.patch rename to patches/server/0547-Add-PlayerKickEvent-causes.patch index 5cb94d101b..d5a0964872 100644 --- a/patches/server/0548-Add-PlayerKickEvent-causes.patch +++ b/patches/server/0547-Add-PlayerKickEvent-causes.patch @@ -43,10 +43,10 @@ index dbcf183483766f39334d7f7e8336033906625f3f..300929a406905f5ff1ede664d5b99fb0 } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 84bc3fac67c8db28a7102f99bffe762cf34a4a7a..695d6265b4a9f98ba630593ba6c47769240bed93 100644 +index e02e57d243bc8bccddcf3e3c40887fb774f5e460..6ad7c34513034c87059f8a0790aea3231dd0d2a9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2289,7 +2289,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Co-authored-by: TotalledZebra diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -index 3f8cca8027051694cb0440373e75f418f73edf87..06455d65c4605ce092bf5300d432087f24186741 100644 +index c99eafab2103c7f5bca7ffba68a10bd853df055f..f7241c5292f1c012404eea11256813fbc2c2df1a 100644 --- a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java -@@ -165,7 +165,7 @@ public class MobGoalHelper { +@@ -164,7 +164,7 @@ public class MobGoalHelper { bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); bukkitMap.put(AbstractFish.class, Fish.class); diff --git a/patches/server/0563-Fix-return-value-of-Block-applyBoneMeal-always-being.patch b/patches/server/0562-Fix-return-value-of-Block-applyBoneMeal-always-being.patch similarity index 100% rename from patches/server/0563-Fix-return-value-of-Block-applyBoneMeal-always-being.patch rename to patches/server/0562-Fix-return-value-of-Block-applyBoneMeal-always-being.patch diff --git a/patches/server/0564-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/0563-Use-getChunkIfLoadedImmediately-in-places.patch similarity index 97% rename from patches/server/0564-Use-getChunkIfLoadedImmediately-in-places.patch rename to patches/server/0563-Use-getChunkIfLoadedImmediately-in-places.patch index 0cfa5936f9..0fb834902a 100644 --- a/patches/server/0564-Use-getChunkIfLoadedImmediately-in-places.patch +++ b/patches/server/0563-Use-getChunkIfLoadedImmediately-in-places.patch @@ -8,7 +8,7 @@ ticket level 33 (yes getChunkIfLoaded will actually perform a chunk load in that case). diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 9a09946b6b178837c44daae894555000668aeb72..8c268f57d44d70df3210510abf7832939d41781d 100644 +index 055650b315d53b56798ded7af2054c3e8e3ee319..c72687fb23e8d01639cce7d79e3f97805d51e01f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -231,7 +231,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0565-Fix-commands-from-signs-not-firing-command-events.patch b/patches/server/0564-Fix-commands-from-signs-not-firing-command-events.patch similarity index 100% rename from patches/server/0565-Fix-commands-from-signs-not-firing-command-events.patch rename to patches/server/0564-Fix-commands-from-signs-not-firing-command-events.patch diff --git a/patches/server/0566-Add-PlayerArmSwingEvent.patch b/patches/server/0565-Add-PlayerArmSwingEvent.patch similarity index 100% rename from patches/server/0566-Add-PlayerArmSwingEvent.patch rename to patches/server/0565-Add-PlayerArmSwingEvent.patch diff --git a/patches/server/0567-Fix-kick-event-leave-message-not-being-sent.patch b/patches/server/0566-Fix-kick-event-leave-message-not-being-sent.patch similarity index 96% rename from patches/server/0567-Fix-kick-event-leave-message-not-being-sent.patch rename to patches/server/0566-Fix-kick-event-leave-message-not-being-sent.patch index 3d2effd695..9c15380b00 100644 --- a/patches/server/0567-Fix-kick-event-leave-message-not-being-sent.patch +++ b/patches/server/0566-Fix-kick-event-leave-message-not-being-sent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix kick event leave message not being sent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index d413c4d445f42f6a923a49ce4f04b13c3ee28f7a..698fe3042670cee5495ab96f475d36c5b837593e 100644 +index e3b8c14bdf674663152936df4d1469e91545d640..36dddec9ddb025790577bdb6b6b21d84bb9d1020 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -289,7 +289,6 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @@ -15,7 +15,7 @@ index d413c4d445f42f6a923a49ce4f04b13c3ee28f7a..698fe3042670cee5495ab96f475d36c5 - public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent // CraftBukkit end public boolean isRealPlayer; // Paper - public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index feb529adf2168025c785ab92d95a3246e73c0236..b43f87ff4b9853b5d4bbea5ff9686d64d9d0d26b 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java diff --git a/patches/server/0568-Don-t-apply-cramming-damage-to-players.patch b/patches/server/0567-Don-t-apply-cramming-damage-to-players.patch similarity index 90% rename from patches/server/0568-Don-t-apply-cramming-damage-to-players.patch rename to patches/server/0567-Don-t-apply-cramming-damage-to-players.patch index 5176f24655..f722e5492c 100644 --- a/patches/server/0568-Don-t-apply-cramming-damage-to-players.patch +++ b/patches/server/0567-Don-t-apply-cramming-damage-to-players.patch @@ -11,7 +11,7 @@ It does not make a lot of sense to damage players if they get crammed, For those who really want it a config option is provided. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 698fe3042670cee5495ab96f475d36c5b837593e..967a61aa38f5361e5fceb8b7761664cb36cf568e 100644 +index 36dddec9ddb025790577bdb6b6b21d84bb9d1020..bcb5eac701749516928d9772ca906c51ebab9b34 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -95,6 +95,7 @@ import net.minecraft.util.Mth; @@ -22,7 +22,7 @@ index 698fe3042670cee5495ab96f475d36c5b837593e..967a61aa38f5361e5fceb8b7761664cb import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; -@@ -1548,7 +1549,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1545,7 +1546,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { @Override public boolean isInvulnerableTo(DamageSource damageSource) { diff --git a/patches/server/0569-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/0568-Rate-options-and-timings-for-sensors-and-behaviors.patch similarity index 100% rename from patches/server/0569-Rate-options-and-timings-for-sensors-and-behaviors.patch rename to patches/server/0568-Rate-options-and-timings-for-sensors-and-behaviors.patch diff --git a/patches/server/0570-Add-missing-forceDrop-toggles.patch b/patches/server/0569-Add-missing-forceDrop-toggles.patch similarity index 100% rename from patches/server/0570-Add-missing-forceDrop-toggles.patch rename to patches/server/0569-Add-missing-forceDrop-toggles.patch diff --git a/patches/server/0571-Stinger-API.patch b/patches/server/0570-Stinger-API.patch similarity index 100% rename from patches/server/0571-Stinger-API.patch rename to patches/server/0570-Stinger-API.patch diff --git a/patches/server/0572-Add-System.out-err-catcher.patch b/patches/server/0571-Add-System.out-err-catcher.patch similarity index 100% rename from patches/server/0572-Add-System.out-err-catcher.patch rename to patches/server/0571-Add-System.out-err-catcher.patch diff --git a/patches/server/0573-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/0572-Prevent-AFK-kick-while-watching-end-credits.patch similarity index 100% rename from patches/server/0573-Prevent-AFK-kick-while-watching-end-credits.patch rename to patches/server/0572-Prevent-AFK-kick-while-watching-end-credits.patch diff --git a/patches/server/0574-Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/server/0573-Allow-skipping-writing-of-comments-to-server.propert.patch similarity index 100% rename from patches/server/0574-Allow-skipping-writing-of-comments-to-server.propert.patch rename to patches/server/0573-Allow-skipping-writing-of-comments-to-server.propert.patch diff --git a/patches/server/0575-Add-PlayerSetSpawnEvent.patch b/patches/server/0574-Add-PlayerSetSpawnEvent.patch similarity index 97% rename from patches/server/0575-Add-PlayerSetSpawnEvent.patch rename to patches/server/0574-Add-PlayerSetSpawnEvent.patch index cc76cab591..511f5579a9 100644 --- a/patches/server/0575-Add-PlayerSetSpawnEvent.patch +++ b/patches/server/0574-Add-PlayerSetSpawnEvent.patch @@ -49,10 +49,10 @@ index a2d0699e8427b2262a2396495111125eccafbb66..15db9368227dbc29d07d74e85bd126b3 } } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 2e9cf68e7e58cffa296bb60ddb97639662b2ab5c..fdf73f71ca34099081f9f80994bbe411052c0149 100644 +index bcb5eac701749516928d9772ca906c51ebab9b34..882dae91f9db702edd233f7cab9f95e9874d1270 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1425,7 +1425,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1422,7 +1422,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else if (this.bedBlocked(blockposition, enumdirection)) { return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.OBSTRUCTED); } else { @@ -61,7 +61,7 @@ index 2e9cf68e7e58cffa296bb60ddb97639662b2ab5c..fdf73f71ca34099081f9f80994bbe411 if (this.level().isDay()) { return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_POSSIBLE_NOW); } else { -@@ -2402,44 +2402,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2399,44 +2399,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false); } @@ -145,7 +145,7 @@ index 2e9cf68e7e58cffa296bb60ddb97639662b2ab5c..fdf73f71ca34099081f9f80994bbe411 } else { this.respawnPosition = null; this.respawnDimension = Level.OVERWORLD; -@@ -2447,6 +2453,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -2444,6 +2450,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.respawnForced = false; } @@ -187,7 +187,7 @@ index ba22ad1e4253477572d10d71db6db0ebc14d6755..94d067e9eeee73183de25165d8c97043 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ddd5bdf07f92f18ad27b34ce63a98a61f8263733..d58e7197da3c4b35b28c2f427e9539c3f1df13b8 100644 +index 8f78f4879dfc46d2214243b927e0cff0257b7692..395d5b5378e122c820fd4632180cf4f859e1f502 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1413,9 +1413,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0576-Make-hoppers-respect-inventory-max-stack-size.patch b/patches/server/0575-Make-hoppers-respect-inventory-max-stack-size.patch similarity index 100% rename from patches/server/0576-Make-hoppers-respect-inventory-max-stack-size.patch rename to patches/server/0575-Make-hoppers-respect-inventory-max-stack-size.patch diff --git a/patches/server/0577-Optimize-entity-tracker-passenger-checks.patch b/patches/server/0576-Optimize-entity-tracker-passenger-checks.patch similarity index 100% rename from patches/server/0577-Optimize-entity-tracker-passenger-checks.patch rename to patches/server/0576-Optimize-entity-tracker-passenger-checks.patch diff --git a/patches/server/0578-Config-option-for-Piglins-guarding-chests.patch b/patches/server/0577-Config-option-for-Piglins-guarding-chests.patch similarity index 100% rename from patches/server/0578-Config-option-for-Piglins-guarding-chests.patch rename to patches/server/0577-Config-option-for-Piglins-guarding-chests.patch diff --git a/patches/server/0579-Add-EntityDamageItemEvent.patch b/patches/server/0578-Add-EntityDamageItemEvent.patch similarity index 100% rename from patches/server/0579-Add-EntityDamageItemEvent.patch rename to patches/server/0578-Add-EntityDamageItemEvent.patch diff --git a/patches/server/0580-Optimize-indirect-passenger-iteration.patch b/patches/server/0579-Optimize-indirect-passenger-iteration.patch similarity index 100% rename from patches/server/0580-Optimize-indirect-passenger-iteration.patch rename to patches/server/0579-Optimize-indirect-passenger-iteration.patch diff --git a/patches/server/0581-Configurable-item-frame-map-cursor-update-interval.patch b/patches/server/0580-Configurable-item-frame-map-cursor-update-interval.patch similarity index 100% rename from patches/server/0581-Configurable-item-frame-map-cursor-update-interval.patch rename to patches/server/0580-Configurable-item-frame-map-cursor-update-interval.patch diff --git a/patches/server/0582-Change-EnderEye-target-without-changing-other-things.patch b/patches/server/0581-Change-EnderEye-target-without-changing-other-things.patch similarity index 100% rename from patches/server/0582-Change-EnderEye-target-without-changing-other-things.patch rename to patches/server/0581-Change-EnderEye-target-without-changing-other-things.patch diff --git a/patches/server/0583-Add-BlockBreakBlockEvent.patch b/patches/server/0582-Add-BlockBreakBlockEvent.patch similarity index 100% rename from patches/server/0583-Add-BlockBreakBlockEvent.patch rename to patches/server/0582-Add-BlockBreakBlockEvent.patch diff --git a/patches/server/0584-Option-to-prevent-data-components-copy-in-smithing-r.patch b/patches/server/0583-Option-to-prevent-data-components-copy-in-smithing-r.patch similarity index 100% rename from patches/server/0584-Option-to-prevent-data-components-copy-in-smithing-r.patch rename to patches/server/0583-Option-to-prevent-data-components-copy-in-smithing-r.patch diff --git a/patches/server/0585-More-CommandBlock-API.patch b/patches/server/0584-More-CommandBlock-API.patch similarity index 100% rename from patches/server/0585-More-CommandBlock-API.patch rename to patches/server/0584-More-CommandBlock-API.patch diff --git a/patches/server/0586-Add-missing-team-sidebar-display-slots.patch b/patches/server/0585-Add-missing-team-sidebar-display-slots.patch similarity index 100% rename from patches/server/0586-Add-missing-team-sidebar-display-slots.patch rename to patches/server/0585-Add-missing-team-sidebar-display-slots.patch diff --git a/patches/server/0587-Add-back-EntityPortalExitEvent.patch b/patches/server/0586-Add-back-EntityPortalExitEvent.patch similarity index 100% rename from patches/server/0587-Add-back-EntityPortalExitEvent.patch rename to patches/server/0586-Add-back-EntityPortalExitEvent.patch diff --git a/patches/server/0588-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0587-Add-methods-to-find-targets-for-lightning-strikes.patch similarity index 94% rename from patches/server/0588-Add-methods-to-find-targets-for-lightning-strikes.patch rename to patches/server/0587-Add-methods-to-find-targets-for-lightning-strikes.patch index fac79b2807..ca096b9dd9 100644 --- a/patches/server/0588-Add-methods-to-find-targets-for-lightning-strikes.patch +++ b/patches/server/0587-Add-methods-to-find-targets-for-lightning-strikes.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Add methods to find targets for lightning strikes public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8c268f57d44d70df3210510abf7832939d41781d..efc27bb4072172f10839c181de9b5fba1f488b6f 100644 +index c72687fb23e8d01639cce7d79e3f97805d51e01f..778d3f3ea2247be5bd6edd382b872f6de5bc359c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -764,6 +764,11 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -31,7 +31,7 @@ index 8c268f57d44d70df3210510abf7832939d41781d..efc27bb4072172f10839c181de9b5fba blockposition1 = blockposition1.above(2); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index bcde7c39e0676bf247a825b40b63f6c7b9f19952..7fbf4fba8df8f47b730a46068e68b33502ed63f8 100644 +index a41c6705aa7e04ad32395f89b95ca76617c9416d..390cacc7916d1322a7e1e8bff004d415e9fa5622 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -689,6 +689,23 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0589-Get-entity-default-attributes.patch b/patches/server/0588-Get-entity-default-attributes.patch similarity index 100% rename from patches/server/0589-Get-entity-default-attributes.patch rename to patches/server/0588-Get-entity-default-attributes.patch diff --git a/patches/server/0590-Left-handed-API.patch b/patches/server/0589-Left-handed-API.patch similarity index 100% rename from patches/server/0590-Left-handed-API.patch rename to patches/server/0589-Left-handed-API.patch diff --git a/patches/server/0591-Add-more-advancement-API.patch b/patches/server/0590-Add-more-advancement-API.patch similarity index 100% rename from patches/server/0591-Add-more-advancement-API.patch rename to patches/server/0590-Add-more-advancement-API.patch diff --git a/patches/server/0592-Add-ItemFactory-getSpawnEgg-API.patch b/patches/server/0591-Add-ItemFactory-getSpawnEgg-API.patch similarity index 100% rename from patches/server/0592-Add-ItemFactory-getSpawnEgg-API.patch rename to patches/server/0591-Add-ItemFactory-getSpawnEgg-API.patch diff --git a/patches/server/0593-Add-critical-damage-API.patch b/patches/server/0592-Add-critical-damage-API.patch similarity index 100% rename from patches/server/0593-Add-critical-damage-API.patch rename to patches/server/0592-Add-critical-damage-API.patch diff --git a/patches/server/0594-Fix-issues-with-mob-conversion.patch b/patches/server/0593-Fix-issues-with-mob-conversion.patch similarity index 100% rename from patches/server/0594-Fix-issues-with-mob-conversion.patch rename to patches/server/0593-Fix-issues-with-mob-conversion.patch diff --git a/patches/server/0595-Add-hasCollision-methods-to-various-places.patch b/patches/server/0594-Add-hasCollision-methods-to-various-places.patch similarity index 100% rename from patches/server/0595-Add-hasCollision-methods-to-various-places.patch rename to patches/server/0594-Add-hasCollision-methods-to-various-places.patch diff --git a/patches/server/0596-Goat-ram-API.patch b/patches/server/0595-Goat-ram-API.patch similarity index 100% rename from patches/server/0596-Goat-ram-API.patch rename to patches/server/0595-Goat-ram-API.patch diff --git a/patches/server/0597-Add-API-for-resetting-a-single-score.patch b/patches/server/0596-Add-API-for-resetting-a-single-score.patch similarity index 100% rename from patches/server/0597-Add-API-for-resetting-a-single-score.patch rename to patches/server/0596-Add-API-for-resetting-a-single-score.patch diff --git a/patches/server/0598-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0597-Add-Raw-Byte-Entity-Serialization.patch similarity index 100% rename from patches/server/0598-Add-Raw-Byte-Entity-Serialization.patch rename to patches/server/0597-Add-Raw-Byte-Entity-Serialization.patch diff --git a/patches/server/0599-Vanilla-command-permission-fixes.patch b/patches/server/0598-Vanilla-command-permission-fixes.patch similarity index 100% rename from patches/server/0599-Vanilla-command-permission-fixes.patch rename to patches/server/0598-Vanilla-command-permission-fixes.patch diff --git a/patches/server/0600-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/server/0599-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch similarity index 93% rename from patches/server/0600-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch rename to patches/server/0599-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch index e615b2ea62..aae11b3a82 100644 --- a/patches/server/0600-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch +++ b/patches/server/0599-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch @@ -9,7 +9,7 @@ chunk through it. This should also be OK from a leak prevention/ state desync POV because the TE is getting unloaded anyways. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index efc27bb4072172f10839c181de9b5fba1f488b6f..4c739717fcf53b28312e8a98f9bf0989c604d0f0 100644 +index 778d3f3ea2247be5bd6edd382b872f6de5bc359c..de154106419d57a6b6c410fedc29cec1dbe532de 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1274,9 +1274,13 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -28,10 +28,10 @@ index efc27bb4072172f10839c181de9b5fba1f488b6f..4c739717fcf53b28312e8a98f9bf0989 } // Spigot End diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index fdf73f71ca34099081f9f80994bbe411052c0149..d868d0776a8ca26deefe2e6b77838c2b502fff57 100644 +index 882dae91f9db702edd233f7cab9f95e9874d1270..cf765213001c3c642477658b7aac0916e64ad5e4 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1718,6 +1718,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1715,6 +1715,18 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); this.doCloseContainer(); } diff --git a/patches/server/0601-Fix-GameProfileCache-concurrency.patch b/patches/server/0600-Fix-GameProfileCache-concurrency.patch similarity index 100% rename from patches/server/0601-Fix-GameProfileCache-concurrency.patch rename to patches/server/0600-Fix-GameProfileCache-concurrency.patch diff --git a/patches/server/0602-Improve-and-expand-AsyncCatcher.patch b/patches/server/0601-Improve-and-expand-AsyncCatcher.patch similarity index 96% rename from patches/server/0602-Improve-and-expand-AsyncCatcher.patch rename to patches/server/0601-Improve-and-expand-AsyncCatcher.patch index a228047ccb..43a86ca3d4 100644 --- a/patches/server/0602-Improve-and-expand-AsyncCatcher.patch +++ b/patches/server/0601-Improve-and-expand-AsyncCatcher.patch @@ -42,7 +42,7 @@ index 85f3dcdc8349683cb79ce1d9fe56eff02af2a7a7..4714931fd5218df160e39f013278b799 this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); return true; diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -index 219062cff8a05c765b092f1525043d9d9a1153ae..1c6e8438219f355274db4e0fa849cdd90648fbb4 100644 +index 1cfc906317f07a44f06a4adf021c44e34a2f1d07..6baa313b8201ed23193d7885c85606b0899ade3c 100644 --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java @@ -78,6 +78,7 @@ public class PersistentEntitySectionManager implements A @@ -166,7 +166,7 @@ index 219062cff8a05c765b092f1525043d9d9a1153ae..1c6e8438219f355274db4e0fa849cdd9 PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason}); } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7fbf4fba8df8f47b730a46068e68b33502ed63f8..c5265e9731f32b08916a60067ee5ae3fcadd35db 100644 +index 390cacc7916d1322a7e1e8bff004d415e9fa5622..786a3722f3a50d828e5abe2ff9d415b0e10995ce 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1758,6 +1758,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -214,12 +214,12 @@ index e3487e8429b285519a0a12d6d283266225b75a80..464d67075e052f13e86b51f3e71d05a6 return true; } diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java -index 78669fa035b7537ff7e533cf32aaf2995625424f..e8e3cc48cf1c58bd8151d1f28df28781859cd0e3 100644 +index bbf0d9d9c44fe8d7add2f978994ec129420814c7..ef2598760458833021ef1bee92137f42c9fe591f 100644 --- a/src/main/java/org/spigotmc/AsyncCatcher.java +++ b/src/main/java/org/spigotmc/AsyncCatcher.java @@ -11,6 +11,7 @@ public class AsyncCatcher { - if ( (AsyncCatcher.enabled || io.papermc.paper.util.TickThread.STRICT_THREAD_CHECKS) && Thread.currentThread() != MinecraftServer.getServer().serverThread ) // Paper + if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) { + MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper throw new IllegalStateException( "Asynchronous " + reason + "!" ); diff --git a/patches/server/0603-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/0602-Add-paper-mobcaps-and-paper-playermobcaps.patch similarity index 99% rename from patches/server/0603-Add-paper-mobcaps-and-paper-playermobcaps.patch rename to patches/server/0602-Add-paper-mobcaps-and-paper-playermobcaps.patch index e945bbb794..3ab90602a9 100644 --- a/patches/server/0603-Add-paper-mobcaps-and-paper-playermobcaps.patch +++ b/patches/server/0602-Add-paper-mobcaps-and-paper-playermobcaps.patch @@ -294,7 +294,7 @@ index 0fc2e453c63b63e12f33cde28ad5afea5657ac57..3c9a9103783495c9015a8cea41562083 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index c5265e9731f32b08916a60067ee5ae3fcadd35db..560d2ff53abd3cdc82d44b45f6896de553b8035c 100644 +index 786a3722f3a50d828e5abe2ff9d415b0e10995ce..0c2734c1d06b6c5dff383f9c6139c0389f220a76 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1716,9 +1716,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0604-Sanitize-ResourceLocation-error-logging.patch b/patches/server/0603-Sanitize-ResourceLocation-error-logging.patch similarity index 100% rename from patches/server/0604-Sanitize-ResourceLocation-error-logging.patch rename to patches/server/0603-Sanitize-ResourceLocation-error-logging.patch diff --git a/patches/server/0605-Manually-inline-methods-in-BlockPosition.patch b/patches/server/0604-Manually-inline-methods-in-BlockPosition.patch similarity index 100% rename from patches/server/0605-Manually-inline-methods-in-BlockPosition.patch rename to patches/server/0604-Manually-inline-methods-in-BlockPosition.patch diff --git a/patches/server/0606-Name-craft-scheduler-threads-according-to-the-plugin.patch b/patches/server/0605-Name-craft-scheduler-threads-according-to-the-plugin.patch similarity index 100% rename from patches/server/0606-Name-craft-scheduler-threads-according-to-the-plugin.patch rename to patches/server/0605-Name-craft-scheduler-threads-according-to-the-plugin.patch diff --git a/patches/server/0607-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/server/0606-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch similarity index 100% rename from patches/server/0607-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch rename to patches/server/0606-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch diff --git a/patches/server/0608-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/server/0607-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch similarity index 100% rename from patches/server/0608-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch rename to patches/server/0607-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch diff --git a/patches/server/0609-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch b/patches/server/0608-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch similarity index 100% rename from patches/server/0609-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch rename to patches/server/0608-Don-t-lookup-fluid-state-when-raytracing-skip-air-bl.patch diff --git a/patches/server/0610-Time-scoreboard-search.patch b/patches/server/0609-Time-scoreboard-search.patch similarity index 100% rename from patches/server/0610-Time-scoreboard-search.patch rename to patches/server/0609-Time-scoreboard-search.patch diff --git a/patches/server/0611-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0610-Oprimise-map-impl-for-tracked-players.patch similarity index 87% rename from patches/server/0611-Oprimise-map-impl-for-tracked-players.patch rename to patches/server/0610-Oprimise-map-impl-for-tracked-players.patch index 667d423e0c..891e360d2c 100644 --- a/patches/server/0611-Oprimise-map-impl-for-tracked-players.patch +++ b/patches/server/0610-Oprimise-map-impl-for-tracked-players.patch @@ -7,10 +7,10 @@ Reference2BooleanOpenHashMap is going to have better lookups than HashMap. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 37bfe3d315210462ed69bb1cb161604e9eb85c36..be0f4a2a9c7fbc359fe79ecf82340db8f7436b22 100644 +index 161792d0226dbb50e9f5ab5c0fe42cc73f44c2a8..b95690dc28dbe8420b0054205c50d14de79f7a42 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1502,7 +1502,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1466,7 +1466,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider final Entity entity; private final int range; SectionPos lastSectionPos; diff --git a/patches/server/0612-Add-missing-InventoryType.patch b/patches/server/0611-Add-missing-InventoryType.patch similarity index 100% rename from patches/server/0612-Add-missing-InventoryType.patch rename to patches/server/0611-Add-missing-InventoryType.patch diff --git a/patches/server/0613-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/0612-Optimise-BlockSoil-nearby-water-lookup.patch similarity index 100% rename from patches/server/0613-Optimise-BlockSoil-nearby-water-lookup.patch rename to patches/server/0612-Optimise-BlockSoil-nearby-water-lookup.patch diff --git a/patches/server/0614-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/server/0613-Fix-merchant-inventory-not-closing-on-entity-removal.patch similarity index 94% rename from patches/server/0614-Fix-merchant-inventory-not-closing-on-entity-removal.patch rename to patches/server/0613-Fix-merchant-inventory-not-closing-on-entity-removal.patch index e15a3485c3..2cd406fbc0 100644 --- a/patches/server/0614-Fix-merchant-inventory-not-closing-on-entity-removal.patch +++ b/patches/server/0613-Fix-merchant-inventory-not-closing-on-entity-removal.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix merchant inventory not closing on entity removal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4c739717fcf53b28312e8a98f9bf0989c604d0f0..0723e6fb396a7afa11772f460a98f68cc815bba0 100644 +index de154106419d57a6b6c410fedc29cec1dbe532de..3c947dc0aea06d66a00aeca51355ea41e8d98f88 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2245,6 +2245,11 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0615-Check-requirement-before-suggesting-root-nodes.patch b/patches/server/0614-Check-requirement-before-suggesting-root-nodes.patch similarity index 100% rename from patches/server/0615-Check-requirement-before-suggesting-root-nodes.patch rename to patches/server/0614-Check-requirement-before-suggesting-root-nodes.patch diff --git a/patches/server/0616-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/0615-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch similarity index 100% rename from patches/server/0616-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch rename to patches/server/0615-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch diff --git a/patches/server/0617-Add-packet-limiter-config.patch b/patches/server/0616-Add-packet-limiter-config.patch similarity index 100% rename from patches/server/0617-Add-packet-limiter-config.patch rename to patches/server/0616-Add-packet-limiter-config.patch diff --git a/patches/server/0618-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/server/0617-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch similarity index 100% rename from patches/server/0618-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch rename to patches/server/0617-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch diff --git a/patches/server/0619-Ensure-valid-vehicle-status.patch b/patches/server/0618-Ensure-valid-vehicle-status.patch similarity index 85% rename from patches/server/0619-Ensure-valid-vehicle-status.patch rename to patches/server/0618-Ensure-valid-vehicle-status.patch index 70f49165db..8b39284257 100644 --- a/patches/server/0619-Ensure-valid-vehicle-status.patch +++ b/patches/server/0618-Ensure-valid-vehicle-status.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Ensure valid vehicle status diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ecd43bbca7ea0e74f506f49fd14f2dd5d467efa1..a9a0e6c495c696a40bdc8147e9a2856500e422e5 100644 +index cf765213001c3c642477658b7aac0916e64ad5e4..780e9ad1ce3434df6366c0a28cae0ce8727cc32f 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -576,7 +576,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -573,7 +573,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } diff --git a/patches/server/0620-Prevent-softlocked-end-exit-portal-generation.patch b/patches/server/0619-Prevent-softlocked-end-exit-portal-generation.patch similarity index 100% rename from patches/server/0620-Prevent-softlocked-end-exit-portal-generation.patch rename to patches/server/0619-Prevent-softlocked-end-exit-portal-generation.patch diff --git a/patches/server/0621-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/server/0620-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch similarity index 100% rename from patches/server/0621-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch rename to patches/server/0620-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch diff --git a/patches/server/0622-Don-t-log-debug-logging-being-disabled.patch b/patches/server/0621-Don-t-log-debug-logging-being-disabled.patch similarity index 100% rename from patches/server/0622-Don-t-log-debug-logging-being-disabled.patch rename to patches/server/0621-Don-t-log-debug-logging-being-disabled.patch diff --git a/patches/server/0623-fix-various-menus-with-empty-level-accesses.patch b/patches/server/0622-fix-various-menus-with-empty-level-accesses.patch similarity index 100% rename from patches/server/0623-fix-various-menus-with-empty-level-accesses.patch rename to patches/server/0622-fix-various-menus-with-empty-level-accesses.patch diff --git a/patches/server/0624-Preserve-overstacked-loot.patch b/patches/server/0623-Preserve-overstacked-loot.patch similarity index 100% rename from patches/server/0624-Preserve-overstacked-loot.patch rename to patches/server/0623-Preserve-overstacked-loot.patch diff --git a/patches/server/0625-Update-head-rotation-in-missing-places.patch b/patches/server/0624-Update-head-rotation-in-missing-places.patch similarity index 100% rename from patches/server/0625-Update-head-rotation-in-missing-places.patch rename to patches/server/0624-Update-head-rotation-in-missing-places.patch diff --git a/patches/server/0626-prevent-unintended-light-block-manipulation.patch b/patches/server/0625-prevent-unintended-light-block-manipulation.patch similarity index 100% rename from patches/server/0626-prevent-unintended-light-block-manipulation.patch rename to patches/server/0625-prevent-unintended-light-block-manipulation.patch diff --git a/patches/server/0627-Fix-CraftCriteria-defaults-map.patch b/patches/server/0626-Fix-CraftCriteria-defaults-map.patch similarity index 100% rename from patches/server/0627-Fix-CraftCriteria-defaults-map.patch rename to patches/server/0626-Fix-CraftCriteria-defaults-map.patch diff --git a/patches/server/0628-Fix-upstreams-block-state-factories.patch b/patches/server/0627-Fix-upstreams-block-state-factories.patch similarity index 100% rename from patches/server/0628-Fix-upstreams-block-state-factories.patch rename to patches/server/0627-Fix-upstreams-block-state-factories.patch diff --git a/patches/server/0629-Configurable-feature-seeds.patch b/patches/server/0628-Configurable-feature-seeds.patch similarity index 100% rename from patches/server/0629-Configurable-feature-seeds.patch rename to patches/server/0628-Configurable-feature-seeds.patch diff --git a/patches/server/0630-Add-root-admin-user-detection.patch b/patches/server/0629-Add-root-admin-user-detection.patch similarity index 100% rename from patches/server/0630-Add-root-admin-user-detection.patch rename to patches/server/0629-Add-root-admin-user-detection.patch diff --git a/patches/server/0631-don-t-attempt-to-teleport-dead-entities.patch b/patches/server/0630-don-t-attempt-to-teleport-dead-entities.patch similarity index 100% rename from patches/server/0631-don-t-attempt-to-teleport-dead-entities.patch rename to patches/server/0630-don-t-attempt-to-teleport-dead-entities.patch diff --git a/patches/server/0632-Prevent-excessive-velocity-through-repeated-crits.patch b/patches/server/0631-Prevent-excessive-velocity-through-repeated-crits.patch similarity index 100% rename from patches/server/0632-Prevent-excessive-velocity-through-repeated-crits.patch rename to patches/server/0631-Prevent-excessive-velocity-through-repeated-crits.patch diff --git a/patches/server/0633-Remove-client-side-code-using-deprecated-for-removal.patch b/patches/server/0632-Remove-client-side-code-using-deprecated-for-removal.patch similarity index 100% rename from patches/server/0633-Remove-client-side-code-using-deprecated-for-removal.patch rename to patches/server/0632-Remove-client-side-code-using-deprecated-for-removal.patch diff --git a/patches/server/0634-Fix-Spigot-growth-modifiers.patch b/patches/server/0633-Fix-Spigot-growth-modifiers.patch similarity index 100% rename from patches/server/0634-Fix-Spigot-growth-modifiers.patch rename to patches/server/0633-Fix-Spigot-growth-modifiers.patch diff --git a/patches/server/0635-Prevent-ContainerOpenersCounter-openCount-from-going.patch b/patches/server/0634-Prevent-ContainerOpenersCounter-openCount-from-going.patch similarity index 100% rename from patches/server/0635-Prevent-ContainerOpenersCounter-openCount-from-going.patch rename to patches/server/0634-Prevent-ContainerOpenersCounter-openCount-from-going.patch diff --git a/patches/server/0636-Add-PlayerItemFrameChangeEvent.patch b/patches/server/0635-Add-PlayerItemFrameChangeEvent.patch similarity index 100% rename from patches/server/0636-Add-PlayerItemFrameChangeEvent.patch rename to patches/server/0635-Add-PlayerItemFrameChangeEvent.patch diff --git a/patches/server/0637-Optimize-HashMapPalette.patch b/patches/server/0636-Optimize-HashMapPalette.patch similarity index 100% rename from patches/server/0637-Optimize-HashMapPalette.patch rename to patches/server/0636-Optimize-HashMapPalette.patch diff --git a/patches/server/0638-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch b/patches/server/0637-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch similarity index 100% rename from patches/server/0638-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch rename to patches/server/0637-Fix-ChunkSnapshot-isSectionEmpty-int-and-optimize-Pa.patch diff --git a/patches/server/0639-Add-more-Campfire-API.patch b/patches/server/0638-Add-more-Campfire-API.patch similarity index 100% rename from patches/server/0639-Add-more-Campfire-API.patch rename to patches/server/0638-Add-more-Campfire-API.patch diff --git a/patches/server/0640-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/0639-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from patches/server/0640-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to patches/server/0639-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/patches/server/0641-Forward-CraftEntity-in-teleport-command.patch b/patches/server/0640-Forward-CraftEntity-in-teleport-command.patch similarity index 100% rename from patches/server/0641-Forward-CraftEntity-in-teleport-command.patch rename to patches/server/0640-Forward-CraftEntity-in-teleport-command.patch diff --git a/patches/server/0642-Improve-scoreboard-entries.patch b/patches/server/0641-Improve-scoreboard-entries.patch similarity index 100% rename from patches/server/0642-Improve-scoreboard-entries.patch rename to patches/server/0641-Improve-scoreboard-entries.patch diff --git a/patches/server/0643-Entity-powdered-snow-API.patch b/patches/server/0642-Entity-powdered-snow-API.patch similarity index 100% rename from patches/server/0643-Entity-powdered-snow-API.patch rename to patches/server/0642-Entity-powdered-snow-API.patch diff --git a/patches/server/0644-Add-API-for-item-entity-health.patch b/patches/server/0643-Add-API-for-item-entity-health.patch similarity index 100% rename from patches/server/0644-Add-API-for-item-entity-health.patch rename to patches/server/0643-Add-API-for-item-entity-health.patch diff --git a/patches/server/0645-Configurable-max-block-light-for-monster-spawning.patch b/patches/server/0644-Configurable-max-block-light-for-monster-spawning.patch similarity index 100% rename from patches/server/0645-Configurable-max-block-light-for-monster-spawning.patch rename to patches/server/0644-Configurable-max-block-light-for-monster-spawning.patch diff --git a/patches/server/0646-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch b/patches/server/0645-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch similarity index 100% rename from patches/server/0646-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch rename to patches/server/0645-Fix-sticky-pistons-and-BlockPistonRetractEvent.patch diff --git a/patches/server/0647-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch b/patches/server/0646-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch similarity index 100% rename from patches/server/0647-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch rename to patches/server/0646-Expose-isFuel-and-canSmelt-methods-to-FurnaceInvento.patch diff --git a/patches/server/0648-Bucketable-API.patch b/patches/server/0647-Bucketable-API.patch similarity index 100% rename from patches/server/0648-Bucketable-API.patch rename to patches/server/0647-Bucketable-API.patch diff --git a/patches/server/0649-Validate-usernames.patch b/patches/server/0648-Validate-usernames.patch similarity index 100% rename from patches/server/0649-Validate-usernames.patch rename to patches/server/0648-Validate-usernames.patch diff --git a/patches/server/0650-Make-water-animal-spawn-height-configurable.patch b/patches/server/0649-Make-water-animal-spawn-height-configurable.patch similarity index 100% rename from patches/server/0650-Make-water-animal-spawn-height-configurable.patch rename to patches/server/0649-Make-water-animal-spawn-height-configurable.patch diff --git a/patches/server/0651-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/0650-Expose-vanilla-BiomeProvider-from-WorldInfo.patch similarity index 97% rename from patches/server/0651-Expose-vanilla-BiomeProvider-from-WorldInfo.patch rename to patches/server/0650-Expose-vanilla-BiomeProvider-from-WorldInfo.patch index b31f8fcb58..885b2a15ca 100644 --- a/patches/server/0651-Expose-vanilla-BiomeProvider-from-WorldInfo.patch +++ b/patches/server/0650-Expose-vanilla-BiomeProvider-from-WorldInfo.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Expose vanilla BiomeProvider from WorldInfo diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 695d6265b4a9f98ba630593ba6c47769240bed93..2559a40546701fefa7f28603cb637108bfc659da 100644 +index 6ad7c34513034c87059f8a0790aea3231dd0d2a9..188b1844ca6ee5a97f7a588121255417a184a4df 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -612,7 +612,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/level/block/state/BlockState;)V diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 87379165355e597d02115907da4a096621caf254..fd732a22916cba613d168bc03a2ef06dd63960a9 100644 +index da556cdbd7eecfd0743924d9ab79142c41f08d0a..c0c26825865404231f57883447328c84cdf32d82 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1383,7 +1383,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0677-Expose-furnace-minecart-push-values.patch b/patches/server/0676-Expose-furnace-minecart-push-values.patch similarity index 100% rename from patches/server/0677-Expose-furnace-minecart-push-values.patch rename to patches/server/0676-Expose-furnace-minecart-push-values.patch diff --git a/patches/server/0678-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch b/patches/server/0677-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch similarity index 100% rename from patches/server/0678-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch rename to patches/server/0677-Fix-cancelling-ProjectileHitEvent-for-piercing-arrow.patch diff --git a/patches/server/0679-More-Projectile-API.patch b/patches/server/0678-More-Projectile-API.patch similarity index 99% rename from patches/server/0679-More-Projectile-API.patch rename to patches/server/0678-More-Projectile-API.patch index ac564ab406..0fbc4c2f87 100644 --- a/patches/server/0679-More-Projectile-API.patch +++ b/patches/server/0678-More-Projectile-API.patch @@ -764,7 +764,7 @@ index ebe547736862b38dd11727124cdd70c7abe7d791..6bed9cce39eacf0f42ee4c6b007d2bde } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java -index 23d61d553be3ab0a62624e469b2782baa2b075db..a147b54668854668b02bbe39c9eae22bb98dc217 100644 +index 75f9405ee3453620e1561857575cc8700971a865..8468bf6676b7ade3508085f44fac8980a8c6081e 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -306,12 +306,23 @@ public final class CraftItemStack extends ItemStack { diff --git a/patches/server/0680-Fix-swamp-hut-cat-generation-deadlock.patch b/patches/server/0679-Fix-swamp-hut-cat-generation-deadlock.patch similarity index 100% rename from patches/server/0680-Fix-swamp-hut-cat-generation-deadlock.patch rename to patches/server/0679-Fix-swamp-hut-cat-generation-deadlock.patch diff --git a/patches/server/0681-Don-t-allow-vehicle-movement-from-players-while-tele.patch b/patches/server/0680-Don-t-allow-vehicle-movement-from-players-while-tele.patch similarity index 100% rename from patches/server/0681-Don-t-allow-vehicle-movement-from-players-while-tele.patch rename to patches/server/0680-Don-t-allow-vehicle-movement-from-players-while-tele.patch diff --git a/patches/server/0682-Implement-getComputedBiome-API.patch b/patches/server/0681-Implement-getComputedBiome-API.patch similarity index 100% rename from patches/server/0682-Implement-getComputedBiome-API.patch rename to patches/server/0681-Implement-getComputedBiome-API.patch diff --git a/patches/server/0683-Make-some-itemstacks-nonnull.patch b/patches/server/0682-Make-some-itemstacks-nonnull.patch similarity index 100% rename from patches/server/0683-Make-some-itemstacks-nonnull.patch rename to patches/server/0682-Make-some-itemstacks-nonnull.patch diff --git a/patches/server/0684-Implement-enchantWithLevels-API.patch b/patches/server/0683-Implement-enchantWithLevels-API.patch similarity index 100% rename from patches/server/0684-Implement-enchantWithLevels-API.patch rename to patches/server/0683-Implement-enchantWithLevels-API.patch diff --git a/patches/server/0685-Fix-saving-in-unloadWorld.patch b/patches/server/0684-Fix-saving-in-unloadWorld.patch similarity index 100% rename from patches/server/0685-Fix-saving-in-unloadWorld.patch rename to patches/server/0684-Fix-saving-in-unloadWorld.patch diff --git a/patches/server/0686-Buffer-OOB-setBlock-calls.patch b/patches/server/0685-Buffer-OOB-setBlock-calls.patch similarity index 100% rename from patches/server/0686-Buffer-OOB-setBlock-calls.patch rename to patches/server/0685-Buffer-OOB-setBlock-calls.patch diff --git a/patches/server/0687-Add-TameableDeathMessageEvent.patch b/patches/server/0686-Add-TameableDeathMessageEvent.patch similarity index 100% rename from patches/server/0687-Add-TameableDeathMessageEvent.patch rename to patches/server/0686-Add-TameableDeathMessageEvent.patch diff --git a/patches/server/0688-Fix-new-block-data-for-EntityChangeBlockEvent.patch b/patches/server/0687-Fix-new-block-data-for-EntityChangeBlockEvent.patch similarity index 100% rename from patches/server/0688-Fix-new-block-data-for-EntityChangeBlockEvent.patch rename to patches/server/0687-Fix-new-block-data-for-EntityChangeBlockEvent.patch diff --git a/patches/server/0689-fix-player-loottables-running-when-mob-loot-gamerule.patch b/patches/server/0688-fix-player-loottables-running-when-mob-loot-gamerule.patch similarity index 88% rename from patches/server/0689-fix-player-loottables-running-when-mob-loot-gamerule.patch rename to patches/server/0688-fix-player-loottables-running-when-mob-loot-gamerule.patch index 11ef07e7f6..184750f3e3 100644 --- a/patches/server/0689-fix-player-loottables-running-when-mob-loot-gamerule.patch +++ b/patches/server/0688-fix-player-loottables-running-when-mob-loot-gamerule.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fix player loottables running when mob loot gamerule is false diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 2a0a182191436cce8889aaa22821d770717ba8a8..8bf10e87954a42694894d107ed5fb13bc9106528 100644 +index 780e9ad1ce3434df6366c0a28cae0ce8727cc32f..787bba01f9cfc735c1082c7c90074f0e0807ec07 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -961,12 +961,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -958,12 +958,14 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } } } diff --git a/patches/server/0690-Ensure-entity-passenger-world-matches-ridden-entity.patch b/patches/server/0689-Ensure-entity-passenger-world-matches-ridden-entity.patch similarity index 100% rename from patches/server/0690-Ensure-entity-passenger-world-matches-ridden-entity.patch rename to patches/server/0689-Ensure-entity-passenger-world-matches-ridden-entity.patch diff --git a/patches/server/0691-cache-resource-keys.patch b/patches/server/0690-cache-resource-keys.patch similarity index 100% rename from patches/server/0691-cache-resource-keys.patch rename to patches/server/0690-cache-resource-keys.patch diff --git a/patches/server/0692-Allow-changing-the-EnderDragon-podium.patch b/patches/server/0691-Allow-changing-the-EnderDragon-podium.patch similarity index 100% rename from patches/server/0692-Allow-changing-the-EnderDragon-podium.patch rename to patches/server/0691-Allow-changing-the-EnderDragon-podium.patch diff --git a/patches/server/0693-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch b/patches/server/0692-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch similarity index 100% rename from patches/server/0693-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch rename to patches/server/0692-Fix-NBT-pieces-overriding-a-block-entity-during-worl.patch diff --git a/patches/server/0694-Prevent-tile-entity-copies-loading-chunks.patch b/patches/server/0693-Prevent-tile-entity-copies-loading-chunks.patch similarity index 100% rename from patches/server/0694-Prevent-tile-entity-copies-loading-chunks.patch rename to patches/server/0693-Prevent-tile-entity-copies-loading-chunks.patch diff --git a/patches/server/0695-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0694-Use-username-instead-of-display-name-in-PlayerList-g.patch similarity index 100% rename from patches/server/0695-Use-username-instead-of-display-name-in-PlayerList-g.patch rename to patches/server/0694-Use-username-instead-of-display-name-in-PlayerList-g.patch diff --git a/patches/server/0696-Expand-PlayerItemDamageEvent.patch b/patches/server/0695-Expand-PlayerItemDamageEvent.patch similarity index 100% rename from patches/server/0696-Expand-PlayerItemDamageEvent.patch rename to patches/server/0695-Expand-PlayerItemDamageEvent.patch diff --git a/patches/server/0697-WorldCreator-keepSpawnLoaded.patch b/patches/server/0696-WorldCreator-keepSpawnLoaded.patch similarity index 100% rename from patches/server/0697-WorldCreator-keepSpawnLoaded.patch rename to patches/server/0696-WorldCreator-keepSpawnLoaded.patch diff --git a/patches/server/0698-Fix-CME-in-CraftPersistentDataTypeRegistry.patch b/patches/server/0697-Fix-CME-in-CraftPersistentDataTypeRegistry.patch similarity index 100% rename from patches/server/0698-Fix-CME-in-CraftPersistentDataTypeRegistry.patch rename to patches/server/0697-Fix-CME-in-CraftPersistentDataTypeRegistry.patch diff --git a/patches/server/0699-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch b/patches/server/0698-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch similarity index 100% rename from patches/server/0699-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch rename to patches/server/0698-Trigger-bee_nest_destroyed-trigger-in-the-correct-pl.patch diff --git a/patches/server/0700-Add-EntityDyeEvent-and-CollarColorable-interface.patch b/patches/server/0699-Add-EntityDyeEvent-and-CollarColorable-interface.patch similarity index 100% rename from patches/server/0700-Add-EntityDyeEvent-and-CollarColorable-interface.patch rename to patches/server/0699-Add-EntityDyeEvent-and-CollarColorable-interface.patch diff --git a/patches/server/0701-Fire-CauldronLevelChange-on-initial-fill.patch b/patches/server/0700-Fire-CauldronLevelChange-on-initial-fill.patch similarity index 100% rename from patches/server/0701-Fire-CauldronLevelChange-on-initial-fill.patch rename to patches/server/0700-Fire-CauldronLevelChange-on-initial-fill.patch diff --git a/patches/server/0702-fix-powder-snow-cauldrons-not-turning-to-water.patch b/patches/server/0701-fix-powder-snow-cauldrons-not-turning-to-water.patch similarity index 100% rename from patches/server/0702-fix-powder-snow-cauldrons-not-turning-to-water.patch rename to patches/server/0701-fix-powder-snow-cauldrons-not-turning-to-water.patch diff --git a/patches/server/0703-Add-PlayerStopUsingItemEvent.patch b/patches/server/0702-Add-PlayerStopUsingItemEvent.patch similarity index 100% rename from patches/server/0703-Add-PlayerStopUsingItemEvent.patch rename to patches/server/0702-Add-PlayerStopUsingItemEvent.patch diff --git a/patches/server/0704-Don-t-tick-markers.patch b/patches/server/0703-Don-t-tick-markers.patch similarity index 95% rename from patches/server/0704-Don-t-tick-markers.patch rename to patches/server/0703-Don-t-tick-markers.patch index c8a214b154..98a89bf35d 100644 --- a/patches/server/0704-Don-t-tick-markers.patch +++ b/patches/server/0703-Don-t-tick-markers.patch @@ -23,7 +23,7 @@ index 67fcba634f8183bb33834ac3b2c3dcfb8d87129e..777b789fdcdf297309cfb36fc7f77e3f } }); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 0723e6fb396a7afa11772f460a98f68cc815bba0..d839dd47eb02ce30119c57ff2c1a46c9570fe913 100644 +index 3c947dc0aea06d66a00aeca51355ea41e8d98f88..ec2996d306d3466867e94bb6e4707f2b5fe13af2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2160,6 +2160,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0705-Expand-FallingBlock-API.patch b/patches/server/0704-Expand-FallingBlock-API.patch similarity index 100% rename from patches/server/0705-Expand-FallingBlock-API.patch rename to patches/server/0704-Expand-FallingBlock-API.patch diff --git a/patches/server/0706-Add-support-for-Proxy-Protocol.patch b/patches/server/0705-Add-support-for-Proxy-Protocol.patch similarity index 100% rename from patches/server/0706-Add-support-for-Proxy-Protocol.patch rename to patches/server/0705-Add-support-for-Proxy-Protocol.patch diff --git a/patches/server/0707-Fix-OfflinePlayer-getBedSpawnLocation.patch b/patches/server/0706-Fix-OfflinePlayer-getBedSpawnLocation.patch similarity index 100% rename from patches/server/0707-Fix-OfflinePlayer-getBedSpawnLocation.patch rename to patches/server/0706-Fix-OfflinePlayer-getBedSpawnLocation.patch diff --git a/patches/server/0708-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch b/patches/server/0707-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch similarity index 100% rename from patches/server/0708-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch rename to patches/server/0707-Fix-FurnaceInventory-for-smokers-and-blast-furnaces.patch diff --git a/patches/server/0709-Sanitize-sent-BlockEntity-NBT.patch b/patches/server/0708-Sanitize-sent-BlockEntity-NBT.patch similarity index 100% rename from patches/server/0709-Sanitize-sent-BlockEntity-NBT.patch rename to patches/server/0708-Sanitize-sent-BlockEntity-NBT.patch diff --git a/patches/server/0710-Disable-component-selector-resolving-in-books-by-def.patch b/patches/server/0709-Disable-component-selector-resolving-in-books-by-def.patch similarity index 100% rename from patches/server/0710-Disable-component-selector-resolving-in-books-by-def.patch rename to patches/server/0709-Disable-component-selector-resolving-in-books-by-def.patch diff --git a/patches/server/0711-Prevent-entity-loading-causing-async-lookups.patch b/patches/server/0710-Prevent-entity-loading-causing-async-lookups.patch similarity index 100% rename from patches/server/0711-Prevent-entity-loading-causing-async-lookups.patch rename to patches/server/0710-Prevent-entity-loading-causing-async-lookups.patch diff --git a/patches/server/0712-Throw-exception-on-world-create-while-being-ticked.patch b/patches/server/0711-Throw-exception-on-world-create-while-being-ticked.patch similarity index 93% rename from patches/server/0712-Throw-exception-on-world-create-while-being-ticked.patch rename to patches/server/0711-Throw-exception-on-world-create-while-being-ticked.patch index ccad54896d..6d760986bc 100644 --- a/patches/server/0712-Throw-exception-on-world-create-while-being-ticked.patch +++ b/patches/server/0711-Throw-exception-on-world-create-while-being-ticked.patch @@ -7,7 +7,7 @@ There are no plans to support creating worlds while worlds are being ticked themselvess. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 2408e5afb9096aa991742983bb573040fbfdb5cb..56ab40965ca6034ed430d4d5c4be99fa69a3a453 100644 +index 8142e4a238066404f3d1685f9cee1a2b91cdd371..acdba56f025fe729398c5549175baad8e6818f62 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -318,6 +318,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1583,7 +1584,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent -@@ -1650,6 +1653,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop maindimensionkey = CraftDimensionUtil.getMainDimensionKey(origin); ResourceKey maindimensionkey1 = CraftDimensionUtil.getMainDimensionKey(this.level()); diff --git a/patches/server/0716-Add-missing-important-BlockStateListPopulator-method.patch b/patches/server/0715-Add-missing-important-BlockStateListPopulator-method.patch similarity index 100% rename from patches/server/0716-Add-missing-important-BlockStateListPopulator-method.patch rename to patches/server/0715-Add-missing-important-BlockStateListPopulator-method.patch diff --git a/patches/server/0717-Nameable-Banner-API.patch b/patches/server/0716-Nameable-Banner-API.patch similarity index 100% rename from patches/server/0717-Nameable-Banner-API.patch rename to patches/server/0716-Nameable-Banner-API.patch diff --git a/patches/server/0718-Don-t-broadcast-messages-to-command-blocks.patch b/patches/server/0717-Don-t-broadcast-messages-to-command-blocks.patch similarity index 100% rename from patches/server/0718-Don-t-broadcast-messages-to-command-blocks.patch rename to patches/server/0717-Don-t-broadcast-messages-to-command-blocks.patch diff --git a/patches/server/0719-Prevent-empty-items-from-being-added-to-world.patch b/patches/server/0718-Prevent-empty-items-from-being-added-to-world.patch similarity index 93% rename from patches/server/0719-Prevent-empty-items-from-being-added-to-world.patch rename to patches/server/0718-Prevent-empty-items-from-being-added-to-world.patch index 5659cfbcab..c9e7ae9955 100644 --- a/patches/server/0719-Prevent-empty-items-from-being-added-to-world.patch +++ b/patches/server/0718-Prevent-empty-items-from-being-added-to-world.patch @@ -7,7 +7,7 @@ The previous solution caused a bunch of bandaid fixes inorder to resolve edge ca Just simply prevent them from being added to the world instead. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d839dd47eb02ce30119c57ff2c1a46c9570fe913..e1e0cf97d2badd26a9391bf0f758edae262a14c2 100644 +index ec2996d306d3466867e94bb6e4707f2b5fe13af2..43d54a7fab4b5d46bf4ca319519a39fda1fc264f 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1235,6 +1235,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0720-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch b/patches/server/0719-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch similarity index 100% rename from patches/server/0720-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch rename to patches/server/0719-Fix-CCE-for-SplashPotion-and-LingeringPotion-spawnin.patch diff --git a/patches/server/0721-Add-Player-getFishHook.patch b/patches/server/0720-Add-Player-getFishHook.patch similarity index 92% rename from patches/server/0721-Add-Player-getFishHook.patch rename to patches/server/0720-Add-Player-getFishHook.patch index d87fa21619..7ab8083ac7 100644 --- a/patches/server/0721-Add-Player-getFishHook.patch +++ b/patches/server/0720-Add-Player-getFishHook.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Player#getFishHook diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java -index 6c500a2ccc050fc44076e443032b0ef9d87a7de8..79faf3c64891899bf5d6d119154aba02d4665b3b 100644 +index 148279d06dc5bf46aa5d4319f0b7d2ebfcee412d..0213898b4d029ea9260a755d6411d909a1b6885c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -160,6 +160,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { diff --git a/patches/server/0722-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch b/patches/server/0721-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch similarity index 100% rename from patches/server/0722-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch rename to patches/server/0721-Do-not-sync-load-chunk-for-dynamic-game-event-listen.patch diff --git a/patches/server/0723-Add-various-missing-EntityDropItemEvent-calls.patch b/patches/server/0722-Add-various-missing-EntityDropItemEvent-calls.patch similarity index 100% rename from patches/server/0723-Add-various-missing-EntityDropItemEvent-calls.patch rename to patches/server/0722-Add-various-missing-EntityDropItemEvent-calls.patch diff --git a/patches/server/0724-Fix-Bee-flower-NPE.patch b/patches/server/0723-Fix-Bee-flower-NPE.patch similarity index 100% rename from patches/server/0724-Fix-Bee-flower-NPE.patch rename to patches/server/0723-Fix-Bee-flower-NPE.patch diff --git a/patches/server/0725-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch b/patches/server/0724-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch similarity index 100% rename from patches/server/0725-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch rename to patches/server/0724-Fix-Spigot-Config-not-using-commands.spam-exclusions.patch diff --git a/patches/server/0726-More-Teleport-API.patch b/patches/server/0725-More-Teleport-API.patch similarity index 99% rename from patches/server/0726-More-Teleport-API.patch rename to patches/server/0725-More-Teleport-API.patch index deb574d5df..658e715895 100644 --- a/patches/server/0726-More-Teleport-API.patch +++ b/patches/server/0725-More-Teleport-API.patch @@ -112,7 +112,7 @@ index 47f24e390efd8eb4cb7f62b5203825f4160772b7..243ac4253a1541dba52126bad96682e4 private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index c92ca61b2af012e58f998c8b08c895007a423f67..17becfd5a08a87682d665151e3539f870b72f981 100644 +index 1ffbb31f2926a1b076ab213cb32dd19c7b0f8768..7f449bc5a0644709b426dba70a5afccc26a37de8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1286,13 +1286,101 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0727-Add-EntityPortalReadyEvent.patch b/patches/server/0726-Add-EntityPortalReadyEvent.patch similarity index 100% rename from patches/server/0727-Add-EntityPortalReadyEvent.patch rename to patches/server/0726-Add-EntityPortalReadyEvent.patch diff --git a/patches/server/0728-Don-t-use-level-random-in-entity-constructors.patch b/patches/server/0727-Don-t-use-level-random-in-entity-constructors.patch similarity index 100% rename from patches/server/0728-Don-t-use-level-random-in-entity-constructors.patch rename to patches/server/0727-Don-t-use-level-random-in-entity-constructors.patch diff --git a/patches/server/0729-Send-block-entities-after-destroy-prediction.patch b/patches/server/0728-Send-block-entities-after-destroy-prediction.patch similarity index 100% rename from patches/server/0729-Send-block-entities-after-destroy-prediction.patch rename to patches/server/0728-Send-block-entities-after-destroy-prediction.patch diff --git a/patches/server/0730-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0729-Warn-on-plugins-accessing-faraway-chunks.patch similarity index 98% rename from patches/server/0730-Warn-on-plugins-accessing-faraway-chunks.patch rename to patches/server/0729-Warn-on-plugins-accessing-faraway-chunks.patch index f3d50c526a..b405c21a44 100644 --- a/patches/server/0730-Warn-on-plugins-accessing-faraway-chunks.patch +++ b/patches/server/0729-Warn-on-plugins-accessing-faraway-chunks.patch @@ -18,7 +18,7 @@ index 38bcf9f410e8a9d47c7d486c28dbc16a6225b650..210c3b6167dac93e550fe849e34b5aa4 private static boolean isOutsideSpawnableHeight(int y) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index fd732a22916cba613d168bc03a2ef06dd63960a9..1ef380cbd77132b743520f952afa8321042bec6d 100644 +index c0c26825865404231f57883447328c84cdf32d82..0c5a583f2ced1ae5e1e92a045ef2ef1cd5b35496 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -295,9 +295,24 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0731-Custom-Chat-Completion-Suggestions-API.patch b/patches/server/0730-Custom-Chat-Completion-Suggestions-API.patch similarity index 94% rename from patches/server/0731-Custom-Chat-Completion-Suggestions-API.patch rename to patches/server/0730-Custom-Chat-Completion-Suggestions-API.patch index 839ee2255a..eb2cf4cb83 100644 --- a/patches/server/0731-Custom-Chat-Completion-Suggestions-API.patch +++ b/patches/server/0730-Custom-Chat-Completion-Suggestions-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Custom Chat Completion Suggestions API diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d0005af63d4ae0081a39797cb62c5ff3e2efa537..bffb3c029e917ccfc4b092a5d213a4d0f7a42ce4 100644 +index 7f449bc5a0644709b426dba70a5afccc26a37de8..7a4ae758616225002cc14060753bb691ee1d94bb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -691,6 +691,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0732-Add-and-fix-missing-BlockFadeEvents.patch b/patches/server/0731-Add-and-fix-missing-BlockFadeEvents.patch similarity index 96% rename from patches/server/0732-Add-and-fix-missing-BlockFadeEvents.patch rename to patches/server/0731-Add-and-fix-missing-BlockFadeEvents.patch index 055406ea3e..062bad35bb 100644 --- a/patches/server/0732-Add-and-fix-missing-BlockFadeEvents.patch +++ b/patches/server/0731-Add-and-fix-missing-BlockFadeEvents.patch @@ -10,7 +10,7 @@ potentially waterlogged block states fading. Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java -index 6e7595193275e88c69b82ebbc9f9df636879a03e..3c4949965c0fad3c6200d0fd1e31ebe844ba6e0e 100644 +index 669234bca9fa50548447f77dc5f314df8d9dd7c9..f2d4264743b6070f36adb66d00a3de0a72b86846 100644 --- a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java @@ -92,6 +92,11 @@ public class FrogspawnBlock extends Block { @@ -39,7 +39,7 @@ index 580c77eeaf88083f2aed2e46e6c57dc1fcf9564c..f4cccbc134b33758cd553a29b9f8e996 FallingBlockEntity.fall(world, pos, iblockdata1); } else { diff --git a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java -index 1eda49c9ce8ee009cb08b18f02f59b37c2118628..38288f20306632e6546c95b4cb1a42806be49975 100644 +index 14a5cd54820243f4ca59857b0d67c1e86457d590..f53808e200bd83ab80954ec5c1e9c14250302be8 100644 --- a/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SnifferEggBlock.java @@ -60,12 +60,26 @@ public class SnifferEggBlock extends Block { diff --git a/patches/server/0733-Collision-API.patch b/patches/server/0732-Collision-API.patch similarity index 100% rename from patches/server/0733-Collision-API.patch rename to patches/server/0732-Collision-API.patch diff --git a/patches/server/0734-Fix-suggest-command-message-for-brigadier-syntax-exc.patch b/patches/server/0733-Fix-suggest-command-message-for-brigadier-syntax-exc.patch similarity index 100% rename from patches/server/0734-Fix-suggest-command-message-for-brigadier-syntax-exc.patch rename to patches/server/0733-Fix-suggest-command-message-for-brigadier-syntax-exc.patch diff --git a/patches/server/0735-Block-Ticking-API.patch b/patches/server/0734-Block-Ticking-API.patch similarity index 100% rename from patches/server/0735-Block-Ticking-API.patch rename to patches/server/0734-Block-Ticking-API.patch diff --git a/patches/server/0736-Add-Velocity-IP-Forwarding-Support.patch b/patches/server/0735-Add-Velocity-IP-Forwarding-Support.patch similarity index 100% rename from patches/server/0736-Add-Velocity-IP-Forwarding-Support.patch rename to patches/server/0735-Add-Velocity-IP-Forwarding-Support.patch diff --git a/patches/server/0737-Add-NamespacedKey-biome-methods.patch b/patches/server/0736-Add-NamespacedKey-biome-methods.patch similarity index 100% rename from patches/server/0737-Add-NamespacedKey-biome-methods.patch rename to patches/server/0736-Add-NamespacedKey-biome-methods.patch diff --git a/patches/server/0738-Fix-plugin-loggers-on-server-shutdown.patch b/patches/server/0737-Fix-plugin-loggers-on-server-shutdown.patch similarity index 92% rename from patches/server/0738-Fix-plugin-loggers-on-server-shutdown.patch rename to patches/server/0737-Fix-plugin-loggers-on-server-shutdown.patch index 896ce1668f..18da0811b4 100644 --- a/patches/server/0738-Fix-plugin-loggers-on-server-shutdown.patch +++ b/patches/server/0737-Fix-plugin-loggers-on-server-shutdown.patch @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..c1d3bac79bb8b4796c013ff4472f75dc + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 56ab40965ca6034ed430d4d5c4be99fa69a3a453..eef519384b5f8f6b2551ed61affe6cb1f3489702 100644 +index acdba56f025fe729398c5549175baad8e6818f62..3aba668f9a34cabc26063c61660ab22f83b1070e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1239,6 +1239,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= 2.0F) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 682c5e9328d965bf335bb06ac7aedf6d49b1c6cb..4bcceef859099405a3d78bc7e6b12c778e906d72 100644 +index c426dbff75f0ad3889594fba9a66669fc71b63e8..cb191389007ccaae2e3af1defc5e95ee571c46ac 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2581,6 +2581,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0793-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch b/patches/server/0792-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch similarity index 100% rename from patches/server/0793-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch rename to patches/server/0792-Expose-pre-collision-moving-velocity-to-VehicleBlock.patch diff --git a/patches/server/0794-config-for-disabling-entity-tag-tags.patch b/patches/server/0793-config-for-disabling-entity-tag-tags.patch similarity index 100% rename from patches/server/0794-config-for-disabling-entity-tag-tags.patch rename to patches/server/0793-config-for-disabling-entity-tag-tags.patch diff --git a/patches/server/0795-Use-single-player-info-update-packet-on-join.patch b/patches/server/0794-Use-single-player-info-update-packet-on-join.patch similarity index 100% rename from patches/server/0795-Use-single-player-info-update-packet-on-join.patch rename to patches/server/0794-Use-single-player-info-update-packet-on-join.patch diff --git a/patches/server/0796-Correctly-shrink-items-during-EntityResurrectEvent.patch b/patches/server/0795-Correctly-shrink-items-during-EntityResurrectEvent.patch similarity index 100% rename from patches/server/0796-Correctly-shrink-items-during-EntityResurrectEvent.patch rename to patches/server/0795-Correctly-shrink-items-during-EntityResurrectEvent.patch diff --git a/patches/server/0797-Win-Screen-API.patch b/patches/server/0796-Win-Screen-API.patch similarity index 93% rename from patches/server/0797-Win-Screen-API.patch rename to patches/server/0796-Win-Screen-API.patch index 6c72c065c2..95dd061087 100644 --- a/patches/server/0797-Win-Screen-API.patch +++ b/patches/server/0796-Win-Screen-API.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Win Screen API public net.minecraft.server.level.ServerPlayer seenCredits diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4bcceef859099405a3d78bc7e6b12c778e906d72..d0cd2a8c99d607e36d37718b9e2c439f4a939535 100644 +index cb191389007ccaae2e3af1defc5e95ee571c46ac..756ba61af10b552c5c0bf86e506a31df0f0ce6f5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1305,6 +1305,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0798-Remove-CraftItemStack-setAmount-null-assignment.patch b/patches/server/0797-Remove-CraftItemStack-setAmount-null-assignment.patch similarity index 100% rename from patches/server/0798-Remove-CraftItemStack-setAmount-null-assignment.patch rename to patches/server/0797-Remove-CraftItemStack-setAmount-null-assignment.patch diff --git a/patches/server/0799-Fix-force-opening-enchantment-tables.patch b/patches/server/0798-Fix-force-opening-enchantment-tables.patch similarity index 100% rename from patches/server/0799-Fix-force-opening-enchantment-tables.patch rename to patches/server/0798-Fix-force-opening-enchantment-tables.patch diff --git a/patches/server/0800-Add-Entity-Body-Yaw-API.patch b/patches/server/0799-Add-Entity-Body-Yaw-API.patch similarity index 100% rename from patches/server/0800-Add-Entity-Body-Yaw-API.patch rename to patches/server/0799-Add-Entity-Body-Yaw-API.patch diff --git a/patches/server/0801-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch b/patches/server/0800-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch similarity index 100% rename from patches/server/0801-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch rename to patches/server/0800-Fix-MC-157464-Prevent-sleeping-villagers-moving-towa.patch diff --git a/patches/server/0802-Add-EntityFertilizeEggEvent.patch b/patches/server/0801-Add-EntityFertilizeEggEvent.patch similarity index 100% rename from patches/server/0802-Add-EntityFertilizeEggEvent.patch rename to patches/server/0801-Add-EntityFertilizeEggEvent.patch diff --git a/patches/server/0803-Fix-HumanEntity-drop-not-updating-the-client-inv.patch b/patches/server/0802-Fix-HumanEntity-drop-not-updating-the-client-inv.patch similarity index 100% rename from patches/server/0803-Fix-HumanEntity-drop-not-updating-the-client-inv.patch rename to patches/server/0802-Fix-HumanEntity-drop-not-updating-the-client-inv.patch diff --git a/patches/server/0804-Add-CompostItemEvent-and-EntityCompostItemEvent.patch b/patches/server/0803-Add-CompostItemEvent-and-EntityCompostItemEvent.patch similarity index 100% rename from patches/server/0804-Add-CompostItemEvent-and-EntityCompostItemEvent.patch rename to patches/server/0803-Add-CompostItemEvent-and-EntityCompostItemEvent.patch diff --git a/patches/server/0805-Correctly-handle-ArmorStand-invisibility.patch b/patches/server/0804-Correctly-handle-ArmorStand-invisibility.patch similarity index 100% rename from patches/server/0805-Correctly-handle-ArmorStand-invisibility.patch rename to patches/server/0804-Correctly-handle-ArmorStand-invisibility.patch diff --git a/patches/server/0806-Fix-advancement-triggers-for-entity-damage.patch b/patches/server/0805-Fix-advancement-triggers-for-entity-damage.patch similarity index 100% rename from patches/server/0806-Fix-advancement-triggers-for-entity-damage.patch rename to patches/server/0805-Fix-advancement-triggers-for-entity-damage.patch diff --git a/patches/server/0807-Fix-text-display-error-on-spawn.patch b/patches/server/0806-Fix-text-display-error-on-spawn.patch similarity index 100% rename from patches/server/0807-Fix-text-display-error-on-spawn.patch rename to patches/server/0806-Fix-text-display-error-on-spawn.patch diff --git a/patches/server/0808-Fix-inventories-returning-null-Locations.patch b/patches/server/0807-Fix-inventories-returning-null-Locations.patch similarity index 100% rename from patches/server/0808-Fix-inventories-returning-null-Locations.patch rename to patches/server/0807-Fix-inventories-returning-null-Locations.patch diff --git a/patches/server/0809-Add-Shearable-API.patch b/patches/server/0808-Add-Shearable-API.patch similarity index 100% rename from patches/server/0809-Add-Shearable-API.patch rename to patches/server/0808-Add-Shearable-API.patch diff --git a/patches/server/0810-Fix-SpawnEggMeta-get-setSpawnedType.patch b/patches/server/0809-Fix-SpawnEggMeta-get-setSpawnedType.patch similarity index 100% rename from patches/server/0810-Fix-SpawnEggMeta-get-setSpawnedType.patch rename to patches/server/0809-Fix-SpawnEggMeta-get-setSpawnedType.patch diff --git a/patches/server/0811-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch b/patches/server/0810-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch similarity index 100% rename from patches/server/0811-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch rename to patches/server/0810-Fix-crash-relating-to-bad-recipes-in-furnace-like-ti.patch diff --git a/patches/server/0812-Treat-sequence-violations-like-they-should-be.patch b/patches/server/0811-Treat-sequence-violations-like-they-should-be.patch similarity index 100% rename from patches/server/0812-Treat-sequence-violations-like-they-should-be.patch rename to patches/server/0811-Treat-sequence-violations-like-they-should-be.patch diff --git a/patches/server/0813-Prevent-causing-expired-keys-from-impacting-new-join.patch b/patches/server/0812-Prevent-causing-expired-keys-from-impacting-new-join.patch similarity index 100% rename from patches/server/0813-Prevent-causing-expired-keys-from-impacting-new-join.patch rename to patches/server/0812-Prevent-causing-expired-keys-from-impacting-new-join.patch diff --git a/patches/server/0814-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch b/patches/server/0813-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch similarity index 91% rename from patches/server/0814-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch rename to patches/server/0813-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch index 9f9f6c26b3..b0096b0c97 100644 --- a/patches/server/0814-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch +++ b/patches/server/0813-Prevent-GameEvents-being-fired-from-unloaded-chunks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent GameEvents being fired from unloaded chunks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index b9d3a98824fc146128f35244f5f15bba97948674..6e9a3b6a1595a1731ca8187d2610c840337a12ed 100644 +index cff225eab588248f1e6487a4a33da006672b3ba4..a27fd023e4f9b6ee113f6b3ed21b4c5aeb7ce15d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1372,6 +1372,11 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0815-Use-array-for-gamerule-storage.patch b/patches/server/0814-Use-array-for-gamerule-storage.patch similarity index 100% rename from patches/server/0815-Use-array-for-gamerule-storage.patch rename to patches/server/0814-Use-array-for-gamerule-storage.patch diff --git a/patches/server/0816-Fix-a-couple-of-upstream-bed-issues.patch b/patches/server/0815-Fix-a-couple-of-upstream-bed-issues.patch similarity index 100% rename from patches/server/0816-Fix-a-couple-of-upstream-bed-issues.patch rename to patches/server/0815-Fix-a-couple-of-upstream-bed-issues.patch diff --git a/patches/server/0817-Fix-demo-flag-not-enabling-demo-mode.patch b/patches/server/0816-Fix-demo-flag-not-enabling-demo-mode.patch similarity index 100% rename from patches/server/0817-Fix-demo-flag-not-enabling-demo-mode.patch rename to patches/server/0816-Fix-demo-flag-not-enabling-demo-mode.patch diff --git a/patches/server/0818-Add-Mob-Experience-reward-API.patch b/patches/server/0817-Add-Mob-Experience-reward-API.patch similarity index 100% rename from patches/server/0818-Add-Mob-Experience-reward-API.patch rename to patches/server/0817-Add-Mob-Experience-reward-API.patch diff --git a/patches/server/0819-Break-redstone-on-top-of-trap-doors-early.patch b/patches/server/0818-Break-redstone-on-top-of-trap-doors-early.patch similarity index 100% rename from patches/server/0819-Break-redstone-on-top-of-trap-doors-early.patch rename to patches/server/0818-Break-redstone-on-top-of-trap-doors-early.patch diff --git a/patches/server/0820-Avoid-Lazy-Initialization-for-Enum-Fields.patch b/patches/server/0819-Avoid-Lazy-Initialization-for-Enum-Fields.patch similarity index 100% rename from patches/server/0820-Avoid-Lazy-Initialization-for-Enum-Fields.patch rename to patches/server/0819-Avoid-Lazy-Initialization-for-Enum-Fields.patch diff --git a/patches/server/0821-More-accurate-isInOpenWater-impl.patch b/patches/server/0820-More-accurate-isInOpenWater-impl.patch similarity index 100% rename from patches/server/0821-More-accurate-isInOpenWater-impl.patch rename to patches/server/0820-More-accurate-isInOpenWater-impl.patch diff --git a/patches/server/0822-Expand-PlayerItemMendEvent.patch b/patches/server/0821-Expand-PlayerItemMendEvent.patch similarity index 98% rename from patches/server/0822-Expand-PlayerItemMendEvent.patch rename to patches/server/0821-Expand-PlayerItemMendEvent.patch index 5cc04e3321..f822118b27 100644 --- a/patches/server/0822-Expand-PlayerItemMendEvent.patch +++ b/patches/server/0821-Expand-PlayerItemMendEvent.patch @@ -30,7 +30,7 @@ index a758b2456acac23095fe4619ae10300a034cb460..a58ff67052fb5f33782f8b5c83465ec0 if (l > 0) { // this.value = l; // CraftBukkit - update exp value of orb for PlayerItemMendEvent calls // Paper - the value field should not be mutated here because it doesn't take "count" into account diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index d0cd2a8c99d607e36d37718b9e2c439f4a939535..7cd9b17e1863a369b578bc2a22d892246e7a02b9 100644 +index 756ba61af10b552c5c0bf86e506a31df0f0ce6f5..b3faca24fa8bdb22d1bf3e581d0396bc444a9f5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1853,11 +1853,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0823-Refresh-ProjectileSource-for-projectiles.patch b/patches/server/0822-Refresh-ProjectileSource-for-projectiles.patch similarity index 100% rename from patches/server/0823-Refresh-ProjectileSource-for-projectiles.patch rename to patches/server/0822-Refresh-ProjectileSource-for-projectiles.patch diff --git a/patches/server/0824-Add-transient-modifier-API.patch b/patches/server/0823-Add-transient-modifier-API.patch similarity index 100% rename from patches/server/0824-Add-transient-modifier-API.patch rename to patches/server/0823-Add-transient-modifier-API.patch diff --git a/patches/server/0825-Fix-block-place-logic.patch b/patches/server/0824-Fix-block-place-logic.patch similarity index 100% rename from patches/server/0825-Fix-block-place-logic.patch rename to patches/server/0824-Fix-block-place-logic.patch diff --git a/patches/server/0826-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch b/patches/server/0825-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch similarity index 100% rename from patches/server/0826-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch rename to patches/server/0825-Fix-spigot-sound-playing-for-BlockItem-ItemStacks.patch diff --git a/patches/server/0827-Call-BlockGrowEvent-for-missing-blocks.patch b/patches/server/0826-Call-BlockGrowEvent-for-missing-blocks.patch similarity index 100% rename from patches/server/0827-Call-BlockGrowEvent-for-missing-blocks.patch rename to patches/server/0826-Call-BlockGrowEvent-for-missing-blocks.patch diff --git a/patches/server/0828-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch b/patches/server/0827-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch similarity index 100% rename from patches/server/0828-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch rename to patches/server/0827-Don-t-enforce-icanhasbukkit-default-if-alias-block-e.patch diff --git a/patches/server/0829-fix-MapLike-spam-for-missing-key-selector.patch b/patches/server/0828-fix-MapLike-spam-for-missing-key-selector.patch similarity index 100% rename from patches/server/0829-fix-MapLike-spam-for-missing-key-selector.patch rename to patches/server/0828-fix-MapLike-spam-for-missing-key-selector.patch diff --git a/patches/server/0830-Fix-sniffer-removeExploredLocation.patch b/patches/server/0829-Fix-sniffer-removeExploredLocation.patch similarity index 100% rename from patches/server/0830-Fix-sniffer-removeExploredLocation.patch rename to patches/server/0829-Fix-sniffer-removeExploredLocation.patch diff --git a/patches/server/0831-Add-method-to-remove-all-active-potion-effects.patch b/patches/server/0830-Add-method-to-remove-all-active-potion-effects.patch similarity index 100% rename from patches/server/0831-Add-method-to-remove-all-active-potion-effects.patch rename to patches/server/0830-Add-method-to-remove-all-active-potion-effects.patch diff --git a/patches/server/0832-Fix-incorrect-crafting-result-amount-for-fireworks.patch b/patches/server/0831-Fix-incorrect-crafting-result-amount-for-fireworks.patch similarity index 100% rename from patches/server/0832-Fix-incorrect-crafting-result-amount-for-fireworks.patch rename to patches/server/0831-Fix-incorrect-crafting-result-amount-for-fireworks.patch diff --git a/patches/server/0833-Add-event-for-player-editing-sign.patch b/patches/server/0832-Add-event-for-player-editing-sign.patch similarity index 100% rename from patches/server/0833-Add-event-for-player-editing-sign.patch rename to patches/server/0832-Add-event-for-player-editing-sign.patch diff --git a/patches/server/0834-Only-tick-item-frames-if-players-can-see-it.patch b/patches/server/0833-Only-tick-item-frames-if-players-can-see-it.patch similarity index 100% rename from patches/server/0834-Only-tick-item-frames-if-players-can-see-it.patch rename to patches/server/0833-Only-tick-item-frames-if-players-can-see-it.patch diff --git a/patches/server/0835-Fix-cmd-permission-levels-for-command-blocks.patch b/patches/server/0834-Fix-cmd-permission-levels-for-command-blocks.patch similarity index 100% rename from patches/server/0835-Fix-cmd-permission-levels-for-command-blocks.patch rename to patches/server/0834-Fix-cmd-permission-levels-for-command-blocks.patch diff --git a/patches/server/0836-Add-option-to-disable-block-updates.patch b/patches/server/0835-Add-option-to-disable-block-updates.patch similarity index 100% rename from patches/server/0836-Add-option-to-disable-block-updates.patch rename to patches/server/0835-Add-option-to-disable-block-updates.patch diff --git a/patches/server/0837-Call-missing-BlockDispenseEvent.patch b/patches/server/0836-Call-missing-BlockDispenseEvent.patch similarity index 100% rename from patches/server/0837-Call-missing-BlockDispenseEvent.patch rename to patches/server/0836-Call-missing-BlockDispenseEvent.patch diff --git a/patches/server/0838-Don-t-load-chunks-for-supporting-block-checks.patch b/patches/server/0837-Don-t-load-chunks-for-supporting-block-checks.patch similarity index 100% rename from patches/server/0838-Don-t-load-chunks-for-supporting-block-checks.patch rename to patches/server/0837-Don-t-load-chunks-for-supporting-block-checks.patch diff --git a/patches/server/0839-Optimize-player-lookups-for-beacons.patch b/patches/server/0838-Optimize-player-lookups-for-beacons.patch similarity index 100% rename from patches/server/0839-Optimize-player-lookups-for-beacons.patch rename to patches/server/0838-Optimize-player-lookups-for-beacons.patch diff --git a/patches/server/0840-Add-Sign-getInteractableSideFor.patch b/patches/server/0839-Add-Sign-getInteractableSideFor.patch similarity index 100% rename from patches/server/0840-Add-Sign-getInteractableSideFor.patch rename to patches/server/0839-Add-Sign-getInteractableSideFor.patch diff --git a/patches/server/0841-fix-item-meta-for-tadpole-buckets.patch b/patches/server/0840-fix-item-meta-for-tadpole-buckets.patch similarity index 100% rename from patches/server/0841-fix-item-meta-for-tadpole-buckets.patch rename to patches/server/0840-fix-item-meta-for-tadpole-buckets.patch diff --git a/patches/server/0842-Fix-BanList-API.patch b/patches/server/0841-Fix-BanList-API.patch similarity index 99% rename from patches/server/0842-Fix-BanList-API.patch rename to patches/server/0841-Fix-BanList-API.patch index 995aa9c90a..780f2ca5be 100644 --- a/patches/server/0842-Fix-BanList-API.patch +++ b/patches/server/0841-Fix-BanList-API.patch @@ -208,7 +208,7 @@ index 172202accf4448a933fcf1ff820316c7910dd7f7..50ee7656580d386db473c054f5c5ec57 return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 7cd9b17e1863a369b578bc2a22d892246e7a02b9..49e22acbcdcdb2108b360c2a6e40c752c12ab9f6 100644 +index b3faca24fa8bdb22d1bf3e581d0396bc444a9f5f..28536a8bfab2c8bdde03852efa0e41cf19a37a9c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1747,23 +1747,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0843-Determine-lava-and-water-fluid-explosion-resistance-.patch b/patches/server/0842-Determine-lava-and-water-fluid-explosion-resistance-.patch similarity index 100% rename from patches/server/0843-Determine-lava-and-water-fluid-explosion-resistance-.patch rename to patches/server/0842-Determine-lava-and-water-fluid-explosion-resistance-.patch diff --git a/patches/server/0844-Fix-possible-NPE-on-painting-creation.patch b/patches/server/0843-Fix-possible-NPE-on-painting-creation.patch similarity index 100% rename from patches/server/0844-Fix-possible-NPE-on-painting-creation.patch rename to patches/server/0843-Fix-possible-NPE-on-painting-creation.patch diff --git a/patches/server/0845-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0844-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch similarity index 100% rename from patches/server/0845-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch rename to patches/server/0844-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch diff --git a/patches/server/0846-ExperienceOrb-should-call-EntitySpawnEvent.patch b/patches/server/0845-ExperienceOrb-should-call-EntitySpawnEvent.patch similarity index 100% rename from patches/server/0846-ExperienceOrb-should-call-EntitySpawnEvent.patch rename to patches/server/0845-ExperienceOrb-should-call-EntitySpawnEvent.patch diff --git a/patches/server/0847-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch b/patches/server/0846-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch similarity index 100% rename from patches/server/0847-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch rename to patches/server/0846-Make-Amethyst-throw-both-Spread-and-Grow-Events.patch diff --git a/patches/server/0848-Add-whitelist-events.patch b/patches/server/0847-Add-whitelist-events.patch similarity index 100% rename from patches/server/0848-Add-whitelist-events.patch rename to patches/server/0847-Add-whitelist-events.patch diff --git a/patches/server/0849-Implement-PlayerFailMoveEvent.patch b/patches/server/0848-Implement-PlayerFailMoveEvent.patch similarity index 100% rename from patches/server/0849-Implement-PlayerFailMoveEvent.patch rename to patches/server/0848-Implement-PlayerFailMoveEvent.patch diff --git a/patches/server/0850-Folia-scheduler-and-owned-region-API.patch b/patches/server/0849-Folia-scheduler-and-owned-region-API.patch similarity index 98% rename from patches/server/0850-Folia-scheduler-and-owned-region-API.patch rename to patches/server/0849-Folia-scheduler-and-owned-region-API.patch index 02f361a409..6657e8e33f 100644 --- a/patches/server/0850-Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/0849-Folia-scheduler-and-owned-region-API.patch @@ -45,14 +45,14 @@ index d2dee700f2c5cc7d6a272e751a933901fe7a55b6..834b85f24df023642f8abf7213fe578a } catch (Throwable ex) { diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..62484ebf4550b05182f693a3180bbac5d5fd906d +index 0000000000000000000000000000000000000000..c03608fec96b51e1867f43d8f42e5aefb1520e46 --- /dev/null +++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java @@ -0,0 +1,181 @@ +package io.papermc.paper.threadedregions; + +import ca.spottedleaf.concurrentutil.util.Validate; -+import io.papermc.paper.util.TickThread; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.world.entity.Entity; +import org.bukkit.craftbukkit.entity.CraftEntity; @@ -1148,10 +1148,10 @@ index 0000000000000000000000000000000000000000..d306f911757a4d556c82c0070d4837db + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 374c20e530d2abd41674d80c711bd3737c6f6941..cbceb0ddea32781f89a19b1edb258bc23b96ee92 100644 +index a72b278826be1d0da79ca619ea9a9a437fa9c54b..2dfa9c4c0c2ef489649944eed89d8c77c482b92f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1579,6 +1579,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> 4, position.blockZ() >> 4 + ); + } + + @Override + public final boolean isOwnedByCurrentRegion(World world, io.papermc.paper.math.Position position, int squareRadiusChunks) { -+ return io.papermc.paper.util.TickThread.isTickThreadFor( ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor( + ((CraftWorld) world).getHandle(), position.blockX() >> 4, position.blockZ() >> 4, squareRadiusChunks + ); + } @@ -1295,7 +1295,7 @@ index 7197cbf15ff9382cbc59c4a58e2f189c8cacbaaa..24097256203990a818aab2716fdb8a4a + @Override + public final boolean isOwnedByCurrentRegion(Location location) { + World world = location.getWorld(); -+ return io.papermc.paper.util.TickThread.isTickThreadFor( ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor( + ((CraftWorld) world).getHandle(), location.getBlockX() >> 4, location.getBlockZ() >> 4 + ); + } @@ -1303,28 +1303,28 @@ index 7197cbf15ff9382cbc59c4a58e2f189c8cacbaaa..24097256203990a818aab2716fdb8a4a + @Override + public final boolean isOwnedByCurrentRegion(Location location, int squareRadiusChunks) { + World world = location.getWorld(); -+ return io.papermc.paper.util.TickThread.isTickThreadFor( ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor( + ((CraftWorld) world).getHandle(), location.getBlockX() >> 4, location.getBlockZ() >> 4, squareRadiusChunks + ); + } + + @Override + public final boolean isOwnedByCurrentRegion(World world, int chunkX, int chunkZ) { -+ return io.papermc.paper.util.TickThread.isTickThreadFor( ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor( + ((CraftWorld) world).getHandle(), chunkX, chunkZ + ); + } + + @Override + public final boolean isOwnedByCurrentRegion(World world, int chunkX, int chunkZ, int squareRadiusChunks) { -+ return io.papermc.paper.util.TickThread.isTickThreadFor( ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor( + ((CraftWorld) world).getHandle(), chunkX, chunkZ, squareRadiusChunks + ); + } + + @Override + public final boolean isOwnedByCurrentRegion(Entity entity) { -+ return io.papermc.paper.util.TickThread.isTickThreadFor(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandleRaw()); ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandleRaw()); + } + // Paper end - Folia reagion threading API + diff --git a/patches/server/0851-Only-erase-allay-memory-on-non-item-targets.patch b/patches/server/0850-Only-erase-allay-memory-on-non-item-targets.patch similarity index 100% rename from patches/server/0851-Only-erase-allay-memory-on-non-item-targets.patch rename to patches/server/0850-Only-erase-allay-memory-on-non-item-targets.patch diff --git a/patches/server/0852-API-for-updating-recipes-on-clients.patch b/patches/server/0851-API-for-updating-recipes-on-clients.patch similarity index 97% rename from patches/server/0852-API-for-updating-recipes-on-clients.patch rename to patches/server/0851-API-for-updating-recipes-on-clients.patch index 5c29dfb157..6ffb4d4c04 100644 --- a/patches/server/0852-API-for-updating-recipes-on-clients.patch +++ b/patches/server/0851-API-for-updating-recipes-on-clients.patch @@ -39,7 +39,7 @@ index de96d7df65713f2fa7b8f2dd068856bb5fa45a45..be6bf7afa3cea4ed48f363e89ccd0790 Iterator iterator1 = this.players.iterator(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 24097256203990a818aab2716fdb8a4a672a1daa..5400493e48b508310adfb51c23b63ff53aeda49f 100644 +index 6d373fb254225aa92a10181d8dd21e2dd7fb063a..71d335984d845c95acf5772e8ae773899a429e84 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1165,6 +1165,18 @@ public final class CraftServer implements Server { diff --git a/patches/server/0853-Fix-rotation-when-spawning-display-entities.patch b/patches/server/0852-Fix-rotation-when-spawning-display-entities.patch similarity index 100% rename from patches/server/0853-Fix-rotation-when-spawning-display-entities.patch rename to patches/server/0852-Fix-rotation-when-spawning-display-entities.patch diff --git a/patches/server/0854-Only-capture-actual-tree-growth.patch b/patches/server/0853-Only-capture-actual-tree-growth.patch similarity index 100% rename from patches/server/0854-Only-capture-actual-tree-growth.patch rename to patches/server/0853-Only-capture-actual-tree-growth.patch diff --git a/patches/server/0855-Use-correct-source-for-mushroom-block-spread-event.patch b/patches/server/0854-Use-correct-source-for-mushroom-block-spread-event.patch similarity index 100% rename from patches/server/0855-Use-correct-source-for-mushroom-block-spread-event.patch rename to patches/server/0854-Use-correct-source-for-mushroom-block-spread-event.patch diff --git a/patches/server/0856-Respect-randomizeData-on-more-entities-when-spawning.patch b/patches/server/0855-Respect-randomizeData-on-more-entities-when-spawning.patch similarity index 100% rename from patches/server/0856-Respect-randomizeData-on-more-entities-when-spawning.patch rename to patches/server/0855-Respect-randomizeData-on-more-entities-when-spawning.patch diff --git a/patches/server/0857-Use-correct-seed-on-api-world-load.patch b/patches/server/0856-Use-correct-seed-on-api-world-load.patch similarity index 92% rename from patches/server/0857-Use-correct-seed-on-api-world-load.patch rename to patches/server/0856-Use-correct-seed-on-api-world-load.patch index f29dbe4467..6c4ddae940 100644 --- a/patches/server/0857-Use-correct-seed-on-api-world-load.patch +++ b/patches/server/0856-Use-correct-seed-on-api-world-load.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Use correct seed on api world load diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 5400493e48b508310adfb51c23b63ff53aeda49f..2e0c07ab0f89043a97bcb15b6c507f6c052d2a4e 100644 +index 71d335984d845c95acf5772e8ae773899a429e84..67a199f022bc9387f7fd69889efec5bad2ed0a5f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1387,7 +1387,7 @@ public final class CraftServer implements Server { diff --git a/patches/server/0858-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch b/patches/server/0857-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch similarity index 100% rename from patches/server/0858-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch rename to patches/server/0857-Remove-UpgradeData-neighbour-ticks-outside-of-range.patch diff --git a/patches/server/0859-Cache-map-ids-on-item-frames.patch b/patches/server/0858-Cache-map-ids-on-item-frames.patch similarity index 100% rename from patches/server/0859-Cache-map-ids-on-item-frames.patch rename to patches/server/0858-Cache-map-ids-on-item-frames.patch diff --git a/patches/server/0860-Fix-custom-statistic-criteria-creation.patch b/patches/server/0859-Fix-custom-statistic-criteria-creation.patch similarity index 100% rename from patches/server/0860-Fix-custom-statistic-criteria-creation.patch rename to patches/server/0859-Fix-custom-statistic-criteria-creation.patch diff --git a/patches/server/0861-Bandaid-fix-for-Effect.patch b/patches/server/0860-Bandaid-fix-for-Effect.patch similarity index 97% rename from patches/server/0861-Bandaid-fix-for-Effect.patch rename to patches/server/0860-Bandaid-fix-for-Effect.patch index bc688c91d4..37c8fc587f 100644 --- a/patches/server/0861-Bandaid-fix-for-Effect.patch +++ b/patches/server/0860-Bandaid-fix-for-Effect.patch @@ -68,7 +68,7 @@ index 71733f918ed84b9879ac1b142ef6205c5e768a9c..c856384019eff2f2d0bb831ebe1ccb0f break; case BONE_MEAL_USE: diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 1ef380cbd77132b743520f952afa8321042bec6d..7fe43ac849d3ee80c447e8c024ea39fd338d616f 100644 +index 0c5a583f2ced1ae5e1e92a045ef2ef1cd5b35496..5c83ca573ccaa75a1d4e8129c96a24e3cf0f3266 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1360,7 +1360,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -81,7 +81,7 @@ index 1ef380cbd77132b743520f952afa8321042bec6d..7fe43ac849d3ee80c447e8c024ea39fd // Special case: the axis is optional for ELECTRIC_SPARK Preconditions.checkArgument(effect.getData() == null || effect == Effect.ELECTRIC_SPARK, "Wrong kind of data for the %s effect", effect); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 49e22acbcdcdb2108b360c2a6e40c752c12ab9f6..4c5249eab8e59b46c902f2cb65f90aa2a66a33d4 100644 +index 28536a8bfab2c8bdde03852efa0e41cf19a37a9c..cb41fad4b94c4da64a699dc1b0848fc08ff2c456 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -917,7 +917,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0862-SculkCatalyst-bloom-API.patch b/patches/server/0861-SculkCatalyst-bloom-API.patch similarity index 100% rename from patches/server/0862-SculkCatalyst-bloom-API.patch rename to patches/server/0861-SculkCatalyst-bloom-API.patch diff --git a/patches/server/0863-API-for-an-entity-s-scoreboard-name.patch b/patches/server/0862-API-for-an-entity-s-scoreboard-name.patch similarity index 100% rename from patches/server/0863-API-for-an-entity-s-scoreboard-name.patch rename to patches/server/0862-API-for-an-entity-s-scoreboard-name.patch diff --git a/patches/server/0864-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/server/0863-Deprecate-and-replace-methods-with-old-StructureType.patch similarity index 96% rename from patches/server/0864-Deprecate-and-replace-methods-with-old-StructureType.patch rename to patches/server/0863-Deprecate-and-replace-methods-with-old-StructureType.patch index 7eeb4db8f2..aba2d09d90 100644 --- a/patches/server/0864-Deprecate-and-replace-methods-with-old-StructureType.patch +++ b/patches/server/0863-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Deprecate and replace methods with old StructureType diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 2e0c07ab0f89043a97bcb15b6c507f6c052d2a4e..56f9b69b5a30c4ee5bcbcb8ae33e26f75b477475 100644 +index 67a199f022bc9387f7fd69889efec5bad2ed0a5f..3ca0d01d4d55d0919624356751144985587ddc25 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1992,6 +1992,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0865-Don-t-tab-complete-namespaced-commands-if-send-names.patch b/patches/server/0864-Don-t-tab-complete-namespaced-commands-if-send-names.patch similarity index 100% rename from patches/server/0865-Don-t-tab-complete-namespaced-commands-if-send-names.patch rename to patches/server/0864-Don-t-tab-complete-namespaced-commands-if-send-names.patch diff --git a/patches/server/0866-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0865-Properly-handle-BlockBreakEvent-isDropItems.patch similarity index 100% rename from patches/server/0866-Properly-handle-BlockBreakEvent-isDropItems.patch rename to patches/server/0865-Properly-handle-BlockBreakEvent-isDropItems.patch diff --git a/patches/server/0867-Fire-entity-death-event-for-ender-dragon.patch b/patches/server/0866-Fire-entity-death-event-for-ender-dragon.patch similarity index 100% rename from patches/server/0867-Fire-entity-death-event-for-ender-dragon.patch rename to patches/server/0866-Fire-entity-death-event-for-ender-dragon.patch diff --git a/patches/server/0868-Configurable-entity-tracking-range-by-Y-coordinate.patch b/patches/server/0867-Configurable-entity-tracking-range-by-Y-coordinate.patch similarity index 91% rename from patches/server/0868-Configurable-entity-tracking-range-by-Y-coordinate.patch rename to patches/server/0867-Configurable-entity-tracking-range-by-Y-coordinate.patch index 8cb5db78e2..b9f6c1d957 100644 --- a/patches/server/0868-Configurable-entity-tracking-range-by-Y-coordinate.patch +++ b/patches/server/0867-Configurable-entity-tracking-range-by-Y-coordinate.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Configurable entity tracking range by Y coordinate Options to configure entity tracking by Y coordinate, also for each entity category. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 91ca37605bf7ba65875b588fe9764b30214f63b6..2943390c0ec7e542d2bb1996dbbd626445c3108e 100644 +index cc7c284079af5ec4fd7085e87a7de47aacda587d..a179fef4a020b66224984e3bf5b4b5255274103c 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1566,6 +1566,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1530,6 +1530,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider double d1 = vec3d.x * vec3d.x + vec3d.z * vec3d.z; double d2 = d0 * d0; boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z); diff --git a/patches/server/0869-Add-Listing-API-for-Player.patch b/patches/server/0868-Add-Listing-API-for-Player.patch similarity index 99% rename from patches/server/0869-Add-Listing-API-for-Player.patch rename to patches/server/0868-Add-Listing-API-for-Player.patch index 8f4e9c9d40..bb270bf016 100644 --- a/patches/server/0869-Add-Listing-API-for-Player.patch +++ b/patches/server/0868-Add-Listing-API-for-Player.patch @@ -119,7 +119,7 @@ index be6bf7afa3cea4ed48f363e89ccd079062edc8d9..9b1a6d8351fb473eec75a2fd08fb892b // Paper end - Use single player info update packet on join player.sentListPacket = true; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4c5249eab8e59b46c902f2cb65f90aa2a66a33d4..204e4e4dd197088457cd6d2a18f86287ca3324b2 100644 +index cb41fad4b94c4da64a699dc1b0848fc08ff2c456..c80cbc9dece765091b2ad9281bdc061df8b491dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -201,6 +201,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0870-Configurable-Region-Compression-Format.patch b/patches/server/0869-Configurable-Region-Compression-Format.patch similarity index 100% rename from patches/server/0870-Configurable-Region-Compression-Format.patch rename to patches/server/0869-Configurable-Region-Compression-Format.patch diff --git a/patches/server/0871-Add-BlockFace-to-BlockDamageEvent.patch b/patches/server/0870-Add-BlockFace-to-BlockDamageEvent.patch similarity index 100% rename from patches/server/0871-Add-BlockFace-to-BlockDamageEvent.patch rename to patches/server/0870-Add-BlockFace-to-BlockDamageEvent.patch diff --git a/patches/server/0872-Fix-NPE-on-Boat-getStatus.patch b/patches/server/0871-Fix-NPE-on-Boat-getStatus.patch similarity index 100% rename from patches/server/0872-Fix-NPE-on-Boat-getStatus.patch rename to patches/server/0871-Fix-NPE-on-Boat-getStatus.patch diff --git a/patches/server/0873-Expand-Pose-API.patch b/patches/server/0872-Expand-Pose-API.patch similarity index 100% rename from patches/server/0873-Expand-Pose-API.patch rename to patches/server/0872-Expand-Pose-API.patch diff --git a/patches/server/0874-More-DragonBattle-API.patch b/patches/server/0873-More-DragonBattle-API.patch similarity index 100% rename from patches/server/0874-More-DragonBattle-API.patch rename to patches/server/0873-More-DragonBattle-API.patch diff --git a/patches/server/0875-Add-PlayerPickItemEvent.patch b/patches/server/0874-Add-PlayerPickItemEvent.patch similarity index 100% rename from patches/server/0875-Add-PlayerPickItemEvent.patch rename to patches/server/0874-Add-PlayerPickItemEvent.patch diff --git a/patches/server/0876-Allow-trident-custom-damage.patch b/patches/server/0875-Allow-trident-custom-damage.patch similarity index 100% rename from patches/server/0876-Allow-trident-custom-damage.patch rename to patches/server/0875-Allow-trident-custom-damage.patch diff --git a/patches/server/0877-Expose-hand-in-BlockCanBuildEvent.patch b/patches/server/0876-Expose-hand-in-BlockCanBuildEvent.patch similarity index 100% rename from patches/server/0877-Expose-hand-in-BlockCanBuildEvent.patch rename to patches/server/0876-Expose-hand-in-BlockCanBuildEvent.patch diff --git a/patches/server/0878-Optimize-nearest-structure-border-iteration.patch b/patches/server/0877-Optimize-nearest-structure-border-iteration.patch similarity index 100% rename from patches/server/0878-Optimize-nearest-structure-border-iteration.patch rename to patches/server/0877-Optimize-nearest-structure-border-iteration.patch diff --git a/patches/server/0879-Implement-OfflinePlayer-isConnected.patch b/patches/server/0878-Implement-OfflinePlayer-isConnected.patch similarity index 94% rename from patches/server/0879-Implement-OfflinePlayer-isConnected.patch rename to patches/server/0878-Implement-OfflinePlayer-isConnected.patch index b56ab203ed..2d00249134 100644 --- a/patches/server/0879-Implement-OfflinePlayer-isConnected.patch +++ b/patches/server/0878-Implement-OfflinePlayer-isConnected.patch @@ -23,7 +23,7 @@ index 4d654c4f0b6210a9841427789ba70ce5d1d308be..9d93130f23addb18b97d7f5ec013faef public String getName() { Player player = this.getPlayer(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 204e4e4dd197088457cd6d2a18f86287ca3324b2..ea742de14280c64f94461ebfb4647536a1dddb4f 100644 +index c80cbc9dece765091b2ad9281bdc061df8b491dc..a996f721fa0794a4551ff1e99ea1b66a723bfaff 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -256,6 +256,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0880-Fix-inventory-desync.patch b/patches/server/0879-Fix-inventory-desync.patch similarity index 97% rename from patches/server/0880-Fix-inventory-desync.patch rename to patches/server/0879-Fix-inventory-desync.patch index faa218a853..dbce7345ef 100644 --- a/patches/server/0880-Fix-inventory-desync.patch +++ b/patches/server/0879-Fix-inventory-desync.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix inventory desync diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ccb4cbb28fc9c565571e1f9da2bf459cec25d36c..b5035cc4b5cfa246487dc5091cc5d43e04253d6d 100644 +index a755d5d8e435e6545ca433ce5c7ea818d5cd6a28..2ba005b04577d424128c60bb77ce07fa63b40251 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -402,6 +402,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -399,6 +399,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { // Use method to resend items in hands in case of client desync, because the item use got cancelled. // For example, when cancelling the leash event diff --git a/patches/server/0881-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/server/0880-Add-titleOverride-to-InventoryOpenEvent.patch similarity index 97% rename from patches/server/0881-Add-titleOverride-to-InventoryOpenEvent.patch rename to patches/server/0880-Add-titleOverride-to-InventoryOpenEvent.patch index c8738e3bfc..ba8d018f54 100644 --- a/patches/server/0881-Add-titleOverride-to-InventoryOpenEvent.patch +++ b/patches/server/0880-Add-titleOverride-to-InventoryOpenEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add titleOverride to InventoryOpenEvent diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b5035cc4b5cfa246487dc5091cc5d43e04253d6d..f568fa18ddcb1a1cd060c469edd6db45431bb53c 100644 +index 2ba005b04577d424128c60bb77ce07fa63b40251..2f880e10c73b48c4989c7623ea6cf368f4afb53a 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1659,12 +1659,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1656,12 +1656,17 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { this.nextContainerCounter(); AbstractContainerMenu container = factory.createMenu(this.containerCounter, this.getInventory(), this); @@ -27,7 +27,7 @@ index b5035cc4b5cfa246487dc5091cc5d43e04253d6d..f568fa18ddcb1a1cd060c469edd6db45 if (container == null && !cancelled) { // Let pre-cancelled events fall through // SPIGOT-5263 - close chest if cancelled if (factory instanceof Container) { -@@ -1686,7 +1691,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -1683,7 +1688,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { } else { // CraftBukkit start this.containerMenu = container; diff --git a/patches/server/0882-Configure-sniffer-egg-hatch-time.patch b/patches/server/0881-Configure-sniffer-egg-hatch-time.patch similarity index 100% rename from patches/server/0882-Configure-sniffer-egg-hatch-time.patch rename to patches/server/0881-Configure-sniffer-egg-hatch-time.patch diff --git a/patches/server/0883-Do-crystal-portal-proximity-check-before-entity-look.patch b/patches/server/0882-Do-crystal-portal-proximity-check-before-entity-look.patch similarity index 100% rename from patches/server/0883-Do-crystal-portal-proximity-check-before-entity-look.patch rename to patches/server/0882-Do-crystal-portal-proximity-check-before-entity-look.patch diff --git a/patches/server/0884-Skip-POI-finding-if-stuck-in-vehicle.patch b/patches/server/0883-Skip-POI-finding-if-stuck-in-vehicle.patch similarity index 100% rename from patches/server/0884-Skip-POI-finding-if-stuck-in-vehicle.patch rename to patches/server/0883-Skip-POI-finding-if-stuck-in-vehicle.patch diff --git a/patches/server/0885-Add-slot-sanity-checks-in-container-clicks.patch b/patches/server/0884-Add-slot-sanity-checks-in-container-clicks.patch similarity index 100% rename from patches/server/0885-Add-slot-sanity-checks-in-container-clicks.patch rename to patches/server/0884-Add-slot-sanity-checks-in-container-clicks.patch diff --git a/patches/server/0886-Call-BlockRedstoneEvents-for-lecterns.patch b/patches/server/0885-Call-BlockRedstoneEvents-for-lecterns.patch similarity index 100% rename from patches/server/0886-Call-BlockRedstoneEvents-for-lecterns.patch rename to patches/server/0885-Call-BlockRedstoneEvents-for-lecterns.patch diff --git a/patches/server/0887-Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/0886-Allow-proper-checking-of-empty-item-stacks.patch similarity index 100% rename from patches/server/0887-Allow-proper-checking-of-empty-item-stacks.patch rename to patches/server/0886-Allow-proper-checking-of-empty-item-stacks.patch diff --git a/patches/server/0888-Fix-silent-equipment-change-for-mobs.patch b/patches/server/0887-Fix-silent-equipment-change-for-mobs.patch similarity index 100% rename from patches/server/0888-Fix-silent-equipment-change-for-mobs.patch rename to patches/server/0887-Fix-silent-equipment-change-for-mobs.patch diff --git a/patches/server/0889-Fix-spigot-s-Forced-Stats.patch b/patches/server/0888-Fix-spigot-s-Forced-Stats.patch similarity index 100% rename from patches/server/0889-Fix-spigot-s-Forced-Stats.patch rename to patches/server/0888-Fix-spigot-s-Forced-Stats.patch diff --git a/patches/server/0890-Add-missing-InventoryHolders-to-inventories.patch b/patches/server/0889-Add-missing-InventoryHolders-to-inventories.patch similarity index 100% rename from patches/server/0890-Add-missing-InventoryHolders-to-inventories.patch rename to patches/server/0889-Add-missing-InventoryHolders-to-inventories.patch diff --git a/patches/server/0891-Do-not-read-tile-entities-in-chunks-that-are-positio.patch b/patches/server/0890-Do-not-read-tile-entities-in-chunks-that-are-positio.patch similarity index 100% rename from patches/server/0891-Do-not-read-tile-entities-in-chunks-that-are-positio.patch rename to patches/server/0890-Do-not-read-tile-entities-in-chunks-that-are-positio.patch diff --git a/patches/server/0892-Add-missing-logs-for-log-ips-config-option.patch b/patches/server/0891-Add-missing-logs-for-log-ips-config-option.patch similarity index 100% rename from patches/server/0892-Add-missing-logs-for-log-ips-config-option.patch rename to patches/server/0891-Add-missing-logs-for-log-ips-config-option.patch diff --git a/patches/server/0893-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch b/patches/server/0892-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch similarity index 100% rename from patches/server/0893-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch rename to patches/server/0892-Fix-race-condition-on-UpgradeData.BlockFixers-class-.patch diff --git a/patches/server/0894-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch b/patches/server/0893-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch similarity index 100% rename from patches/server/0894-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch rename to patches/server/0893-Fix-NPE-in-AdvancementProgress-getDateAwarded.patch diff --git a/patches/server/0895-Fix-team-sidebar-objectives-not-being-cleared.patch b/patches/server/0894-Fix-team-sidebar-objectives-not-being-cleared.patch similarity index 100% rename from patches/server/0895-Fix-team-sidebar-objectives-not-being-cleared.patch rename to patches/server/0894-Fix-team-sidebar-objectives-not-being-cleared.patch diff --git a/patches/server/0896-Fix-missing-map-initialize-event-call.patch b/patches/server/0895-Fix-missing-map-initialize-event-call.patch similarity index 95% rename from patches/server/0896-Fix-missing-map-initialize-event-call.patch rename to patches/server/0895-Fix-missing-map-initialize-event-call.patch index 214c9bce18..1ee21864ad 100644 --- a/patches/server/0896-Fix-missing-map-initialize-event-call.patch +++ b/patches/server/0895-Fix-missing-map-initialize-event-call.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Fix missing map initialize event call public net.minecraft.world.level.storage.DimensionDataStorage readSavedData(Ljava/util/function/Function;Lnet/minecraft/util/datafix/DataFixTypes;Ljava/lang/String;)Lnet/minecraft/world/level/saveddata/SavedData; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 6e9a3b6a1595a1731ca8187d2610c840337a12ed..8b5eabea1a0926c22b58ef8761caee3a06aa5ee0 100644 +index a27fd023e4f9b6ee113f6b3ed21b4c5aeb7ce15d..c5e404dcdab14dc0b972aa3286b05e21d9ea67e0 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1662,13 +1662,24 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0897-Update-entity-data-when-attaching-firework-to-entity.patch b/patches/server/0896-Update-entity-data-when-attaching-firework-to-entity.patch similarity index 100% rename from patches/server/0897-Update-entity-data-when-attaching-firework-to-entity.patch rename to patches/server/0896-Update-entity-data-when-attaching-firework-to-entity.patch diff --git a/patches/server/0898-Fix-UnsafeValues-loadAdvancement.patch b/patches/server/0897-Fix-UnsafeValues-loadAdvancement.patch similarity index 100% rename from patches/server/0898-Fix-UnsafeValues-loadAdvancement.patch rename to patches/server/0897-Fix-UnsafeValues-loadAdvancement.patch diff --git a/patches/server/0899-Add-player-idle-duration-API.patch b/patches/server/0898-Add-player-idle-duration-API.patch similarity index 91% rename from patches/server/0899-Add-player-idle-duration-API.patch rename to patches/server/0898-Add-player-idle-duration-API.patch index eac8276c5d..9e5130fc3a 100644 --- a/patches/server/0899-Add-player-idle-duration-API.patch +++ b/patches/server/0898-Add-player-idle-duration-API.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add player idle duration API Implements API for getting and resetting a player's idle duration. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index ea742de14280c64f94461ebfb4647536a1dddb4f..bababc918704a671ee4635ba0c79219d94474821 100644 +index a996f721fa0794a4551ff1e99ea1b66a723bfaff..e443e260afbda55cc9888efd60d9b5f56dcbf55b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3419,6 +3419,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0900-Don-t-check-if-we-can-see-non-visible-entities.patch b/patches/server/0899-Don-t-check-if-we-can-see-non-visible-entities.patch similarity index 85% rename from patches/server/0900-Don-t-check-if-we-can-see-non-visible-entities.patch rename to patches/server/0899-Don-t-check-if-we-can-see-non-visible-entities.patch index 246f9bf864..dbe3bb37ce 100644 --- a/patches/server/0900-Don-t-check-if-we-can-see-non-visible-entities.patch +++ b/patches/server/0899-Don-t-check-if-we-can-see-non-visible-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't check if we can see non-visible entities diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 2943390c0ec7e542d2bb1996dbbd626445c3108e..7bc142fd0ba58846f1b2ac57df0bfc044966f4ed 100644 +index a179fef4a020b66224984e3bf5b4b5255274103c..12361438efd12e327c8f6c2c1b233f05075402f8 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1577,7 +1577,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1541,7 +1541,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - Configurable entity tracking range by Y // CraftBukkit start - respect vanish API diff --git a/patches/server/0901-Fix-NPE-in-SculkBloomEvent-world-access.patch b/patches/server/0900-Fix-NPE-in-SculkBloomEvent-world-access.patch similarity index 100% rename from patches/server/0901-Fix-NPE-in-SculkBloomEvent-world-access.patch rename to patches/server/0900-Fix-NPE-in-SculkBloomEvent-world-access.patch diff --git a/patches/server/0902-Allow-null-itemstack-for-Player-sendEquipmentChange.patch b/patches/server/0901-Allow-null-itemstack-for-Player-sendEquipmentChange.patch similarity index 90% rename from patches/server/0902-Allow-null-itemstack-for-Player-sendEquipmentChange.patch rename to patches/server/0901-Allow-null-itemstack-for-Player-sendEquipmentChange.patch index ef0d009597..ec4d42387a 100644 --- a/patches/server/0902-Allow-null-itemstack-for-Player-sendEquipmentChange.patch +++ b/patches/server/0901-Allow-null-itemstack-for-Player-sendEquipmentChange.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow null itemstack for Player#sendEquipmentChange diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index bababc918704a671ee4635ba0c79219d94474821..cb2cda2cb472b6ca0dd9b4fd1aea74ec3d215bbf 100644 +index e443e260afbda55cc9888efd60d9b5f56dcbf55b..f337c32fa4521d6ddd1c4d6102404db389f23b71 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1127,7 +1127,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0903-Optimize-VarInts.patch b/patches/server/0902-Optimize-VarInts.patch similarity index 100% rename from patches/server/0903-Optimize-VarInts.patch rename to patches/server/0902-Optimize-VarInts.patch diff --git a/patches/server/0904-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/server/0903-Add-API-to-get-the-collision-shape-of-a-block-before.patch similarity index 100% rename from patches/server/0904-Add-API-to-get-the-collision-shape-of-a-block-before.patch rename to patches/server/0903-Add-API-to-get-the-collision-shape-of-a-block-before.patch diff --git a/patches/server/0905-Add-predicate-for-blocks-when-raytracing.patch b/patches/server/0904-Add-predicate-for-blocks-when-raytracing.patch similarity index 98% rename from patches/server/0905-Add-predicate-for-blocks-when-raytracing.patch rename to patches/server/0904-Add-predicate-for-blocks-when-raytracing.patch index 96bceb6bfa..3d4d267627 100644 --- a/patches/server/0905-Add-predicate-for-blocks-when-raytracing.patch +++ b/patches/server/0904-Add-predicate-for-blocks-when-raytracing.patch @@ -47,7 +47,7 @@ index c978f3b2d42f512e982f289e76c2422e41b7eec6..bb8e962e63c7a2d931f9bd7f7c002aa3 Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 7fe43ac849d3ee80c447e8c024ea39fd338d616f..e216ac53f94cc5bcd90330a21e0cbda11b65b6ac 100644 +index 5c83ca573ccaa75a1d4e8129c96a24e3cf0f3266..29fa82c15411fbdae09e45e334209dcc93aa1789 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1094,9 +1094,15 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0906-Broadcast-take-item-packets-with-collector-as-source.patch b/patches/server/0905-Broadcast-take-item-packets-with-collector-as-source.patch similarity index 100% rename from patches/server/0906-Broadcast-take-item-packets-with-collector-as-source.patch rename to patches/server/0905-Broadcast-take-item-packets-with-collector-as-source.patch diff --git a/patches/server/0907-Expand-LingeringPotion-API.patch b/patches/server/0906-Expand-LingeringPotion-API.patch similarity index 100% rename from patches/server/0907-Expand-LingeringPotion-API.patch rename to patches/server/0906-Expand-LingeringPotion-API.patch diff --git a/patches/server/0908-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch b/patches/server/0907-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch similarity index 97% rename from patches/server/0908-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch rename to patches/server/0907-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch index 00e51b071b..0ff11632f4 100644 --- a/patches/server/0908-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch +++ b/patches/server/0907-Fix-strikeLightningEffect-powers-lightning-rods-and-.patch @@ -45,7 +45,7 @@ index 0471d9c85af02133f99cca4e181b83b58a3f1abc..4f701788bd21b61cad251a3a88f9bc41 BlockState iblockdata = BaseFireBlock.getState(this.level(), blockposition); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e216ac53f94cc5bcd90330a21e0cbda11b65b6ac..202470633343add6768caa000bda05a0b5d93f4e 100644 +index 29fa82c15411fbdae09e45e334209dcc93aa1789..612dc787880e58e8325a658a63f9fe7536d0860c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -726,7 +726,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0909-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/server/0908-Add-hand-to-fish-event-for-all-player-interactions.patch similarity index 100% rename from patches/server/0909-Add-hand-to-fish-event-for-all-player-interactions.patch rename to patches/server/0908-Add-hand-to-fish-event-for-all-player-interactions.patch diff --git a/patches/server/0910-Fix-several-issues-with-EntityBreedEvent.patch b/patches/server/0909-Fix-several-issues-with-EntityBreedEvent.patch similarity index 100% rename from patches/server/0910-Fix-several-issues-with-EntityBreedEvent.patch rename to patches/server/0909-Fix-several-issues-with-EntityBreedEvent.patch diff --git a/patches/server/0911-Add-UUID-attribute-modifier-API.patch b/patches/server/0910-Add-UUID-attribute-modifier-API.patch similarity index 100% rename from patches/server/0911-Add-UUID-attribute-modifier-API.patch rename to patches/server/0910-Add-UUID-attribute-modifier-API.patch diff --git a/patches/server/0912-Fix-missing-event-call-for-entity-teleport-API.patch b/patches/server/0911-Fix-missing-event-call-for-entity-teleport-API.patch similarity index 100% rename from patches/server/0912-Fix-missing-event-call-for-entity-teleport-API.patch rename to patches/server/0911-Fix-missing-event-call-for-entity-teleport-API.patch diff --git a/patches/server/0913-Lazily-create-LootContext-for-criterions.patch b/patches/server/0912-Lazily-create-LootContext-for-criterions.patch similarity index 100% rename from patches/server/0913-Lazily-create-LootContext-for-criterions.patch rename to patches/server/0912-Lazily-create-LootContext-for-criterions.patch diff --git a/patches/server/0914-Don-t-fire-sync-events-during-worldgen.patch b/patches/server/0913-Don-t-fire-sync-events-during-worldgen.patch similarity index 99% rename from patches/server/0914-Don-t-fire-sync-events-during-worldgen.patch rename to patches/server/0913-Don-t-fire-sync-events-during-worldgen.patch index 01cd11852f..9ee1999a85 100644 --- a/patches/server/0914-Don-t-fire-sync-events-during-worldgen.patch +++ b/patches/server/0913-Don-t-fire-sync-events-during-worldgen.patch @@ -19,7 +19,7 @@ where generation happened directly to a ServerLevel and the entity still has the flag set. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8b5eabea1a0926c22b58ef8761caee3a06aa5ee0..53fdf4e104f36a2bd88fdf26d8c68cd3daf61574 100644 +index c5e404dcdab14dc0b972aa3286b05e21d9ea67e0..aaaf5b91402a1562311dfdc287193a1aefbaf9a7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1224,6 +1224,7 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0915-Add-Structure-check-API.patch b/patches/server/0914-Add-Structure-check-API.patch similarity index 93% rename from patches/server/0915-Add-Structure-check-API.patch rename to patches/server/0914-Add-Structure-check-API.patch index 93eeb5ef48..38a42bd17d 100644 --- a/patches/server/0915-Add-Structure-check-API.patch +++ b/patches/server/0914-Add-Structure-check-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add Structure check API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 202470633343add6768caa000bda05a0b5d93f4e..b3bc35956228a997a88d4af2f7b5810f1c09d5b8 100644 +index 612dc787880e58e8325a658a63f9fe7536d0860c..ebb119ab9f5a8ae580e54cb3c102cd86f948a8d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -236,6 +236,20 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0916-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch b/patches/server/0915-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch similarity index 100% rename from patches/server/0916-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch rename to patches/server/0915-Fix-CraftMetaItem-getAttributeModifier-duplication-c.patch diff --git a/patches/server/0917-Restore-vanilla-entity-drops-behavior.patch b/patches/server/0916-Restore-vanilla-entity-drops-behavior.patch similarity index 99% rename from patches/server/0917-Restore-vanilla-entity-drops-behavior.patch rename to patches/server/0916-Restore-vanilla-entity-drops-behavior.patch index 7aa60b4674..cb805e0e1b 100644 --- a/patches/server/0917-Restore-vanilla-entity-drops-behavior.patch +++ b/patches/server/0916-Restore-vanilla-entity-drops-behavior.patch @@ -9,10 +9,10 @@ on dropping the item instead of generalizing it for all dropped items like CB does. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f568fa18ddcb1a1cd060c469edd6db45431bb53c..191dfbd0f15c3a21278f3c4f9ce29f1698e0836c 100644 +index 2f880e10c73b48c4989c7623ea6cf368f4afb53a..7f83f40c76eac2ce5b053dc651224c44701613ea 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -978,20 +978,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -975,20 +975,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { if (this.isRemoved()) { return; } diff --git a/patches/server/0918-Dont-resend-blocks-on-interactions.patch b/patches/server/0917-Dont-resend-blocks-on-interactions.patch similarity index 100% rename from patches/server/0918-Dont-resend-blocks-on-interactions.patch rename to patches/server/0917-Dont-resend-blocks-on-interactions.patch diff --git a/patches/server/0919-add-more-scoreboard-API.patch b/patches/server/0918-add-more-scoreboard-API.patch similarity index 100% rename from patches/server/0919-add-more-scoreboard-API.patch rename to patches/server/0918-add-more-scoreboard-API.patch diff --git a/patches/server/0920-Improve-Registry.patch b/patches/server/0919-Improve-Registry.patch similarity index 100% rename from patches/server/0920-Improve-Registry.patch rename to patches/server/0919-Improve-Registry.patch diff --git a/patches/server/0921-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch b/patches/server/0920-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch similarity index 100% rename from patches/server/0921-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch rename to patches/server/0920-Fix-NPE-on-null-loc-for-EntityTeleportEvent.patch diff --git a/patches/server/0922-Add-experience-points-API.patch b/patches/server/0921-Add-experience-points-API.patch similarity index 97% rename from patches/server/0922-Add-experience-points-API.patch rename to patches/server/0921-Add-experience-points-API.patch index e4e988cec2..f29e610a9b 100644 --- a/patches/server/0922-Add-experience-points-API.patch +++ b/patches/server/0921-Add-experience-points-API.patch @@ -18,7 +18,7 @@ index 950ce40d268d89ff3c503116081db6c9ccd65329..454b29d8c9e42e328933aa578f49d28f // Paper start - send while respecting visibility private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index cb2cda2cb472b6ca0dd9b4fd1aea74ec3d215bbf..3a1777539f378f1e41bbd6b972c12a726afe5feb 100644 +index f337c32fa4521d6ddd1c4d6102404db389f23b71..4d3838c5184296451089697fd3f7438a7f1be762 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -1921,6 +1921,49 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/0923-Add-drops-to-shear-events.patch b/patches/server/0922-Add-drops-to-shear-events.patch similarity index 100% rename from patches/server/0923-Add-drops-to-shear-events.patch rename to patches/server/0922-Add-drops-to-shear-events.patch diff --git a/patches/server/0924-Add-PlayerShieldDisableEvent.patch b/patches/server/0923-Add-PlayerShieldDisableEvent.patch similarity index 100% rename from patches/server/0924-Add-PlayerShieldDisableEvent.patch rename to patches/server/0923-Add-PlayerShieldDisableEvent.patch diff --git a/patches/server/0925-Validate-ResourceLocation-in-NBT-reading.patch b/patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch similarity index 100% rename from patches/server/0925-Validate-ResourceLocation-in-NBT-reading.patch rename to patches/server/0924-Validate-ResourceLocation-in-NBT-reading.patch diff --git a/patches/server/0926-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0925-Properly-handle-experience-dropping-on-block-break.patch similarity index 100% rename from patches/server/0926-Properly-handle-experience-dropping-on-block-break.patch rename to patches/server/0925-Properly-handle-experience-dropping-on-block-break.patch diff --git a/patches/server/0927-Fixup-NamespacedKey-handling.patch b/patches/server/0926-Fixup-NamespacedKey-handling.patch similarity index 100% rename from patches/server/0927-Fixup-NamespacedKey-handling.patch rename to patches/server/0926-Fixup-NamespacedKey-handling.patch diff --git a/patches/server/0928-Expose-LootTable-of-DecoratedPot.patch b/patches/server/0927-Expose-LootTable-of-DecoratedPot.patch similarity index 100% rename from patches/server/0928-Expose-LootTable-of-DecoratedPot.patch rename to patches/server/0927-Expose-LootTable-of-DecoratedPot.patch diff --git a/patches/server/0929-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0928-Reduce-allocation-of-Vec3D-by-entity-tracker.patch similarity index 96% rename from patches/server/0929-Reduce-allocation-of-Vec3D-by-entity-tracker.patch rename to patches/server/0928-Reduce-allocation-of-Vec3D-by-entity-tracker.patch index 16af41429a..243b47d2f4 100644 --- a/patches/server/0929-Reduce-allocation-of-Vec3D-by-entity-tracker.patch +++ b/patches/server/0928-Reduce-allocation-of-Vec3D-by-entity-tracker.patch @@ -18,10 +18,10 @@ index a043ac10834562d357ef0b5aded2e916e2a0d056..74276c368016fcc4dbf9579b2ecbadc9 @VisibleForTesting static long encode(double value) { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 7bc142fd0ba58846f1b2ac57df0bfc044966f4ed..a03385b1b0a2f9b98319137b87d917856d3c632c 100644 +index 12361438efd12e327c8f6c2c1b233f05075402f8..56ef427af5cdfa9b673089cabc43167012b343bc 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1560,10 +1560,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1524,10 +1524,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public void updatePlayer(ServerPlayer player) { org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot if (player != this.entity) { diff --git a/patches/server/0930-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0929-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch similarity index 100% rename from patches/server/0930-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch rename to patches/server/0929-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch diff --git a/patches/server/0931-Add-ShulkerDuplicateEvent.patch b/patches/server/0930-Add-ShulkerDuplicateEvent.patch similarity index 100% rename from patches/server/0931-Add-ShulkerDuplicateEvent.patch rename to patches/server/0930-Add-ShulkerDuplicateEvent.patch diff --git a/patches/server/0932-Add-api-for-spawn-egg-texture-colors.patch b/patches/server/0931-Add-api-for-spawn-egg-texture-colors.patch similarity index 100% rename from patches/server/0932-Add-api-for-spawn-egg-texture-colors.patch rename to patches/server/0931-Add-api-for-spawn-egg-texture-colors.patch diff --git a/patches/server/0933-Add-Lifecycle-Event-system.patch b/patches/server/0932-Add-Lifecycle-Event-system.patch similarity index 99% rename from patches/server/0933-Add-Lifecycle-Event-system.patch rename to patches/server/0932-Add-Lifecycle-Event-system.patch index 6c4f2f8644..8217c1e749 100644 --- a/patches/server/0933-Add-Lifecycle-Event-system.patch +++ b/patches/server/0932-Add-Lifecycle-Event-system.patch @@ -719,7 +719,7 @@ index 2e96308696e131f3f013469a395e5ddda2c5d529..65a66e484c1c39c5f41d97db52f31c67 } catch (Throwable e) { LOGGER.error("Failed to run bootstrapper for %s. This plugin will not be loaded.".formatted(provider.getSource()), e); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 56f9b69b5a30c4ee5bcbcb8ae33e26f75b477475..1699f091839eb30fffc064a83ad369b8aee3ed4f 100644 +index 3ca0d01d4d55d0919624356751144985587ddc25..4bb633d202eebd679a07ce45f486b301717dbafd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1038,6 +1038,11 @@ public final class CraftServer implements Server { diff --git a/patches/server/0934-ItemStack-Tooltip-API.patch b/patches/server/0933-ItemStack-Tooltip-API.patch similarity index 100% rename from patches/server/0934-ItemStack-Tooltip-API.patch rename to patches/server/0933-ItemStack-Tooltip-API.patch diff --git a/patches/server/0935-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/server/0934-Add-getChunkSnapshot-includeLightData-parameter.patch similarity index 100% rename from patches/server/0935-Add-getChunkSnapshot-includeLightData-parameter.patch rename to patches/server/0934-Add-getChunkSnapshot-includeLightData-parameter.patch diff --git a/patches/server/0936-Add-FluidState-API.patch b/patches/server/0935-Add-FluidState-API.patch similarity index 100% rename from patches/server/0936-Add-FluidState-API.patch rename to patches/server/0935-Add-FluidState-API.patch diff --git a/patches/server/0937-add-number-format-api.patch b/patches/server/0936-add-number-format-api.patch similarity index 100% rename from patches/server/0937-add-number-format-api.patch rename to patches/server/0936-add-number-format-api.patch diff --git a/patches/server/0938-improve-BanList-types.patch b/patches/server/0937-improve-BanList-types.patch similarity index 93% rename from patches/server/0938-improve-BanList-types.patch rename to patches/server/0937-improve-BanList-types.patch index c63e72309a..5f8c62e060 100644 --- a/patches/server/0938-improve-BanList-types.patch +++ b/patches/server/0937-improve-BanList-types.patch @@ -5,7 +5,7 @@ Subject: [PATCH] improve BanList types diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1699f091839eb30fffc064a83ad369b8aee3ed4f..edd3fc01c3e4f8eeedf9b6e646cd31c3db7a89dc 100644 +index 4bb633d202eebd679a07ce45f486b301717dbafd..70b13bab453d50d72c3df9fed06b3956fe2703fe 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2245,6 +2245,21 @@ public final class CraftServer implements Server { diff --git a/patches/server/0939-Expanded-Hopper-API.patch b/patches/server/0938-Expanded-Hopper-API.patch similarity index 100% rename from patches/server/0939-Expanded-Hopper-API.patch rename to patches/server/0938-Expanded-Hopper-API.patch diff --git a/patches/server/0940-Add-BlockBreakProgressUpdateEvent.patch b/patches/server/0939-Add-BlockBreakProgressUpdateEvent.patch similarity index 93% rename from patches/server/0940-Add-BlockBreakProgressUpdateEvent.patch rename to patches/server/0939-Add-BlockBreakProgressUpdateEvent.patch index 125844c5b6..3e5409551e 100644 --- a/patches/server/0940-Add-BlockBreakProgressUpdateEvent.patch +++ b/patches/server/0939-Add-BlockBreakProgressUpdateEvent.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add BlockBreakProgressUpdateEvent diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 53fdf4e104f36a2bd88fdf26d8c68cd3daf61574..10063efb983dcef6dd0a9d55ecff49c26371bbb1 100644 +index aaaf5b91402a1562311dfdc287193a1aefbaf9a7..fd6e0f1a67f56e3b5fe97894919c7e4e1b90c4e8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1320,6 +1320,17 @@ public class ServerLevel extends Level implements WorldGenLevel { diff --git a/patches/server/0941-Deprecate-ItemStack-setType.patch b/patches/server/0940-Deprecate-ItemStack-setType.patch similarity index 100% rename from patches/server/0941-Deprecate-ItemStack-setType.patch rename to patches/server/0940-Deprecate-ItemStack-setType.patch diff --git a/patches/server/0942-Add-CartographyItemEvent.patch b/patches/server/0941-Add-CartographyItemEvent.patch similarity index 100% rename from patches/server/0942-Add-CartographyItemEvent.patch rename to patches/server/0941-Add-CartographyItemEvent.patch diff --git a/patches/server/0943-More-Raid-API.patch b/patches/server/0942-More-Raid-API.patch similarity index 97% rename from patches/server/0943-More-Raid-API.patch rename to patches/server/0942-More-Raid-API.patch index c98e63a452..5f013c673c 100644 --- a/patches/server/0943-More-Raid-API.patch +++ b/patches/server/0942-More-Raid-API.patch @@ -86,7 +86,7 @@ index b8ce1c1c2447f9cff1717bfcfd6eb911ade0d4b3..51f21af9d75769abdcba713b9aa33392 + // Paper end - more Raid API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b3bc35956228a997a88d4af2f7b5810f1c09d5b8..8f88ccec6b8947ca2738dc07c23aebe258145c83 100644 +index ebb119ab9f5a8ae580e54cb3c102cd86f948a8d2..94640aa827c9b2e1d0174eb012fdb37c0851f501 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2306,6 +2306,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/0944-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0943-Add-onboarding-message-for-initial-server-start.patch similarity index 96% rename from patches/server/0944-Add-onboarding-message-for-initial-server-start.patch rename to patches/server/0943-Add-onboarding-message-for-initial-server-start.patch index e3249e5435..ed4f8105fc 100644 --- a/patches/server/0944-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0943-Add-onboarding-message-for-initial-server-start.patch @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index cc847dce0116b8260790b890b1d5452c280e186c..2a5453707bc172d8d0efe3f11959cb0b5f830984 100644 +index 701196635f9c08d62d785fa1b448313937259c76..5160dc617cc5037cd3f10479454159f2a9984169 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -25,6 +25,7 @@ public class GlobalConfiguration extends ConfigurationPart { @@ -29,7 +29,7 @@ index cc847dce0116b8260790b890b1d5452c280e186c..2a5453707bc172d8d0efe3f11959cb0b return instance; } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index cbceb0ddea32781f89a19b1edb258bc23b96ee92..fc0f17cd7ed4fcf10e0396aeeed115280318128d 100644 +index 2dfa9c4c0c2ef489649944eed89d8c77c482b92f..e055769071841d56ec7e2a64fc519d1f8b48ff42 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1136,6 +1136,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -2255,7 +2255,7 @@ index fc0f17cd7ed4fcf10e0396aeeed115280318128d..e14c0e1ccf526f81e28db5545d9e2351 this.packRepository.setSelected(dataPacks); WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()); -@@ -2195,8 +2197,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { -+ -+ protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); -+ { -+ this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ protected static final Entity[] EMPTY_LIST = new Entity[0]; -+ -+ protected Entity[] entities = EMPTY_LIST; -+ protected int count; -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public boolean contains(final Entity entity) { -+ return this.entityToIndex.containsKey(entity.getId()); -+ } -+ -+ public boolean remove(final Entity entity) { -+ final int index = this.entityToIndex.remove(entity.getId()); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the entity at the end to this index -+ final int endIndex = --this.count; -+ final Entity end = this.entities[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.entityToIndex.put(end.getId(), index); // update index -+ } -+ this.entities[index] = end; -+ this.entities[endIndex] = null; -+ -+ return true; -+ } -+ -+ public boolean add(final Entity entity) { -+ final int count = this.count; -+ final int currIndex = this.entityToIndex.putIfAbsent(entity.getId(), count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ Entity[] list = this.entities; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.entities = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = entity; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public Entity getChecked(final int index) { -+ if (index < 0 || index >= this.count) { -+ throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); -+ } -+ return this.entities[index]; -+ } -+ -+ public Entity getUnchecked(final int index) { -+ return this.entities[index]; -+ } -+ -+ public Entity[] getRawData() { -+ return this.entities; -+ } -+ -+ public void clear() { -+ this.entityToIndex.clear(); -+ Arrays.fill(this.entities, 0, this.count, null); -+ this.count = 0; -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new Iterator() { -+ -+ Entity lastRet; -+ int current; -+ -+ @Override -+ public boolean hasNext() { -+ return this.current < EntityList.this.count; -+ } -+ -+ @Override -+ public Entity next() { -+ if (this.current >= EntityList.this.count) { -+ throw new NoSuchElementException(); -+ } -+ return this.lastRet = EntityList.this.entities[this.current++]; -+ } -+ -+ @Override -+ public void remove() { -+ final Entity lastRet = this.lastRet; -+ -+ if (lastRet == null) { -+ throw new IllegalStateException(); -+ } -+ this.lastRet = null; -+ -+ EntityList.this.remove(lastRet); -+ --this.current; -+ } -+ }; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fcfbca333234c09f7c056bbfcd9ac8860b20a8db ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -@@ -0,0 +1,125 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap; -+import java.util.Arrays; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.GlobalPalette; -+ -+public final class IBlockDataList { -+ -+ private static final GlobalPalette GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY); -+ -+ // map of location -> (index | (location << 16) | (palette id << 32)) -+ private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f); -+ { -+ this.map.defaultReturnValue(Long.MAX_VALUE); -+ } -+ -+ private static final long[] EMPTY_LIST = new long[0]; -+ -+ private long[] byIndex = EMPTY_LIST; -+ private int size; -+ -+ public static int getLocationKey(final int x, final int y, final int z) { -+ return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4)); -+ } -+ -+ public static BlockState getBlockDataFromRaw(final long raw) { -+ return GLOBAL_PALETTE.valueFor((int)(raw >>> 32)); -+ } -+ -+ public static int getIndexFromRaw(final long raw) { -+ return (int)(raw & 0xFFFF); -+ } -+ -+ public static int getLocationFromRaw(final long raw) { -+ return (int)((raw >>> 16) & 0xFFFF); -+ } -+ -+ public static long getRawFromValues(final int index, final int location, final BlockState data) { -+ return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32); -+ } -+ -+ public static long setIndexRawValues(final long value, final int index) { -+ return value & ~(0xFFFF) | (index); -+ } -+ -+ public long add(final int x, final int y, final int z, final BlockState data) { -+ return this.add(getLocationKey(x, y, z), data); -+ } -+ -+ public long add(final int location, final BlockState data) { -+ final long curr = this.map.get((short)location); -+ -+ if (curr == Long.MAX_VALUE) { -+ final int index = this.size++; -+ final long raw = getRawFromValues(index, location, data); -+ this.map.put((short)location, raw); -+ -+ if (index >= this.byIndex.length) { -+ this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L)); -+ } -+ -+ this.byIndex[index] = raw; -+ return raw; -+ } else { -+ final int index = getIndexFromRaw(curr); -+ final long raw = this.byIndex[index] = getRawFromValues(index, location, data); -+ -+ this.map.put((short)location, raw); -+ -+ return raw; -+ } -+ } -+ -+ public long remove(final int x, final int y, final int z) { -+ return this.remove(getLocationKey(x, y, z)); -+ } -+ -+ public long remove(final int location) { -+ final long ret = this.map.remove((short)location); -+ final int index = getIndexFromRaw(ret); -+ if (ret == Long.MAX_VALUE) { -+ return ret; -+ } -+ -+ // move the entry at the end to this index -+ final int endIndex = --this.size; -+ final long end = this.byIndex[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index)); -+ } -+ this.byIndex[index] = end; -+ this.byIndex[endIndex] = 0L; -+ -+ return ret; -+ } -+ -+ public int size() { -+ return this.size; -+ } -+ -+ public long getRaw(final int index) { -+ return this.byIndex[index]; -+ } -+ -+ public int getLocation(final int index) { -+ return getLocationFromRaw(this.getRaw(index)); -+ } -+ -+ public BlockState getData(final int index) { -+ return getBlockDataFromRaw(this.getRaw(index)); -+ } -+ -+ public void clear() { -+ this.size = 0; -+ this.map.clear(); -+ } -+ -+ public LongIterator getRawIterator() { -+ return this.map.values().iterator(); -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c21e00812f1aaa1279834a0562d360d6b89e146c ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IteratorSafeOrderedReferenceSet.java -@@ -0,0 +1,312 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.objects.Reference2IntLinkedOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2IntMap; -+import java.util.Arrays; -+import java.util.NoSuchElementException; -+ -+public final class IteratorSafeOrderedReferenceSet { -+ -+ public static final int ITERATOR_FLAG_SEE_ADDITIONS = 1 << 0; -+ -+ private final Reference2IntLinkedOpenHashMap indexMap; -+ private int firstInvalidIndex = -1; -+ -+ /* list impl */ -+ private E[] listElements; -+ private int listSize; -+ -+ private final double maxFragFactor; -+ -+ private int iteratorCount; -+ -+ public IteratorSafeOrderedReferenceSet() { -+ this(16, 0.75f, 16, 0.2); -+ } -+ -+ public IteratorSafeOrderedReferenceSet(final int setCapacity, final float setLoadFactor, final int arrayCapacity, -+ final double maxFragFactor) { -+ this.indexMap = new Reference2IntLinkedOpenHashMap<>(setCapacity, setLoadFactor); -+ this.indexMap.defaultReturnValue(-1); -+ this.maxFragFactor = maxFragFactor; -+ this.listElements = (E[])new Object[arrayCapacity]; -+ } -+ -+ /* -+ public void check() { -+ int iterated = 0; -+ ReferenceOpenHashSet check = new ReferenceOpenHashSet<>(); -+ if (this.listElements != null) { -+ for (int i = 0; i < this.listSize; ++i) { -+ Object obj = this.listElements[i]; -+ if (obj != null) { -+ iterated++; -+ if (!check.add((E)obj)) { -+ throw new IllegalStateException("contains duplicate"); -+ } -+ if (!this.contains((E)obj)) { -+ throw new IllegalStateException("desync"); -+ } -+ } -+ } -+ } -+ -+ if (iterated != this.size()) { -+ throw new IllegalStateException("Size is mismatched! Got " + iterated + ", expected " + this.size()); -+ } -+ -+ check.clear(); -+ iterated = 0; -+ for (final java.util.Iterator iterator = this.unsafeIterator(IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS); iterator.hasNext();) { -+ final E element = iterator.next(); -+ iterated++; -+ if (!check.add(element)) { -+ throw new IllegalStateException("contains duplicate (iterator is wrong)"); -+ } -+ if (!this.contains(element)) { -+ throw new IllegalStateException("desync (iterator is wrong)"); -+ } -+ } -+ -+ if (iterated != this.size()) { -+ throw new IllegalStateException("Size is mismatched! (iterator is wrong) Got " + iterated + ", expected " + this.size()); -+ } -+ } -+ */ -+ -+ private double getFragFactor() { -+ return 1.0 - ((double)this.indexMap.size() / (double)this.listSize); -+ } -+ -+ public int createRawIterator() { -+ ++this.iteratorCount; -+ if (this.indexMap.isEmpty()) { -+ return -1; -+ } else { -+ return this.firstInvalidIndex == 0 ? this.indexMap.getInt(this.indexMap.firstKey()) : 0; -+ } -+ } -+ -+ public int advanceRawIterator(final int index) { -+ final E[] elements = this.listElements; -+ int ret = index + 1; -+ for (int len = this.listSize; ret < len; ++ret) { -+ if (elements[ret] != null) { -+ return ret; -+ } -+ } -+ -+ return -1; -+ } -+ -+ public void finishRawIterator() { -+ if (--this.iteratorCount == 0) { -+ if (this.getFragFactor() >= this.maxFragFactor) { -+ this.defrag(); -+ } -+ } -+ } -+ -+ public boolean remove(final E element) { -+ final int index = this.indexMap.removeInt(element); -+ if (index >= 0) { -+ if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) { -+ this.firstInvalidIndex = index; -+ } -+ if (this.listElements[index] != element) { -+ throw new IllegalStateException(); -+ } -+ this.listElements[index] = null; -+ if (this.iteratorCount == 0 && this.getFragFactor() >= this.maxFragFactor) { -+ this.defrag(); -+ } -+ //this.check(); -+ return true; -+ } -+ return false; -+ } -+ -+ public boolean contains(final E element) { -+ return this.indexMap.containsKey(element); -+ } -+ -+ public boolean add(final E element) { -+ final int listSize = this.listSize; -+ -+ final int previous = this.indexMap.putIfAbsent(element, listSize); -+ if (previous != -1) { -+ return false; -+ } -+ -+ if (listSize >= this.listElements.length) { -+ this.listElements = Arrays.copyOf(this.listElements, listSize * 2); -+ } -+ this.listElements[listSize] = element; -+ this.listSize = listSize + 1; -+ -+ //this.check(); -+ return true; -+ } -+ -+ private void defrag() { -+ if (this.firstInvalidIndex < 0) { -+ return; // nothing to do -+ } -+ -+ if (this.indexMap.isEmpty()) { -+ Arrays.fill(this.listElements, 0, this.listSize, null); -+ this.listSize = 0; -+ this.firstInvalidIndex = -1; -+ //this.check(); -+ return; -+ } -+ -+ final E[] backingArray = this.listElements; -+ -+ int lastValidIndex; -+ java.util.Iterator> iterator; -+ -+ if (this.firstInvalidIndex == 0) { -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(); -+ lastValidIndex = 0; -+ } else { -+ lastValidIndex = this.firstInvalidIndex; -+ final E key = backingArray[lastValidIndex - 1]; -+ iterator = this.indexMap.reference2IntEntrySet().fastIterator(new Reference2IntMap.Entry() { -+ @Override -+ public int getIntValue() { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public int setValue(int i) { -+ throw new UnsupportedOperationException(); -+ } -+ -+ @Override -+ public E getKey() { -+ return key; -+ } -+ }); -+ } -+ -+ while (iterator.hasNext()) { -+ final Reference2IntMap.Entry entry = iterator.next(); -+ -+ final int newIndex = lastValidIndex++; -+ backingArray[newIndex] = entry.getKey(); -+ entry.setValue(newIndex); -+ } -+ -+ // cleanup end -+ Arrays.fill(backingArray, lastValidIndex, this.listSize, null); -+ this.listSize = lastValidIndex; -+ this.firstInvalidIndex = -1; -+ //this.check(); -+ } -+ -+ public E rawGet(final int index) { -+ return this.listElements[index]; -+ } -+ -+ public int size() { -+ // always returns the correct amount - listSize can be different -+ return this.indexMap.size(); -+ } -+ -+ public IteratorSafeOrderedReferenceSet.Iterator iterator() { -+ return this.iterator(0); -+ } -+ -+ public IteratorSafeOrderedReferenceSet.Iterator iterator(final int flags) { -+ ++this.iteratorCount; -+ return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); -+ } -+ -+ public java.util.Iterator unsafeIterator() { -+ return this.unsafeIterator(0); -+ } -+ public java.util.Iterator unsafeIterator(final int flags) { -+ return new BaseIterator<>(this, false, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize); -+ } -+ -+ public static interface Iterator extends java.util.Iterator { -+ -+ public void finishedIterating(); -+ -+ } -+ -+ private static final class BaseIterator implements IteratorSafeOrderedReferenceSet.Iterator { -+ -+ private final IteratorSafeOrderedReferenceSet set; -+ private final boolean canFinish; -+ private final int maxIndex; -+ private int nextIndex; -+ private E pendingValue; -+ private boolean finished; -+ private E lastReturned; -+ -+ private BaseIterator(final IteratorSafeOrderedReferenceSet set, final boolean canFinish, final int maxIndex) { -+ this.set = set; -+ this.canFinish = canFinish; -+ this.maxIndex = maxIndex; -+ } -+ -+ @Override -+ public boolean hasNext() { -+ if (this.finished) { -+ return false; -+ } -+ if (this.pendingValue != null) { -+ return true; -+ } -+ -+ final E[] elements = this.set.listElements; -+ int index, len; -+ for (index = this.nextIndex, len = Math.min(this.maxIndex, this.set.listSize); index < len; ++index) { -+ final E element = elements[index]; -+ if (element != null) { -+ this.pendingValue = element; -+ this.nextIndex = index + 1; -+ return true; -+ } -+ } -+ -+ this.nextIndex = index; -+ return false; -+ } -+ -+ @Override -+ public E next() { -+ if (!this.hasNext()) { -+ throw new NoSuchElementException(); -+ } -+ final E ret = this.pendingValue; -+ -+ this.pendingValue = null; -+ this.lastReturned = ret; -+ -+ return ret; -+ } -+ -+ @Override -+ public void remove() { -+ final E lastReturned = this.lastReturned; -+ if (lastReturned == null) { -+ throw new IllegalStateException(); -+ } -+ this.lastReturned = null; -+ this.set.remove(lastReturned); -+ } -+ -+ @Override -+ public void finishedIterating() { -+ if (this.finished || !this.canFinish) { -+ throw new IllegalStateException(); -+ } -+ this.lastReturned = null; -+ this.finished = true; -+ this.set.finishRawIterator(); -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..93e8c8134da8ee1a9b777c708f992922a1a7de8b ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java -@@ -0,0 +1,135 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; -+import java.util.Arrays; -+import java.util.Iterator; -+import java.util.NoSuchElementException; -+ -+public final class ReferenceList implements Iterable { -+ -+ private final Reference2IntOpenHashMap referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f); -+ { -+ this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ -+ private static final Object[] EMPTY_LIST = new Object[0]; -+ -+ private E[] references; -+ private int count; -+ -+ public ReferenceList() { -+ this((E[])EMPTY_LIST, 0); -+ } -+ -+ public ReferenceList(final E[] array, final int count) { -+ this.references = array; -+ this.count = count; -+ } -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public boolean contains(final E obj) { -+ return this.referenceToIndex.containsKey(obj); -+ } -+ -+ public boolean remove(final E obj) { -+ final int index = this.referenceToIndex.removeInt(obj); -+ if (index == Integer.MIN_VALUE) { -+ return false; -+ } -+ -+ // move the object at the end to this index -+ final int endIndex = --this.count; -+ final E end = (E)this.references[endIndex]; -+ if (index != endIndex) { -+ // not empty after this call -+ this.referenceToIndex.put(end, index); // update index -+ } -+ this.references[index] = end; -+ this.references[endIndex] = null; -+ -+ return true; -+ } -+ -+ public boolean add(final E obj) { -+ final int count = this.count; -+ final int currIndex = this.referenceToIndex.putIfAbsent(obj, count); -+ -+ if (currIndex != Integer.MIN_VALUE) { -+ return false; // already in this list -+ } -+ -+ E[] list = this.references; -+ -+ if (list.length == count) { -+ // resize required -+ list = this.references = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ } -+ -+ list[count] = obj; -+ this.count = count + 1; -+ -+ return true; -+ } -+ -+ public E getChecked(final int index) { -+ if (index < 0 || index >= this.count) { -+ throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); -+ } -+ return this.references[index]; -+ } -+ -+ public E getUnchecked(final int index) { -+ return this.references[index]; -+ } -+ -+ public Object[] getRawData() { -+ return this.references; -+ } -+ -+ public E[] getRawDataUnchecked() { -+ return this.references; -+ } -+ -+ public void clear() { -+ this.referenceToIndex.clear(); -+ Arrays.fill(this.references, 0, this.count, null); -+ this.count = 0; -+ } -+ -+ @Override -+ public Iterator iterator() { -+ return new Iterator<>() { -+ private E lastRet; -+ private int current; -+ -+ @Override -+ public boolean hasNext() { -+ return this.current < ReferenceList.this.count; -+ } -+ -+ @Override -+ public E next() { -+ if (this.current >= ReferenceList.this.count) { -+ throw new NoSuchElementException(); -+ } -+ return this.lastRet = ReferenceList.this.references[this.current++]; -+ } -+ -+ @Override -+ public void remove() { -+ final E lastRet = this.lastRet; -+ -+ if (lastRet == null) { -+ throw new IllegalStateException(); -+ } -+ this.lastRet = null; -+ -+ ReferenceList.this.remove(lastRet); -+ --this.current; -+ } -+ }; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..db92261a6cb3758391108361096417c61bc82cdc ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/SortedList.java -@@ -0,0 +1,117 @@ -+package ca.spottedleaf.moonrise.common.list; -+ -+import java.lang.reflect.Array; -+import java.util.Arrays; -+import java.util.Comparator; -+ -+public final class SortedList { -+ -+ private static final Object[] EMPTY_LIST = new Object[0]; -+ -+ private Comparator comparator; -+ private E[] elements; -+ private int count; -+ -+ public SortedList(final Comparator comparator) { -+ this((E[])EMPTY_LIST, comparator); -+ } -+ -+ public SortedList(final E[] elements, final Comparator comparator) { -+ this.elements = elements; -+ this.comparator = comparator; -+ } -+ -+ // start, end are inclusive -+ private static int insertIdx(final E[] elements, final E element, final Comparator comparator, -+ int start, int end) { -+ while (start <= end) { -+ final int middle = (start + end) >>> 1; -+ -+ final E middleVal = elements[middle]; -+ -+ final int cmp = comparator.compare(element, middleVal); -+ -+ if (cmp < 0) { -+ end = middle - 1; -+ } else { -+ start = middle + 1; -+ } -+ } -+ -+ return start; -+ } -+ -+ public int size() { -+ return this.count; -+ } -+ -+ public boolean isEmpty() { -+ return this.count == 0; -+ } -+ -+ public int add(final E element) { -+ E[] elements = this.elements; -+ final int count = this.count; -+ this.count = count + 1; -+ final Comparator comparator = this.comparator; -+ -+ final int idx = insertIdx(elements, element, comparator, 0, count - 1); -+ -+ if (count >= elements.length) { -+ // copy and insert at the same time -+ if (idx == count) { -+ this.elements = elements = Arrays.copyOf(elements, (int)Math.max(4L, count * 2L)); // overflow results in negative -+ elements[count] = element; -+ return idx; -+ } else { -+ final E[] newElements = (E[])Array.newInstance(elements.getClass().getComponentType(), (int)Math.max(4L, count * 2L)); -+ System.arraycopy(elements, 0, newElements, 0, idx); -+ newElements[idx] = element; -+ System.arraycopy(elements, idx, newElements, idx + 1, count - idx); -+ this.elements = newElements; -+ return idx; -+ } -+ } else { -+ if (idx == count) { -+ // no copy needed -+ elements[idx] = element; -+ return idx; -+ } else { -+ // shift elements down -+ System.arraycopy(elements, idx, elements, idx + 1, count - idx); -+ elements[idx] = element; -+ return idx; -+ } -+ } -+ } -+ -+ public E get(final int idx) { -+ if (idx < 0 || idx >= this.count) { -+ throw new IndexOutOfBoundsException(idx); -+ } -+ return this.elements[idx]; -+ } -+ -+ -+ public E remove(final E element) { -+ E[] elements = this.elements; -+ final int count = this.count; -+ final Comparator comparator = this.comparator; -+ -+ final int idx = Arrays.binarySearch(elements, 0, count, element, comparator); -+ if (idx < 0) { -+ return null; -+ } -+ -+ final int last = this.count - 1; -+ this.count = last; -+ -+ final E ret = elements[idx]; -+ -+ System.arraycopy(elements, idx + 1, elements, idx, last - idx); -+ -+ elements[last] = null; -+ -+ return ret; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..62caf61a4b0b7ebc764006ea8bbd0274594d9f4a ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2IntArraySortedMap.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import it.unimi.dsi.fastutil.ints.Int2IntFunction; -+ -+import java.util.Arrays; -+ -+public class Int2IntArraySortedMap { -+ -+ protected int[] key; -+ protected int[] val; -+ protected int size; -+ -+ public Int2IntArraySortedMap() { -+ this.key = new int[8]; -+ this.val = new int[8]; -+ } -+ -+ public int put(final int key, final int value) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ final int current = this.val[index]; -+ this.val[index] = value; -+ return current; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ this.val[insert] = value; -+ -+ return 0; -+ } -+ -+ public int computeIfAbsent(final int key, final Int2IntFunction producer) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ return this.val[index]; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ -+ return this.val[insert] = producer.apply(key); -+ } -+ -+ public int get(final int key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ return 0; -+ } -+ return this.val[index]; -+ } -+ -+ public int getFloor(final int key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ final int insert = -(index + 1) - 1; -+ return insert < 0 ? 0 : this.val[insert]; -+ } -+ return this.val[index]; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fea9e8ba7caaf6259614090d4f872619470d32f9 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Int2ObjectArraySortedMap.java -@@ -0,0 +1,74 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import java.util.Arrays; -+import java.util.function.IntFunction; -+ -+public class Int2ObjectArraySortedMap { -+ -+ protected int[] key; -+ protected V[] val; -+ protected int size; -+ -+ public Int2ObjectArraySortedMap() { -+ this.key = new int[8]; -+ this.val = (V[])new Object[8]; -+ } -+ -+ public V put(final int key, final V value) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ final V current = this.val[index]; -+ this.val[index] = value; -+ return current; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ -+ this.key[insert] = key; -+ this.val[insert] = value; -+ -+ return null; -+ } -+ -+ public V computeIfAbsent(final int key, final IntFunction producer) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ return this.val[index]; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ -+ this.key[insert] = key; -+ -+ return this.val[insert] = producer.apply(key); -+ } -+ -+ public V get(final int key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ return null; -+ } -+ return this.val[index]; -+ } -+ -+ public V getFloor(final int key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ final int insert = -(index + 1); -+ return this.val[insert]; -+ } -+ return this.val[index]; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c077ca606934e9f13da3a8e2a194f82a99fe9ae9 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2IntArraySortedMap.java -@@ -0,0 +1,77 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import it.unimi.dsi.fastutil.longs.Long2IntFunction; -+ -+import java.util.Arrays; -+ -+public class Long2IntArraySortedMap { -+ -+ protected long[] key; -+ protected int[] val; -+ protected int size; -+ -+ public Long2IntArraySortedMap() { -+ this.key = new long[8]; -+ this.val = new int[8]; -+ } -+ -+ public int put(final long key, final int value) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ final int current = this.val[index]; -+ this.val[index] = value; -+ return current; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ this.val[insert] = value; -+ -+ return 0; -+ } -+ -+ public int computeIfAbsent(final long key, final Long2IntFunction producer) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ return this.val[index]; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ -+ return this.val[insert] = producer.apply(key); -+ } -+ -+ public int get(final long key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ return 0; -+ } -+ return this.val[index]; -+ } -+ -+ public int getFloor(final long key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ final int insert = -(index + 1) - 1; -+ return insert < 0 ? 0 : this.val[insert]; -+ } -+ return this.val[index]; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b24d037af5709196b66c79c692e1814cd5b20e49 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/Long2ObjectArraySortedMap.java -@@ -0,0 +1,76 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import java.util.Arrays; -+import java.util.function.LongFunction; -+ -+public class Long2ObjectArraySortedMap { -+ -+ protected long[] key; -+ protected V[] val; -+ protected int size; -+ -+ public Long2ObjectArraySortedMap() { -+ this.key = new long[8]; -+ this.val = (V[])new Object[8]; -+ } -+ -+ public V put(final long key, final V value) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ final V current = this.val[index]; -+ this.val[index] = value; -+ return current; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ this.val[insert] = value; -+ -+ return null; -+ } -+ -+ public V computeIfAbsent(final long key, final LongFunction producer) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index >= 0) { -+ return this.val[index]; -+ } -+ final int insert = -(index + 1); -+ // shift entries down -+ if (this.size >= this.val.length) { -+ this.key = Arrays.copyOf(this.key, this.key.length * 2); -+ this.val = Arrays.copyOf(this.val, this.val.length * 2); -+ } -+ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); -+ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); -+ ++this.size; -+ -+ this.key[insert] = key; -+ -+ return this.val[insert] = producer.apply(key); -+ } -+ -+ public V get(final long key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ return null; -+ } -+ return this.val[index]; -+ } -+ -+ public V getFloor(final long key) { -+ final int index = Arrays.binarySearch(this.key, 0, this.size, key); -+ if (index < 0) { -+ final int insert = -(index + 1) - 1; -+ return insert < 0 ? null : this.val[insert]; -+ } -+ return this.val[index]; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..aa86882bb7b0712f29d7344009093c0e7a81be84 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2BooleanMap.java -@@ -0,0 +1,48 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import it.unimi.dsi.fastutil.longs.Long2BooleanFunction; -+import it.unimi.dsi.fastutil.longs.Long2BooleanLinkedOpenHashMap; -+ -+public final class SynchronisedLong2BooleanMap { -+ private final Long2BooleanLinkedOpenHashMap map = new Long2BooleanLinkedOpenHashMap(); -+ private final int limit; -+ -+ public SynchronisedLong2BooleanMap(final int limit) { -+ this.limit = limit; -+ } -+ -+ // must hold lock on map -+ private void purgeEntries() { -+ while (this.map.size() > this.limit) { -+ this.map.removeLastBoolean(); -+ } -+ } -+ -+ public boolean remove(final long key) { -+ synchronized (this.map) { -+ return this.map.remove(key); -+ } -+ } -+ -+ // note: -+ public boolean getOrCompute(final long key, final Long2BooleanFunction ifAbsent) { -+ synchronized (this.map) { -+ if (this.map.containsKey(key)) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ } -+ -+ final boolean put = ifAbsent.get(key); -+ -+ synchronized (this.map) { -+ if (this.map.containsKey(key)) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ this.map.putAndMoveToFirst(key, put); -+ -+ this.purgeEntries(); -+ -+ return put; -+ } -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..dbb51afc6cefe0071fe3ddcd2c1109f2755c3b4d ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/map/SynchronisedLong2ObjectMap.java -@@ -0,0 +1,47 @@ -+package ca.spottedleaf.moonrise.common.map; -+ -+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -+import java.util.function.BiFunction; -+ -+public final class SynchronisedLong2ObjectMap { -+ private final Long2ObjectLinkedOpenHashMap map = new Long2ObjectLinkedOpenHashMap<>(); -+ private final int limit; -+ -+ public SynchronisedLong2ObjectMap(final int limit) { -+ this.limit = limit; -+ } -+ -+ // must hold lock on map -+ private void purgeEntries() { -+ while (this.map.size() > this.limit) { -+ this.map.removeLast(); -+ } -+ } -+ -+ public V get(final long key) { -+ synchronized (this.map) { -+ return this.map.getAndMoveToFirst(key); -+ } -+ } -+ -+ public V put(final long key, final V value) { -+ synchronized (this.map) { -+ final V ret = this.map.putAndMoveToFirst(key, value); -+ this.purgeEntries(); -+ return ret; -+ } -+ } -+ -+ public V compute(final long key, final BiFunction remappingFunction) { -+ synchronized (this.map) { -+ // first, compute the value - if one is added, it will be at the last entry -+ this.map.compute(key, remappingFunction); -+ // move the entry to first, just in case it was added at last -+ final V ret = this.map.getAndMoveToFirst(key); -+ // now purge the last entries -+ this.purgeEntries(); -+ -+ return ret; -+ } -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9c0eff9017b24bb65b1029cefb5d0bfcb9beff01 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/AllocatingRateLimiter.java -@@ -0,0 +1,75 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+public final class AllocatingRateLimiter { -+ -+ // max difference granularity in ns -+ private final long maxGranularity; -+ -+ private double allocation = 0.0; -+ private long lastAllocationUpdate; -+ // the carry is used to store the remainder of the last take, so that the take amount remains the same (minus floating point error) -+ // over any time period using take regardless of the number of take calls or the intervals between the take calls -+ // i.e. take obtains 3.5 elements, stores 0.5 to this field for the next take() call to use and returns 3 -+ private double takeCarry = 0.0; -+ private long lastTakeUpdate; -+ -+ public AllocatingRateLimiter(final long maxGranularity) { -+ this.maxGranularity = maxGranularity; -+ } -+ -+ public void reset(final long time) { -+ this.allocation = 0.0; -+ this.lastAllocationUpdate = time; -+ this.takeCarry = 0.0; -+ this.lastTakeUpdate = time; -+ } -+ -+ // rate in units/s, and time in ns -+ public void tickAllocation(final long time, final double rate, final double maxAllocation) { -+ final long diff = Math.min(this.maxGranularity, time - this.lastAllocationUpdate); -+ this.lastAllocationUpdate = time; -+ -+ this.allocation = Math.min(maxAllocation - this.takeCarry, this.allocation + rate * (diff*1.0E-9D)); -+ } -+ -+ public long previewAllocation(final long time, final double rate, final long maxTake) { -+ if (maxTake < 1L) { -+ return 0L; -+ } -+ -+ final long diff = Math.min(this.maxGranularity, time - this.lastTakeUpdate); -+ -+ // note: abs(takeCarry) <= 1.0 -+ final double take = Math.min( -+ Math.min((double)maxTake - this.takeCarry, this.allocation), -+ rate * (diff*1.0E-9) +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +index da323a1105347d5cf4b946df10ded78a953236f2..79ea42ff287beadb997d5d805a3d5faa6f80216a 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java +@@ -1,6 +1,10 @@ + package ca.spottedleaf.moonrise.common.util; + + import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; ++import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; ++import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; + import com.mojang.logging.LogUtils; + import net.minecraft.server.level.ChunkHolder; + import net.minecraft.server.level.FullChunkStatus; +@@ -17,203 +21,46 @@ import java.util.function.Consumer; + public final class ChunkSystem { + + private static final Logger LOGGER = LogUtils.getLogger(); +- private static final net.minecraft.world.level.chunk.status.ChunkStep FULL_CHUNK_STEP = net.minecraft.world.level.chunk.status.ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL); +- +- private static int getDistance(final ChunkStatus status) { +- return FULL_CHUNK_STEP.getAccumulatedRadiusOf(status); +- } + + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { + scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); + } + + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { +- level.chunkSource.mainThreadProcessor.execute(run); ++ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority); + } + + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, + final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, + final Consumer onComplete) { +- if (gen) { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- return; +- } +- scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { +- if (chunk == null) { +- if (onComplete != null) { +- onComplete.accept(null); +- } +- } else { +- if (chunk.getPersistedStatus().isOrAfter(toStatus)) { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- } else { +- if (onComplete != null) { +- onComplete.accept(null); +- } +- } +- } +- }); ++ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); + } + +- static final net.minecraft.server.level.TicketType CHUNK_LOAD = net.minecraft.server.level.TicketType.create("chunk_load", Long::compareTo); +- +- private static long chunkLoadCounter = 0L; + public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, + final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { +- if (!org.bukkit.Bukkit.isPrimaryThread()) { +- scheduleChunkTask(level, chunkX, chunkZ, () -> { +- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- }, priority); +- return; +- } +- +- final int minLevel = 33 + getDistance(toStatus); +- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; +- final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); +- +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- level.chunkSource.runDistanceManagerUpdates(); +- +- final Consumer loadCallback = (final ChunkAccess chunk) -> { +- try { +- if (onComplete != null) { +- onComplete.accept(chunk); +- } +- } catch (final Throwable thr) { +- LOGGER.error("Exception handling chunk load callback", thr); +- com.destroystokyo.paper.util.SneakyThrow.sneaky(thr); +- } finally { +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); +- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- } +- }; +- +- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (holder == null || holder.getTicketLevel() > minLevel) { +- loadCallback.accept(null); +- return; +- } +- +- final java.util.concurrent.CompletableFuture> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap); +- +- if (loadFuture.isDone()) { +- loadCallback.accept(loadFuture.join().orElse(null)); +- return; +- } +- +- loadFuture.whenCompleteAsync((final net.minecraft.server.level.ChunkResult result, final Throwable thr) -> { +- if (thr != null) { +- loadCallback.accept(null); +- return; +- } +- loadCallback.accept(result.orElse(null)); +- }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- }); ++ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + } + + public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, + final FullChunkStatus toStatus, final boolean addTicket, + final PrioritisedExecutor.Priority priority, final Consumer onComplete) { +- // This method goes unused until the chunk system rewrite +- if (toStatus == FullChunkStatus.INACCESSIBLE) { +- throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); +- } +- +- if (!org.bukkit.Bukkit.isPrimaryThread()) { +- scheduleChunkTask(level, chunkX, chunkZ, () -> { +- scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); +- }, priority); +- return; +- } +- +- final int minLevel = 33 - (toStatus.ordinal() - 1); +- final int radius = toStatus.ordinal() - 1; +- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; +- final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ); +- +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- level.chunkSource.runDistanceManagerUpdates(); +- +- final Consumer loadCallback = (final LevelChunk chunk) -> { +- try { +- if (onComplete != null) { +- onComplete.accept(chunk); +- } +- } catch (final Throwable thr) { +- LOGGER.error("Exception handling chunk load callback", thr); +- com.destroystokyo.paper.util.SneakyThrow.sneaky(thr); +- } finally { +- if (addTicket) { +- level.chunkSource.addTicketAtLevel(net.minecraft.server.level.TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); +- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); +- } +- } +- }; +- +- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- +- if (holder == null || holder.getTicketLevel() > minLevel) { +- loadCallback.accept(null); +- return; +- } +- +- final java.util.concurrent.CompletableFuture> tickingState; +- switch (toStatus) { +- case FULL: { +- tickingState = holder.getFullChunkFuture(); +- break; +- } +- case BLOCK_TICKING: { +- tickingState = holder.getTickingChunkFuture(); +- break; +- } +- case ENTITY_TICKING: { +- tickingState = holder.getEntityTickingChunkFuture(); +- break; +- } +- default: { +- throw new IllegalStateException("Cannot reach here"); +- } +- } +- +- if (tickingState.isDone()) { +- loadCallback.accept(tickingState.join().orElse(null)); +- return; +- } +- +- tickingState.whenCompleteAsync((final net.minecraft.server.level.ChunkResult result, final Throwable thr) -> { +- if (thr != null) { +- loadCallback.accept(null); +- return; +- } +- loadCallback.accept(result.orElse(null)); +- }, (final Runnable r) -> { +- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); +- }); ++ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + } + + public static List getVisibleChunkHolders(final ServerLevel level) { +- return new java.util.ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); ++ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders(); + } + + public static List getUpdatingChunkHolders(final ServerLevel level) { +- return new java.util.ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); ++ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders(); + } + + public static int getVisibleChunkHolderCount(final ServerLevel level) { +- return level.chunkSource.chunkMap.visibleChunkMap.size(); ++ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size(); + } + + public static int getUpdatingChunkHolderCount(final ServerLevel level) { +- return level.chunkSource.chunkMap.updatingChunkMap.size(); ++ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size(); + } + + public static boolean hasAnyChunkHolders(final ServerLevel level) { +@@ -232,52 +79,83 @@ public final class ChunkSystem { + + } + +- public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource()) ++ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk); ++ } + ++ public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().add( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); -+ -+ return (long)Math.floor(this.takeCarry + take); -+ } -+ -+ // rate in units/s, and time in ns -+ public long takeAllocation(final long time, final double rate, final long maxTake) { -+ if (maxTake < 1L) { -+ return 0L; -+ } -+ -+ double ret = this.takeCarry; -+ final long diff = Math.min(this.maxGranularity, time - this.lastTakeUpdate); -+ this.lastTakeUpdate = time; -+ -+ // note: abs(takeCarry) <= 1.0 -+ final double take = Math.min( -+ Math.min((double)maxTake - this.takeCarry, this.allocation), -+ rate * (diff*1.0E-9) + } + + public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getLoadedChunks().remove( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() + ); -+ -+ ret += take; -+ this.allocation -= take; -+ -+ final long retInteger = (long)Math.floor(ret); -+ this.takeCarry = ret - (double)retInteger; -+ -+ return retInteger; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java -new file mode 100644 -index 0000000000000000000000000000000000000000..460e27ab0506c83a28934800ee74ee886d4b025e ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java -@@ -0,0 +1,297 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+ -+public final class Delayed26WayDistancePropagator3D { -+ -+ // this map is considered "stale" unless updates are propagated. -+ protected final Delayed8WayDistancePropagator2D.LevelMap levels = new Delayed8WayDistancePropagator2D.LevelMap(8192*2, 0.6f); -+ -+ // this map is never stale -+ protected final Long2ByteOpenHashMap sources = new Long2ByteOpenHashMap(4096, 0.6f); -+ -+ // Generally updates to positions are made close to other updates, so we link to decrease cache misses when -+ // propagating updates -+ protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet(); -+ -+ @FunctionalInterface -+ public static interface LevelChangeCallback { -+ -+ /** -+ * This can be called for intermediate updates. So do not rely on newLevel being close to or -+ * the exact level that is expected after a full propagation has occured. -+ */ -+ public void onLevelUpdate(final long coordinate, final byte oldLevel, final byte newLevel); -+ -+ } -+ -+ protected final LevelChangeCallback changeCallback; -+ -+ public Delayed26WayDistancePropagator3D() { -+ this(null); -+ } -+ -+ public Delayed26WayDistancePropagator3D(final LevelChangeCallback changeCallback) { -+ this.changeCallback = changeCallback; -+ } -+ -+ public int getLevel(final long pos) { -+ return this.levels.get(pos); -+ } -+ -+ public int getLevel(final int x, final int y, final int z) { -+ return this.levels.get(CoordinateUtils.getChunkSectionKey(x, y, z)); -+ } -+ -+ public void setSource(final int x, final int y, final int z, final int level) { -+ this.setSource(CoordinateUtils.getChunkSectionKey(x, y, z), level); -+ } -+ -+ public void setSource(final long coordinate, final int level) { -+ if ((level & 63) != level || level == 0) { -+ throw new IllegalArgumentException("Level must be in (0, 63], not " + level); -+ } -+ -+ final byte byteLevel = (byte)level; -+ final byte oldLevel = this.sources.put(coordinate, byteLevel); -+ -+ if (oldLevel == byteLevel) { -+ return; // nothing to do -+ } -+ -+ // queue to update later -+ this.updatedSources.add(coordinate); -+ } -+ -+ public void removeSource(final int x, final int y, final int z) { -+ this.removeSource(CoordinateUtils.getChunkSectionKey(x, y, z)); -+ } -+ -+ public void removeSource(final long coordinate) { -+ if (this.sources.remove(coordinate) != 0) { -+ this.updatedSources.add(coordinate); -+ } -+ } -+ -+ // queues used for BFS propagating levels -+ protected final Delayed8WayDistancePropagator2D.WorkQueue[] levelIncreaseWorkQueues = new Delayed8WayDistancePropagator2D.WorkQueue[64]; -+ { -+ for (int i = 0; i < this.levelIncreaseWorkQueues.length; ++i) { -+ this.levelIncreaseWorkQueues[i] = new Delayed8WayDistancePropagator2D.WorkQueue(); -+ } -+ } -+ protected final Delayed8WayDistancePropagator2D.WorkQueue[] levelRemoveWorkQueues = new Delayed8WayDistancePropagator2D.WorkQueue[64]; -+ { -+ for (int i = 0; i < this.levelRemoveWorkQueues.length; ++i) { -+ this.levelRemoveWorkQueues[i] = new Delayed8WayDistancePropagator2D.WorkQueue(); -+ } -+ } -+ protected long levelIncreaseWorkQueueBitset; -+ protected long levelRemoveWorkQueueBitset; -+ -+ protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { -+ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[level]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelIncreaseWorkQueueBitset |= (1L << level); -+ } -+ -+ protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { -+ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[index]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelIncreaseWorkQueueBitset |= (1L << index); -+ } -+ -+ protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { -+ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[level]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelRemoveWorkQueueBitset |= (1L << level); -+ } -+ -+ public boolean propagateUpdates() { -+ if (this.updatedSources.isEmpty()) { -+ return false; -+ } -+ -+ boolean ret = false; -+ -+ for (final LongIterator iterator = this.updatedSources.iterator(); iterator.hasNext();) { -+ final long coordinate = iterator.nextLong(); -+ -+ final byte currentLevel = this.levels.get(coordinate); -+ final byte updatedSource = this.sources.get(coordinate); -+ -+ if (currentLevel == updatedSource) { -+ continue; -+ } -+ ret = true; -+ -+ if (updatedSource > currentLevel) { -+ // level increase -+ this.addToIncreaseWorkQueue(coordinate, updatedSource); -+ } else { -+ // level decrease -+ this.addToRemoveWorkQueue(coordinate, currentLevel); -+ // if the current coordinate is a source, then the decrease propagation will detect that and queue -+ // the source propagation -+ } -+ } -+ -+ this.updatedSources.clear(); -+ -+ // propagate source level increases first for performance reasons (in crowded areas hopefully the additions -+ // make the removes remove less) -+ this.propagateIncreases(); -+ -+ // now we propagate the decreases (which will then re-propagate clobbered sources) -+ this.propagateDecreases(); -+ -+ return ret; -+ } -+ -+ protected void propagateIncreases() { -+ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset); -+ this.levelIncreaseWorkQueueBitset != 0L; -+ this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) { -+ -+ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; -+ while (!queue.queuedLevels.isEmpty()) { -+ final long coordinate = queue.queuedCoordinates.removeFirstLong(); -+ byte level = queue.queuedLevels.removeFirstByte(); -+ -+ final boolean neighbourCheck = level < 0; -+ -+ final byte currentLevel; -+ if (neighbourCheck) { -+ level = (byte)-level; -+ currentLevel = this.levels.get(coordinate); -+ } else { -+ currentLevel = this.levels.putIfGreater(coordinate, level); -+ } -+ -+ if (neighbourCheck) { -+ // used when propagating from decrease to indicate that this level needs to check its neighbours -+ // this means the level at coordinate could be equal, but would still need neighbours checked -+ -+ if (currentLevel != level) { -+ // something caused the level to change, which means something propagated to it (which means -+ // us propagating here is redundant), or something removed the level (which means we -+ // cannot propagate further) -+ continue; -+ } -+ } else if (currentLevel >= level) { -+ // something higher/equal propagated -+ continue; -+ } -+ if (this.changeCallback != null) { -+ this.changeCallback.onLevelUpdate(coordinate, currentLevel, level); -+ } -+ -+ if (level == 1) { -+ // can't propagate 0 to neighbours -+ continue; -+ } -+ -+ // propagate to neighbours -+ final byte neighbourLevel = (byte)(level - 1); -+ final int x = CoordinateUtils.getChunkSectionX(coordinate); -+ final int y = CoordinateUtils.getChunkSectionY(coordinate); -+ final int z = CoordinateUtils.getChunkSectionZ(coordinate); -+ -+ for (int dy = -1; dy <= 1; ++dy) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ if ((dy | dz | dx) == 0) { -+ // already propagated to coordinate -+ continue; -+ } -+ -+ // sure we can check the neighbour level in the map right now and avoid a propagation, -+ // but then we would still have to recheck it when popping the value off of the queue! -+ // so just avoid the double lookup -+ final long neighbourCoordinate = CoordinateUtils.getChunkSectionKey(dx + x, dy + y, dz + z); -+ this.addToIncreaseWorkQueue(neighbourCoordinate, neighbourLevel); -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ protected void propagateDecreases() { -+ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset); -+ this.levelRemoveWorkQueueBitset != 0L; -+ this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) { -+ -+ final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; -+ while (!queue.queuedLevels.isEmpty()) { -+ final long coordinate = queue.queuedCoordinates.removeFirstLong(); -+ final byte level = queue.queuedLevels.removeFirstByte(); -+ -+ final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); -+ if (currentLevel == 0) { -+ // something else removed -+ continue; -+ } -+ -+ if (currentLevel > level) { -+ // something higher propagated here or we hit the propagation of another source -+ // in the second case we need to re-propagate because we could have just clobbered another source's -+ // propagation -+ this.addToIncreaseWorkQueue(coordinate, currentLevel, (byte)-currentLevel); // indicate to the increase code that the level's neighbours need checking -+ continue; -+ } -+ -+ if (this.changeCallback != null) { -+ this.changeCallback.onLevelUpdate(coordinate, currentLevel, (byte)0); -+ } -+ -+ final byte source = this.sources.get(coordinate); -+ if (source != 0) { -+ // must re-propagate source later -+ this.addToIncreaseWorkQueue(coordinate, source); -+ } -+ -+ if (level == 0) { -+ // can't propagate -1 to neighbours -+ // we have to check neighbours for removing 1 just in case the neighbour is 2 -+ continue; -+ } -+ -+ // propagate to neighbours -+ final byte neighbourLevel = (byte)(level - 1); -+ final int x = CoordinateUtils.getChunkSectionX(coordinate); -+ final int y = CoordinateUtils.getChunkSectionY(coordinate); -+ final int z = CoordinateUtils.getChunkSectionZ(coordinate); -+ -+ for (int dy = -1; dy <= 1; ++dy) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ for (int dx = -1; dx <= 1; ++dx) { -+ if ((dy | dz | dx) == 0) { -+ // already propagated to coordinate -+ continue; -+ } -+ -+ // sure we can check the neighbour level in the map right now and avoid a propagation, -+ // but then we would still have to recheck it when popping the value off of the queue! -+ // so just avoid the double lookup -+ final long neighbourCoordinate = CoordinateUtils.getChunkSectionKey(dx + x, dy + y, dz + z); -+ this.addToRemoveWorkQueue(neighbourCoordinate, neighbourLevel); -+ } -+ } -+ } -+ } -+ } -+ -+ // propagate sources we clobbered in the process -+ this.propagateIncreases(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ab2fa1563d5e32a5313dfcc1da411cab45fb5ca0 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java -@@ -0,0 +1,718 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import it.unimi.dsi.fastutil.HashCommon; -+import it.unimi.dsi.fastutil.bytes.ByteArrayFIFOQueue; -+import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; -+import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; -+import it.unimi.dsi.fastutil.longs.LongIterator; -+import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; -+ -+public final class Delayed8WayDistancePropagator2D { -+ -+ // Test -+ /* -+ protected static void test(int x, int z, com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap reference, Delayed8WayDistancePropagator2D test) { -+ int got = test.getLevel(x, z); -+ -+ int expect = 0; -+ Object[] nearest = reference.getObjectsInRange(x, z) == null ? null : reference.getObjectsInRange(x, z).getBackingSet(); -+ if (nearest != null) { -+ for (Object _obj : nearest) { -+ if (_obj instanceof Ticket) { -+ Ticket ticket = (Ticket)_obj; -+ long ticketCoord = reference.getLastCoordinate(ticket); -+ int viewDistance = reference.getLastViewDistance(ticket); -+ int distance = Math.max(com.destroystokyo.paper.util.math.IntegerUtil.branchlessAbs(MCUtil.getCoordinateX(ticketCoord) - x), -+ com.destroystokyo.paper.util.math.IntegerUtil.branchlessAbs(MCUtil.getCoordinateZ(ticketCoord) - z)); -+ int level = viewDistance - distance; -+ if (level > expect) { -+ expect = level; -+ } -+ } -+ } -+ } -+ -+ if (expect != got) { -+ throw new IllegalStateException("Expected " + expect + " at pos (" + x + "," + z + ") but got " + got); -+ } -+ } -+ -+ static class Ticket { -+ -+ int x; -+ int z; -+ -+ final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet empty -+ = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); -+ -+ } -+ -+ public static void main(final String[] args) { -+ com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap reference = new com.destroystokyo.paper.util.misc.DistanceTrackingAreaMap() { -+ @Override -+ protected com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getEmptySetFor(Ticket object) { -+ return object.empty; -+ } -+ }; -+ Delayed8WayDistancePropagator2D test = new Delayed8WayDistancePropagator2D(); -+ -+ final int maxDistance = 64; -+ // test origin -+ { -+ Ticket originTicket = new Ticket(); -+ int originDistance = 31; -+ // test single source -+ reference.add(originTicket, 0, 0, originDistance); -+ test.setSource(0, 0, originDistance); test.propagateUpdates(); // set and propagate -+ for (int dx = -originDistance; dx <= originDistance; ++dx) { -+ for (int dz = -originDistance; dz <= originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ // test single source decrease -+ reference.update(originTicket, 0, 0, originDistance/2); -+ test.setSource(0, 0, originDistance/2); test.propagateUpdates(); // set and propagate -+ for (int dx = -originDistance; dx <= originDistance; ++dx) { -+ for (int dz = -originDistance; dz <= originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ // test source increase -+ originDistance = 2*originDistance; -+ reference.update(originTicket, 0, 0, originDistance); -+ test.setSource(0, 0, originDistance); test.propagateUpdates(); // set and propagate -+ for (int dx = -4*originDistance; dx <= 4*originDistance; ++dx) { -+ for (int dz = -4*originDistance; dz <= 4*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ reference.remove(originTicket); -+ test.removeSource(0, 0); test.propagateUpdates(); -+ } -+ -+ // test multiple sources at origin -+ { -+ int originDistance = 31; -+ java.util.List list = new java.util.ArrayList<>(); -+ for (int i = 0; i < 10; ++i) { -+ Ticket a = new Ticket(); -+ list.add(a); -+ a.x = (i & 1) == 1 ? -i : i; -+ a.z = (i & 1) == 1 ? -i : i; -+ } -+ for (Ticket ticket : list) { -+ reference.add(ticket, ticket.x, ticket.z, originDistance); -+ test.setSource(ticket.x, ticket.z, originDistance); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { -+ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket level decrease -+ -+ for (Ticket ticket : list) { -+ reference.update(ticket, ticket.x, ticket.z, originDistance/2); -+ test.setSource(ticket.x, ticket.z, originDistance/2); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { -+ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket level increase -+ -+ for (Ticket ticket : list) { -+ reference.update(ticket, ticket.x, ticket.z, originDistance*2); -+ test.setSource(ticket.x, ticket.z, originDistance*2); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { -+ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket remove -+ for (int i = 0, len = list.size(); i < len; ++i) { -+ if ((i & 3) != 0) { -+ continue; -+ } -+ Ticket ticket = list.get(i); -+ reference.remove(ticket); -+ test.removeSource(ticket.x, ticket.z); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { -+ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ } -+ -+ // now test at coordinate offsets -+ // test offset -+ { -+ Ticket originTicket = new Ticket(); -+ int originDistance = 31; -+ int offX = 54432; -+ int offZ = -134567; -+ // test single source -+ reference.add(originTicket, offX, offZ, originDistance); -+ test.setSource(offX, offZ, originDistance); test.propagateUpdates(); // set and propagate -+ for (int dx = -originDistance; dx <= originDistance; ++dx) { -+ for (int dz = -originDistance; dz <= originDistance; ++dz) { -+ test(dx + offX, dz + offZ, reference, test); -+ } -+ } -+ // test single source decrease -+ reference.update(originTicket, offX, offZ, originDistance/2); -+ test.setSource(offX, offZ, originDistance/2); test.propagateUpdates(); // set and propagate -+ for (int dx = -originDistance; dx <= originDistance; ++dx) { -+ for (int dz = -originDistance; dz <= originDistance; ++dz) { -+ test(dx + offX, dz + offZ, reference, test); -+ } -+ } -+ // test source increase -+ originDistance = 2*originDistance; -+ reference.update(originTicket, offX, offZ, originDistance); -+ test.setSource(offX, offZ, originDistance); test.propagateUpdates(); // set and propagate -+ for (int dx = -4*originDistance; dx <= 4*originDistance; ++dx) { -+ for (int dz = -4*originDistance; dz <= 4*originDistance; ++dz) { -+ test(dx + offX, dz + offZ, reference, test); -+ } -+ } -+ -+ reference.remove(originTicket); -+ test.removeSource(offX, offZ); test.propagateUpdates(); -+ } -+ -+ // test multiple sources at origin -+ { -+ int originDistance = 31; -+ int offX = 54432; -+ int offZ = -134567; -+ java.util.List list = new java.util.ArrayList<>(); -+ for (int i = 0; i < 10; ++i) { -+ Ticket a = new Ticket(); -+ list.add(a); -+ a.x = offX + ((i & 1) == 1 ? -i : i); -+ a.z = offZ + ((i & 1) == 1 ? -i : i); -+ } -+ for (Ticket ticket : list) { -+ reference.add(ticket, ticket.x, ticket.z, originDistance); -+ test.setSource(ticket.x, ticket.z, originDistance); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { -+ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket level decrease -+ -+ for (Ticket ticket : list) { -+ reference.update(ticket, ticket.x, ticket.z, originDistance/2); -+ test.setSource(ticket.x, ticket.z, originDistance/2); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -8*originDistance; dx <= 8*originDistance; ++dx) { -+ for (int dz = -8*originDistance; dz <= 8*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket level increase -+ -+ for (Ticket ticket : list) { -+ reference.update(ticket, ticket.x, ticket.z, originDistance*2); -+ test.setSource(ticket.x, ticket.z, originDistance*2); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { -+ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ -+ // test ticket remove -+ for (int i = 0, len = list.size(); i < len; ++i) { -+ if ((i & 3) != 0) { -+ continue; -+ } -+ Ticket ticket = list.get(i); -+ reference.remove(ticket); -+ test.removeSource(ticket.x, ticket.z); -+ } -+ test.propagateUpdates(); -+ -+ for (int dx = -16*originDistance; dx <= 16*originDistance; ++dx) { -+ for (int dz = -16*originDistance; dz <= 16*originDistance; ++dz) { -+ test(dx, dz, reference, test); -+ } -+ } -+ } -+ } -+ */ -+ -+ // this map is considered "stale" unless updates are propagated. -+ protected final LevelMap levels = new LevelMap(8192*2, 0.6f); -+ -+ // this map is never stale -+ protected final Long2ByteOpenHashMap sources = new Long2ByteOpenHashMap(4096, 0.6f); -+ -+ // Generally updates to positions are made close to other updates, so we link to decrease cache misses when -+ // propagating updates -+ protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet(); -+ -+ @FunctionalInterface -+ public static interface LevelChangeCallback { -+ -+ /** -+ * This can be called for intermediate updates. So do not rely on newLevel being close to or -+ * the exact level that is expected after a full propagation has occured. -+ */ -+ public void onLevelUpdate(final long coordinate, final byte oldLevel, final byte newLevel); -+ -+ } -+ -+ protected final LevelChangeCallback changeCallback; -+ -+ public Delayed8WayDistancePropagator2D() { -+ this(null); -+ } -+ -+ public Delayed8WayDistancePropagator2D(final LevelChangeCallback changeCallback) { -+ this.changeCallback = changeCallback; -+ } -+ -+ public int getLevel(final long pos) { -+ return this.levels.get(pos); -+ } -+ -+ public int getLevel(final int x, final int z) { -+ return this.levels.get(CoordinateUtils.getChunkKey(x, z)); -+ } -+ -+ public void setSource(final int x, final int z, final int level) { -+ this.setSource(CoordinateUtils.getChunkKey(x, z), level); -+ } -+ -+ public void setSource(final long coordinate, final int level) { -+ if ((level & 63) != level || level == 0) { -+ throw new IllegalArgumentException("Level must be in (0, 63], not " + level); -+ } -+ -+ final byte byteLevel = (byte)level; -+ final byte oldLevel = this.sources.put(coordinate, byteLevel); -+ -+ if (oldLevel == byteLevel) { -+ return; // nothing to do -+ } -+ -+ // queue to update later -+ this.updatedSources.add(coordinate); -+ } -+ -+ public void removeSource(final int x, final int z) { -+ this.removeSource(CoordinateUtils.getChunkKey(x, z)); -+ } -+ -+ public void removeSource(final long coordinate) { -+ if (this.sources.remove(coordinate) != 0) { -+ this.updatedSources.add(coordinate); -+ } -+ } -+ -+ // queues used for BFS propagating levels -+ protected final WorkQueue[] levelIncreaseWorkQueues = new WorkQueue[64]; -+ { -+ for (int i = 0; i < this.levelIncreaseWorkQueues.length; ++i) { -+ this.levelIncreaseWorkQueues[i] = new WorkQueue(); -+ } -+ } -+ protected final WorkQueue[] levelRemoveWorkQueues = new WorkQueue[64]; -+ { -+ for (int i = 0; i < this.levelRemoveWorkQueues.length; ++i) { -+ this.levelRemoveWorkQueues[i] = new WorkQueue(); -+ } -+ } -+ protected long levelIncreaseWorkQueueBitset; -+ protected long levelRemoveWorkQueueBitset; -+ -+ protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { -+ final WorkQueue queue = this.levelIncreaseWorkQueues[level]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelIncreaseWorkQueueBitset |= (1L << level); -+ } -+ -+ protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { -+ final WorkQueue queue = this.levelIncreaseWorkQueues[index]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelIncreaseWorkQueueBitset |= (1L << index); -+ } -+ -+ protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { -+ final WorkQueue queue = this.levelRemoveWorkQueues[level]; -+ queue.queuedCoordinates.enqueue(coordinate); -+ queue.queuedLevels.enqueue(level); -+ -+ this.levelRemoveWorkQueueBitset |= (1L << level); -+ } -+ -+ public boolean propagateUpdates() { -+ if (this.updatedSources.isEmpty()) { -+ return false; -+ } -+ -+ boolean ret = false; -+ -+ for (final LongIterator iterator = this.updatedSources.iterator(); iterator.hasNext();) { -+ final long coordinate = iterator.nextLong(); -+ -+ final byte currentLevel = this.levels.get(coordinate); -+ final byte updatedSource = this.sources.get(coordinate); -+ -+ if (currentLevel == updatedSource) { -+ continue; -+ } -+ ret = true; -+ -+ if (updatedSource > currentLevel) { -+ // level increase -+ this.addToIncreaseWorkQueue(coordinate, updatedSource); -+ } else { -+ // level decrease -+ this.addToRemoveWorkQueue(coordinate, currentLevel); -+ // if the current coordinate is a source, then the decrease propagation will detect that and queue -+ // the source propagation -+ } -+ } -+ -+ this.updatedSources.clear(); -+ -+ // propagate source level increases first for performance reasons (in crowded areas hopefully the additions -+ // make the removes remove less) -+ this.propagateIncreases(); -+ -+ // now we propagate the decreases (which will then re-propagate clobbered sources) -+ this.propagateDecreases(); -+ -+ return ret; -+ } -+ -+ protected void propagateIncreases() { -+ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset); -+ this.levelIncreaseWorkQueueBitset != 0L; -+ this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) { -+ -+ final WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; -+ while (!queue.queuedLevels.isEmpty()) { -+ final long coordinate = queue.queuedCoordinates.removeFirstLong(); -+ byte level = queue.queuedLevels.removeFirstByte(); -+ -+ final boolean neighbourCheck = level < 0; -+ -+ final byte currentLevel; -+ if (neighbourCheck) { -+ level = (byte)-level; -+ currentLevel = this.levels.get(coordinate); -+ } else { -+ currentLevel = this.levels.putIfGreater(coordinate, level); -+ } -+ -+ if (neighbourCheck) { -+ // used when propagating from decrease to indicate that this level needs to check its neighbours -+ // this means the level at coordinate could be equal, but would still need neighbours checked -+ -+ if (currentLevel != level) { -+ // something caused the level to change, which means something propagated to it (which means -+ // us propagating here is redundant), or something removed the level (which means we -+ // cannot propagate further) -+ continue; -+ } -+ } else if (currentLevel >= level) { -+ // something higher/equal propagated -+ continue; -+ } -+ if (this.changeCallback != null) { -+ this.changeCallback.onLevelUpdate(coordinate, currentLevel, level); -+ } -+ -+ if (level == 1) { -+ // can't propagate 0 to neighbours -+ continue; -+ } -+ -+ // propagate to neighbours -+ final byte neighbourLevel = (byte)(level - 1); -+ final int x = (int)coordinate; -+ final int z = (int)(coordinate >>> 32); -+ -+ for (int dx = -1; dx <= 1; ++dx) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ if ((dx | dz) == 0) { -+ // already propagated to coordinate -+ continue; -+ } -+ -+ // sure we can check the neighbour level in the map right now and avoid a propagation, -+ // but then we would still have to recheck it when popping the value off of the queue! -+ // so just avoid the double lookup -+ final long neighbourCoordinate = CoordinateUtils.getChunkKey(x + dx, z + dz); -+ this.addToIncreaseWorkQueue(neighbourCoordinate, neighbourLevel); -+ } -+ } -+ } -+ } -+ } -+ -+ protected void propagateDecreases() { -+ for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset); -+ this.levelRemoveWorkQueueBitset != 0L; -+ this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) { -+ -+ final WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; -+ while (!queue.queuedLevels.isEmpty()) { -+ final long coordinate = queue.queuedCoordinates.removeFirstLong(); -+ final byte level = queue.queuedLevels.removeFirstByte(); -+ -+ final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); -+ if (currentLevel == 0) { -+ // something else removed -+ continue; -+ } -+ -+ if (currentLevel > level) { -+ // something higher propagated here or we hit the propagation of another source -+ // in the second case we need to re-propagate because we could have just clobbered another source's -+ // propagation -+ this.addToIncreaseWorkQueue(coordinate, currentLevel, (byte)-currentLevel); // indicate to the increase code that the level's neighbours need checking -+ continue; -+ } -+ -+ if (this.changeCallback != null) { -+ this.changeCallback.onLevelUpdate(coordinate, currentLevel, (byte)0); -+ } -+ -+ final byte source = this.sources.get(coordinate); -+ if (source != 0) { -+ // must re-propagate source later -+ this.addToIncreaseWorkQueue(coordinate, source); -+ } -+ -+ if (level == 0) { -+ // can't propagate -1 to neighbours -+ // we have to check neighbours for removing 1 just in case the neighbour is 2 -+ continue; -+ } -+ -+ // propagate to neighbours -+ final byte neighbourLevel = (byte)(level - 1); -+ final int x = (int)coordinate; -+ final int z = (int)(coordinate >>> 32); -+ -+ for (int dx = -1; dx <= 1; ++dx) { -+ for (int dz = -1; dz <= 1; ++dz) { -+ if ((dx | dz) == 0) { -+ // already propagated to coordinate -+ continue; -+ } -+ -+ // sure we can check the neighbour level in the map right now and avoid a propagation, -+ // but then we would still have to recheck it when popping the value off of the queue! -+ // so just avoid the double lookup -+ final long neighbourCoordinate = CoordinateUtils.getChunkKey(x + dx, z + dz); -+ this.addToRemoveWorkQueue(neighbourCoordinate, neighbourLevel); -+ } -+ } -+ } -+ } -+ -+ // propagate sources we clobbered in the process -+ this.propagateIncreases(); -+ } -+ -+ protected static final class LevelMap extends Long2ByteOpenHashMap { -+ public LevelMap() { -+ super(); -+ } -+ -+ public LevelMap(final int expected, final float loadFactor) { -+ super(expected, loadFactor); -+ } -+ -+ // copied from superclass -+ private int find(final long k) { -+ if (k == 0L) { -+ return this.containsNullKey ? this.n : -(this.n + 1); -+ } else { -+ final long[] key = this.key; -+ long curr; -+ int pos; -+ if ((curr = key[pos = (int)HashCommon.mix(k) & this.mask]) == 0L) { -+ return -(pos + 1); -+ } else if (k == curr) { -+ return pos; -+ } else { -+ while((curr = key[pos = pos + 1 & this.mask]) != 0L) { -+ if (k == curr) { -+ return pos; -+ } -+ } -+ -+ return -(pos + 1); -+ } -+ } -+ } -+ -+ // copied from superclass -+ private void insert(final int pos, final long k, final byte v) { -+ if (pos == this.n) { -+ this.containsNullKey = true; -+ } -+ -+ this.key[pos] = k; -+ this.value[pos] = v; -+ if (this.size++ >= this.maxFill) { -+ this.rehash(HashCommon.arraySize(this.size + 1, this.f)); -+ } -+ } -+ -+ // copied from superclass -+ public byte putIfGreater(final long key, final byte value) { -+ final int pos = this.find(key); -+ if (pos < 0) { -+ if (this.defRetValue < value) { -+ this.insert(-pos - 1, key, value); -+ } -+ return this.defRetValue; -+ } else { -+ final byte curr = this.value[pos]; -+ if (value > curr) { -+ this.value[pos] = value; -+ return curr; -+ } -+ return curr; -+ } -+ } -+ -+ // copied from superclass -+ private void removeEntry(final int pos) { -+ --this.size; -+ this.shiftKeys(pos); -+ if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { -+ this.rehash(this.n / 2); -+ } -+ } -+ -+ // copied from superclass -+ private void removeNullEntry() { -+ this.containsNullKey = false; -+ --this.size; -+ if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { -+ this.rehash(this.n / 2); -+ } -+ } -+ -+ // copied from superclass -+ public byte removeIfGreaterOrEqual(final long key, final byte value) { -+ if (key == 0L) { -+ if (!this.containsNullKey) { -+ return this.defRetValue; -+ } -+ final byte current = this.value[this.n]; -+ if (value >= current) { -+ this.removeNullEntry(); -+ return current; -+ } -+ return current; -+ } else { -+ long[] keys = this.key; -+ byte[] values = this.value; -+ long curr; -+ int pos; -+ if ((curr = keys[pos = (int)HashCommon.mix(key) & this.mask]) == 0L) { -+ return this.defRetValue; -+ } else if (key == curr) { -+ final byte current = values[pos]; -+ if (value >= current) { -+ this.removeEntry(pos); -+ return current; -+ } -+ return current; -+ } else { -+ while((curr = keys[pos = pos + 1 & this.mask]) != 0L) { -+ if (key == curr) { -+ final byte current = values[pos]; -+ if (value >= current) { -+ this.removeEntry(pos); -+ return current; -+ } -+ return current; -+ } -+ } -+ -+ return this.defRetValue; -+ } -+ } -+ } -+ } -+ -+ protected static final class WorkQueue { -+ -+ public final NoResizeLongArrayFIFODeque queuedCoordinates = new NoResizeLongArrayFIFODeque(); -+ public final NoResizeByteArrayFIFODeque queuedLevels = new NoResizeByteArrayFIFODeque(); -+ -+ } -+ -+ protected static final class NoResizeLongArrayFIFODeque extends LongArrayFIFOQueue { -+ -+ /** -+ * Assumes non-empty. If empty, undefined behaviour. -+ */ -+ public long removeFirstLong() { -+ // copied from superclass -+ long t = this.array[this.start]; -+ if (++this.start == this.length) { -+ this.start = 0; -+ } -+ -+ return t; -+ } -+ } -+ -+ protected static final class NoResizeByteArrayFIFODeque extends ByteArrayFIFOQueue { -+ -+ /** -+ * Assumes non-empty. If empty, undefined behaviour. -+ */ -+ public byte removeFirstByte() { -+ // copied from superclass -+ byte t = this.array[this.start]; -+ if (++this.start == this.length) { -+ this.start = 0; -+ } -+ -+ return t; -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fdde1f5f988d581db41945916635cdd826a10680 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java -@@ -0,0 +1,209 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.moonrise.common.list.ReferenceList; -+import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.MoonriseConstants; -+import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem; -+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; -+import net.minecraft.core.BlockPos; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.level.ChunkPos; -+ -+public final class NearbyPlayers { -+ -+ public static enum NearbyMapType { -+ GENERAL, -+ GENERAL_SMALL, -+ GENERAL_REALLY_SMALL, -+ TICK_VIEW_DISTANCE, -+ VIEW_DISTANCE, -+ SPAWN_RANGE, -+ } -+ -+ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values(); -+ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length; -+ -+ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1; -+ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10; -+ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3; -+ -+ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4); -+ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4); -+ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4); -+ -+ private final ServerLevel world; -+ private final Reference2ReferenceOpenHashMap players = new Reference2ReferenceOpenHashMap<>(); -+ private final Long2ReferenceOpenHashMap byChunk = new Long2ReferenceOpenHashMap<>(); -+ -+ public NearbyPlayers(final ServerLevel world) { -+ this.world = world; -+ } -+ -+ public void addPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES]; -+ if (this.players.putIfAbsent(player, newTrackers) != null) { -+ throw new IllegalStateException("Already have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) { -+ // use 0 for default, will be updated by tickPlayer -+ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0); -+ } -+ -+ // update view distances -+ this.tickPlayer(player); -+ } -+ -+ public void removePlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.remove(player); -+ if (players == null) { -+ return; // May be called during teleportation before the player is actually placed -+ } -+ -+ for (final TrackedPlayer tracker : players) { -+ tracker.remove(); -+ } -+ } -+ -+ public void tickPlayer(final ServerPlayer player) { -+ final TrackedPlayer[] players = this.players.get(player); -+ if (players == null) { -+ throw new IllegalStateException("Don't have player " + player); -+ } -+ -+ final ChunkPos chunk = player.chunkPosition(); -+ -+ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE); -+ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player)); -+ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getLoadViewDistance(player)); -+ } -+ -+ public TrackedChunk getChunk(final ChunkPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public TrackedChunk getChunk(final BlockPos pos) { -+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ } -+ -+ public ReferenceList getPlayers(final BlockPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayers(final ChunkPos pos, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public ReferenceList getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) { -+ final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4)); -+ -+ return chunk == null ? null : chunk.players[type.ordinal()]; -+ } -+ -+ public static final class TrackedChunk { -+ -+ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0]; -+ -+ private final ReferenceList[] players = new ReferenceList[TOTAL_MAP_TYPES]; -+ private int nonEmptyLists; -+ private long updateCount; -+ -+ public boolean isEmpty() { -+ return this.nonEmptyLists == 0; -+ } -+ -+ public long getUpdateCount() { -+ return this.updateCount; -+ } -+ -+ public ReferenceList getPlayers(final NearbyMapType type) { -+ return this.players[type.ordinal()]; -+ } -+ -+ public void addPlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ ++this.nonEmptyLists; -+ (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY, 0)).add(player); -+ return; -+ } -+ -+ if (!list.add(player)) { -+ throw new IllegalStateException("Already contains player " + player); -+ } -+ } -+ -+ public void removePlayer(final ServerPlayer player, final NearbyMapType type) { -+ ++this.updateCount; -+ -+ final int idx = type.ordinal(); -+ final ReferenceList list = this.players[idx]; -+ if (list == null) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (!list.remove(player)) { -+ throw new IllegalStateException("Does not contain player " + player); -+ } -+ -+ if (list.size() == 0) { -+ this.players[idx] = null; -+ --this.nonEmptyLists; -+ } -+ } -+ } -+ -+ private final class TrackedPlayer extends SingleUserAreaMap { -+ -+ private final NearbyMapType type; -+ -+ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) { -+ super(player); -+ this.type = type; -+ } -+ -+ @Override -+ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> { -+ return new TrackedChunk(); -+ }).addPlayer(parameter, this.type); -+ } -+ -+ @Override -+ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) { -+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); -+ -+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey); -+ if (chunk == null) { -+ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey)); -+ } -+ -+ chunk.removePlayer(parameter, this.type); -+ -+ if (chunk.isEmpty()) { -+ NearbyPlayers.this.byChunk.remove(chunkKey); -+ } -+ } -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..61f70247486fd15ed3ffc5b606582dc6a2dd81d3 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/SingleUserAreaMap.java -@@ -0,0 +1,232 @@ -+package ca.spottedleaf.moonrise.common.misc; -+ -+import ca.spottedleaf.concurrentutil.util.IntegerUtil; -+ -+public abstract class SingleUserAreaMap { -+ -+ private static final int NOT_SET = Integer.MIN_VALUE; -+ -+ private final T parameter; -+ private int lastChunkX = NOT_SET; -+ private int lastChunkZ = NOT_SET; -+ private int distance = NOT_SET; -+ -+ public SingleUserAreaMap(final T parameter) { -+ this.parameter = parameter; -+ } -+ -+ /* math sign function except 0 returns 1 */ -+ protected static int sign(int val) { -+ return 1 | (val >> (Integer.SIZE - 1)); -+ } -+ -+ protected abstract void addCallback(final T parameter, final int chunkX, final int chunkZ); -+ -+ protected abstract void removeCallback(final T parameter, final int chunkX, final int chunkZ); -+ -+ private void addToNew(final T parameter, final int chunkX, final int chunkZ, final int distance) { -+ final int maxX = chunkX + distance; -+ final int maxZ = chunkZ + distance; -+ -+ for (int cx = chunkX - distance; cx <= maxX; ++cx) { -+ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { -+ this.addCallback(parameter, cx, cz); -+ } -+ } -+ } -+ -+ private void removeFromOld(final T parameter, final int chunkX, final int chunkZ, final int distance) { -+ final int maxX = chunkX + distance; -+ final int maxZ = chunkZ + distance; -+ -+ for (int cx = chunkX - distance; cx <= maxX; ++cx) { -+ for (int cz = chunkZ - distance; cz <= maxZ; ++cz) { -+ this.removeCallback(parameter, cx, cz); -+ } -+ } -+ } -+ -+ public final boolean add(final int chunkX, final int chunkZ, final int distance) { -+ if (distance < 0) { -+ throw new IllegalArgumentException(Integer.toString(distance)); -+ } -+ if (this.lastChunkX != NOT_SET) { -+ return false; -+ } -+ this.lastChunkX = chunkX; -+ this.lastChunkZ = chunkZ; -+ this.distance = distance; -+ -+ this.addToNew(this.parameter, chunkX, chunkZ, distance); -+ -+ return true; -+ } -+ -+ public final boolean update(final int toX, final int toZ, final int newViewDistance) { -+ if (newViewDistance < 0) { -+ throw new IllegalArgumentException(Integer.toString(newViewDistance)); -+ } -+ final int fromX = this.lastChunkX; -+ final int fromZ = this.lastChunkZ; -+ final int oldViewDistance = this.distance; -+ if (fromX == NOT_SET) { -+ return false; -+ } -+ -+ this.lastChunkX = toX; -+ this.lastChunkZ = toZ; -+ this.distance = newViewDistance; -+ -+ final T parameter = this.parameter; -+ -+ -+ final int dx = toX - fromX; -+ final int dz = toZ - fromZ; -+ -+ final int totalX = IntegerUtil.branchlessAbs(fromX - toX); -+ final int totalZ = IntegerUtil.branchlessAbs(fromZ - toZ); -+ -+ if (Math.max(totalX, totalZ) > (2 * Math.max(newViewDistance, oldViewDistance))) { -+ // teleported -+ this.removeFromOld(parameter, fromX, fromZ, oldViewDistance); -+ this.addToNew(parameter, toX, toZ, newViewDistance); -+ return true; -+ } -+ -+ if (oldViewDistance != newViewDistance) { -+ // remove loop -+ -+ final int oldMinX = fromX - oldViewDistance; -+ final int oldMinZ = fromZ - oldViewDistance; -+ final int oldMaxX = fromX + oldViewDistance; -+ final int oldMaxZ = fromZ + oldViewDistance; -+ for (int currX = oldMinX; currX <= oldMaxX; ++currX) { -+ for (int currZ = oldMinZ; currZ <= oldMaxZ; ++currZ) { -+ -+ // only remove if we're outside the new view distance... -+ if (Math.max(IntegerUtil.branchlessAbs(currX - toX), IntegerUtil.branchlessAbs(currZ - toZ)) > newViewDistance) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ // add loop -+ -+ final int newMinX = toX - newViewDistance; -+ final int newMinZ = toZ - newViewDistance; -+ final int newMaxX = toX + newViewDistance; -+ final int newMaxZ = toZ + newViewDistance; -+ for (int currX = newMinX; currX <= newMaxX; ++currX) { -+ for (int currZ = newMinZ; currZ <= newMaxZ; ++currZ) { -+ -+ // only add if we're outside the old view distance... -+ if (Math.max(IntegerUtil.branchlessAbs(currX - fromX), IntegerUtil.branchlessAbs(currZ - fromZ)) > oldViewDistance) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ // x axis is width -+ // z axis is height -+ // right refers to the x axis of where we moved -+ // top refers to the z axis of where we moved -+ -+ // same view distance -+ -+ // used for relative positioning -+ final int up = sign(dz); // 1 if dz >= 0, -1 otherwise -+ final int right = sign(dx); // 1 if dx >= 0, -1 otherwise -+ -+ // The area excluded by overlapping the two view distance squares creates four rectangles: -+ // Two on the left, and two on the right. The ones on the left we consider the "removed" section -+ // and on the right the "added" section. -+ // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually -+ // exclusive to the regions they surround. -+ -+ // 4 points of the rectangle -+ int maxX; // exclusive -+ int minX; // inclusive -+ int maxZ; // exclusive -+ int minZ; // inclusive -+ -+ if (dx != 0) { -+ // handle right addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX + (oldViewDistance * right) + right; // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle up addition -+ -+ maxX = toX + (oldViewDistance * right) + right; // exclusive -+ minX = toX - (oldViewDistance * right); // inclusive -+ maxZ = toZ + (oldViewDistance * up) + up; // exclusive -+ minZ = fromZ + (oldViewDistance * up) + up; // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.addCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dx != 0) { -+ // handle left removal -+ -+ maxX = toX - (oldViewDistance * right); // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = fromZ + (oldViewDistance * up) + up; // exclusive -+ minZ = toZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ if (dz != 0) { -+ // handle down removal -+ -+ maxX = fromX + (oldViewDistance * right) + right; // exclusive -+ minX = fromX - (oldViewDistance * right); // inclusive -+ maxZ = toZ - (oldViewDistance * up); // exclusive -+ minZ = fromZ - (oldViewDistance * up); // inclusive -+ -+ for (int currX = minX; currX != maxX; currX += right) { -+ for (int currZ = minZ; currZ != maxZ; currZ += up) { -+ this.removeCallback(parameter, currX, currZ); -+ } -+ } -+ } -+ -+ return true; -+ } -+ -+ public final boolean remove() { -+ final int chunkX = this.lastChunkX; -+ final int chunkZ = this.lastChunkZ; -+ final int distance = this.distance; -+ if (chunkX == NOT_SET) { -+ return false; -+ } -+ -+ this.lastChunkX = this.lastChunkZ = this.distance = NOT_SET; -+ -+ this.removeFromOld(this.parameter, chunkX, chunkZ, distance); -+ -+ return true; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java b/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4123edddc556c47f3f8d83523c125fd2e46b30e2 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/set/OptimizedSmallEnumSet.java -@@ -0,0 +1,68 @@ -+package ca.spottedleaf.moonrise.common.set; -+ -+import java.util.Collection; -+ -+public final class OptimizedSmallEnumSet> { -+ -+ private final Class enumClass; -+ private long backingSet; -+ -+ public OptimizedSmallEnumSet(final Class clazz) { -+ if (clazz == null) { -+ throw new IllegalArgumentException("Null class"); -+ } -+ if (!clazz.isEnum()) { -+ throw new IllegalArgumentException("Class must be enum, not " + clazz.getCanonicalName()); -+ } -+ this.enumClass = clazz; -+ } -+ -+ public boolean addUnchecked(final E element) { -+ final int ordinal = element.ordinal(); -+ final long key = 1L << ordinal; -+ -+ final long prev = this.backingSet; -+ this.backingSet = prev | key; -+ -+ return (prev & key) == 0; -+ } -+ -+ public boolean removeUnchecked(final E element) { -+ final int ordinal = element.ordinal(); -+ final long key = 1L << ordinal; -+ -+ final long prev = this.backingSet; -+ this.backingSet = prev & ~key; -+ -+ return (prev & key) != 0; -+ } -+ -+ public void clear() { -+ this.backingSet = 0L; -+ } -+ -+ public int size() { -+ return Long.bitCount(this.backingSet); -+ } -+ -+ public void addAllUnchecked(final Collection enums) { -+ for (final E element : enums) { -+ if (element == null) { -+ throw new NullPointerException("Null element"); -+ } -+ this.backingSet |= (1L << element.ordinal()); -+ } -+ } -+ -+ public long getBackingSet() { -+ return this.backingSet; -+ } -+ -+ public boolean hasCommonElements(final OptimizedSmallEnumSet other) { -+ return (other.backingSet & this.backingSet) != 0; -+ } -+ -+ public boolean hasElement(final E element) { -+ return (this.backingSet & (1L << element.ordinal())) != 0; -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java -new file mode 100644 -index 0000000000000000000000000000000000000000..31b92bd48828cbea25b44a9f0f96886347aa1ae6 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java -@@ -0,0 +1,129 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.SectionPos; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.phys.Vec3; -+ -+public final class CoordinateUtils { -+ -+ // the chunk keys are compatible with vanilla -+ -+ public static long getChunkKey(final BlockPos pos) { -+ return ((long)(pos.getZ() >> 4) << 32) | ((pos.getX() >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final Entity entity) { -+ return ((Mth.lfloor(entity.getZ()) >> 4) << 32) | ((Mth.lfloor(entity.getX()) >> 4) & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final ChunkPos pos) { -+ return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final SectionPos pos) { -+ return ((long)pos.getZ() << 32) | (pos.getX() & 0xFFFFFFFFL); -+ } -+ -+ public static long getChunkKey(final int x, final int z) { -+ return ((long)z << 32) | (x & 0xFFFFFFFFL); -+ } -+ -+ public static int getChunkX(final long chunkKey) { -+ return (int)chunkKey; -+ } -+ -+ public static int getChunkZ(final long chunkKey) { -+ return (int)(chunkKey >>> 32); -+ } -+ -+ public static int getChunkCoordinate(final double blockCoordinate) { -+ return Mth.floor(blockCoordinate) >> 4; -+ } -+ -+ // the section keys are compatible with vanilla's -+ -+ static final int SECTION_X_BITS = 22; -+ static final long SECTION_X_MASK = (1L << SECTION_X_BITS) - 1; -+ static final int SECTION_Y_BITS = 20; -+ static final long SECTION_Y_MASK = (1L << SECTION_Y_BITS) - 1; -+ static final int SECTION_Z_BITS = 22; -+ static final long SECTION_Z_MASK = (1L << SECTION_Z_BITS) - 1; -+ // format is y,z,x (in order of LSB to MSB) -+ static final int SECTION_Y_SHIFT = 0; -+ static final int SECTION_Z_SHIFT = SECTION_Y_SHIFT + SECTION_Y_BITS; -+ static final int SECTION_X_SHIFT = SECTION_Z_SHIFT + SECTION_X_BITS; -+ static final int SECTION_TO_BLOCK_SHIFT = 4; -+ -+ public static long getChunkSectionKey(final int x, final int y, final int z) { -+ return ((x & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((y & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((z & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final SectionPos pos) { -+ return ((pos.getX() & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((pos.getY() & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((pos.getZ() & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final ChunkPos pos, final int y) { -+ return ((pos.x & SECTION_X_MASK) << SECTION_X_SHIFT) -+ | ((y & SECTION_Y_MASK) << SECTION_Y_SHIFT) -+ | ((pos.z & SECTION_Z_MASK) << SECTION_Z_SHIFT); -+ } -+ -+ public static long getChunkSectionKey(final BlockPos pos) { -+ return (((long)pos.getX() << (SECTION_X_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_X_MASK << SECTION_X_SHIFT)) | -+ ((pos.getY() >> SECTION_TO_BLOCK_SHIFT) & (SECTION_Y_MASK << SECTION_Y_SHIFT)) | -+ (((long)pos.getZ() << (SECTION_Z_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_Z_MASK << SECTION_Z_SHIFT)); -+ } -+ -+ public static long getChunkSectionKey(final Entity entity) { -+ return ((Mth.lfloor(entity.getX()) << (SECTION_X_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_X_MASK << SECTION_X_SHIFT)) | -+ ((Mth.lfloor(entity.getY()) >> SECTION_TO_BLOCK_SHIFT) & (SECTION_Y_MASK << SECTION_Y_SHIFT)) | -+ ((Mth.lfloor(entity.getZ()) << (SECTION_Z_SHIFT - SECTION_TO_BLOCK_SHIFT)) & (SECTION_Z_MASK << SECTION_Z_SHIFT)); -+ } -+ -+ public static int getChunkSectionX(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_X_SHIFT + SECTION_X_BITS)) >> (Long.SIZE - SECTION_X_BITS)); -+ } -+ -+ public static int getChunkSectionY(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_Y_SHIFT + SECTION_Y_BITS)) >> (Long.SIZE - SECTION_Y_BITS)); -+ } -+ -+ public static int getChunkSectionZ(final long key) { -+ return (int)(key << (Long.SIZE - (SECTION_Z_SHIFT + SECTION_Z_BITS)) >> (Long.SIZE - SECTION_Z_BITS)); -+ } -+ -+ public static int getBlockX(final Vec3 pos) { -+ return Mth.floor(pos.x); -+ } -+ -+ public static int getBlockY(final Vec3 pos) { -+ return Mth.floor(pos.y); -+ } -+ -+ public static int getBlockZ(final Vec3 pos) { -+ return Mth.floor(pos.z); -+ } -+ -+ public static int getChunkX(final Vec3 pos) { -+ return Mth.floor(pos.x) >> 4; -+ } -+ -+ public static int getChunkY(final Vec3 pos) { -+ return Mth.floor(pos.y) >> 4; -+ } -+ -+ public static int getChunkZ(final Vec3 pos) { -+ return Mth.floor(pos.z) >> 4; -+ } -+ -+ private CoordinateUtils() { -+ throw new RuntimeException(); -+ } -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0531f25aaad162386a029d33e68d7c8336b9d5d1 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/FlatBitsetUtil.java -@@ -0,0 +1,109 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import java.util.Objects; -+ -+public final class FlatBitsetUtil { -+ -+ private static final int LOG2_LONG = 6; -+ private static final long ALL_SET = -1L; -+ private static final int BITS_PER_LONG = Long.SIZE; -+ -+ // from inclusive -+ // to exclusive -+ public static int firstSet(final long[] bitset, final int from, final int to) { -+ if ((from | to | (to - from)) < 0) { -+ throw new IndexOutOfBoundsException(); -+ } -+ -+ int bitsetIdx = from >>> LOG2_LONG; -+ int bitIdx = from & ~(BITS_PER_LONG - 1); -+ -+ long tmp = bitset[bitsetIdx] & (ALL_SET << from); -+ for (;;) { -+ if (tmp != 0L) { -+ final int ret = bitIdx | Long.numberOfTrailingZeros(tmp); -+ return ret >= to ? -1 : ret; -+ } -+ -+ bitIdx += BITS_PER_LONG; -+ -+ if (bitIdx >= to) { -+ return -1; -+ } -+ -+ tmp = bitset[++bitsetIdx]; -+ } -+ } -+ -+ // from inclusive -+ // to exclusive -+ public static int firstClear(final long[] bitset, final int from, final int to) { -+ if ((from | to | (to - from)) < 0) { -+ throw new IndexOutOfBoundsException(); -+ } -+ // like firstSet, but invert the bitset -+ -+ int bitsetIdx = from >>> LOG2_LONG; -+ int bitIdx = from & ~(BITS_PER_LONG - 1); -+ -+ long tmp = (~bitset[bitsetIdx]) & (ALL_SET << from); -+ for (;;) { -+ if (tmp != 0L) { -+ final int ret = bitIdx | Long.numberOfTrailingZeros(tmp); -+ return ret >= to ? -1 : ret; -+ } -+ -+ bitIdx += BITS_PER_LONG; -+ -+ if (bitIdx >= to) { -+ return -1; -+ } -+ -+ tmp = ~bitset[++bitsetIdx]; -+ } -+ } -+ -+ // from inclusive -+ // to exclusive -+ public static void clearRange(final long[] bitset, final int from, int to) { -+ if ((from | to | (to - from)) < 0) { -+ throw new IndexOutOfBoundsException(); -+ } -+ -+ if (from == to) { -+ return; -+ } -+ -+ --to; -+ -+ final int fromBitsetIdx = from >>> LOG2_LONG; -+ final int toBitsetIdx = to >>> LOG2_LONG; -+ -+ final long keepFirst = ~(ALL_SET << from); -+ final long keepLast = ~(ALL_SET >>> ((BITS_PER_LONG - 1) ^ to)); -+ -+ Objects.checkFromToIndex(fromBitsetIdx, toBitsetIdx, bitset.length); -+ -+ if (fromBitsetIdx == toBitsetIdx) { -+ // special case: need to keep both first and last -+ bitset[fromBitsetIdx] &= (keepFirst | keepLast); -+ } else { -+ bitset[fromBitsetIdx] &= keepFirst; -+ -+ for (int i = fromBitsetIdx + 1; i < toBitsetIdx; ++i) { -+ bitset[i] = 0L; -+ } -+ -+ bitset[toBitsetIdx] &= keepLast; -+ } -+ } -+ -+ // from inclusive -+ // to exclusive -+ public static boolean isRangeSet(final long[] bitset, final int from, final int to) { -+ return firstClear(bitset, from, to) == -1; -+ } -+ -+ -+ private FlatBitsetUtil() {} -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..91efda726b87a8a8f28dee84e31b6a7063752ebd ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/JsonUtil.java -@@ -0,0 +1,34 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import com.google.gson.JsonElement; -+import com.google.gson.internal.Streams; -+import com.google.gson.stream.JsonWriter; -+import java.io.File; -+import java.io.FileOutputStream; -+import java.io.IOException; -+import java.io.PrintStream; -+import java.io.StringWriter; -+import java.nio.charset.StandardCharsets; -+ -+public final class JsonUtil { -+ -+ public static void writeJson(final JsonElement element, final File file) throws IOException { -+ final StringWriter stringWriter = new StringWriter(); -+ final JsonWriter jsonWriter = new JsonWriter(stringWriter); -+ jsonWriter.setIndent(" "); -+ jsonWriter.setLenient(false); -+ Streams.write(element, jsonWriter); -+ -+ final String jsonString = stringWriter.toString(); -+ -+ final File parent = file.getParentFile(); -+ if (parent != null) { -+ parent.mkdirs(); -+ } -+ file.createNewFile(); -+ try (final PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) { -+ out.print(jsonString); -+ } -+ } -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ac6f284ee4469d16c5655328b2488d7612832353 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java -@@ -0,0 +1,10 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+public final class MixinWorkarounds { -+ -+ // mixins tries to find the owner of the clone() method, which doesn't exist and NPEs -+ public static long[] clone(final long[] values) { -+ return values.clone(); -+ } -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ef1c9e1e8636a14b5215c6c55d3032bacfd94cac ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java -@@ -0,0 +1,45 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+ -+public final class MoonriseCommon { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class); -+ -+ // Paper start -+ public static PrioritisedThreadPool WORKER_POOL; -+ public static int WORKER_THREADS; -+ public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) { -+ // Paper end -+ int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; -+ if (defaultWorkerThreads <= 4) { -+ defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; -+ } else { -+ defaultWorkerThreads = defaultWorkerThreads / 2; -+ } -+ defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); -+ -+ int workerThreads = chunkSystem.workerThreads; -+ -+ if (workerThreads <= 0) { -+ workerThreads = defaultWorkerThreads; -+ } -+ -+ WORKER_POOL = new PrioritisedThreadPool( -+ "Paper Worker Pool", workerThreads, -+ (final Thread thread, final Integer id) -> { -+ thread.setName("Paper Common Worker #" + id.intValue()); -+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { -+ @Override -+ public void uncaughtException(final Thread thread, final Throwable throwable) { -+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); -+ } -+ }); -+ }, (long)(20.0e6)); // 20ms -+ WORKER_THREADS = workerThreads; -+ } -+ -+ private MoonriseCommon() {} -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java -@@ -0,0 +1,9 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+public final class MoonriseConstants { -+ -+ public static final int MAX_VIEW_DISTANCE = 32; -+ -+ private MoonriseConstants() {} -+ -+} -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e95cc73ddf20050aa4a241b0a309240e2bf46abd ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java -@@ -0,0 +1,54 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.LevelHeightAccessor; -+ -+public final class WorldUtil { -+ -+ // min, max are inclusive -+ -+ public static int getMaxSection(final LevelHeightAccessor world) { -+ return world.getMaxSection() - 1; // getMaxSection() is exclusive -+ } -+ -+ public static int getMinSection(final LevelHeightAccessor world) { -+ return world.getMinSection(); -+ } -+ -+ public static int getMaxLightSection(final LevelHeightAccessor world) { -+ return getMaxSection(world) + 1; -+ } -+ -+ public static int getMinLightSection(final LevelHeightAccessor world) { -+ return getMinSection(world) - 1; -+ } -+ -+ -+ -+ public static int getTotalSections(final LevelHeightAccessor world) { -+ return getMaxSection(world) - getMinSection(world) + 1; -+ } -+ -+ public static int getTotalLightSections(final LevelHeightAccessor world) { -+ return getMaxLightSection(world) - getMinLightSection(world) + 1; -+ } -+ -+ public static int getMinBlockY(final LevelHeightAccessor world) { -+ return getMinSection(world) << 4; -+ } -+ -+ public static int getMaxBlockY(final LevelHeightAccessor world) { -+ return (getMaxSection(world) << 4) | 15; -+ } -+ -+ public static String getWorldName(final Level world) { -+ if (world == null) { -+ return "null world"; -+ } -+ return world.getWorld().getName(); -+ } -+ -+ private WorldUtil() { -+ throw new RuntimeException(); + } -+} + ++ public static void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) { ++ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource()) ++ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null); + } + + public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { +- ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().add( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() ++ ); ++ if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { ++ chunk.postProcessGeneration(); ++ } ++ ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk); ++ ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet(); + } + + public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { +- ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getTickingChunks().remove( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() ++ ); + } + + public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { +- ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().add( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() ++ ); + } + + public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { +- ++ ((ChunkSystemServerLevel)((ServerLevel)chunk.getLevel())).moonrise$getEntityTickingChunks().remove( ++ ((ChunkSystemLevelChunk)chunk).moonrise$getChunkAndHolder() ++ ); + } + + public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { +- return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ); ++ return null; + } + + public static int getSendViewDistance(final ServerPlayer player) { +- return getLoadViewDistance(player); ++ return RegionizedPlayerChunkLoader.getAPISendViewDistance(player); + } + + public static int getLoadViewDistance(final ServerPlayer player) { +- final ServerLevel level = player.serverLevel(); +- if (level == null) { +- return org.bukkit.Bukkit.getViewDistance(); +- } +- return level.chunkSource.chunkMap.getPlayerViewDistance(player); ++ return RegionizedPlayerChunkLoader.getLoadViewDistance(player); + } + + public static int getTickViewDistance(final ServerPlayer player) { +- final ServerLevel level = player.serverLevel(); +- if (level == null) { +- return org.bukkit.Bukkit.getSimulationDistance(); +- } +- return level.chunkSource.chunkMap.distanceManager.simulationDistance; ++ return RegionizedPlayerChunkLoader.getAPITickViewDistance(player); ++ } ++ ++ public static void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) { ++ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player); ++ } ++ ++ public static void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) { ++ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player); ++ } ++ ++ public static void updateMaps(final ServerLevel world, final ServerPlayer player) { ++ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player); + } + + private ChunkSystem() {} +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +index 7deb341b7e2b4592ae3f88733d6cacf6e58764e4..b3bac1beeb0b4be8e110a61acf46740d556801ef 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +@@ -90,7 +90,7 @@ public class TickThread extends Thread { + } + + public static boolean isTickThread() { +- return org.bukkit.Bukkit.isPrimaryThread(); // Paper ++ return Thread.currentThread() instanceof TickThread; + } + + public static boolean isShutdownThread() { diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java b/src/main/java/ca/spottedleaf/moonrise/patches/block_counting/BlockCountingBitStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..aef4fc0d3c272febe675d1ac846b88e58b4e7533 @@ -3412,174 +401,6 @@ index 0000000000000000000000000000000000000000..08338917dc61c856eaba0b76e05c1497 + public BlockState moonrise$getBlock(final int x, final int y, final int z); + +} -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystem.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c2ff037e180393de6576f12c32c665ef640d6f50 ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystem.java -@@ -0,0 +1,162 @@ -+package ca.spottedleaf.moonrise.patches.chunk_system; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; -+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; -+import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; -+import ca.spottedleaf.moonrise.patches.chunk_system.world.ChunkSystemServerChunkCache; -+import com.mojang.logging.LogUtils; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.server.level.FullChunkStatus; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.status.ChunkStatus; -+import org.slf4j.Logger; -+import java.util.List; -+import java.util.function.Consumer; -+ -+public final class ChunkSystem { -+ -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -+ scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ } -+ -+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority); -+ } -+ -+ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, -+ final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, -+ final Consumer onComplete) { -+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); -+ } -+ -+ // Paper - rewrite chunk system -+ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, -+ final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ } -+ -+ public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, -+ final FullChunkStatus toStatus, final boolean addTicket, -+ final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -+ } -+ -+ public static List getVisibleChunkHolders(final ServerLevel level) { -+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders(); -+ } -+ -+ public static List getUpdatingChunkHolders(final ServerLevel level) { -+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.getOldChunkHolders(); -+ } -+ -+ public static int getVisibleChunkHolderCount(final ServerLevel level) { -+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size(); -+ } -+ -+ public static int getUpdatingChunkHolderCount(final ServerLevel level) { -+ return ((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().chunkHolderManager.size(); -+ } -+ -+ public static boolean hasAnyChunkHolders(final ServerLevel level) { -+ return getUpdatingChunkHolderCount(level) != 0; -+ } -+ -+ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onEntityPreAdd(level, entity); -+ } -+ -+ public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(level, holder); -+ } -+ -+ public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(level, holder); -+ } -+ -+ public static void onChunkPreBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource()) -+ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, chunk); -+ } -+ -+ public static void onChunkBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(chunk, holder); -+ chunk.loadCallback(); // Paper -+ } -+ -+ public static void onChunkNotBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(chunk, holder); -+ chunk.unloadCallback(); // Paper -+ } -+ -+ public static void onChunkPostNotBorder(final LevelChunk chunk, final ChunkHolder holder) { -+ ((ChunkSystemServerChunkCache)((ServerLevel)chunk.getLevel()).getChunkSource()) -+ .moonrise$setFullChunk(chunk.getPos().x, chunk.getPos().z, null); -+ } -+ -+ public static void onChunkTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, holder); -+ if (!((ChunkSystemLevelChunk)chunk).moonrise$isPostProcessingDone()) { -+ chunk.postProcessGeneration(); -+ } -+ ((ServerLevel)chunk.getLevel()).startTickingChunk(chunk); -+ ((ServerLevel)chunk.getLevel()).getChunkSource().chunkMap.tickingGenerated.incrementAndGet(); -+ } -+ -+ public static void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(chunk, holder); -+ } -+ -+ public static void onChunkEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, holder); -+ } -+ -+ public static void onChunkNotEntityTicking(final LevelChunk chunk, final ChunkHolder holder) { -+ // TODO move hook -+ io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(chunk, holder); -+ } -+ -+ public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { -+ return null; -+ } -+ -+ public static int getSendViewDistance(final ServerPlayer player) { -+ return RegionizedPlayerChunkLoader.getAPISendViewDistance(player); -+ } -+ -+ public static int getLoadViewDistance(final ServerPlayer player) { -+ return RegionizedPlayerChunkLoader.getLoadViewDistance(player); -+ } -+ -+ public static int getTickViewDistance(final ServerPlayer player) { -+ return RegionizedPlayerChunkLoader.getAPITickViewDistance(player); -+ } -+ -+ public static void addPlayerToDistanceMaps(final ServerLevel world, final ServerPlayer player) { -+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().addPlayer(player); -+ } -+ -+ public static void removePlayerFromDistanceMaps(final ServerLevel world, final ServerPlayer player) { -+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().removePlayer(player); -+ } -+ -+ public static void updateMaps(final ServerLevel world, final ServerPlayer player) { -+ ((ChunkSystemServerLevel)world).moonrise$getPlayerChunkLoader().updatePlayer(player); -+ } -+ -+ private ChunkSystem() {} -+} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java new file mode 100644 index 0000000000000000000000000000000000000000..49160a30b8e19e5c5ada811fbcae2a05959524f3 @@ -3750,10 +571,10 @@ index 0000000000000000000000000000000000000000..73df26b27146bbad2106d57b22dd3c79 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..c833f78d083b8f661087471c35bc90f65af1b525 +index 0000000000000000000000000000000000000000..3218cbf84f54daf06e84442d5eb1a36d8da6b215 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/io/RegionFileIOThread.java -@@ -0,0 +1,1239 @@ +@@ -0,0 +1,1240 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.io; + +import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; @@ -3765,6 +586,7 @@ index 0000000000000000000000000000000000000000..c833f78d083b8f661087471c35bc90f6 +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import net.minecraft.nbt.CompoundTag; @@ -4052,7 +874,7 @@ index 0000000000000000000000000000000000000000..c833f78d083b8f661087471c35bc90f6 + * @return The priroity to use with blocking I/O on the current thread. + */ + public static Priority getIOBlockingPriorityForCurrentThread() { -+ if (io.papermc.paper.util.TickThread.isTickThread()) { ++ if (TickThread.isTickThread()) { + return Priority.BLOCKING; + } + return Priority.HIGHEST; @@ -5201,18 +2023,20 @@ index 0000000000000000000000000000000000000000..0b58701342d573fa43cdd06681534854 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..1a06c2c139e930d2081e605b460ae5403de8c3ea +index 0000000000000000000000000000000000000000..b8a87b7e6505feb76ce1bd58c84615256cf6faa6 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/ChunkSystemServerLevel.java -@@ -0,0 +1,53 @@ +@@ -0,0 +1,61 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.moonrise.common.list.ReferenceList; +import ca.spottedleaf.moonrise.common.misc.NearbyPlayers; +import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; +import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import net.minecraft.core.BlockPos; ++import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import java.util.List; @@ -5257,6 +2081,12 @@ index 0000000000000000000000000000000000000000..1a06c2c139e930d2081e605b460ae540 + public void moonrise$setLastMidTickFailure(final long time); + + public NearbyPlayers moonrise$getNearbyPlayers(); ++ ++ public ReferenceList moonrise$getLoadedChunks(); ++ ++ public ReferenceList moonrise$getTickingChunks(); ++ ++ public ReferenceList moonrise$getEntityTickingChunks(); +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java new file mode 100644 @@ -5339,16 +2169,22 @@ index 0000000000000000000000000000000000000000..883fe6401f1b9711fa544d18a815b4d6 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemLevelChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemLevelChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..755b08dd32e568d341ceef8a8aef841831a0781d +index 0000000000000000000000000000000000000000..5b092bca7027e37aeee8f4b852ad896dd0d5febc --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemLevelChunk.java -@@ -0,0 +1,7 @@ +@@ -0,0 +1,13 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.chunk; + ++import net.minecraft.server.level.ServerChunkCache; ++ +public interface ChunkSystemLevelChunk { + + public boolean moonrise$isPostProcessingDone(); + ++ public ServerChunkCache.ChunkAndHolder moonrise$getChunkAndHolder(); ++ ++ public void moonrise$setChunkAndHolder(final ServerChunkCache.ChunkAndHolder holder); ++ +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java new file mode 100644 @@ -6177,10 +3013,10 @@ index 0000000000000000000000000000000000000000..997b05167c19472acb98edac32d4548c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..a346435abac725b4e024acf4a1589a51caac8d69 +index 0000000000000000000000000000000000000000..efc0c1acc8239dd7b00211a1d3bfd3fc3b2c810c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -@@ -0,0 +1,1077 @@ +@@ -0,0 +1,1083 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; @@ -6274,6 +3110,8 @@ index 0000000000000000000000000000000000000000..a346435abac725b4e024acf4a1589a51 + + protected abstract void entityEndTicking(final Entity entity); + ++ protected abstract boolean screenEntity(final Entity entity); ++ + private static Entity maskNonAccessible(final Entity entity) { + if (entity == null) { + return null; @@ -6595,6 +3433,10 @@ index 0000000000000000000000000000000000000000..a346435abac725b4e024acf4a1589a51 + return false; + } + ++ if (!this.screenEntity(entity)) { ++ return false; ++ } ++ + Entity currentlyMapped = this.entityById.putIfAbsent((long)entity.getId(), entity); + if (currentlyMapped != null) { + LOGGER.warn("Entity id already exists: " + entity.getId() + ", mapped to " + currentlyMapped + ", can't add " + entity); @@ -7261,10 +4103,10 @@ index 0000000000000000000000000000000000000000..a346435abac725b4e024acf4a1589a51 \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..77e81414d43826955da8af85ec1bd0009af4e1b9 +index 0000000000000000000000000000000000000000..edcde00206d068bd79175fea33efa05b0e8c1562 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/client/ClientEntityLookup.java -@@ -0,0 +1,118 @@ +@@ -0,0 +1,123 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.client; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; @@ -7363,6 +4205,11 @@ index 0000000000000000000000000000000000000000..77e81414d43826955da8af85ec1bd000 + + } + ++ @Override ++ protected boolean screenEntity(final Entity entity) { ++ return true; ++ } ++ + public void markTicking(final long pos) { + if (this.tickingChunks.add(pos)) { + final int chunkX = CoordinateUtils.getChunkX(pos); @@ -7385,10 +4232,10 @@ index 0000000000000000000000000000000000000000..77e81414d43826955da8af85ec1bd000 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..4747499e84b05d499364622b0f750fdd66b737e0 +index 0000000000000000000000000000000000000000..465469e44346c50f30f3abd6b44f4173ccfcf248 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/dfl/DefaultEntityLookup.java -@@ -0,0 +1,109 @@ +@@ -0,0 +1,114 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; @@ -7474,6 +4321,11 @@ index 0000000000000000000000000000000000000000..4747499e84b05d499364622b0f750fdd + + } + ++ @Override ++ protected boolean screenEntity(final Entity entity) { ++ return true; ++ } ++ + protected static final class DefaultLevelCallback implements LevelCallback { + + @Override @@ -7500,13 +4352,15 @@ index 0000000000000000000000000000000000000000..4747499e84b05d499364622b0f750fdd +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..eb1b0b3594ae6861a05010949ba94a60f73ecc8b +index 0000000000000000000000000000000000000000..dacf2b2988ce603879fe525a3418ac77f8a663f7 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/server/ServerEntityLookup.java -@@ -0,0 +1,106 @@ +@@ -0,0 +1,113 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server; + +import ca.spottedleaf.moonrise.common.list.ReferenceList; ++import ca.spottedleaf.moonrise.common.util.TickThread; ++import ca.spottedleaf.moonrise.common.util.ChunkSystem; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup; @@ -7520,8 +4374,8 @@ index 0000000000000000000000000000000000000000..eb1b0b3594ae6861a05010949ba94a60 + private static final Entity[] EMPTY_ENTITY_ARRAY = new Entity[0]; + + private final ServerLevel serverWorld; -+ public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY, 0); // Moonrise - entity tracker -+ public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY, 0); // Moonrise - entity tracker ++ public final ReferenceList trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker ++ public final ReferenceList trackerUnloadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker + + public ServerEntityLookup(final ServerLevel world, final LevelCallback worldCallback) { + super(world, worldCallback); @@ -7540,12 +4394,12 @@ index 0000000000000000000000000000000000000000..eb1b0b3594ae6861a05010949ba94a60 + + @Override + protected void checkThread(final int chunkX, final int chunkZ, final String reason) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.serverWorld, chunkX, chunkZ, reason); ++ TickThread.ensureTickThread(this.serverWorld, chunkX, chunkZ, reason); + } + + @Override + protected void checkThread(final Entity entity, final String reason) { -+ io.papermc.paper.util.TickThread.ensureTickThread(entity, reason); ++ TickThread.ensureTickThread(entity, reason); + } + + @Override @@ -7609,6 +4463,11 @@ index 0000000000000000000000000000000000000000..eb1b0b3594ae6861a05010949ba94a60 + protected void entityEndTicking(final Entity entity) { + + } ++ ++ @Override ++ protected boolean screenEntity(final Entity entity) { ++ return ChunkSystem.screenEntity(this.serverWorld, entity); ++ } +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/ChunkSystemPoiManager.java new file mode 100644 @@ -7653,13 +4512,14 @@ index 0000000000000000000000000000000000000000..89b956b8fdf1a0d862a843104511005e +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..cd1302a3aee6f543f39d71b91725128fa1aeddcc +index 0000000000000000000000000000000000000000..fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -@@ -0,0 +1,211 @@ +@@ -0,0 +1,212 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.poi; + +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; @@ -7707,7 +4567,7 @@ index 0000000000000000000000000000000000000000..cd1302a3aee6f543f39d71b91725128f + } + + public void load() { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Loading in poi chunk off-main"); ++ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Loading in poi chunk off-main"); + if (this.loaded) { + return; + } @@ -7918,7 +4778,7 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442a8eb32fd +index 0000000000000000000000000000000000000000..244674dc44d80ee5ce78d2ed2c6ab94fd5d3d07f --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -0,0 +1,1076 @@ @@ -7929,7 +4789,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 +import ca.spottedleaf.moonrise.common.misc.AllocatingRateLimiter; +import ca.spottedleaf.moonrise.common.misc.SingleUserAreaMap; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; -+import ca.spottedleaf.moonrise.common.util.MoonriseCommon; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemChunkHolder; @@ -8104,7 +4964,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + public void addPlayer(final ServerPlayer player) { -+ io.papermc.paper.util.TickThread.ensureTickThread(player, "Cannot add player to player chunk loader async"); ++ TickThread.ensureTickThread(player, "Cannot add player to player chunk loader async"); + if (!((ChunkSystemServerPlayer)player).moonrise$isRealPlayer()) { + return; + } @@ -8129,7 +4989,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + public void removePlayer(final ServerPlayer player) { -+ io.papermc.paper.util.TickThread.ensureTickThread(player, "Cannot remove player from player chunk loader async"); ++ TickThread.ensureTickThread(player, "Cannot remove player from player chunk loader async"); + if (!((ChunkSystemServerPlayer)player).moonrise$isRealPlayer()) { + return; + } @@ -8223,7 +5083,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + public void tick() { -+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick player chunk loader async"); ++ TickThread.ensureTickThread("Cannot tick player chunk loader async"); + long currTime = System.nanoTime(); + for (final ServerPlayer player : new java.util.ArrayList<>(this.world.players())) { + final PlayerChunkLoaderData loader = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader(); @@ -8551,7 +5411,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + void updateQueues(final long time) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.player, "Cannot tick player chunk loader async"); ++ TickThread.ensureTickThread(this.player, "Cannot tick player chunk loader async"); + if (this.removed) { + throw new IllegalStateException("Ticking removed player chunk loader"); + } @@ -8736,7 +5596,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + final int pendingSendX = CoordinateUtils.getChunkX(pendingSend); + final int pendingSendZ = CoordinateUtils.getChunkZ(pendingSend); + final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(pendingSendX, pendingSendZ); -+ if (!this.areNeighboursGenerated(pendingSendX, pendingSendZ, 1) || !io.papermc.paper.util.TickThread.isTickThreadFor(this.world, pendingSendX, pendingSendZ)) { ++ if (!this.areNeighboursGenerated(pendingSendX, pendingSendZ, 1) || !TickThread.isTickThreadFor(this.world, pendingSendX, pendingSendZ)) { + // nothing to do + // the target chunk may not be owned by this region, but this should be resolved in the future + break; @@ -8763,7 +5623,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + void add() { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); ++ TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); + if (this.removed) { + throw new IllegalStateException("Adding removed player chunk loader"); + } @@ -8819,7 +5679,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + void update() { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.player, "Cannot update player asynchronously"); ++ TickThread.ensureTickThread(this.player, "Cannot update player asynchronously"); + if (this.removed) { + throw new IllegalStateException("Updating removed player chunk loader"); + } @@ -8971,7 +5831,7 @@ index 0000000000000000000000000000000000000000..f063ab3ff122b920bcc4aa4f5bf9a442 + } + + void remove() { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); ++ TickThread.ensureTickThread(this.player, "Cannot add player asynchronously"); + if (this.removed) { + throw new IllegalStateException("Removing removed player chunk loader"); + } @@ -9151,10 +6011,10 @@ index 0000000000000000000000000000000000000000..7eafc5b7cba23d8dec92ecc1050afe3f \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c9cb81f42 +index 0000000000000000000000000000000000000000..58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -0,0 +1,1427 @@ +@@ -0,0 +1,1428 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; @@ -9162,8 +6022,9 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.MoonriseCommon; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem; ++import ca.spottedleaf.moonrise.common.util.ChunkSystem; +import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; @@ -9341,7 +6202,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + } + + public void close(final boolean save, final boolean halt) { -+ io.papermc.paper.util.TickThread.ensureTickThread("Closing world off-main"); ++ TickThread.ensureTickThread("Closing world off-main"); + if (halt) { + LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); + if (!this.taskScheduler.halt(true, TimeUnit.SECONDS.toNanos(60L))) { @@ -10017,7 +6878,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + } + + public ChunkEntitySlices getOrCreateEntityChunk(final int chunkX, final int chunkZ, final boolean transientChunk) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create entity chunk off-main"); ++ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create entity chunk off-main"); + ChunkEntitySlices ret; + + NewChunkHolder current = this.getChunkHolder(chunkX, chunkZ); @@ -10098,7 +6959,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + } + + public PoiChunk loadPoiChunk(final int chunkX, final int chunkZ) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create poi chunk off-main"); ++ TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Cannot create poi chunk off-main"); + PoiChunk ret; + + NewChunkHolder current = this.getChunkHolder(chunkX, chunkZ); @@ -10166,7 +7027,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + if (changedFullStatus.isEmpty()) { + return; + } -+ if (!io.papermc.paper.util.TickThread.isTickThread()) { ++ if (!TickThread.isTickThread()) { + this.taskScheduler.scheduleChunkTask(() -> { + final ArrayDeque pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate; + for (int i = 0, len = changedFullStatus.size(); i < len; ++i) { @@ -10193,7 +7054,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + + // note: never call while inside the chunk system, this will absolutely break everything + public void processUnloads() { -+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot unload chunks off-main"); ++ TickThread.ensureTickThread("Cannot unload chunks off-main"); + + if (BLOCK_TICKET_UPDATES.get() == Boolean.TRUE) { + throw new IllegalStateException("Cannot unload chunks recursively"); @@ -10472,7 +7333,7 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c + + List changedFullStatus = null; + -+ final boolean isTickThread = io.papermc.paper.util.TickThread.isTickThread(); ++ final boolean isTickThread = TickThread.isTickThread(); + + boolean ret = false; + final boolean canProcessFullUpdates = processFullUpdates & isTickThread; @@ -10584,10 +7445,10 @@ index 0000000000000000000000000000000000000000..1030e1b059f7ccdedd9c00527c3dd20c +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java new file mode 100644 -index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c71a168a8a +index 0000000000000000000000000000000000000000..b1456c1ddf24b625c6caf41a9379d8c011e1c36c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkTaskScheduler.java -@@ -0,0 +1,1037 @@ +@@ -0,0 +1,1038 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; @@ -10598,6 +7459,7 @@ index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c7 +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; +import ca.spottedleaf.moonrise.common.util.JsonUtil; +import ca.spottedleaf.moonrise.common.util.MoonriseCommon; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; @@ -10955,7 +7817,7 @@ index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c7 + } + + public boolean executeMainThreadTask() { -+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot execute main thread task off-main"); ++ TickThread.ensureTickThread("Cannot execute main thread task off-main"); + return this.mainThreadExecutor.executeTask(); + } + @@ -10974,7 +7836,7 @@ index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c7 + public void scheduleTickingState(final int chunkX, final int chunkZ, final FullChunkStatus toStatus, + final boolean addTicket, final PrioritisedExecutor.Priority priority, + final Consumer onComplete) { -+ if (!io.papermc.paper.util.TickThread.isTickThread()) { ++ if (!TickThread.isTickThread()) { + this.scheduleChunkTask(chunkX, chunkZ, () -> { + ChunkTaskScheduler.this.scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + }, priority); @@ -11165,7 +8027,7 @@ index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c7 + + public void scheduleChunkLoad(final int chunkX, final int chunkZ, final ChunkStatus toStatus, final boolean addTicket, + final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -+ if (!io.papermc.paper.util.TickThread.isTickThread()) { ++ if (!TickThread.isTickThread()) { + this.scheduleChunkTask(chunkX, chunkZ, () -> { + ChunkTaskScheduler.this.scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, onComplete); + }, priority); @@ -11627,10 +8489,10 @@ index 0000000000000000000000000000000000000000..c1c119e2e788d5963de3a74a6b9724c7 +} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..a7ada64a78e36642a6d5ce4a767bff12e675bb16 +index 0000000000000000000000000000000000000000..1dfddea4fd7e89fb6fd9fa49f7ab5e6f48e6ef3c --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -0,0 +1,2034 @@ +@@ -0,0 +1,2035 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +import ca.spottedleaf.concurrentutil.completable.Completable; @@ -11640,8 +8502,9 @@ index 0000000000000000000000000000000000000000..a7ada64a78e36642a6d5ce4a767bff12 +import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.TickThread; +import ca.spottedleaf.moonrise.common.util.WorldUtil; -+import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem; ++import ca.spottedleaf.moonrise.common.util.ChunkSystem; +import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; +import ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData; +import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; @@ -11705,7 +8568,7 @@ index 0000000000000000000000000000000000000000..a7ada64a78e36642a6d5ce4a767bff12 + private CompoundTag pendingEntityChunk; + + ChunkEntitySlices loadInEntityChunk(final boolean transientChunk) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot sync load entity data off-main"); ++ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot sync load entity data off-main"); + final CompoundTag entityChunk; + final ChunkEntitySlices ret; + final ReentrantAreaLock.Node schedulingLock = this.scheduler.schedulingLockArea.lock(this.chunkX, this.chunkZ); @@ -12856,7 +9719,7 @@ index 0000000000000000000000000000000000000000..a7ada64a78e36642a6d5ce4a767bff12 + + // only to be called on the main thread, no locks need to be held + public boolean handleFullStatusChange(final List changedFullStatus) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot update full status thread off-main"); ++ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot update full status thread off-main"); + + boolean ret = false; + @@ -13303,7 +10166,7 @@ index 0000000000000000000000000000000000000000..a7ada64a78e36642a6d5ce4a767bff12 + public static final record SaveStat(boolean savedChunk, boolean savedEntityChunk, boolean savedPoiChunk) {} + + public SaveStat save(final boolean shutdown) { -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); ++ TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); + + ChunkAccess chunk = this.getCurrentChunk(); + PoiChunk poi = this.getPoiChunk(); @@ -16026,20 +12889,21 @@ index 0000000000000000000000000000000000000000..e0b26ccb63596748b80fc6a5e47e373b \ No newline at end of file diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..49774d42f35eeeac5e2b334cce40e6dcca6d01ed +index 0000000000000000000000000000000000000000..fbdf721e8b4cfe6cef4ee60c53c680cbfc858d88 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java -@@ -0,0 +1,139 @@ +@@ -0,0 +1,142 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; ++import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiManager; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; -+import net.minecraft.server.level.ChunkMap; ++import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ImposterProtoChunk; @@ -16097,6 +12961,8 @@ index 0000000000000000000000000000000000000000..49774d42f35eeeac5e2b334cce40e6dc + this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false)); + } + ++ ((ChunkSystemLevelChunk)chunk).moonrise$setChunkAndHolder(new ServerChunkCache.ChunkAndHolder(chunk, this.chunkHolder.vanillaChunkHolder)); ++ + final NewChunkHolder chunkHolder = this.chunkHolder; + + chunk.setFullStatus(chunkHolder::getChunkStatus); @@ -18316,6 +15182,41 @@ index 0000000000000000000000000000000000000000..4b9e2fa963c14f65f15407c1814c543c + public LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ); + +} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e97e7d276faf055c89207385d3820debffb06463 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java +@@ -0,0 +1,7 @@ ++package ca.spottedleaf.moonrise.patches.chunk_tick_iteration; ++ ++public final class ChunkTickConstants { ++ ++ public static final int PLAYER_SPAWN_TRACK_RANGE = 8; ++ ++} +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickDistanceManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickDistanceManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f28fd0e01e2bdda0daf9d775e514a7253d32d8d0 +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickDistanceManager.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.moonrise.patches.chunk_tick_iteration; ++ ++import net.minecraft.core.SectionPos; ++import net.minecraft.server.level.ServerPlayer; ++ ++public interface ChunkTickDistanceManager { ++ ++ public void moonrise$addPlayer(final ServerPlayer player, final SectionPos pos); ++ ++ public void moonrise$removePlayer(final ServerPlayer player, final SectionPos pos); ++ ++ public void moonrise$updatePlayer(final ServerPlayer player, ++ final SectionPos oldPos, final SectionPos newPos, ++ final boolean oldIgnore, final boolean newIgnore); ++ ++} diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..748ab4d637ce463272bae4fdbab6842a27385126 @@ -24898,259 +21799,6 @@ index 0000000000000000000000000000000000000000..57692a503e147a00ac4e1586cd78e12b + + private SaveUtil() {} +} -diff --git a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -index a79abe9b26f68d573812e91554124783075ae17a..183d99ec9b94ca20a823c46a2d6bf0a215046d48 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -+++ b/src/main/java/io/papermc/paper/chunk/system/ChunkSystem.java -@@ -25,6 +25,10 @@ import java.util.List; - import java.util.concurrent.CompletableFuture; - import java.util.function.Consumer; - -+/** -+ * @deprecated Use {@link ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem} -+ */ -+@Deprecated(forRemoval = true) - public final class ChunkSystem { - - private static final Logger LOGGER = LogUtils.getLogger(); -@@ -35,35 +39,17 @@ public final class ChunkSystem { - } - - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { -- scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleChunkTask(level, chunkX, chunkZ, run); // Paper - reroute - } - - public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) { -- level.chunkSource.mainThreadProcessor.execute(run); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleChunkTask(level, chunkX, chunkZ, run, priority); // Paper - reroute - } - - public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, - final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority, - final Consumer onComplete) { -- if (gen) { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- return; -- } -- scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> { -- if (chunk == null) { -- if (onComplete != null) { -- onComplete.accept(null); -- } -- } else { -- if (chunk.getPersistedStatus().isOrAfter(toStatus)) { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- } else { -- if (onComplete != null) { -- onComplete.accept(null); -- } -- } -- } -- }); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleChunkLoad(level, chunkX, chunkZ, gen, toStatus, addTicket, priority, onComplete); // Paper - reroute - } - - static final TicketType CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo); -@@ -71,160 +57,29 @@ public final class ChunkSystem { - private static long chunkLoadCounter = 0L; - public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus, - final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -- if (!Bukkit.isPrimaryThread()) { -- scheduleChunkTask(level, chunkX, chunkZ, () -> { -- scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- }, priority); -- return; -- } -- -- final int minLevel = 33 + ChunkSystem.getDistance(toStatus); -- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -- -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- level.chunkSource.runDistanceManagerUpdates(); -- -- final Consumer loadCallback = (final ChunkAccess chunk) -> { -- try { -- if (onComplete != null) { -- onComplete.accept(chunk); -- } -- } catch (final Throwable thr) { -- LOGGER.error("Exception handling chunk load callback", thr); -- SneakyThrow.sneaky(thr); -- } finally { -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- } -- }; -- -- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture> loadFuture = holder.scheduleChunkGenerationTask(toStatus, level.chunkSource.chunkMap); -- -- if (loadFuture.isDone()) { -- loadCallback.accept(loadFuture.join().orElse(null)); -- return; -- } -- -- loadFuture.whenCompleteAsync((final ChunkResult result, final Throwable thr) -> { -- if (thr != null) { -- loadCallback.accept(null); -- return; -- } -- loadCallback.accept(result.orElse(null)); -- }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -- }); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - reroute - } - - public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ, - final FullChunkStatus toStatus, final boolean addTicket, - final PrioritisedExecutor.Priority priority, final Consumer onComplete) { -- // This method goes unused until the chunk system rewrite -- if (toStatus == FullChunkStatus.INACCESSIBLE) { -- throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status"); -- } -- -- if (!Bukkit.isPrimaryThread()) { -- scheduleChunkTask(level, chunkX, chunkZ, () -> { -- scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); -- }, priority); -- return; -- } -- -- final int minLevel = 33 - (toStatus.ordinal() - 1); -- final int radius = toStatus.ordinal() - 1; -- final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null; -- final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); -- -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- level.chunkSource.runDistanceManagerUpdates(); -- -- final Consumer loadCallback = (final LevelChunk chunk) -> { -- try { -- if (onComplete != null) { -- onComplete.accept(chunk); -- } -- } catch (final Throwable thr) { -- LOGGER.error("Exception handling chunk load callback", thr); -- SneakyThrow.sneaky(thr); -- } finally { -- if (addTicket) { -- level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos); -- level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference); -- } -- } -- }; -- -- final ChunkHolder holder = level.chunkSource.chunkMap.updatingChunkMap.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); -- -- if (holder == null || holder.getTicketLevel() > minLevel) { -- loadCallback.accept(null); -- return; -- } -- -- final CompletableFuture> tickingState; -- switch (toStatus) { -- case FULL: { -- tickingState = holder.getFullChunkFuture(); -- break; -- } -- case BLOCK_TICKING: { -- tickingState = holder.getTickingChunkFuture(); -- break; -- } -- case ENTITY_TICKING: { -- tickingState = holder.getEntityTickingChunkFuture(); -- break; -- } -- default: { -- throw new IllegalStateException("Cannot reach here"); -- } -- } -- -- if (tickingState.isDone()) { -- loadCallback.accept(tickingState.join().orElse(null)); -- return; -- } -- -- tickingState.whenCompleteAsync((final ChunkResult result, final Throwable thr) -> { -- if (thr != null) { -- loadCallback.accept(null); -- return; -- } -- loadCallback.accept(result.orElse(null)); -- }, (final Runnable r) -> { -- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST); -- }); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete); // Paper - reroute - } - - public static List getVisibleChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values()); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getVisibleChunkHolders(level); // Paper - reroute - } - - public static List getUpdatingChunkHolders(final ServerLevel level) { -- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values()); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getUpdatingChunkHolders(level); // Paper - reroute - } - - public static int getVisibleChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.visibleChunkMap.size(); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getVisibleChunkHolderCount(level); // Paper - reroute - } - - public static int getUpdatingChunkHolderCount(final ServerLevel level) { -- return level.chunkSource.chunkMap.updatingChunkMap.size(); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getUpdatingChunkHolderCount(level); // Paper - reroute - } - - public static boolean hasAnyChunkHolders(final ServerLevel level) { -@@ -268,27 +123,19 @@ public final class ChunkSystem { - } - - public static ChunkHolder getUnloadingChunkHolder(final ServerLevel level, final int chunkX, final int chunkZ) { -- return level.chunkSource.chunkMap.getUnloadingChunkHolder(chunkX, chunkZ); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getUnloadingChunkHolder(level, chunkX, chunkZ); // Paper - reroute - } - - public static int getSendViewDistance(final ServerPlayer player) { -- return getLoadViewDistance(player); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getSendViewDistance(player); // Paper - reroute - } - - public static int getLoadViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); -- if (level == null) { -- return Bukkit.getViewDistance(); -- } -- return level.chunkSource.chunkMap.getPlayerViewDistance(player); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getLoadViewDistance(player); // Paper - reroute - } - - public static int getTickViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); -- if (level == null) { -- return Bukkit.getSimulationDistance(); -- } -- return level.chunkSource.chunkMap.distanceManager.simulationDistance; -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getTickViewDistance(player); // Paper - reroute - } - - private ChunkSystem() { diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java index 46bf42d5ea9e7b046f962531c5962d287cf44a41..362765d977aaa1996f9cef3404c0676d7bbddf38 100644 --- a/src/main/java/io/papermc/paper/command/PaperCommand.java @@ -25666,132 +22314,6 @@ index 0000000000000000000000000000000000000000..8424cf9d4617b4732d44cc460d25b044 + } + +} -diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java -index 73e83d56a340f0c7dcb8ff737d621003e72c6de4..d05297d77147ab68f8c5bb08f13a1f882a686c4f 100644 ---- a/src/main/java/io/papermc/paper/util/TickThread.java -+++ b/src/main/java/io/papermc/paper/util/TickThread.java -@@ -6,7 +6,7 @@ import net.minecraft.world.entity.Entity; - import org.bukkit.Bukkit; - import java.util.concurrent.atomic.AtomicInteger; - --public final class TickThread extends Thread { -+public class TickThread extends Thread { - - public static final boolean STRICT_THREAD_CHECKS = Boolean.getBoolean("paper.strict-thread-checks"); - -@@ -16,6 +16,10 @@ public final class TickThread extends Thread { - } - } - -+ /** -+ * @deprecated -+ */ -+ @Deprecated - public static void softEnsureTickThread(final String reason) { - if (!STRICT_THREAD_CHECKS) { - return; -@@ -23,6 +27,10 @@ public final class TickThread extends Thread { - ensureTickThread(reason); - } - -+ /** -+ * @deprecated -+ */ -+ @Deprecated - public static void ensureTickThread(final String reason) { - if (!isTickThread()) { - MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -@@ -30,6 +38,21 @@ public final class TickThread extends Thread { - } - } - -+ public static void ensureTickThread(final ServerLevel world, final net.minecraft.core.BlockPos pos, final String reason) { -+ if (!isTickThreadFor(world, pos)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final ServerLevel world, final net.minecraft.world.level.ChunkPos pos, final String reason) { -+ if (!isTickThreadFor(world, pos)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ - public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) { - if (!isTickThreadFor(world, chunkX, chunkZ)) { - MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -@@ -44,6 +67,21 @@ public final class TickThread extends Thread { - } - } - -+ public static void ensureTickThread(final ServerLevel world, final net.minecraft.world.phys.AABB aabb, final String reason) { -+ if (!isTickThreadFor(world, aabb)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ public static void ensureTickThread(final ServerLevel world, final double blockX, final double blockZ, final String reason) { -+ if (!isTickThreadFor(world, blockX, blockZ)) { -+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); -+ throw new IllegalStateException(reason); -+ } -+ } -+ -+ - public final int id; /* We don't override getId as the spec requires that it be unique (with respect to all other threads) */ - - private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); -@@ -66,13 +104,45 @@ public final class TickThread extends Thread { - } - - public static boolean isTickThread() { -- return Bukkit.isPrimaryThread(); -+ return Thread.currentThread() instanceof TickThread; -+ } -+ -+ public static boolean isShutdownThread() { -+ return false; -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final net.minecraft.core.BlockPos pos) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final net.minecraft.world.level.ChunkPos pos) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final net.minecraft.world.phys.Vec3 pos) { -+ return isTickThread(); - } - - public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) { - return isTickThread(); - } - -+ public static boolean isTickThreadFor(final ServerLevel world, final net.minecraft.world.phys.AABB aabb) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final double blockX, final double blockZ) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final net.minecraft.world.phys.Vec3 position, final net.minecraft.world.phys.Vec3 deltaMovement, final int buffer) { -+ return isTickThread(); -+ } -+ -+ public static boolean isTickThreadFor(final ServerLevel world, final int fromChunkX, final int fromChunkZ, final int toChunkX, final int toChunkZ) { -+ return isTickThread(); -+ } -+ - public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ, final int radius) { - return isTickThread(); - } diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java index 03c45ee77276462818a6f774b5945b25924aa3f0..f15dd2ccb99ade10ac1e49b63e6f4080bd39b3c9 100644 --- a/src/main/java/net/minecraft/core/Direction.java @@ -25914,7 +22436,7 @@ index c33f85b570f159ab465b5a10a8044a81f2797f43..244a19ecd0234fa1d7a6ecfea2075159 DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index e14c0e1ccf526f81e28db5545d9e2351641e1bc8..91cc3eb6db2875710064f6b31413ccc84af56bb2 100644 +index c97fb8eec949c693d4e822d8cf2e666a0858f20c..4a4ce372dd105d07f58d7d93d856cb3969969806 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -198,7 +198,7 @@ import org.bukkit.event.server.ServerLoadEvent; @@ -25931,7 +22453,7 @@ index e14c0e1ccf526f81e28db5545d9e2351641e1bc8..91cc3eb6db2875710064f6b31413ccc8 public static S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); - Thread thread = new Thread(() -> { -+ Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system ++ Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system ((MinecraftServer) atomicreference.get()).runServer(); }, "Server thread"); @@ -26103,7 +22625,7 @@ index e14c0e1ccf526f81e28db5545d9e2351641e1bc8..91cc3eb6db2875710064f6b31413ccc8 return true; } else { boolean ret = false; // Paper - force execution of all worlds, do not just bias the first -@@ -1594,7 +1667,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { @@ -26112,14 +22634,14 @@ index e14c0e1ccf526f81e28db5545d9e2351641e1bc8..91cc3eb6db2875710064f6b31413ccc8 if (entity.isRemoved()) { continue; } -@@ -2656,6 +2729,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop playersSentChunkTo = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_PLAYER_ARRAY, 0); ++ private final ca.spottedleaf.moonrise.common.list.ReferenceList playersSentChunkTo = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_PLAYER_ARRAY); + + private ChunkMap getChunkMap() { + return (ChunkMap)this.playerProvider; @@ -26550,7 +23072,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - chunkResult.ifSuccess(chunk -> { - if (ChunkHolder.this.fullChunkCreateCount == expectCreateCount) { - ChunkHolder.this.isFullChunkReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkBorder(chunk, this); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkBorder(chunk, this); - } - }); - }); @@ -26561,7 +23083,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - if (flag && !flag1) { - // Paper start - if (this.isFullChunkReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper - } - // Paper end - this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); @@ -26579,7 +23101,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - chunkResult.ifSuccess(chunk -> { - // note: Here is a very good place to add callbacks to logic waiting on this. - ChunkHolder.this.isTickingReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkTicking(chunk, this); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkTicking(chunk, this); - }); - }); - // Paper end @@ -26589,7 +23111,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - if (flag2 && !flag3) { - // Paper start - if (this.isTickingReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); // Paper - } - // Paper end - this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage @@ -26610,7 +23132,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - this.entityTickingChunkFuture.thenAccept(chunkResult -> { - chunkResult.ifSuccess(chunk -> { - ChunkHolder.this.isEntityTickingReady = true; -- io.papermc.paper.chunk.system.ChunkSystem.onChunkEntityTicking(chunk, this); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkEntityTicking(chunk, this); - }); - }); - // Paper end @@ -26620,7 +23142,7 @@ index c643bb0daa5cd264fd6ebab7acf0a2bdd7fe7029..9bc59697fc71d4e3c226aa7fe958f571 - if (flag4 && !flag5) { - // Paper start - if (this.isEntityTickingReady) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().orElseThrow(IllegalStateException::new), this); - } - // Paper end - this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage @@ -26704,7 +23226,7 @@ index d9ad32acdf46a43a649334a3b736aeb7b3af21d1..fae17a075d7efaf24d916877dd5968eb public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius(); public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed18617193568f0d 100644 +index 56ef427af5cdfa9b673089cabc43167012b343bc..edb36dee707433d4f9419aef6ac6cc0bec5f285e 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -122,10 +122,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -26745,14 +23267,13 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() public final CallbackExecutor callbackExecutor = new CallbackExecutor(); -@@ -198,23 +193,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - // Paper end +@@ -174,22 +169,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper start public final ChunkHolder getUnloadingChunkHolder(int chunkX, int chunkZ) { -- return this.pendingUnloads.get(io.papermc.paper.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); +- return this.pendingUnloads.get(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkX, chunkZ)); + return null; // Paper - rewrite chunk system } - public final io.papermc.paper.util.player.NearbyPlayers nearbyPlayers; // Paper end public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { @@ -26772,7 +23293,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 Path path = session.getDimensionPath(world.dimension()); this.storageName = path.getFileName().toString(); -@@ -245,15 +238,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -220,15 +213,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.chunkStatusListener = chunkStatusChangeListener; ProcessorMailbox threadedmailbox1 = ProcessorMailbox.create(executor, "light"); @@ -26788,10 +23309,10 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 this.setServerViewDistance(viewDistance); - this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, this.mainThreadMailbox); + this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, null); // Paper - rewrite chunk system - // Paper start - this.nearbyPlayers = new io.papermc.paper.util.player.NearbyPlayers(this.level); - // Paper end -@@ -292,23 +283,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + } + + // Paper start +@@ -259,23 +250,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } boolean isChunkTracked(ServerPlayer player, int chunkX, int chunkZ) { @@ -26817,7 +23338,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } protected ThreadedLevelLightEngine getLightEngine() { -@@ -317,20 +296,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -284,20 +263,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Nullable protected ChunkHolder getUpdatingChunkIfPresent(long pos) { @@ -26847,7 +23368,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } public String getChunkDebugData(ChunkPos chunkPos) { -@@ -359,55 +340,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -326,55 +307,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private CompletableFuture>> getChunkRangeFuture(ChunkHolder centerChunk, int margin, IntFunction distanceToStatus) { @@ -26904,7 +23425,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } public ReportedException debugFuturesAndCreateReportedException(IllegalStateException exception, String details) { -@@ -437,93 +370,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -404,93 +337,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public CompletableFuture> prepareEntityTickingChunk(ChunkHolder holder) { @@ -26942,7 +23463,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 - } else { - holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this); - // Paper start -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderCreate(this.level, holder); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderCreate(this.level, holder); - // Paper end - } - @@ -26972,7 +23493,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 protected void saveAllChunks(boolean flush) { - if (flush) { -- List list = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper +- List list = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).toList(); // Paper - MutableBoolean mutableboolean = new MutableBoolean(); - - do { @@ -26995,7 +23516,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 - }); - this.flushWorker(); - } else { -- io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded); - } - + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.saveAllChunks( @@ -27004,11 +23525,11 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } protected void tick(BooleanSupplier shouldKeepTicking) { -@@ -540,134 +403,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -507,134 +370,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public boolean hasWork() { -- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || io.papermc.paper.chunk.system.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper +- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || ca.spottedleaf.moonrise.common.util.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -27046,7 +23567,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 - } - - int l = 0; -- Iterator objectiterator = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper +- Iterator objectiterator = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper - - while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) { - if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) { @@ -27069,7 +23590,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 - // Paper start - boolean removed; - if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) { -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); - // Paper end - LevelChunk chunk; - @@ -27089,7 +23610,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 - this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null); - this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong()); - } else if (removed) { // Paper start -- io.papermc.paper.chunk.system.ChunkSystem.onChunkHolderDelete(this.level, holder); +- ca.spottedleaf.moonrise.common.util.ChunkSystem.onChunkHolderDelete(this.level, holder); - } // Paper end - - } @@ -27145,7 +23666,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } private static boolean isChunkDataValid(CompoundTag nbt) { -@@ -727,137 +481,44 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -694,137 +448,44 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @Override public GenerationChunkHolder acquireGeneration(long pos) { @@ -27292,7 +23813,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } public int getTickingGenerated() { -@@ -865,135 +526,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -832,135 +493,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean saveChunkIfNeeded(ChunkHolder chunkHolder) { @@ -27416,7 +23937,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 public int getPlayerViewDistance(ServerPlayer player) { // Paper - public - return Mth.clamp(player.requestedViewDistance(), 2, this.serverViewDistance); -+ return ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.getSendViewDistance(player); // Paper - rewrite chunk system ++ return ca.spottedleaf.moonrise.common.util.ChunkSystem.getSendViewDistance(player); // Paper - rewrite chunk system } private void markChunkPendingToSend(ServerPlayer player, ChunkPos pos) { @@ -27480,7 +24001,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 @Nullable public LevelChunk getChunkToSend(long pos) { ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos); -@@ -1059,7 +669,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1026,7 +636,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } // CraftBukkit start @@ -27489,25 +24010,31 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 return this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator().getTypeNameForDataFixer(), chunkcoordintpair, this.level); // CraftBukkit end } -@@ -1153,7 +763,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1117,19 +727,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + this.updatePlayerPos(player); + if (!flag1) { + this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player); ++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$addPlayer(player, SectionPos.of(player)); // Paper - chunk tick iteration optimisation } player.setChunkTrackingView(ChunkTrackingView.EMPTY); - this.updateChunkTracking(player); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.addPlayerToDistanceMaps(this.level, player); // Paper - rewrite chunk system - this.addPlayerToDistanceMaps(player); // Paper - distance maps ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.addPlayerToDistanceMaps(this.level, player); // Paper - rewrite chunk system } else { SectionPos sectionposition = player.getLastSectionPos(); -@@ -1164,7 +774,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + this.playerMap.removePlayer(player); + if (!flag2) { + this.distanceManager.removePlayer(sectionposition, player); ++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$removePlayer(player, SectionPos.of(player)); // Paper - chunk tick iteration optimisation } - this.removePlayerFromDistanceMaps(player); // Paper - distance maps - this.applyChunkTrackingView(player, ChunkTrackingView.EMPTY); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.removePlayerFromDistanceMaps(this.level, player); // Paper - rewrite chunk system ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.removePlayerFromDistanceMaps(this.level, player); // Paper - rewrite chunk system } } -@@ -1176,17 +786,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1141,17 +753,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -27526,7 +24053,15 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 SectionPos sectionposition = player.getLastSectionPos(); SectionPos sectionposition1 = SectionPos.of((EntityAccess) player); -@@ -1212,71 +812,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1161,6 +763,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + + if (flag2 || flag != flag1) { + this.updatePlayerPos(player); ++ ((ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager)this.distanceManager).moonrise$updatePlayer(player, sectionposition, sectionposition1, flag, flag1); // Paper - chunk tick iteration optimisation + if (!flag) { + this.distanceManager.removePlayer(sectionposition, player); + } +@@ -1177,70 +780,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.playerMap.unIgnorePlayer(player); } @@ -27534,8 +24069,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 + // Paper - rewrite chunk system } - this.updateMaps(player); // Paper - distance maps -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.updateMaps(this.level, player); // Paper - rewrite chunk system ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.updateMaps(this.level, player); // Paper - rewrite chunk system } private void updateChunkTracking(ServerPlayer player) { @@ -27609,7 +24143,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } public void addEntity(Entity entity) { -@@ -1304,6 +864,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1268,6 +831,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker this.entityMap.put(entity.getId(), playerchunkmap_entitytracker); @@ -27622,7 +24156,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 playerchunkmap_entitytracker.updatePlayers(this.level.players()); if (entity instanceof ServerPlayer) { ServerPlayer entityplayer = (ServerPlayer) entity; -@@ -1344,16 +910,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1308,16 +877,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider playerchunkmap_entitytracker1.broadcastRemoved(); } entity.tracker = null; // Paper - We're no longer tracked @@ -27677,7 +24211,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 List list = Lists.newArrayList(); List list1 = this.level.players(); -@@ -1460,27 +1059,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1424,27 +1026,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void waitForLightBeforeSending(ChunkPos centerPos, int radius) { @@ -27715,7 +24249,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 } @Nullable -@@ -1496,7 +1093,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1460,7 +1060,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } } @@ -27724,7 +24258,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 public final ServerEntity serverEntity; final Entity entity; -@@ -1504,6 +1101,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1468,6 +1068,84 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider SectionPos lastSectionPos; public final Set seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl @@ -27774,7 +24308,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 + public final void moonrise$removeNonTickThreadPlayers() { + boolean foundToRemove = false; + for (final ServerPlayerConnection conn : this.seenBy) { -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(conn.getPlayer())) { ++ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(conn.getPlayer())) { + foundToRemove = true; + break; + } @@ -27786,7 +24320,7 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 + + for (final ServerPlayerConnection conn : new java.util.ArrayList<>(this.seenBy)) { + ServerPlayer player = conn.getPlayer(); -+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(player)) { ++ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(player)) { + this.removePlayer(player); + } + } @@ -27810,15 +24344,15 @@ index a03385b1b0a2f9b98319137b87d917856d3c632c..d843bc04ae93d11d7820cab5ed186171 this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit this.entity = entity; diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java -index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0201aab62 100644 +index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..6d0e396e148557e401939860cd7af0baefaf9f19 100644 --- a/src/main/java/net/minecraft/server/level/DistanceManager.java +++ b/src/main/java/net/minecraft/server/level/DistanceManager.java -@@ -36,66 +36,36 @@ import net.minecraft.world.level.ChunkPos; +@@ -36,66 +36,60 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.LevelChunk; import org.slf4j.Logger; -public abstract class DistanceManager { -+public abstract class DistanceManager implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager { // Paper - rewrite chunk system ++public abstract class DistanceManager implements ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemDistanceManager, ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickDistanceManager { // Paper - rewrite chunk system // Paper - chunk tick iteration optimisation static final Logger LOGGER = LogUtils.getLogger(); static final int PLAYER_TICKET_LEVEL = ChunkLevel.byStatus(FullChunkStatus.ENTITY_TICKING); @@ -27826,8 +24360,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 final Long2ObjectMap> playersPerChunk = new Long2ObjectOpenHashMap(); - public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); - private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker(); -+ // Paper - rewrite chunk system - private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); +- private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8); - private final TickingTracker tickingTicketsTracker = new TickingTracker(); - private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(32); - final Set chunksToUpdateFutures = Sets.newHashSet(); @@ -27836,6 +24369,8 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 - final ProcessorHandle ticketThrottlerReleaser; - final LongSet ticketsToRelease = new LongOpenHashSet(); - final Executor mainThreadExecutor; ++ // Paper - rewrite chunk system ++ // Paper - chunk tick iteration optimisation + // Paper - rewrite chunk system private long ticketTickCounter; - public int simulationDistance = 10; @@ -27847,6 +24382,30 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 + return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.moonrise$getChunkMap().level).moonrise$getChunkTaskScheduler().chunkHolderManager; + } + // Paper end - rewrite chunk system ++ // Paper start - chunk tick iteration optimisation ++ private final ca.spottedleaf.moonrise.common.misc.PositionCountingAreaMap spawnChunkTracker = new ca.spottedleaf.moonrise.common.misc.PositionCountingAreaMap<>(); ++ ++ @Override ++ public final void moonrise$addPlayer(final ServerPlayer player, final SectionPos pos) { ++ this.spawnChunkTracker.add(player, pos.x(), pos.z(), ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); ++ } ++ ++ @Override ++ public final void moonrise$removePlayer(final ServerPlayer player, final SectionPos pos) { ++ this.spawnChunkTracker.remove(player); ++ } ++ ++ @Override ++ public final void moonrise$updatePlayer(final ServerPlayer player, ++ final SectionPos oldPos, final SectionPos newPos, ++ final boolean oldIgnore, final boolean newIgnore) { ++ if (newIgnore) { ++ this.spawnChunkTracker.remove(player); ++ } else { ++ this.spawnChunkTracker.addOrUpdate(player, newPos.x(), newPos.z(), ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); ++ } ++ } ++ // Paper end - chunk tick iteration optimisation + protected DistanceManager(Executor workerExecutor, Executor mainThreadExecutor, ChunkMap chunkMap) { Objects.requireNonNull(mainThreadExecutor); @@ -27892,7 +24451,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 } -@@ -112,86 +82,15 @@ public abstract class DistanceManager { +@@ -112,86 +106,15 @@ public abstract class DistanceManager { protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k); public boolean runAllUpdates(ChunkMap chunkLoadingManager) { @@ -27982,7 +24541,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 } public void addTicket(TicketType type, ChunkPos pos, int level, T argument) { -@@ -210,13 +109,7 @@ public abstract class DistanceManager { +@@ -210,13 +133,7 @@ public abstract class DistanceManager { } public boolean addRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -27997,7 +24556,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 } public void removeRegionTicket(TicketType type, ChunkPos pos, int radius, T argument) { -@@ -225,32 +118,21 @@ public abstract class DistanceManager { +@@ -225,32 +142,21 @@ public abstract class DistanceManager { } public boolean removeRegionTicketAtDistance(TicketType tickettype, ChunkPos chunkcoordintpair, int i, T t0) { @@ -28036,22 +24595,26 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 } -@@ -262,8 +144,7 @@ public abstract class DistanceManager { +@@ -261,9 +167,8 @@ public abstract class DistanceManager { + ((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> { return new ObjectOpenHashSet(); })).add(player); - this.naturalSpawnChunkCounter.update(i, 0, true); +- this.naturalSpawnChunkCounter.update(i, 0, true); - this.playerTicketManager.update(i, 0, true); - this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); ++ // Paper - chunk tick iteration optimisation + // Paper - rewrite chunk system } public void removePlayer(SectionPos pos, ServerPlayer player) { -@@ -276,39 +157,39 @@ public abstract class DistanceManager { +@@ -275,151 +180,81 @@ public abstract class DistanceManager { + if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully if (objectset == null || objectset.isEmpty()) { // Paper this.playersPerChunk.remove(i); - this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); +- this.naturalSpawnChunkCounter.update(i, Integer.MAX_VALUE, false); - this.playerTicketManager.update(i, Integer.MAX_VALUE, false); - this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair); ++ // Paper - chunk tick iteration optimisation + // Paper - rewrite chunk system } @@ -28099,7 +24662,16 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 } -@@ -323,103 +204,35 @@ public abstract class DistanceManager { + public int getNaturalSpawnChunkCount() { +- this.naturalSpawnChunkCounter.runAllUpdates(); +- return this.naturalSpawnChunkCounter.chunks.size(); ++ return this.spawnChunkTracker.getTotalPositions(); // Paper - chunk tick iteration optimisation + } + + public boolean hasPlayersNearby(long chunkPos) { +- this.naturalSpawnChunkCounter.runAllUpdates(); +- return this.naturalSpawnChunkCounter.chunks.containsKey(chunkPos); ++ return this.spawnChunkTracker.hasObjectsNear(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(chunkPos), ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(chunkPos)); // Paper - chunk tick iteration optimisation } public String getDebugStatus() { @@ -28210,7 +24782,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 private class ChunkTicketTracker extends ChunkTracker { private static final int MAX_LEVEL = ChunkLevel.MAX_LEVEL + 1; -@@ -465,7 +278,7 @@ public abstract class DistanceManager { +@@ -465,7 +300,7 @@ public abstract class DistanceManager { public int runDistanceUpdates(int distance) { return this.runUpdates(distance); } @@ -28219,7 +24791,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 private class FixedPlayerDistanceChunkTracker extends ChunkTracker { -@@ -545,6 +358,7 @@ public abstract class DistanceManager { +@@ -545,6 +380,7 @@ public abstract class DistanceManager { } } @@ -28227,7 +24799,7 @@ index cbabbfbb9967ddf9a56f3be24a88e0fcd4415aa2..71abe25cfb73af3857cbc85980aa32d0 private class PlayerTicketTracker extends DistanceManager.FixedPlayerDistanceChunkTracker { private int viewDistance = 0; -@@ -639,5 +453,5 @@ public abstract class DistanceManager { +@@ -639,5 +475,5 @@ public abstract class DistanceManager { private boolean haveTicketFor(int distance) { return distance <= this.viewDistance; } @@ -28561,7 +25133,7 @@ index 3dc1daa3c6a04d3ff1a2353773b465fc380994a2..3575782f13a7f3c52e64dc5046803305 } } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda54f9b6c3 100644 +index 60f678c26fb5144386d8697ddfd5b6d841563b6f..9aec513f05b10e78579f79ccda6acf285f13222e 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -46,7 +46,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp @@ -28573,7 +25145,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda public static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); // Paper private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); -@@ -73,6 +73,61 @@ public class ServerChunkCache extends ChunkSource { +@@ -71,6 +71,61 @@ public class ServerChunkCache extends ChunkSource { private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); long chunkFutureAwaitCounter; // Paper end @@ -28602,7 +25174,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda + completable::complete + ); + -+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) { ++ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.level, chunkX, chunkZ)) { + ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.pushChunkWait(this.level, chunkX, chunkZ); + this.mainThreadProcessor.managedBlock(completable::isDone); + ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.popChunkWait(); @@ -28635,7 +25207,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { this.level = world; -@@ -99,13 +154,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -97,13 +152,7 @@ public class ServerChunkCache extends ChunkSource { } // CraftBukkit end // Paper start @@ -28650,7 +25222,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda @Nullable public ChunkAccess getChunkAtImmediately(int x, int z) { -@@ -176,63 +225,25 @@ public class ServerChunkCache extends ChunkSource { +@@ -174,63 +223,25 @@ public class ServerChunkCache extends ChunkSource { @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) { @@ -28724,7 +25296,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } private void clearCache() { -@@ -263,56 +274,59 @@ public class ServerChunkCache extends ChunkSource { +@@ -261,56 +272,59 @@ public class ServerChunkCache extends ChunkSource { } private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { @@ -28733,7 +25305,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda - int l = ChunkLevel.byStatus(leastStatus); - ChunkHolder playerchunk = this.getVisibleChunkIfPresent(k); + // Paper start - rewrite chunk system -+ io.papermc.paper.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main"); - // CraftBukkit start - don't add new ticket for currently unloading chunk - boolean currentlyUnloading = false; @@ -28820,7 +25392,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } @Override -@@ -325,16 +339,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -323,16 +337,7 @@ public class ServerChunkCache extends ChunkSource { } public boolean runDistanceManagerUpdates() { // Paper - public @@ -28838,7 +25410,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } // Paper start -@@ -344,13 +349,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -342,13 +347,14 @@ public class ServerChunkCache extends ChunkSource { // Paper end public boolean isPositionTicking(long pos) { @@ -28857,7 +25429,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings this.chunkMap.saveAllChunks(flush); } // Paper - Timings -@@ -363,12 +369,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -361,12 +367,7 @@ public class ServerChunkCache extends ChunkSource { } public void close(boolean save) throws IOException { @@ -28871,7 +25443,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } // CraftBukkit start - modelled on below -@@ -396,6 +397,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -394,6 +395,7 @@ public class ServerChunkCache extends ChunkSource { this.level.getProfiler().popPush("chunks"); if (tickChunks) { this.level.timings.chunks.startTiming(); // Paper - timings @@ -28879,7 +25451,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda this.tickChunks(); this.level.timings.chunks.stopTiming(); // Paper - timings this.chunkMap.tick(); -@@ -410,6 +412,7 @@ public class ServerChunkCache extends ChunkSource { +@@ -408,6 +410,7 @@ public class ServerChunkCache extends ChunkSource { } private void tickChunks() { @@ -28887,7 +25459,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda long i = this.level.getGameTime(); long j = i - this.lastInhabitedUpdate; -@@ -462,14 +465,19 @@ public class ServerChunkCache extends ChunkSource { +@@ -460,14 +463,19 @@ public class ServerChunkCache extends ChunkSource { LevelChunk chunk1 = chunkproviderserver_a.chunk; ChunkPos chunkcoordintpair = chunk1.getPos(); @@ -28909,7 +25481,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } } } -@@ -495,11 +503,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -493,11 +501,12 @@ public class ServerChunkCache extends ChunkSource { } private void getFullChunk(long pos, Consumer chunkConsumer) { @@ -28926,7 +25498,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda } -@@ -593,6 +602,12 @@ public class ServerChunkCache extends ChunkSource { +@@ -591,6 +600,12 @@ public class ServerChunkCache extends ChunkSource { this.chunkMap.setServerViewDistance(watchDistance); } @@ -28939,7 +25511,7 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda public void setSimulationDistance(int simulationDistance) { this.distanceManager.updateSimulationDistance(simulationDistance); } -@@ -671,16 +686,14 @@ public class ServerChunkCache extends ChunkSource { +@@ -669,21 +684,19 @@ public class ServerChunkCache extends ChunkSource { @Override // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task public boolean pollTask() { @@ -28961,6 +25533,12 @@ index be9604a0f267558c95125852d86761a2f175732a..337383b8aa00f5f33e770dcc0b087cda // CraftBukkit end } } + +- private static record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) { ++ public static record ChunkAndHolder(LevelChunk chunk, ChunkHolder holder) { // Paper - rewrite chunk system - public + + } + } diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java index 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..12d86f27d04bffed8c3844e36b42fbc2f84dacff 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java @@ -28978,7 +25556,7 @@ index 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..12d86f27d04bffed8c3844e36b42fbc2 if (!list.equals(this.lastPassengers)) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5824a841f 100644 +index c97292f22a3402dbd59cef4af554954dc1d4f91a..c759555241649cf5b355268066375341a54477f2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -184,7 +184,7 @@ import org.bukkit.event.weather.LightningStrikeEvent; @@ -28999,7 +25577,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 private final GameEventDispatcher gameEventDispatcher; public boolean noSave; private final SleepStatus sleepStatus; -@@ -339,6 +339,176 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -339,6 +339,195 @@ public class ServerLevel extends Level implements WorldGenLevel { return player != null && player.level() == this ? player : null; } // Paper end - optimise getPlayerByUUID @@ -29014,6 +25592,10 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 + private long lastMidTickFailure; + private long tickedBlocksOrFluids; + private final ca.spottedleaf.moonrise.common.misc.NearbyPlayers nearbyPlayers = new ca.spottedleaf.moonrise.common.misc.NearbyPlayers((ServerLevel)(Object)this); ++ private static final ServerChunkCache.ChunkAndHolder[] EMPTY_CHUNK_AND_HOLDERS = new ServerChunkCache.ChunkAndHolder[0]; ++ private final ca.spottedleaf.moonrise.common.list.ReferenceList loadedChunks = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_CHUNK_AND_HOLDERS); ++ private final ca.spottedleaf.moonrise.common.list.ReferenceList tickingChunks = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_CHUNK_AND_HOLDERS); ++ private final ca.spottedleaf.moonrise.common.list.ReferenceList entityTickingChunks = new ca.spottedleaf.moonrise.common.list.ReferenceList<>(EMPTY_CHUNK_AND_HOLDERS); + + @Override + public final LevelChunk moonrise$getFullChunkIfLoaded(final int chunkX, final int chunkZ) { @@ -29172,11 +25754,26 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 + public final ca.spottedleaf.moonrise.common.misc.NearbyPlayers moonrise$getNearbyPlayers() { + return this.nearbyPlayers; + } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getLoadedChunks() { ++ return this.loadedChunks; ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getTickingChunks() { ++ return this.tickingChunks; ++ } ++ ++ @Override ++ public final ca.spottedleaf.moonrise.common.list.ReferenceList moonrise$getEntityTickingChunks() { ++ return this.entityTickingChunks; ++ } + // Paper end - rewrite chunk system // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -@@ -385,14 +555,13 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -385,14 +574,13 @@ public class ServerLevel extends Level implements WorldGenLevel { DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); @@ -29194,7 +25791,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -420,6 +589,19 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -420,6 +608,19 @@ public class ServerLevel extends Level implements WorldGenLevel { this.randomSequences = (RandomSequences) Objects.requireNonNullElseGet(randomsequences, () -> { return (RandomSequences) this.getDataStorage().computeIfAbsent(RandomSequences.factory(l), "random_sequences"); }); @@ -29214,7 +25811,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -553,7 +735,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -553,7 +754,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.push("checkDespawn"); entity.checkDespawn(); gameprofilerfiller.pop(); @@ -29223,7 +25820,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 Entity entity1 = entity.getVehicle(); if (entity1 != null) { -@@ -578,13 +760,16 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -578,13 +779,16 @@ public class ServerLevel extends Level implements WorldGenLevel { } gameprofilerfiller.push("entityManagement"); @@ -29242,7 +25839,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } protected void tickTime() { -@@ -626,6 +811,63 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -626,6 +830,63 @@ public class ServerLevel extends Level implements WorldGenLevel { }); } @@ -29306,7 +25903,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 public void tickChunk(LevelChunk chunk, int randomTickSpeed) { ChunkPos chunkcoordintpair = chunk.getPos(); boolean flag = this.isRaining(); -@@ -675,35 +917,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -675,35 +936,7 @@ public class ServerLevel extends Level implements WorldGenLevel { gameprofilerfiller.popPush("tickBlocks"); timings.chunkTicksBlocks.startTiming(); // Paper if (randomTickSpeed > 0) { @@ -29343,7 +25940,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } timings.chunkTicksBlocks.stopTiming(); // Paper -@@ -976,6 +1190,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -976,6 +1209,11 @@ public class ServerLevel extends Level implements WorldGenLevel { if (fluid1.is(fluid)) { fluid1.tick(this, pos); } @@ -29355,7 +25952,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } -@@ -985,6 +1204,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -985,6 +1223,11 @@ public class ServerLevel extends Level implements WorldGenLevel { if (iblockdata.is(block)) { iblockdata.tick(this, pos, this.random); } @@ -29367,7 +25964,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } -@@ -1061,6 +1285,11 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1061,6 +1304,11 @@ public class ServerLevel extends Level implements WorldGenLevel { } public void save(@Nullable ProgressListener progressListener, boolean flush, boolean savingDisabled) { @@ -29379,7 +25976,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 ServerChunkCache chunkproviderserver = this.getChunkSource(); if (!savingDisabled) { -@@ -1076,16 +1305,21 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1076,16 +1324,21 @@ public class ServerLevel extends Level implements WorldGenLevel { } timings.worldSaveChunks.startTiming(); // Paper @@ -29407,7 +26004,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1218,7 +1452,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1218,7 +1471,7 @@ public class ServerLevel extends Level implements WorldGenLevel { this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED); } @@ -29416,7 +26013,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } // CraftBukkit start -@@ -1249,7 +1483,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1249,7 +1502,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } // CraftBukkit end @@ -29425,7 +26022,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } } -@@ -1260,11 +1494,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1260,11 +1513,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -29438,7 +26035,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1850,7 +2080,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1850,7 +2099,7 @@ public class ServerLevel extends Level implements WorldGenLevel { } } @@ -29447,7 +26044,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 bufferedwriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedwriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedwriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1899,7 +2129,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1899,7 +2148,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BufferedWriter bufferedwriter2 = Files.newBufferedWriter(path1); try { @@ -29456,7 +26053,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } catch (Throwable throwable4) { if (bufferedwriter2 != null) { try { -@@ -1920,7 +2150,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -1920,7 +2169,7 @@ public class ServerLevel extends Level implements WorldGenLevel { BufferedWriter bufferedwriter3 = Files.newBufferedWriter(path2); try { @@ -29465,7 +26062,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } catch (Throwable throwable6) { if (bufferedwriter3 != null) { try { -@@ -2062,7 +2292,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2062,7 +2311,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @VisibleForTesting public String getWatchdogStats() { @@ -29474,7 +26071,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }), this.blockEntityTickers.size(), ServerLevel.getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), this.getFluidTicks().count(), this.gatherChunkSourceStats()); } -@@ -2092,15 +2322,25 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2092,15 +2341,25 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -29503,7 +26100,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } public void startTickingChunk(LevelChunk chunk) { -@@ -2120,34 +2360,47 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2120,34 +2379,47 @@ public class ServerLevel extends Level implements WorldGenLevel { @Override public void close() throws IOException { super.close(); @@ -29558,7 +26155,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 } @Override -@@ -2173,7 +2426,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -2173,7 +2445,7 @@ public class ServerLevel extends Level implements WorldGenLevel { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); crashreportsystemdetails.setDetail("Loaded entity count", () -> { @@ -29568,7 +26165,7 @@ index 4d7e234d379a451c4bb53bc2fcdf22cb191f8d1a..bb3826481d6165991f4201ed39d56fa5 return crashreportsystemdetails; } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 191dfbd0f15c3a21278f3c4f9ce29f1698e0836c..ba64e42a58b4b760815f54228ebf7a46fd14734e 100644 +index 7f83f40c76eac2ce5b053dc651224c44701613ea..fd61e10fd3151bf8cc206a93d4ede22a7c681dbf 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -199,7 +199,7 @@ import org.bukkit.event.player.PlayerToggleSneakEvent; @@ -29580,7 +26177,7 @@ index 191dfbd0f15c3a21278f3c4f9ce29f1698e0836c..ba64e42a58b4b760815f54228ebf7a46 private static final Logger LOGGER = LogUtils.getLogger(); private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; -@@ -297,6 +297,36 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { +@@ -296,6 +296,36 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player { public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -30643,7 +27240,7 @@ index 2e2101274f3afebbae783fa119f5cae8104de45d..4f4b7e738fe604808d837a38d23bf437 @Override diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2841c3b44 100644 +index fb63036d26d2b5370472b741b23bebd71e247463..d7a6eab60bf26916f78f858e224573560e581fef 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java @@ -38,12 +38,153 @@ import net.minecraft.world.level.chunk.storage.RegionStorageInfo; @@ -30684,7 +27281,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2 + final int chunkY = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionY(pos); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionZ(pos); + -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); + + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; + final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk ret = manager.getPoiChunkIfLoaded(chunkX, chunkZ, true); @@ -30698,7 +27295,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2 + final int chunkY = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionY(pos); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionZ(pos); + -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); + + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; + @@ -30720,7 +27317,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2 + final int chunkY = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionY(pos); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkSectionZ(pos); + -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Accessing poi chunk off-main"); + + final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager manager = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager; + @@ -30741,7 +27338,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2 + public final void moonrise$onUnload(final long coordinate) { // Paper - rewrite chunk system + final int chunkX = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(coordinate); + final int chunkZ = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(coordinate); -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Unloading poi chunk off-main"); + for (int section = this.levelHeightAccessor.getMinSection(); section < this.levelHeightAccessor.getMaxSection(); ++section) { + final long sectionPos = SectionPos.asLong(chunkX, section, chunkZ); + this.updateDistanceTracking(sectionPos); @@ -30752,7 +27349,7 @@ index fb63036d26d2b5370472b741b23bebd71e247463..274ddf479d38495d84838f9cd73c13d2 + public final void moonrise$loadInPoiChunk(final ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk poiChunk) { + final int chunkX = poiChunk.chunkX; + final int chunkZ = poiChunk.chunkZ; -+ io.papermc.paper.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this.world, chunkX, chunkZ, "Loading poi chunk off-main"); + for (int sectionY = this.levelHeightAccessor.getMinSection(); sectionY < this.levelHeightAccessor.getMaxSection(); ++sectionY) { + final PoiSection section = poiChunk.getSection(sectionY); + if (section != null && !((ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection)section).moonrise$isEmpty()) { @@ -31539,7 +28136,7 @@ index bff83fe413c7baef4ba56a3270ea4463a58c792f..a248d859cbce48f4a34c4771a7acffc1 } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index e27d3547d1e19c137e05e6b8d075127a8bafb237..c4c2dc649e69d6097fbf6884ce82a34efb3e0e4d 100644 +index e27d3547d1e19c137e05e6b8d075127a8bafb237..a016fb2140d6a43172c3fbc623b23f6d57798d9e 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -81,6 +81,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -32112,7 +28709,7 @@ index e27d3547d1e19c137e05e6b8d075127a8bafb237..c4c2dc649e69d6097fbf6884ce82a34e // Paper end - Perf: Optimize capturedTileEntities lookup // CraftBukkit end - return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && Thread.currentThread() != this.thread ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); -+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system ++ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system } public void setBlockEntity(BlockEntity blockEntity) { @@ -32744,7 +29341,7 @@ index 365074be989aa4a178114fd5e9810f1a68640196..4af698930712389881601069a921f054 @Override public BlockEntity getBlockEntity(BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df600a95ee 100644 +index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..3fa7bfa09b9d529b5cb9cad923f21343159cfa35 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -53,7 +53,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; @@ -32771,17 +29368,28 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df } // CraftBukkit start -@@ -119,6 +127,28 @@ public class LevelChunk extends ChunkAccess { +@@ -119,6 +127,39 @@ public class LevelChunk extends ChunkAccess { // Paper start boolean loadedTicketLevel; // Paper end + // Paper start - rewrite chunk system + private boolean postProcessingDone; ++ private net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder; + + @Override + public final boolean moonrise$isPostProcessingDone() { + return this.postProcessingDone; + } ++ ++ @Override ++ public final net.minecraft.server.level.ServerChunkCache.ChunkAndHolder moonrise$getChunkAndHolder() { ++ return this.chunkAndHolder; ++ } ++ ++ @Override ++ public final void moonrise$setChunkAndHolder(final net.minecraft.server.level.ServerChunkCache.ChunkAndHolder holder) { ++ this.chunkAndHolder = holder; ++ } + // Paper end - rewrite chunk system + // Paper start - get block chunk optimisation + private static final BlockState AIR_BLOCKSTATE = Blocks.AIR.defaultBlockState(); @@ -32800,7 +29408,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor entityLoader) { this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), entityLoader, protoChunk.getBlendingData()); -@@ -148,13 +178,19 @@ public class LevelChunk extends ChunkAccess { +@@ -148,13 +189,19 @@ public class LevelChunk extends ChunkAccess { } } @@ -32821,7 +29429,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df } @Override -@@ -337,7 +373,7 @@ public class LevelChunk extends ChunkAccess { +@@ -337,7 +384,7 @@ public class LevelChunk extends ChunkAccess { ProfilerFiller gameprofilerfiller = this.level.getProfiler(); gameprofilerfiller.push("updateSkyLightSources"); @@ -32830,7 +29438,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df gameprofilerfiller.popPush("queueCheckLight"); this.level.getChunkSource().getLightEngine().checkBlock(blockposition); gameprofilerfiller.pop(); -@@ -597,11 +633,12 @@ public class LevelChunk extends ChunkAccess { +@@ -597,11 +644,12 @@ public class LevelChunk extends ChunkAccess { // CraftBukkit start public void loadCallback() { @@ -32844,7 +29452,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df if (server != null) { /* * If it's a new world, the first few chunks are generated inside -@@ -610,6 +647,7 @@ public class LevelChunk extends ChunkAccess { +@@ -610,6 +658,7 @@ public class LevelChunk extends ChunkAccess { */ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); @@ -32852,7 +29460,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df if (this.needsDecoration) { try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper -@@ -638,13 +676,15 @@ public class LevelChunk extends ChunkAccess { +@@ -638,13 +687,15 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -32870,7 +29478,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df // Paper start this.loadedTicketLevel = false; // Paper end -@@ -652,8 +692,27 @@ public class LevelChunk extends ChunkAccess { +@@ -652,8 +703,27 @@ public class LevelChunk extends ChunkAccess { @Override public boolean isUnsaved() { @@ -32899,7 +29507,7 @@ index 602ad80c2b93d320bf2a25832d25a58cb8c72e4b..214bb6759d2670042d87b2fd0aae41df // CraftBukkit end public boolean isEmpty() { -@@ -759,6 +818,7 @@ public class LevelChunk extends ChunkAccess { +@@ -759,6 +829,7 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -33344,7 +29952,7 @@ index f6e08a8334633ff1532616d051bed46b702d0091..4e56398a6fb8b97199f4c74ebebc1055 private final ChunkStatus status; @Nullable diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index d42585bccb03f8ee1be5e37cfbe8520af4cc5454..977bebe8657abc5cb84ede8276d6781cde20e847 100644 +index d42585bccb03f8ee1be5e37cfbe8520af4cc5454..cb5196f0ff7b9a59927c60b9d24c987a150e69f1 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -165,7 +165,7 @@ public class ChunkSerializer { @@ -33372,7 +29980,7 @@ index d42585bccb03f8ee1be5e37cfbe8520af4cc5454..977bebe8657abc5cb84ede8276d6781c + // Paper start - async chunk saving + // must be called sync + public static ca.spottedleaf.moonrise.patches.chunk_system.async_save.AsyncChunkSaveData getAsyncSaveData(ServerLevel world, ChunkAccess chunk) { -+ io.papermc.paper.util.TickThread.ensureTickThread(world, chunk.locX, chunk.locZ, "Preparing async chunk save data"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(world, chunk.locX, chunk.locZ, "Preparing async chunk save data"); + + final CompoundTag tickLists = new CompoundTag(); + ChunkSerializer.saveTicks(world, tickLists, chunk.getTicksForSerialization()); @@ -36052,7 +32660,7 @@ index 69c7fe5bf5b914276a9f7a0e57ce668e569d91f9..33322b57b4c6922f4daad0f584733f0f @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 77f3ac4e45a691181a94831cf49f7840c9f88e3a..05e44a1448f30ceb8cecba2bed76f51aac5543f9 100644 +index 2f7119ca17cf0df445c0c34804e40acb209a5b0d..06215f56f1cae5197c827b8100432ab2ef9aa976 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1419,7 +1419,7 @@ public final class CraftServer implements Server { @@ -36078,12 +32686,12 @@ index 77f3ac4e45a691181a94831cf49f7840c9f88e3a..05e44a1448f30ceb8cecba2bed76f51a @Override public boolean isPrimaryThread() { - return Thread.currentThread().equals(this.console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) -+ return io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system ++ return ca.spottedleaf.moonrise.common.util.TickThread.isTickThread(); // Paper - rewrite chunk system } // Paper start - Adventure diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 8f88ccec6b8947ca2738dc07c23aebe258145c83..cdc704364cf339084537d089e654f6078f8be783 100644 +index 94640aa827c9b2e1d0174eb012fdb37c0851f501..5ad2ceb1274648631689215702a12463c681152c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -456,10 +456,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -36185,16 +32793,10 @@ index 8f88ccec6b8947ca2738dc07c23aebe258145c83..cdc704364cf339084537d089e654f607 // Paper start - implement pointers diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 3480f06d4476c5c200246e6200e2eda2a5de1a5a..62bfde27a182be24710eb3b72448e82da58afc8f 100644 +index 65a6952d48f40f3fd73d6693b61be9d29741f2f6..4e7da1be4acf1028022e62a652df3e262a85fa0f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3492,12 +3492,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - - @Override - public int getViewDistance() { -- return io.papermc.paper.chunk.system.ChunkSystem.getLoadViewDistance(this.getHandle()); -+ return io.papermc.paper.chunk.system.ChunkSystem.getLoadViewDistance(this.getHandle()) - 1; // Paper - rewrite chunk system - TODO do this better - } +@@ -3497,7 +3497,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setViewDistance(final int viewDistance) { @@ -36257,20 +32859,20 @@ index fceed3d08ee6f4c171685986bb19d2be592eedc6..bf18f9ad7dec2b09ebfcb5ec6566f255 // Paper end } diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java -index e8e3cc48cf1c58bd8151d1f28df28781859cd0e3..67c8e90d3a2a93d858371d7fc1c3aaac3fdef71c 100644 +index ef2598760458833021ef1bee92137f42c9fe591f..1f23e775eba1c34e01145bd91b0ce26fed6ca9de 100644 --- a/src/main/java/org/spigotmc/AsyncCatcher.java +++ b/src/main/java/org/spigotmc/AsyncCatcher.java @@ -9,7 +9,7 @@ public class AsyncCatcher public static void catchOp(String reason) { -- if ( (AsyncCatcher.enabled || io.papermc.paper.util.TickThread.STRICT_THREAD_CHECKS) && Thread.currentThread() != MinecraftServer.getServer().serverThread ) // Paper -+ if (!io.papermc.paper.util.TickThread.isTickThread()) // Paper // Paper - rewrite chunk system +- if ( AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) ++ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) // Paper // Paper - rewrite chunk system { MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); // Paper throw new IllegalStateException( "Asynchronous " + reason + "!" ); diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index ad282d34919716b75acd10426cd071da9d064a51..bab2bd91528a8b2e9e74a3f9eb061d52619102f6 100644 +index ad282d34919716b75acd10426cd071da9d064a51..529df2a41dd93d6e1505053bd04032dbf0cdaa31 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -8,7 +8,7 @@ import java.util.logging.Logger; @@ -36278,7 +32880,7 @@ index ad282d34919716b75acd10426cd071da9d064a51..bab2bd91528a8b2e9e74a3f9eb061d52 import org.bukkit.Bukkit; -public class WatchdogThread extends Thread -+public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - rewrite chunk system ++public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThread // Paper - rewrite chunk system { private static WatchdogThread instance; diff --git a/patches/server/0990-Rewrite-dataconverter-system.patch b/patches/server/0989-Rewrite-dataconverter-system.patch similarity index 100% rename from patches/server/0990-Rewrite-dataconverter-system.patch rename to patches/server/0989-Rewrite-dataconverter-system.patch diff --git a/patches/server/0991-disable-forced-empty-world-ticks.patch b/patches/server/0990-disable-forced-empty-world-ticks.patch similarity index 87% rename from patches/server/0991-disable-forced-empty-world-ticks.patch rename to patches/server/0990-disable-forced-empty-world-ticks.patch index a9fa9f8360..747f78f9fd 100644 --- a/patches/server/0991-disable-forced-empty-world-ticks.patch +++ b/patches/server/0990-disable-forced-empty-world-ticks.patch @@ -5,10 +5,10 @@ Subject: [PATCH] disable forced empty world ticks diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index bb3826481d6165991f4201ed39d56fa5824a841f..2e30f8a12391222e612a9c1bf56e93625f52a8dc 100644 +index c759555241649cf5b355268066375341a54477f2..7da9729a6ac0684624f900a9e47f24e35bd3f3d9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -710,7 +710,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -729,7 +729,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.handlingTick = false; gameprofilerfiller.pop(); diff --git a/patches/server/0992-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0991-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 98% rename from patches/server/0992-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch rename to patches/server/0991-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index 229e45202f..ed5debe49c 100644 --- a/patches/server/0992-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch +++ b/patches/server/0991-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -29,7 +29,7 @@ index 02367ef1371dde94ff6c4cd40bd32e800d6ccaaf..7b0fc7135bc107103dcaed6dc0707b18 this.x = x; this.y = y; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index c4c2dc649e69d6097fbf6884ce82a34efb3e0e4d..2dcd2f9085de19a91f32f161b89572ec1fbe4805 100644 +index a016fb2140d6a43172c3fbc623b23f6d57798d9e..5b893b93a3495b13ae266fb8054d0a454cf02660 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -824,7 +824,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl diff --git a/patches/server/0993-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0992-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch similarity index 97% rename from patches/server/0993-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch rename to patches/server/0992-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index f2c0d4389a..fe409f5c40 100644 --- a/patches/server/0993-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/patches/server/0992-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -13,10 +13,10 @@ custom renderers are in use, defaulting to the much simpler Vanilla system. Additionally, numerous issues to player position tracking on maps has been fixed. diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2e30f8a12391222e612a9c1bf56e93625f52a8dc..162671f8e370c84832b18697a1ef787981e1632d 100644 +index 7da9729a6ac0684624f900a9e47f24e35bd3f3d9..978208f74b6f1d3f859165e951d41013a5f00256 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2518,6 +2518,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2537,6 +2537,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. { if ( iter.next().player == entity ) { diff --git a/patches/server/0994-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/server/0993-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch similarity index 98% rename from patches/server/0994-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch rename to patches/server/0993-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch index 6f9e63f228..23a10511a6 100644 --- a/patches/server/0994-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch +++ b/patches/server/0993-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch @@ -62,7 +62,7 @@ index bb8e962e63c7a2d931f9bd7f7c002aa35cfa5fd3..0fa131a6c98adb498fc8d534e0e39647 default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) { // Paper start - Add predicate for blocks when raytracing diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 2dcd2f9085de19a91f32f161b89572ec1fbe4805..2809990109e624db95d400aba7a1cc588bc767c2 100644 +index 5b893b93a3495b13ae266fb8054d0a454cf02660..77b7c252d27f527d9b51e8419abe7af1d4b51d29 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -816,10 +816,87 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl diff --git a/patches/server/0995-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0994-Optimize-Network-Manager-and-add-advanced-packet-sup.patch similarity index 100% rename from patches/server/0995-Optimize-Network-Manager-and-add-advanced-packet-sup.patch rename to patches/server/0994-Optimize-Network-Manager-and-add-advanced-packet-sup.patch diff --git a/patches/server/0996-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0995-Allow-Saving-of-Oversized-Chunks.patch similarity index 100% rename from patches/server/0996-Allow-Saving-of-Oversized-Chunks.patch rename to patches/server/0995-Allow-Saving-of-Oversized-Chunks.patch diff --git a/patches/server/0997-Flat-bedrock-generator-settings.patch b/patches/server/0996-Flat-bedrock-generator-settings.patch similarity index 100% rename from patches/server/0997-Flat-bedrock-generator-settings.patch rename to patches/server/0996-Flat-bedrock-generator-settings.patch diff --git a/patches/server/0998-Entity-Activation-Range-2.0.patch b/patches/server/0997-Entity-Activation-Range-2.0.patch similarity index 98% rename from patches/server/0998-Entity-Activation-Range-2.0.patch rename to patches/server/0997-Entity-Activation-Range-2.0.patch index 588b66fec0..59596a9c67 100644 --- a/patches/server/0998-Entity-Activation-Range-2.0.patch +++ b/patches/server/0997-Entity-Activation-Range-2.0.patch @@ -17,7 +17,7 @@ Adds villagers as separate config public net.minecraft.world.entity.Entity isInsidePortal diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d6732352f0c 100644 +index 978208f74b6f1d3f859165e951d41013a5f00256..1196eb573317ad01b6df0ae2d38aa17a72da2535 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2,7 +2,6 @@ package net.minecraft.server.level; @@ -28,7 +28,7 @@ index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d67 import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; -@@ -1216,17 +1215,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1235,17 +1234,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. ++TimingHistory.entityTicks; // Paper - timings // Spigot start co.aikar.timings.Timing timer; // Paper @@ -50,7 +50,7 @@ index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d67 try { // Paper end - timings entity.setOldPosAndRot(); -@@ -1237,9 +1236,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1256,9 +1255,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickNonPassenger"); @@ -64,7 +64,7 @@ index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d67 Iterator iterator = entity.getPassengers().iterator(); while (iterator.hasNext()) { -@@ -1247,13 +1250,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1266,13 +1269,18 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(entity, entity1); } @@ -84,7 +84,7 @@ index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d67 passenger.setOldPosAndRot(); ++passenger.tickCount; ProfilerFiller gameprofilerfiller = this.getProfiler(); -@@ -1262,8 +1270,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1281,8 +1289,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString(); }); gameprofilerfiller.incrementCounter("tickPassenger"); @@ -102,7 +102,7 @@ index 162671f8e370c84832b18697a1ef787981e1632d..8b6a1a80a3bf95e7f17c6b64d0949d67 gameprofilerfiller.pop(); Iterator iterator = passenger.getPassengers().iterator(); -@@ -1273,6 +1290,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1292,6 +1309,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(passenger, entity2); } @@ -340,7 +340,7 @@ index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d + } diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 2809990109e624db95d400aba7a1cc588bc767c2..bd1f7cf95288a15b2a06a93878303b03ac603e5e 100644 +index 77b7c252d27f527d9b51e8419abe7af1d4b51d29..ecf2f478932c9ccc5a7ac47c8f17bd44217c703b 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -157,6 +157,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl diff --git a/patches/server/0999-Optional-per-player-mob-spawns.patch b/patches/server/0998-Optional-per-player-mob-spawns.patch similarity index 91% rename from patches/server/0999-Optional-per-player-mob-spawns.patch rename to patches/server/0998-Optional-per-player-mob-spawns.patch index 807e87ea3f..a5b1729654 100644 --- a/patches/server/0999-Optional-per-player-mob-spawns.patch +++ b/patches/server/0998-Optional-per-player-mob-spawns.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Optional per player mob spawns diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index d843bc04ae93d11d7820cab5ed18617193568f0d..152cd6b1671785b495caeb7e535f58df864ce24c 100644 +index edb36dee707433d4f9419aef6ac6cc0bec5f285e..c282566ee45d79b4fb3297989e054c803873a294 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -256,8 +256,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - return this.nearbyPlayers; +@@ -223,8 +223,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } + // Paper start + // Paper start - Optional per player mob spawns + public void updatePlayerMobTypeMap(final Entity entity) { + if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { @@ -19,14 +19,14 @@ index d843bc04ae93d11d7820cab5ed18617193568f0d..152cd6b1671785b495caeb7e535f58df + } + final int index = entity.getType().getCategory().ordinal(); + -+ final com.destroystokyo.paper.util.maplist.ReferenceList inRange = -+ this.getNearbyPlayers().getPlayers(entity.chunkPosition(), io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); ++ final ca.spottedleaf.moonrise.common.list.ReferenceList inRange = ++ this.level.moonrise$getNearbyPlayers().getPlayers(entity.chunkPosition(), ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); + if (inRange == null) { + return; + } -+ final Object[] backingSet = inRange.getRawData(); ++ final ServerPlayer[] backingSet = inRange.getRawDataUnchecked(); + for (int i = 0, len = inRange.size(); i < len; i++) { -+ ++((ServerPlayer)backingSet[i]).mobCounts[index]; ++ ++(backingSet[i].mobCounts[index]); + } + } public int getMobCountNear(final ServerPlayer player, final net.minecraft.world.entity.MobCategory mobCategory) { @@ -37,10 +37,10 @@ index d843bc04ae93d11d7820cab5ed18617193568f0d..152cd6b1671785b495caeb7e535f58df // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index d2cb358c340bcf7532fd25eccdd33c6945d16de4..2211c054f55e962082eac82aedf5ca625e5b25f2 100644 +index 9aec513f05b10e78579f79ccda6acf285f13222e..96a03770d47c47e07615815bcc3d474d6cd7711b 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -439,7 +439,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -437,7 +437,19 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon gameprofilerfiller.popPush("naturalSpawnCount"); this.level.timings.countNaturalMobs.startTiming(); // Paper - timings int k = this.distanceManager.getNaturalSpawnChunkCount(); @@ -62,7 +62,7 @@ index d2cb358c340bcf7532fd25eccdd33c6945d16de4..2211c054f55e962082eac82aedf5ca62 this.lastSpawnState = spawnercreature_d; diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index ba64e42a58b4b760815f54228ebf7a46fd14734e..6277ec3353c6e552b898b525ce2af76a0c84943d 100644 +index fd61e10fd3151bf8cc206a93d4ede22a7c681dbf..23ddb7735623e502eda2b7b3029c6597f4b0f9a0 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -275,6 +275,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -77,7 +77,7 @@ index ba64e42a58b4b760815f54228ebf7a46fd14734e..6277ec3353c6e552b898b525ce2af76a // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index ea6533c1ac218aa075da3401807a06fcb7892321..0679636530ca1afd077c43b0fa605a2ac74e0522 100644 +index ea6533c1ac218aa075da3401807a06fcb7892321..364510c0d0667e67aa3b25099a021f5f856fc113 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -67,6 +67,12 @@ public final class NaturalSpawner { @@ -123,12 +123,12 @@ index ea6533c1ac218aa075da3401807a06fcb7892321..0679636530ca1afd077c43b0fa605a2a + + if (world.paperConfig().entities.spawning.perPlayerMobSpawns) { + int minDiff = Integer.MAX_VALUE; -+ final com.destroystokyo.paper.util.maplist.ReferenceList inRange = -+ world.chunkSource.chunkMap.getNearbyPlayers().getPlayers(chunk.getPos(), io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); ++ final ca.spottedleaf.moonrise.common.list.ReferenceList inRange = ++ world.moonrise$getNearbyPlayers().getPlayers(chunk.getPos(), ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); + if (inRange != null) { -+ final Object[] backingSet = inRange.getRawData(); ++ final net.minecraft.server.level.ServerPlayer[] backingSet = inRange.getRawDataUnchecked(); + for (int k = 0, len = inRange.size(); k < len; k++) { -+ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear((net.minecraft.server.level.ServerPlayer)backingSet[k], enumcreaturetype), minDiff); ++ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(backingSet[k], enumcreaturetype), minDiff); + } + } + difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; diff --git a/patches/server/1000-Anti-Xray.patch b/patches/server/0999-Anti-Xray.patch similarity index 99% rename from patches/server/1000-Anti-Xray.patch rename to patches/server/0999-Anti-Xray.patch index bacd340c00..ad8ecc1c7a 100644 --- a/patches/server/1000-Anti-Xray.patch +++ b/patches/server/0999-Anti-Xray.patch @@ -1104,10 +1104,10 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72 private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 8b6a1a80a3bf95e7f17c6b64d0949d6732352f0c..6a844382882a69bfc690b956fa8d59c2d0ea0bd3 100644 +index 1196eb573317ad01b6df0ae2d38aa17a72da2535..a5320b96148d79f8d2493060718688786466e6dd 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -515,7 +515,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -534,7 +534,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. // Holder holder = worlddimension.type(); // CraftBukkit - decompile error // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error @@ -1168,7 +1168,7 @@ index 9b1a6d8351fb473eec75a2fd08fb892b770e3586..0d0b07c9199be9ca0d5ac3feb1d44f14 } // Paper end - Send empty chunk diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index bd1f7cf95288a15b2a06a93878303b03ac603e5e..d077b7be012af2092caa6fe9c56f4ac712d27874 100644 +index ecf2f478932c9ccc5a7ac47c8f17bd44217c703b..ae7cd8df617dba09abb9ca1108aff719a9c3304f 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -1231,7 +1231,7 @@ index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821 } diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 214bb6759d2670042d87b2fd0aae41df600a95ee..d4429eedd9164d4b7c367345a8c662a1129d0430 100644 +index 3fa7bfa09b9d529b5cb9cad923f21343159cfa35..8c865cd4e50ad55679a8bd89835caa40cc101f35 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -91,7 +91,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -1510,7 +1510,7 @@ index 9a2bf744abd8916d492e901be889223591bac3fd..1dd415c96d17eff8e7555c33d3c52e57 int getSerializedSize(); diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 977bebe8657abc5cb84ede8276d6781cde20e847..6d461849da76894244e6212a75da0c6e4fb459c3 100644 +index cb5196f0ff7b9a59927c60b9d24c987a150e69f1..711541a9b12b823c1da779ed6027a53e9078a733 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java @@ -73,7 +73,7 @@ import org.slf4j.Logger; @@ -1574,7 +1574,7 @@ index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd12 private static final byte[] EMPTY_LIGHT = new byte[2048]; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 05e44a1448f30ceb8cecba2bed76f51aac5543f9..caf6ff33b42472d30f28629470e12889f50490cc 100644 +index 06215f56f1cae5197c827b8100432ab2ef9aa976..81fa2bab6841ab375ff310d0fbbe6349fd44872a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2677,7 +2677,7 @@ public final class CraftServer implements Server { @@ -1587,7 +1587,7 @@ index 05e44a1448f30ceb8cecba2bed76f51aac5543f9..caf6ff33b42472d30f28629470e12889 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index cdc704364cf339084537d089e654f6078f8be783..fe9e8d1d4ae1f7a4e8f4cf5688004fc969422b3c 100644 +index 5ad2ceb1274648631689215702a12463c681152c..86ed89a2eae5f36d902cd8dc4bd0389e066b4bba 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -465,11 +465,16 @@ public class CraftWorld extends CraftRegionAccessor implements World { diff --git a/patches/server/1001-Eigencraft-redstone-implementation.patch b/patches/server/1000-Eigencraft-redstone-implementation.patch similarity index 100% rename from patches/server/1001-Eigencraft-redstone-implementation.patch rename to patches/server/1000-Eigencraft-redstone-implementation.patch diff --git a/patches/server/1002-Add-Alternate-Current-redstone-implementation.patch b/patches/server/1001-Add-Alternate-Current-redstone-implementation.patch similarity index 99% rename from patches/server/1002-Add-Alternate-Current-redstone-implementation.patch rename to patches/server/1001-Add-Alternate-Current-redstone-implementation.patch index 3aeaef70d8..17df7da36c 100644 --- a/patches/server/1002-Add-Alternate-Current-redstone-implementation.patch +++ b/patches/server/1001-Add-Alternate-Current-redstone-implementation.patch @@ -2009,7 +2009,7 @@ index 0000000000000000000000000000000000000000..33cd90c30c22200a4e1ae64f40a0bf78 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 6a844382882a69bfc690b956fa8d59c2d0ea0bd3..a994456adb0034c0662151f4ae28c1c06f91333e 100644 +index a5320b96148d79f8d2493060718688786466e6dd..472655c55b1f5c213da9b6c1940a353bafdac509 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -228,6 +228,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. @@ -2020,7 +2020,7 @@ index 6a844382882a69bfc690b956fa8d59c2d0ea0bd3..a994456adb0034c0662151f4ae28c1c0 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately -@@ -2449,6 +2450,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2468,6 +2469,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. return crashreportsystemdetails; } @@ -2035,7 +2035,7 @@ index 6a844382882a69bfc690b956fa8d59c2d0ea0bd3..a994456adb0034c0662151f4ae28c1c0 EntityCallbacks() {} diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index d077b7be012af2092caa6fe9c56f4ac712d27874..20a7971b75ee39bceedf7670a5c600fd014db4cb 100644 +index ae7cd8df617dba09abb9ca1108aff719a9c3304f..9501a2527bb0db91dd5494ccb4066b9629993e59 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -2013,4 +2013,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl diff --git a/patches/server/1003-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/patches/server/1002-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 84% rename from patches/server/1003-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to patches/server/1002-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 83f592b0c7..e670998b87 100644 --- a/patches/server/1003-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/patches/server/1002-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -6,11 +6,11 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 152cd6b1671785b495caeb7e535f58df864ce24c..344966d3deb640eb99bc9c9e318e6e6780421907 100644 +index c282566ee45d79b4fb3297989e054c803873a294..dc64227e3b0d7855ef8870935aa437b78eea2407 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -273,8 +273,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - ++((ServerPlayer)backingSet[i]).mobCounts[index]; +@@ -240,8 +240,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + ++(backingSet[i].mobCounts[index]); } } + // Paper start - per player mob count backoff @@ -19,14 +19,14 @@ index 152cd6b1671785b495caeb7e535f58df864ce24c..344966d3deb640eb99bc9c9e318e6e67 + return; + } + int idx = mobCategory.ordinal(); -+ final com.destroystokyo.paper.util.maplist.ReferenceList inRange = -+ this.getNearbyPlayers().getPlayersByChunk(chunkX, chunkZ, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); ++ final ca.spottedleaf.moonrise.common.list.ReferenceList inRange = ++ this.level.moonrise$getNearbyPlayers().getPlayersByChunk(chunkX, chunkZ, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.TICK_VIEW_DISTANCE); + if (inRange == null) { + return; + } -+ final Object[] backingSet = inRange.getRawData(); ++ final ServerPlayer[] backingSet = inRange.getRawDataUnchecked(); + for (int i = 0, len = inRange.size(); i < len; i++) { -+ ++((ServerPlayer)backingSet[i]).mobBackoffCounts[idx]; ++ ++(backingSet[i].mobBackoffCounts[idx]); + } + } + // Paper end - per player mob count backoff @@ -37,10 +37,10 @@ index 152cd6b1671785b495caeb7e535f58df864ce24c..344966d3deb640eb99bc9c9e318e6e67 } // Paper end diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 2211c054f55e962082eac82aedf5ca625e5b25f2..61e222fb129c5733411ce95aaa5f035dbd95b01a 100644 +index 96a03770d47c47e07615815bcc3d474d6cd7711b..5f195875564822f422127462fbbeea5df4a4e1cb 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -445,7 +445,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -443,7 +443,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled // re-set mob counts for (ServerPlayer player : this.level.players) { @@ -60,7 +60,7 @@ index 2211c054f55e962082eac82aedf5ca625e5b25f2..61e222fb129c5733411ce95aaa5f035d spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); } else { diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 6277ec3353c6e552b898b525ce2af76a0c84943d..9d1e68c09fa7093cf0f6fa636f90cb15a44cbb38 100644 +index 23ddb7735623e502eda2b7b3029c6597f4b0f9a0..13ec84754b4fb5e8442fe305d70a24e420945181 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -279,6 +279,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple @@ -72,7 +72,7 @@ index 6277ec3353c6e552b898b525ce2af76a0c84943d..9d1e68c09fa7093cf0f6fa636f90cb15 // CraftBukkit start public CraftPlayer.TransferCookieConnection transferCookieConnection; diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 0679636530ca1afd077c43b0fa605a2ac74e0522..ed8032495af9ce9c23419224814b8d27e4a97c17 100644 +index 364510c0d0667e67aa3b25099a021f5f856fc113..e524b27d185da3e88668f8ef107517272860bd66 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java @@ -272,6 +272,11 @@ public final class NaturalSpawner { diff --git a/patches/server/1004-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/1003-Use-Velocity-compression-and-cipher-natives.patch similarity index 100% rename from patches/server/1004-Use-Velocity-compression-and-cipher-natives.patch rename to patches/server/1003-Use-Velocity-compression-and-cipher-natives.patch diff --git a/patches/server/1005-Optimize-Collision-to-not-load-chunks.patch b/patches/server/1004-Optimize-Collision-to-not-load-chunks.patch similarity index 100% rename from patches/server/1005-Optimize-Collision-to-not-load-chunks.patch rename to patches/server/1004-Optimize-Collision-to-not-load-chunks.patch diff --git a/patches/server/1006-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/1005-Optimize-GoalSelector-Goal.Flag-Set-operations.patch similarity index 80% rename from patches/server/1006-Optimize-GoalSelector-Goal.Flag-Set-operations.patch rename to patches/server/1005-Optimize-GoalSelector-Goal.Flag-Set-operations.patch index 1f46712639..65f5e3531e 100644 --- a/patches/server/1006-Optimize-GoalSelector-Goal.Flag-Set-operations.patch +++ b/patches/server/1005-Optimize-GoalSelector-Goal.Flag-Set-operations.patch @@ -7,7 +7,7 @@ Optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation. diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java -index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..dd423302b1baa64ef86ded87a29659342e28c142 100644 +index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..47741efa48258c3c30b1d59504bf3121c236cadb 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java @@ -4,7 +4,16 @@ import java.util.EnumSet; @@ -16,12 +16,12 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..dd423302b1baa64ef86ded87a2965934 public abstract class Goal { - private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); + private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. -+ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector ++ private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector + + // Paper start - remove streams from pathfindergoalselector; make sure types are not empty + public Goal() { + if (this.goalTypes.size() == 0) { -+ this.goalTypes.add(Flag.UNKNOWN_BEHAVIOR); ++ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR); + } + } + // Paper end - remove streams from pathfindergoalselector @@ -36,9 +36,9 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..dd423302b1baa64ef86ded87a2965934 - this.flags.addAll(controls); + // Paper start - remove streams from pathfindergoalselector + this.goalTypes.clear(); -+ this.goalTypes.addAll(controls); ++ this.goalTypes.addAllUnchecked(controls); + if (this.goalTypes.size() == 0) { -+ this.goalTypes.add(Flag.UNKNOWN_BEHAVIOR); ++ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR); + } + // Paper end - remove streams from pathfindergoalselector } @@ -51,14 +51,14 @@ index 16f9a98b8a939e5ca7e2dc04f87134a7ed66736b..dd423302b1baa64ef86ded87a2965934 - public EnumSet getFlags() { - return this.flags; + // Paper start - remove streams from pathfindergoalselector -+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet getFlags() { ++ public ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet getFlags() { + return this.goalTypes; + // Paper end - remove streams from pathfindergoalselector } protected int adjustedTickDelay(int ticks) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337402f7025 100644 +index 074ef807258139f818e30494126585262c2f33c0..9bdbf3e9453bc3ce96d52d04b8cde0d05f7356d8 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -25,7 +25,8 @@ public class GoalSelector { @@ -67,7 +67,7 @@ index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337 private final Supplier profiler; - private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); + private static final Goal.Flag[] GOAL_FLAG_VALUES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector -+ private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector ++ private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector private int curRate; public GoalSelector(Supplier profiler) { @@ -84,7 +84,7 @@ index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337 - - return false; + // Paper start -+ private static boolean goalContainsAnyFlags(WrappedGoal goal, com.destroystokyo.paper.util.set.OptimizedSmallEnumSet controls) { ++ private static boolean goalContainsAnyFlags(WrappedGoal goal, ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet controls) { + return goal.getFlags().hasCommonElements(controls); } @@ -94,7 +94,7 @@ index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337 + int wrappedGoalSize = goal.getFlags().size(); + for (int i = 0; i < wrappedGoalSize; ++i) { + final Goal.Flag flag = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)]; -+ flagIterator ^= io.papermc.paper.util.IntegerUtil.getTrailingBit(flagIterator); ++ flagIterator ^= ca.spottedleaf.concurrentutil.util.IntegerUtil.getTrailingBit(flagIterator); + // Paper end if (!goalsByControl.getOrDefault(flag, NO_GOAL).canBeReplacedBy(goal)) { return false; @@ -123,7 +123,7 @@ index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337 + int wrappedGoalSize = wrappedGoal2.getFlags().size(); + for (int i = 0; i < wrappedGoalSize; ++i) { + final Goal.Flag flag = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)]; -+ flagIterator ^= io.papermc.paper.util.IntegerUtil.getTrailingBit(flagIterator); ++ flagIterator ^= ca.spottedleaf.concurrentutil.util.IntegerUtil.getTrailingBit(flagIterator); + // Paper end WrappedGoal wrappedGoal3 = this.lockedFlags.getOrDefault(flag, NO_GOAL); wrappedGoal3.stop(); @@ -133,17 +133,17 @@ index 074ef807258139f818e30494126585262c2f33c0..74d4f653d5c7f1923c59019effd78337 public void disableControlFlag(Goal.Flag control) { - this.disabledFlags.add(control); -+ this.goalTypes.add(control); // Paper - remove streams from pathfindergoalselector ++ this.goalTypes.addUnchecked(control); // Paper - remove streams from pathfindergoalselector } public void enableControlFlag(Goal.Flag control) { - this.disabledFlags.remove(control); -+ this.goalTypes.remove(control); // Paper - remove streams from pathfindergoalselector ++ this.goalTypes.removeUnchecked(control); // Paper - remove streams from pathfindergoalselector } public void setControlFlag(Goal.Flag control, boolean enabled) { diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java -index b02d3deb550830245c8945ef17d3073ea930fdda..65ccdbaa5230c02d44a5959bca0f6fc30237a6fd 100644 +index b02d3deb550830245c8945ef17d3073ea930fdda..8cf2e0db6b2f7d3a50f2ac1c3f4f0c6c2434b5ba 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java @@ -69,8 +69,10 @@ public class WrappedGoal extends Goal { @@ -152,7 +152,7 @@ index b02d3deb550830245c8945ef17d3073ea930fdda..65ccdbaa5230c02d44a5959bca0f6fc3 @Override - public EnumSet getFlags() { + // Paper start - remove streams from pathfindergoalselector -+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet getFlags() { ++ public ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet getFlags() { return this.goal.getFlags(); + // Paper end - remove streams from pathfindergoalselector } diff --git a/patches/server/1007-Optimize-Hoppers.patch b/patches/server/1006-Optimize-Hoppers.patch similarity index 99% rename from patches/server/1007-Optimize-Hoppers.patch rename to patches/server/1006-Optimize-Hoppers.patch index 7203ad1a95..dc55a79c71 100644 --- a/patches/server/1007-Optimize-Hoppers.patch +++ b/patches/server/1006-Optimize-Hoppers.patch @@ -50,10 +50,10 @@ index 0000000000000000000000000000000000000000..5c42823726e70ce6c9d0121d07431548 + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 91cc3eb6db2875710064f6b31413ccc84af56bb2..17b0e570016504d1b7704bbfa9ff2e3233b45d09 100644 +index 4a4ce372dd105d07f58d7d93d856cb3969969806..fb3dcce4e1888f96fdd260740d9d955962d879fc 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1722,6 +1722,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent diff --git a/patches/server/1008-Entity-load-save-limit-per-chunk.patch b/patches/server/1007-Entity-load-save-limit-per-chunk.patch similarity index 100% rename from patches/server/1008-Entity-load-save-limit-per-chunk.patch rename to patches/server/1007-Entity-load-save-limit-per-chunk.patch diff --git a/patches/server/1009-Optimize-Voxel-Shape-Merging.patch b/patches/server/1008-Optimize-Voxel-Shape-Merging.patch similarity index 100% rename from patches/server/1009-Optimize-Voxel-Shape-Merging.patch rename to patches/server/1008-Optimize-Voxel-Shape-Merging.patch diff --git a/patches/server/1010-Optimize-Bit-Operations-by-inlining.patch b/patches/server/1009-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from patches/server/1010-Optimize-Bit-Operations-by-inlining.patch rename to patches/server/1009-Optimize-Bit-Operations-by-inlining.patch diff --git a/patches/server/1011-Remove-streams-from-hot-code.patch b/patches/server/1010-Remove-streams-from-hot-code.patch similarity index 100% rename from patches/server/1011-Remove-streams-from-hot-code.patch rename to patches/server/1010-Remove-streams-from-hot-code.patch diff --git a/patches/server/1012-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/1011-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from patches/server/1012-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to patches/server/1011-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/patches/server/1013-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/server/1012-Custom-table-implementation-for-blockstate-state-loo.patch similarity index 100% rename from patches/server/1013-Custom-table-implementation-for-blockstate-state-loo.patch rename to patches/server/1012-Custom-table-implementation-for-blockstate-state-loo.patch diff --git a/patches/server/1014-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/1013-Fix-entity-type-tags-suggestions-in-selectors.patch similarity index 100% rename from patches/server/1014-Fix-entity-type-tags-suggestions-in-selectors.patch rename to patches/server/1013-Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/1015-Handle-Oversized-block-entities-in-chunks.patch b/patches/server/1014-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from patches/server/1015-Handle-Oversized-block-entities-in-chunks.patch rename to patches/server/1014-Handle-Oversized-block-entities-in-chunks.patch diff --git a/patches/server/1016-API-for-checking-sent-chunks.patch b/patches/server/1015-API-for-checking-sent-chunks.patch similarity index 93% rename from patches/server/1016-API-for-checking-sent-chunks.patch rename to patches/server/1015-API-for-checking-sent-chunks.patch index 5129c9a08a..ea42e9e7d9 100644 --- a/patches/server/1016-API-for-checking-sent-chunks.patch +++ b/patches/server/1015-API-for-checking-sent-chunks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] API for checking sent chunks diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index f063ab3ff122b920bcc4aa4f5bf9a442a8eb32fd..95d2d4417591b921d1ddf73025565cff6aabddd7 100644 +index 244674dc44d80ee5ce78d2ed2c6ab94fd5d3d07f..bdf9244ab7e62f5d6cdd6e21e1a5daee1ddb37f4 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -1072,5 +1072,10 @@ public final class RegionizedPlayerChunkLoader { @@ -20,7 +20,7 @@ index f063ab3ff122b920bcc4aa4f5bf9a442a8eb32fd..95d2d4417591b921d1ddf73025565cff } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 62bfde27a182be24710eb3b72448e82da58afc8f..d01b45a48d412e3cb591acee101730704574448a 100644 +index 4e7da1be4acf1028022e62a652df3e262a85fa0f..a62ed0a348c22c1f315ca0deba63f7c2d09b709e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -3484,6 +3484,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { diff --git a/patches/server/1017-Check-distance-in-entity-interactions.patch b/patches/server/1016-Check-distance-in-entity-interactions.patch similarity index 100% rename from patches/server/1017-Check-distance-in-entity-interactions.patch rename to patches/server/1016-Check-distance-in-entity-interactions.patch diff --git a/patches/server/1018-Configurable-Sand-Duping.patch b/patches/server/1017-Configurable-Sand-Duping.patch similarity index 100% rename from patches/server/1018-Configurable-Sand-Duping.patch rename to patches/server/1017-Configurable-Sand-Duping.patch diff --git a/patches/server/1019-Optimise-general-POI-access.patch b/patches/server/1018-Optimise-general-POI-access.patch similarity index 99% rename from patches/server/1019-Optimise-general-POI-access.patch rename to patches/server/1018-Optimise-general-POI-access.patch index f8e4fb9c3d..b3636fe591 100644 --- a/patches/server/1019-Optimise-general-POI-access.patch +++ b/patches/server/1018-Optimise-general-POI-access.patch @@ -32,12 +32,14 @@ had to be specifically modified. diff --git a/src/main/java/io/papermc/paper/util/PoiAccess.java b/src/main/java/io/papermc/paper/util/PoiAccess.java new file mode 100644 -index 0000000000000000000000000000000000000000..d8190b56d216b0e48bfc2d5739bdf533bf95b425 +index 0000000000000000000000000000000000000000..f39294b1f83c4022be5ced4da781103a1eee2daf --- /dev/null +++ b/src/main/java/io/papermc/paper/util/PoiAccess.java -@@ -0,0 +1,804 @@ +@@ -0,0 +1,806 @@ +package io.papermc.paper.util; + ++import ca.spottedleaf.moonrise.common.util.CoordinateUtils; ++import ca.spottedleaf.moonrise.common.util.WorldUtil; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.doubles.Double2ObjectMap; +import it.unimi.dsi.fastutil.doubles.Double2ObjectRBTreeMap; @@ -884,7 +886,7 @@ index d5a549f08b98c80a5cf0eef02cb8a389c32dfecb..92731b6b593289e9f583c9b705b219e8 BlockPos blockPos = path.getTarget(); Optional> optional = poiManager.getType(blockPos); diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 274ddf479d38495d84838f9cd73c13d2841c3b44..0be7346f9c5e89ea03c69f7c8ba4733d2c7759fc 100644 +index d7a6eab60bf26916f78f858e224573560e581fef..a908bf1dc5e821dcf6981a8c21076fb0bdc6516d 100644 --- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java +++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java @@ -268,36 +268,45 @@ public class PoiManager extends SectionStorage implements ca.spotted diff --git a/patches/server/1020-Improve-performance-of-mass-crafts.patch b/patches/server/1019-Improve-performance-of-mass-crafts.patch similarity index 100% rename from patches/server/1020-Improve-performance-of-mass-crafts.patch rename to patches/server/1019-Improve-performance-of-mass-crafts.patch diff --git a/patches/server/1021-Properly-resend-entities.patch b/patches/server/1020-Properly-resend-entities.patch similarity index 100% rename from patches/server/1021-Properly-resend-entities.patch rename to patches/server/1020-Properly-resend-entities.patch diff --git a/patches/server/1022-Registry-Modification-API.patch b/patches/server/1021-Registry-Modification-API.patch similarity index 100% rename from patches/server/1022-Registry-Modification-API.patch rename to patches/server/1021-Registry-Modification-API.patch diff --git a/patches/server/1023-Add-registry-entry-and-builders.patch b/patches/server/1022-Add-registry-entry-and-builders.patch similarity index 100% rename from patches/server/1023-Add-registry-entry-and-builders.patch rename to patches/server/1022-Add-registry-entry-and-builders.patch diff --git a/patches/server/1024-Improved-Watchdog-Support.patch b/patches/server/1023-Improved-Watchdog-Support.patch similarity index 95% rename from patches/server/1024-Improved-Watchdog-Support.patch rename to patches/server/1023-Improved-Watchdog-Support.patch index 2e3fc383a2..2a66e33d6e 100644 --- a/patches/server/1024-Improved-Watchdog-Support.patch +++ b/patches/server/1023-Improved-Watchdog-Support.patch @@ -71,7 +71,7 @@ index 589a8bf75be6ccc59f1e5dd5d8d9afed41c4772d..b24265573fdef5d9a964bcd76146f345 cause = cause.getCause(); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 17b0e570016504d1b7704bbfa9ff2e3233b45d09..5d41801c2378ac27b67b977a8ab30158b717d4d3 100644 +index fb3dcce4e1888f96fdd260740d9d955962d879fc..25300f6011c213b67876552abcb12c290d586fe4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -307,7 +307,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); - Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system + Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system @@ -1005,6 +1008,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0 && new File( split[0] ).isFile() ) diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index bab2bd91528a8b2e9e74a3f9eb061d52619102f6..8ef5c345b7ba5ef869a1b0468f431c0f47cf2319 100644 +index 529df2a41dd93d6e1505053bd04032dbf0cdaa31..c9e17225bc52fe5e7b2dc0908db225a86c6e94d1 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -11,6 +11,7 @@ import org.bukkit.Bukkit; - public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - rewrite chunk system + public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThread // Paper - rewrite chunk system { + public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper - Improved watchdog support private static WatchdogThread instance; private long timeoutTime; private boolean restart; -@@ -39,6 +40,7 @@ public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - +@@ -39,6 +40,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre { if ( WatchdogThread.instance == null ) { @@ -367,7 +367,7 @@ index bab2bd91528a8b2e9e74a3f9eb061d52619102f6..8ef5c345b7ba5ef869a1b0468f431c0f WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart ); WatchdogThread.instance.start(); } else -@@ -70,12 +72,13 @@ public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - +@@ -70,12 +72,13 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre // Paper start Logger log = Bukkit.getServer().getLogger(); long currentTime = WatchdogThread.monotonicMillis(); @@ -384,7 +384,7 @@ index bab2bd91528a8b2e9e74a3f9eb061d52619102f6..8ef5c345b7ba5ef869a1b0468f431c0f lastEarlyWarning = currentTime; if (isLongTimeout) { // Paper end -@@ -136,9 +139,24 @@ public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - +@@ -136,9 +139,24 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre if ( isLongTimeout ) { diff --git a/patches/server/1025-Proxy-ItemStack-to-CraftItemStack.patch b/patches/server/1024-Proxy-ItemStack-to-CraftItemStack.patch similarity index 100% rename from patches/server/1025-Proxy-ItemStack-to-CraftItemStack.patch rename to patches/server/1024-Proxy-ItemStack-to-CraftItemStack.patch diff --git a/patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch b/patches/server/1025-Make-a-PDC-view-accessible-directly-from-ItemStack.patch similarity index 100% rename from patches/server/1026-Make-a-PDC-view-accessible-directly-from-ItemStack.patch rename to patches/server/1025-Make-a-PDC-view-accessible-directly-from-ItemStack.patch diff --git a/patches/server/1027-Prioritize-Minecraft-commands-in-function-parsing-an.patch b/patches/server/1026-Prioritize-Minecraft-commands-in-function-parsing-an.patch similarity index 100% rename from patches/server/1027-Prioritize-Minecraft-commands-in-function-parsing-an.patch rename to patches/server/1026-Prioritize-Minecraft-commands-in-function-parsing-an.patch diff --git a/patches/server/1028-optimize-dirt-and-snow-spreading.patch b/patches/server/1027-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from patches/server/1028-optimize-dirt-and-snow-spreading.patch rename to patches/server/1027-optimize-dirt-and-snow-spreading.patch diff --git a/patches/server/1029-Fix-NPE-for-Jukebox-setRecord.patch b/patches/server/1028-Fix-NPE-for-Jukebox-setRecord.patch similarity index 100% rename from patches/server/1029-Fix-NPE-for-Jukebox-setRecord.patch rename to patches/server/1028-Fix-NPE-for-Jukebox-setRecord.patch diff --git a/patches/server/1030-Fix-CraftWorld-isChunkGenerated.patch b/patches/server/1029-Fix-CraftWorld-isChunkGenerated.patch similarity index 92% rename from patches/server/1030-Fix-CraftWorld-isChunkGenerated.patch rename to patches/server/1029-Fix-CraftWorld-isChunkGenerated.patch index f91e8b2bd0..48ae6e61ad 100644 --- a/patches/server/1030-Fix-CraftWorld-isChunkGenerated.patch +++ b/patches/server/1029-Fix-CraftWorld-isChunkGenerated.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Fix CraftWorld#isChunkGenerated The upstream implementation is returning true for non-full chunks. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index fe9e8d1d4ae1f7a4e8f4cf5688004fc969422b3c..8045d6c9398d1c88595da6e41aa1ed27fb6fbad0 100644 +index 86ed89a2eae5f36d902cd8dc4bd0389e066b4bba..362ca138a5cd5ad19f1300015c2571794adc3649 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -367,11 +367,28 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -28,7 +28,7 @@ index fe9e8d1d4ae1f7a4e8f4cf5688004fc969422b3c..8045d6c9398d1c88595da6e41aa1ed27 + return chunk instanceof ImposterProtoChunk || chunk instanceof net.minecraft.world.level.chunk.LevelChunk; } + final java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); -+ ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystem.scheduleChunkLoad( ++ ca.spottedleaf.moonrise.common.util.ChunkSystem.scheduleChunkLoad( + this.world, x, z, false, ChunkStatus.EMPTY, true, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, future::complete + ); + world.getChunkSource().mainThreadProcessor.managedBlock(future::isDone); diff --git a/patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch b/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch similarity index 92% rename from patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch rename to patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch index 401b927f05..206968f773 100644 --- a/patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch +++ b/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch @@ -14,10 +14,10 @@ on chunk holder remove if the holder is present in the unload queue and log the stacktrace. diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index d5fc5756ea960096ff23376a6b7ac68a2a462d22..0715514c8bb49c805b04f42ff37903a7d590aaa8 100644 +index 1dfddea4fd7e89fb6fd9fa49f7ab5e6f48e6ef3c..4068138e4ec0ccb02f5925f8b5a31381882f08e0 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -748,9 +748,22 @@ public final class NewChunkHolder { +@@ -749,9 +749,22 @@ public final class NewChunkHolder { /** Unloaded from chunk map */ private boolean unloaded; @@ -40,7 +40,7 @@ index d5fc5756ea960096ff23376a6b7ac68a2a462d22..0715514c8bb49c805b04f42ff37903a7 } private boolean inUnloadQueue = false; -@@ -768,12 +781,14 @@ public final class NewChunkHolder { +@@ -769,12 +782,14 @@ public final class NewChunkHolder { // ensure in unload queue if (!this.inUnloadQueue) { this.inUnloadQueue = true; diff --git a/patches/server/1032-fix-horse-inventories.patch b/patches/server/1031-fix-horse-inventories.patch similarity index 100% rename from patches/server/1032-fix-horse-inventories.patch rename to patches/server/1031-fix-horse-inventories.patch diff --git a/patches/server/1033-Only-call-EntityDamageEvents-before-actuallyHurt.patch b/patches/server/1032-Only-call-EntityDamageEvents-before-actuallyHurt.patch similarity index 100% rename from patches/server/1033-Only-call-EntityDamageEvents-before-actuallyHurt.patch rename to patches/server/1032-Only-call-EntityDamageEvents-before-actuallyHurt.patch diff --git a/patches/server/1034-Fix-entity-tracker-desync-when-new-players-are-added.patch b/patches/server/1033-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 97% rename from patches/server/1034-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to patches/server/1033-Fix-entity-tracker-desync-when-new-players-are-added.patch index 024bf5125d..5dfbf91a2f 100644 --- a/patches/server/1034-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/patches/server/1033-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -48,10 +48,10 @@ index 1a5e73fd97781f3903e5ef13aa0352c64fbc2cc1..4126d82e83810126eb4a41b4587dc993 entityTrackerEntry.getLastSentYRot(), entity.getType(), diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 344966d3deb640eb99bc9c9e318e6e6780421907..6df79aab2f0a75bbe347dc92e9ed5d62ceec7983 100644 +index dc64227e3b0d7855ef8870935aa437b78eea2407..4799af2ce8f44e8f99365323d57f099c551a5eb7 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1302,6 +1302,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1269,6 +1269,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider this.serverEntity.addPairing(player); } // Paper end - entity tracking events diff --git a/patches/server/1035-Lag-compensation-ticks.patch b/patches/server/1034-Lag-compensation-ticks.patch similarity index 95% rename from patches/server/1035-Lag-compensation-ticks.patch rename to patches/server/1034-Lag-compensation-ticks.patch index 34a7372bd6..ad77998efa 100644 --- a/patches/server/1035-Lag-compensation-ticks.patch +++ b/patches/server/1034-Lag-compensation-ticks.patch @@ -8,7 +8,7 @@ Areas affected by lag comepnsation: - Eating food items diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 5d41801c2378ac27b67b977a8ab30158b717d4d3..c0935474538849b9274fab8fad13b8aa56b58f1f 100644 +index 25300f6011c213b67876552abcb12c290d586fe4..3431a075cdfcd21a236f3350decb46068fd2e6b8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -322,6 +322,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); -@@ -1766,6 +1767,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers @@ -28,11 +28,11 @@ index 5d41801c2378ac27b67b977a8ab30158b717d4d3..c0935474538849b9274fab8fad13b8aa this.profiler.push(() -> { String s = String.valueOf(worldserver); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index a994456adb0034c0662151f4ae28c1c06f91333e..bee76ffe45e97c9c03430cf5a52d279421bc6536 100644 +index 472655c55b1f5c213da9b6c1940a353bafdac509..86288143a54e1d786672a81c05698b37fa5d8de2 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -509,6 +509,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - return this.nearbyPlayers; +@@ -528,6 +528,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + return this.entityTickingChunks; } // Paper end - rewrite chunk system + // Paper start - lag compensation diff --git a/patches/server/1036-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1035-Detail-more-information-in-watchdog-dumps.patch similarity index 94% rename from patches/server/1036-Detail-more-information-in-watchdog-dumps.patch rename to patches/server/1035-Detail-more-information-in-watchdog-dumps.patch index e629b56acf..23700d6582 100644 --- a/patches/server/1036-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/server/1035-Detail-more-information-in-watchdog-dumps.patch @@ -76,10 +76,10 @@ index d0d36a57ec4896bcb74970f8fb24d8f3e17db133..e2c24813f59c2fd075c740ac1842a38f }); throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD; diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index bee76ffe45e97c9c03430cf5a52d279421bc6536..e4cdbbf8a37f1363711ecd23f9c0eadcc95f7209 100644 +index 86288143a54e1d786672a81c05698b37fa5d8de2..1d74a728c03e2c6ffe0e795a5f24eac471a75157 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1223,7 +1223,26 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1242,7 +1242,26 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. } @@ -97,7 +97,7 @@ index bee76ffe45e97c9c03430cf5a52d279421bc6536..e4cdbbf8a37f1363711ecd23f9c0eadc + public void tickNonPassenger(Entity entity) { + // Paper start - log detailed entity tick information -+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main"); + try { + if (currentlyTickingEntity.get() == null) { + currentlyTickingEntity.lazySet(entity); @@ -106,7 +106,7 @@ index bee76ffe45e97c9c03430cf5a52d279421bc6536..e4cdbbf8a37f1363711ecd23f9c0eadc ++TimingHistory.entityTicks; // Paper - timings // Spigot start co.aikar.timings.Timing timer; // Paper -@@ -1263,7 +1282,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1282,7 +1301,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. this.tickPassenger(entity, entity1); } // } finally { timer.stopTiming(); } // Paper - timings - move up @@ -122,7 +122,7 @@ index bee76ffe45e97c9c03430cf5a52d279421bc6536..e4cdbbf8a37f1363711ecd23f9c0eadc private void tickPassenger(Entity vehicle, Entity passenger) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5608576f461ce9dec9827f9f581adc5d5757baf1..be9976a994dd04cf53048567576dd3484facf625 100644 +index 5608576f461ce9dec9827f9f581adc5d5757baf1..f0eb2fcbaadb5796cb48050d2f9f88a6100bdb4a 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1086,8 +1086,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -157,7 +157,7 @@ index 5608576f461ce9dec9827f9f581adc5d5757baf1..be9976a994dd04cf53048567576dd348 public void move(MoverType movementType, Vec3 movement) { final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity + // Paper start - detailed watchdog information -+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main"); ++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); + synchronized (this.posLock) { + this.moveStartX = this.getX(); + this.moveStartY = this.getY(); @@ -204,10 +204,10 @@ index 5608576f461ce9dec9827f9f581adc5d5757baf1..be9976a994dd04cf53048567576dd348 int j = Mth.floor(y); int k = Mth.floor(z); diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index 8ef5c345b7ba5ef869a1b0468f431c0f47cf2319..5e583d7226ce60d965ce9f019900793d45742d30 100644 +index c9e17225bc52fe5e7b2dc0908db225a86c6e94d1..f7a4fee9bb25ff256dc2e5ea26bfbceca6a49167 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java -@@ -22,6 +22,78 @@ public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - +@@ -22,6 +22,78 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre private volatile long lastTick; private volatile boolean stopping; @@ -286,7 +286,7 @@ index 8ef5c345b7ba5ef869a1b0468f431c0f47cf2319..5e583d7226ce60d965ce9f019900793d private WatchdogThread(long timeoutTime, boolean restart) { super( "Paper Watchdog Thread" ); -@@ -119,6 +191,7 @@ public class WatchdogThread extends io.papermc.paper.util.TickThread // Paper - +@@ -119,6 +191,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - rewrite chunk system diff --git a/patches/server/1037-Write-SavedData-IO-async.patch b/patches/server/1036-Write-SavedData-IO-async.patch similarity index 95% rename from patches/server/1037-Write-SavedData-IO-async.patch rename to patches/server/1036-Write-SavedData-IO-async.patch index 1565f5f4e4..8f31373c74 100644 --- a/patches/server/1037-Write-SavedData-IO-async.patch +++ b/patches/server/1036-Write-SavedData-IO-async.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Write SavedData IO async Co-Authored-By: Shane Freeder diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 61e222fb129c5733411ce95aaa5f035dbd95b01a..3575fe6f57457ab865a29d20836512f6f5a98115 100644 +index 5f195875564822f422127462fbbeea5df4a4e1cb..5149f7a5f0ee8620df582dcf26151e5842463cae 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -370,6 +370,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -368,6 +368,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon public void close(boolean save) throws IOException { ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system @@ -24,10 +24,10 @@ index 61e222fb129c5733411ce95aaa5f035dbd95b01a..3575fe6f57457ab865a29d20836512f6 // CraftBukkit start - modelled on below diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index e4cdbbf8a37f1363711ecd23f9c0eadcc95f7209..9b463cd43bcf763faab04012137695a575f16729 100644 +index 1d74a728c03e2c6ffe0e795a5f24eac471a75157..46e8dd8dae25e1b2124e9c8031844fbe96eb6e1a 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1354,7 +1354,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1373,7 +1373,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel")); } @@ -36,7 +36,7 @@ index e4cdbbf8a37f1363711ecd23f9c0eadcc95f7209..9b463cd43bcf763faab04012137695a5 if (progressListener != null) { progressListener.progressStage(Component.translatable("menu.savingChunks")); } -@@ -1385,12 +1385,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -1404,12 +1404,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. // CraftBukkit end } diff --git a/patches/server/1038-Correctly-call-PlayerItemBreakEvent.patch b/patches/server/1037-Correctly-call-PlayerItemBreakEvent.patch similarity index 100% rename from patches/server/1038-Correctly-call-PlayerItemBreakEvent.patch rename to patches/server/1037-Correctly-call-PlayerItemBreakEvent.patch diff --git a/patches/server/1039-Add-ItemType-getItemRarity.patch b/patches/server/1038-Add-ItemType-getItemRarity.patch similarity index 100% rename from patches/server/1039-Add-ItemType-getItemRarity.patch rename to patches/server/1038-Add-ItemType-getItemRarity.patch diff --git a/patches/server/1040-Incremental-chunk-and-player-saving.patch b/patches/server/1039-Incremental-chunk-and-player-saving.patch similarity index 94% rename from patches/server/1040-Incremental-chunk-and-player-saving.patch rename to patches/server/1039-Incremental-chunk-and-player-saving.patch index f6f0f055f9..9f7aaf836e 100644 --- a/patches/server/1040-Incremental-chunk-and-player-saving.patch +++ b/patches/server/1039-Incremental-chunk-and-player-saving.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Incremental chunk and player saving diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c0935474538849b9274fab8fad13b8aa56b58f1f..aeae4f8d4ead24db315631c3d2c0b930d0d51e02 100644 +index 3431a075cdfcd21a236f3350decb46068fd2e6b8..86f890280bfabac3b14b771ae67d28653ab2e3e8 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -992,7 +992,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop