Yatopia/patches/server/0034-Optimise-portals.patch
Ivan Pekov 37e61be6c2
Updated upstream and sidestream (Tuinity/Purpur)
Closes #289
Also dropped some patches which are useless.

Changes in Purpur: Paper upstream updates
Changes in Tuinity: Paper updated
2020-11-20 09:14:39 +02:00

121 lines
6.3 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 0473972ae760096ac541c87f8b10f16ab07d7079..faf44b060da5189e06732f699fa6766665c1b391 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 net.yatopia.server.list.GlueList<>();
+ 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 net.yatopia.server.list.GlueList<>();
@@ -323,6 +335,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 8b9f5797a6bee47ff16ee713777b5220dbb0afc6..1a0a30a1e7a231d05109428b2f57ae91841f3579 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 net.yatopia.server.list.GlueList<>();
+ 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;
}