Yatopia/patches/server/0031-Optimise-portals.patch
Ivan Pekov 2b78178637
Updated Upstream and Sidestream(s) (Tuinity/Purpur)
Upstream/An Sidestream has released updates that appears to apply and compile correctly
This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing.

Tuinity Changes:
69e6a4c Updated Upstream (Paper)

Purpur Changes:
391f9ad Updated Upstream (Paper)
2020-12-17 09:48:17 +02:00

121 lines
6.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Sun, 15 Nov 2020 17:06:33 +0200
Subject: [PATCH] Optimise portals
Chunk preloading is being done asynchronously and the code around stuff getting filtered has been
optimised.
diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java
index e10995ec30dd9a10d781b3c1709fd2db5a9becdd..456af55b5908f7192a63c6b15fb93a3480015ab6 100644
--- a/src/main/java/net/minecraft/server/PortalTravelAgent.java
+++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java
@@ -22,6 +22,8 @@ public class PortalTravelAgent {
// int i = flag ? 16 : 128;
// CraftBukkit end
+ // Yatopia start - replace
+ /*
villageplace.a(this.world, blockposition, i);
Optional<VillagePlaceRecord> optional = villageplace.b((villageplacetype) -> {
return villageplacetype == VillagePlaceType.v;
@@ -32,6 +34,24 @@ public class PortalTravelAgent {
})).filter((villageplacerecord) -> {
return this.world.getType(villageplacerecord.f()).b(BlockProperties.E);
}).findFirst();
+ */
+ villageplace.preloadChunks(world.getChunkProvider(), blockposition, i);
+ java.util.List<VillagePlaceRecord> poiList = villageplace.getFilteredPoiList(
+ (placeType) -> placeType == VillagePlaceType.v,
+ (record) -> world.getType(record.getPosition()).contains(BlockProperties.E),
+ blockposition, i, VillagePlace.Occupancy.ANY);
+ Optional<VillagePlaceRecord> optional = Optional.empty();
+ if (!poiList.isEmpty()) {
+ if (poiList.size() > 1) {
+ poiList.sort(
+ Comparator.comparingDouble(
+ (VillagePlaceRecord record) -> record.getPosition().distanceSquared(blockposition)
+ ).thenComparingInt((record) -> record.getPosition().getY())
+ );
+ }
+ optional = Optional.of(poiList.get(0));
+ }
+ // Yatopia end
return optional.map((villageplacerecord) -> {
BlockPosition blockposition1 = villageplacerecord.f();
diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java
index cd9c619dd038abafede98703946d37e53595af73..1ddd7c7d3a7d331e3a37c11cd345089146c112e0 100644
--- a/src/main/java/net/minecraft/server/VillagePlace.java
+++ b/src/main/java/net/minecraft/server/VillagePlace.java
@@ -80,6 +80,18 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
}
return ret;
}
+ public java.util.List<VillagePlaceRecord> getFilteredPoiList(Predicate<VillagePlaceType> filter, Predicate<VillagePlaceRecord> filterRecords, BlockPosition pos, int i, VillagePlace.Occupancy occupancy) {
+ int j = org.apache.commons.math3.util.FastMath.floorDiv(i, 16) + 1;
+
+ java.util.List<ChunkCoordIntPair> list = ChunkCoordIntPair.streamList(new ChunkCoordIntPair(pos), j);
+ java.util.List<VillagePlaceRecord> ret = new java.util.ArrayList<>();
+ for (ChunkCoordIntPair chunkPos : list) {
+ for (int k = 0; k < 16; k++) {
+ this.d(SectionPosition.a(chunkPos, k).asLong()).ifPresent(section -> ret.addAll(section.getFilteredList(filter, filterRecords, occupancy)));
+ }
+ }
+ return ret;
+ }
public java.util.List<VillagePlaceRecord> cList(Predicate<VillagePlaceType> predicate, BlockPosition pos, int i, VillagePlace.Occupancy occupancy) {
int j = i * i;
java.util.List<VillagePlaceRecord> ret = new java.util.ArrayList<>();
@@ -333,6 +345,18 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
*/ // Yatopia end
}
+ // Yatopia start - this ^ but we accept ChunkProviderServer for async :)
+ public void preloadChunks(ChunkProviderServer chunkProvider, BlockPosition pos, int radius) {
+ for (SectionPosition sectionPos : SectionPosition.getPosList(new ChunkCoordIntPair(pos), org.apache.commons.math3.util.FastMath.floorDiv(radius, 16))) {
+ boolean shouldContinue = this.d(sectionPos.asLong()).map(VillagePlaceSection::isValid).orElse(false);
+ if (shouldContinue) {
+ ChunkCoordIntPair chunkPos = sectionPos.asChunkPos();
+ if (b.add(chunkPos.pair())) { chunkProvider.getChunkAtAsynchronously(chunkPos.x, chunkPos.z, true, false); }
+ }
+ }
+ }
+ // Yatopia end
+
final class a extends LightEngineGraphSection {
private final Long2ByteMap b = new Long2ByteOpenHashMap();
diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java
index 15d2b2c21e61369b5c7897914ccf0aa950f44668..5bc361c60bdf58122513fef267f60bd385d4af24 100644
--- a/src/main/java/net/minecraft/server/VillagePlaceSection.java
+++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java
@@ -69,6 +69,19 @@ public class VillagePlaceSection {
}
return ret;
}
+ public java.util.List<VillagePlaceRecord> getFilteredList(Predicate<VillagePlaceType> predicate, Predicate<VillagePlaceRecord> recordFilter, VillagePlace.Occupancy occupancy) {
+ java.util.List<VillagePlaceRecord> ret = new java.util.ArrayList<>();
+ for (Map.Entry<VillagePlaceType, Set<VillagePlaceRecord>> entry : c.entrySet()) {
+ if (predicate.test(entry.getKey())) {
+ for (VillagePlaceRecord record : entry.getValue()) {
+ if (occupancy.getPredicate().test(record) && recordFilter.test(record)) {
+ ret.add(record);
+ }
+ }
+ }
+ }
+ return ret;
+ }
// Yatopia end
public Stream<VillagePlaceRecord> a(Predicate<VillagePlaceType> predicate, VillagePlace.Occupancy villageplace_occupancy) {
return this.c.entrySet().stream().filter((entry) -> {
@@ -174,6 +187,7 @@ public class VillagePlaceSection {
this.c.clear();
}
+ final boolean isValid() { return a(); } // Yatopia - OBFHELPER
boolean a() {
return this.e;
}