From 68a80a09cc3271be6f24fbd8ed840c75297a791d Mon Sep 17 00:00:00 2001 From: MrIvanPlays Date: Mon, 10 Aug 2020 19:45:18 +0300 Subject: [PATCH 1/6] Port 1.15.2 Villager optimizations Tested & works without issues. Also added some more obfuscation helpers for easier maintenance & update between major releases --- ...rt-serverside-behavior-of-keepalives.patch | 2 +- .../0565-Optimize-Villagers.patch | 212 ++++++++++-------- 2 files changed, 125 insertions(+), 89 deletions(-) rename removed/1.16/0530-Optimize-Villagers.patch => Spigot-Server-Patches/0565-Optimize-Villagers.patch (56%) diff --git a/Spigot-Server-Patches/0174-revert-serverside-behavior-of-keepalives.patch b/Spigot-Server-Patches/0174-revert-serverside-behavior-of-keepalives.patch index cfe42a288ae8..43e5a3113849 100644 --- a/Spigot-Server-Patches/0174-revert-serverside-behavior-of-keepalives.patch +++ b/Spigot-Server-Patches/0174-revert-serverside-behavior-of-keepalives.patch @@ -17,7 +17,7 @@ from networking or during connections flood of chunk packets on slower clients, at the cost of dead connections being kept open for longer. diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 01747ea997a68f55803553c330287b1bbe866c29..2eb2ddcb4456437bb449a86c18fb24c8629870a7 100644 +index 985420238c9da53ab3b11d531f002a3d5f9a3d73..a1dd21a1b4ee6b3c6bbed545f75582730871ea98 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -70,7 +70,7 @@ public class PlayerConnection implements PacketListenerPlayIn { diff --git a/removed/1.16/0530-Optimize-Villagers.patch b/Spigot-Server-Patches/0565-Optimize-Villagers.patch similarity index 56% rename from removed/1.16/0530-Optimize-Villagers.patch rename to Spigot-Server-Patches/0565-Optimize-Villagers.patch index d7cec2bf869d..cdff4e6c4c62 100644 --- a/removed/1.16/0530-Optimize-Villagers.patch +++ b/Spigot-Server-Patches/0565-Optimize-Villagers.patch @@ -1,6 +1,6 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar -Date: Tue, 26 May 2020 21:32:05 -0400 +Date: Mon, 10 Aug 2020 17:12:02 +0300 Subject: [PATCH] Optimize Villagers This change reimplements the entire BehaviorFindPosition method to @@ -39,29 +39,38 @@ So we cache that and only rebuild it if professions change, which should be neve a plugin manipulates and adds custom professions, which it will handle by rebuilding. diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -index 35eb3a5a61145e94d5b0c77c0eb13bfa46fac23b..6861b1a345496a83900b0ef702ba34315a030ef6 100644 +index 63a761ebef80d4af09cdc2682e496d78492c4a3a..466180158919c4bf9fde54791511702b36181f29 100644 --- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java +++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -@@ -29,8 +29,55 @@ public class BehaviorFindPosition extends Behavior { +@@ -48,7 +48,7 @@ public class BehaviorFindPosition extends Behavior { + if (this.d && entitycreature.isBaby()) { + return false; + } else if (this.f == 0L) { +- this.f = entitycreature.world.getTime() + (long) worldserver.random.nextInt(20); ++ this.f = entitycreature.world.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper + return false; + } else { + return worldserver.getTime() >= this.f; +@@ -56,12 +56,56 @@ public class BehaviorFindPosition extends Behavior { + } protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) { - this.f = 0; -- this.d = worldserver.getTime() + (long) worldserver.getRandom().nextInt(20); -+ this.d = worldserver.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper - VillagePlace villageplace = worldserver.B(); -+ +- this.f = i + 20L + (long) worldserver.getRandom().nextInt(20); ++ this.f = i + 20L + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper + VillagePlace villageplace = worldserver.y(); + + // Paper start - replace implementation completely -+ BlockPosition blockposition2 = new BlockPosition(entitycreature); ++ BlockPosition blockposition2 = new BlockPosition(entitycreature.locX(), entitycreature.locY(), entitycreature.locZ()); + int dist = 48; + int requiredDist = dist * dist; + int cdist = Math.floorDiv(dist, 16); -+ Predicate predicate = this.a.c(); ++ Predicate predicate = this.b.getPredicate(); + int maxPoiAttempts = 4; + int poiAttempts = 0; + OUT: + for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) { + for (int i1 = 0; i1 < 16; i1++) { -+ java.util.Optional section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v()); ++ java.util.Optional section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).asLong()); + if (section == null || !section.isPresent()) continue; + for (java.util.Map.Entry> e : section.get().getRecords().entrySet()) { + if (!predicate.test(e.getKey())) continue; @@ -70,19 +79,18 @@ index 35eb3a5a61145e94d5b0c77c0eb13bfa46fac23b..6861b1a345496a83900b0ef702ba3431 + + BlockPosition pos = record.getPosition(); + long key = pos.asLong(); -+ if (this.e.containsKey(key)) { ++ if (this.g.containsKey(key)) { + continue; + } + double poiDist = pos.distanceSquared(blockposition2); + if (poiDist <= (double) requiredDist) { -+ this.e.put(key, (long) (this.d + Math.sqrt(poiDist) * 4)); // use dist instead of 40 to blacklist longer if farther distance ++ this.g.put(key, new BehaviorFindPosition.a(java.util.concurrent.ThreadLocalRandom.current(), (long) (this.f + Math.sqrt(poiDist) * 4))); // use dist instead of 40 to blacklist longer if farther distance + ++poiAttempts; -+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.a.d()); ++ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.b.getValidRange()); + -+ if (pathentity != null && pathentity.h()) { -+ record.decreaseVacancy(); -+ GlobalPos globalPos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), pos); -+ entitycreature.getBehaviorController().setMemory(this.b, globalPos); ++ if (pathentity != null && pathentity.canReach()) { ++ GlobalPos globalPos = GlobalPos.create(worldserver.getDimensionKey(), pos); ++ entitycreature.getBehaviorController().setMemory(c, globalPos); + break OUT; + } + if (poiAttempts >= maxPoiAttempts) { @@ -93,25 +101,40 @@ index 35eb3a5a61145e94d5b0c77c0eb13bfa46fac23b..6861b1a345496a83900b0ef702ba3431 + } + } + } -+ // Clean up - vanilla does this only when it runs out, but that would push it to try farther POI's... -+ this.e.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.d); ++ + this.g.long2ObjectEntrySet().removeIf((entry) -> { +- return !((BehaviorFindPosition.a) entry.getValue()).b(i); ++ return entry.getValue().b < f; + }); + /* Predicate predicate = (blockposition) -> { - long j = blockposition.asLong(); + BehaviorFindPosition.a behaviorfindposition_a = (BehaviorFindPosition.a) this.g.get(blockposition.asLong()); -@@ -61,6 +108,6 @@ public class BehaviorFindPosition extends Behavior { - return entry.getLongValue() < this.d; - }); +@@ -103,6 +147,7 @@ public class BehaviorFindPosition extends Behavior { + } } -- + + */ // Paper end } - } + + static class a { +diff --git a/src/main/java/net/minecraft/server/PathEntity.java b/src/main/java/net/minecraft/server/PathEntity.java +index c81a5d50c480b064ab60ed6f25f9e2c0bedb6ece..f633796f754fd1b80047033c37a38b099d9b9a9c 100644 +--- a/src/main/java/net/minecraft/server/PathEntity.java ++++ b/src/main/java/net/minecraft/server/PathEntity.java +@@ -114,6 +114,7 @@ public class PathEntity { + } + } + ++ public final boolean canReach() { return this.j(); } // Paper - OBFHELPER + public boolean j() { + return this.h; + } diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java -index a6d8ef5eb44f3f851a3a1be4032ca21ab1d7f2b2..c3e8a0145d63843736d2060f978cdf38df359563 100644 +index 04256a95108b8182e8f808e856e0d2b62165e242..b42590586ab68facdb3e25ea91a9e19348019dbf 100644 --- a/src/main/java/net/minecraft/server/RegionFileSection.java +++ b/src/main/java/net/minecraft/server/RegionFileSection.java -@@ -51,29 +51,15 @@ public class RegionFileSection extends RegionFi +@@ -52,10 +52,13 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab @Nullable protected Optional c(long i) { @@ -121,51 +144,41 @@ index a6d8ef5eb44f3f851a3a1be4032ca21ab1d7f2b2..c3e8a0145d63843736d2060f978cdf38 + protected final Optional getSection(long i) { return d(i); } // Paper - OBFHELPER protected Optional d(long i) { -- SectionPosition sectionposition = SectionPosition.a(i); -- -- if (this.b(sectionposition)) { -- return Optional.empty(); -- } else { -- Optional optional = this.c(i); -- -- if (optional != null) { -- return optional; -- } else { -- this.b(sectionposition.u()); -- optional = this.c(i); -- if (optional == null) { -- throw (IllegalStateException) SystemUtils.c(new IllegalStateException()); -- } else { -- return optional; -- } -- } -- } + // Paper start - replace method - never load POI data sync, we load this in chunk load already, reduce ops ++ /* + SectionPosition sectionposition = SectionPosition.a(i); + + if (this.b(sectionposition)) { +@@ -75,6 +78,10 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab + } + } + } ++ */ + // If it's an unloaded chunk, well too bad. + return this.c(i); + // Paper end } protected boolean b(SectionPosition sectionposition) { -@@ -117,7 +103,7 @@ public class RegionFileSection extends RegionFi +@@ -118,7 +125,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab private void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops, @Nullable T t0) { if (t0 == null) { for (int i = 0; i < 16; ++i) { -- this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); -+ //this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); // Paper - NO!!! +- this.c.put(SectionPosition.a(chunkcoordintpair, i).s(), Optional.empty()); ++ //this.c.put(SectionPosition.a(chunkcoordintpair, i).s(), Optional.empty()); // Paper - NO!!! } } else { Dynamic dynamic = new Dynamic(dynamicops, t0); -@@ -135,7 +121,7 @@ public class RegionFileSection extends RegionFi - }, dynamic2); +@@ -140,7 +147,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab + return dataresult.resultOrPartial(logger::error); }); - this.c.put(i1, optional); + if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!! - optional.ifPresent((minecraftserializable) -> { + optional.ifPresent((object) -> { this.b(i1); if (flag) { -@@ -199,7 +185,7 @@ public class RegionFileSection extends RegionFi +@@ -213,7 +220,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab if (optional != null && optional.isPresent()) { this.d.add(i); } else { @@ -174,19 +187,23 @@ index a6d8ef5eb44f3f851a3a1be4032ca21ab1d7f2b2..c3e8a0145d63843736d2060f978cdf38 } } +diff --git a/src/main/java/net/minecraft/server/SectionPosition.java b/src/main/java/net/minecraft/server/SectionPosition.java +index f95925f1c5d091f1a129d0437bb6e175c6ac080f..6c8695d659e369e993d959f8b92309953f21ab1f 100644 +--- a/src/main/java/net/minecraft/server/SectionPosition.java ++++ b/src/main/java/net/minecraft/server/SectionPosition.java +@@ -173,6 +173,7 @@ public class SectionPosition extends BaseBlockPosition { + return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count + } + ++ public long asLong() { return s(); } // Paper - OBFHELPER + public long s() { + return (((long) getX() & 4194303L) << 42) | (((long) getY() & 1048575L)) | (((long) getZ() & 4194303L) << 20); // Paper - Simplify to reduce instruction count + } diff --git a/src/main/java/net/minecraft/server/VillagePlaceRecord.java b/src/main/java/net/minecraft/server/VillagePlaceRecord.java -index 1e9d7a3f902eb4571b93bb0e58cba966365f07b8..44535a3e2c3320aac472c5a7ee557fac7bab2530 100644 +index 0b40c2f4dada7d8432e3f91e9cf206c2bda3b24b..ac1a7b7f82436568e10e10b30aab7d1588a8b640 100644 --- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java +++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java -@@ -32,6 +32,7 @@ public class VillagePlaceRecord implements MinecraftSerializable { - return dynamicops.createMap(ImmutableMap.of(dynamicops.createString("pos"), this.a.a(dynamicops), dynamicops.createString("type"), dynamicops.createString(IRegistry.POINT_OF_INTEREST_TYPE.getKey(this.b).toString()), dynamicops.createString("free_tickets"), dynamicops.createInt(this.c))); - } - -+ protected final boolean decreaseVacancy() { return b(); } // Paper - OBFHELPER - protected boolean b() { - if (this.c <= 0) { - return false; -@@ -42,6 +43,7 @@ public class VillagePlaceRecord implements MinecraftSerializable { +@@ -44,6 +44,7 @@ public class VillagePlaceRecord { } } @@ -194,7 +211,7 @@ index 1e9d7a3f902eb4571b93bb0e58cba966365f07b8..44535a3e2c3320aac472c5a7ee557fac protected boolean c() { if (this.c >= this.b.b()) { return false; -@@ -52,14 +54,17 @@ public class VillagePlaceRecord implements MinecraftSerializable { +@@ -54,14 +55,17 @@ public class VillagePlaceRecord { } } @@ -208,62 +225,81 @@ index 1e9d7a3f902eb4571b93bb0e58cba966365f07b8..44535a3e2c3320aac472c5a7ee557fac return this.c != this.b.b(); } -+ public final BlockPosition getPosition() { return f(); } // Paper ++ public final BlockPosition getPosition() { return f(); } // Paper - OBFHELPER public BlockPosition f() { return this.a; } diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java -index 3f2602dbe0995f8d01d4a1428d919405d711a205..436b064c3b277143075386fc9a71027fb5962681 100644 +index 77c66bc9952542d2444b402896a3d9f622ca2ff9..0f27429b960395130410f4d96ff285a59a35d4d6 100644 --- a/src/main/java/net/minecraft/server/VillagePlaceSection.java +++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java -@@ -23,7 +23,7 @@ public class VillagePlaceSection implements MinecraftSerializable { +@@ -23,12 +23,12 @@ public class VillagePlaceSection { private static final Logger LOGGER = LogManager.getLogger(); - private final Short2ObjectMap b = new Short2ObjectOpenHashMap(); -- private final Map> c = Maps.newHashMap(); -+ private final Map> c = Maps.newHashMap(); public final Map> getRecords() { return c; } // Paper - OBFHELPER + private final Short2ObjectMap b; +- private final Map> c; ++ private final Map> c; public final Map> getRecords() { return c; } // Paper - OBFHELPER private final Runnable d; private boolean e; + public static Codec a(Runnable runnable) { +- Codec codec = RecordCodecBuilder.create((instance) -> { ++ Codec codec = RecordCodecBuilder.create((instance) -> { // Paper - decompile fix + return instance.group(RecordCodecBuilder.point(runnable), Codec.BOOL.optionalFieldOf("Valid", false).forGetter((villageplacesection) -> { + return villageplacesection.e; + }), VillagePlaceRecord.a(runnable).listOf().fieldOf("Records").forGetter((villageplacesection) -> { diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java -index ab3e054cd2f38756a5d802d4d981022318ab047d..c1f293fc98d3efb4665cfb9036f208b842fc8e36 100644 +index a5718af9b614ae505067131f04ebb490617d6aa4..18e4c2b6f8616ededba36caf0b76d39a11ae20b2 100644 --- a/src/main/java/net/minecraft/server/VillagePlaceType.java +++ b/src/main/java/net/minecraft/server/VillagePlaceType.java -@@ -12,8 +12,14 @@ import java.util.stream.Stream; +@@ -14,11 +14,20 @@ import java.util.stream.Collectors; public class VillagePlaceType { + static Set professionCache; // Paper - private static final Predicate v = (villageplacetype) -> { -- return ((Set) IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet())).contains(villageplacetype); + private static final Supplier> y = Suppliers.memoize(() -> { + return (Set) IRegistry.VILLAGER_PROFESSION.g().map(VillagerProfession::b).collect(Collectors.toSet()); + }); + public static final Predicate a = (villageplacetype) -> { +- return ((Set) VillagePlaceType.y.get()).contains(villageplacetype); + // Paper start + if (professionCache == null) { -+ professionCache = IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet()); ++ professionCache = new java.util.HashSet<>(); ++ for (VillagerProfession profession : IRegistry.VILLAGER_PROFESSION) { ++ professionCache.add(profession.getPlaceType()); ++ } + } + return professionCache.contains(villageplacetype); + // Paper end }; - public static final Predicate a = (villageplacetype) -> { + public static final Predicate b = (villageplacetype) -> { return true; -@@ -89,11 +95,11 @@ public class VillagePlaceType { +@@ -83,10 +92,12 @@ public class VillagePlaceType { + return this.D; } - private static VillagePlaceType a(String s, Set set, int i, int j) { -- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, j)))); -+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, j)))); // Paper - decompile error ++ public final Predicate getPredicate() { return c(); } // Paper - OBFHELPER + public Predicate c() { + return this.E; } - private static VillagePlaceType a(String s, Set set, int i, Predicate predicate, int j) { -- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, predicate, j)))); -+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, predicate, j)))); // Paper - decompile error ++ public final int getValidRange() { return d(); } // Paper - OBFHELPER + public int d() { + return this.F; } - - private static VillagePlaceType a(VillagePlaceType villageplacetype) { diff --git a/src/main/java/net/minecraft/server/VillagerProfession.java b/src/main/java/net/minecraft/server/VillagerProfession.java -index c38296165b33698bc15fe49a2de0d0d19cfb910a..f9d7a16c79a4e3ffe8b6e7ed469236a93892f01d 100644 +index 3c60da7ac6faebe9d964e893974e42613c59b4c1..ffdd9cdde094fcb401cf69daab12aa39623632df 100644 --- a/src/main/java/net/minecraft/server/VillagerProfession.java +++ b/src/main/java/net/minecraft/server/VillagerProfession.java -@@ -61,6 +61,7 @@ public class VillagerProfession { +@@ -35,6 +35,7 @@ public class VillagerProfession { + this.t = soundeffect; + } + ++ public final VillagePlaceType getPlaceType() { return b(); } // Paper - OBFHELPER + public VillagePlaceType b() { + return this.q; + } +@@ -61,6 +62,7 @@ public class VillagerProfession { } static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet immutableset, ImmutableSet immutableset1, @Nullable SoundEffect soundeffect) { From 506f50d70dc20afc157db97ad34a81f5cb64c1af Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Wed, 2 Sep 2020 20:32:13 +0300 Subject: [PATCH 2/6] Fix raid issues Thanks Proxi Co-authored-by: Mariell Hoversholm --- .../0565-Optimize-Villagers.patch | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Spigot-Server-Patches/0565-Optimize-Villagers.patch b/Spigot-Server-Patches/0565-Optimize-Villagers.patch index cdff4e6c4c62..6330a91ca002 100644 --- a/Spigot-Server-Patches/0565-Optimize-Villagers.patch +++ b/Spigot-Server-Patches/0565-Optimize-Villagers.patch @@ -39,9 +39,18 @@ So we cache that and only rebuild it if professions change, which should be neve a plugin manipulates and adds custom professions, which it will handle by rebuilding. diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -index 63a761ebef80d4af09cdc2682e496d78492c4a3a..466180158919c4bf9fde54791511702b36181f29 100644 +index 63a761ebef80d4af09cdc2682e496d78492c4a3a..bab411b102355bc32ea1d2119604d8d363f6ba66 100644 --- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java +++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java +@@ -16,7 +16,7 @@ public class BehaviorFindPosition extends Behavior { + private final VillagePlaceType b; + private final MemoryModuleType c; + private final boolean d; +- private final Optional e; ++ private final Optional e; private Optional getPoiAcquisitionEvent() { return this.e; } // Paper - OBFHELPER + private long f; + private final Long2ObjectMap g; + @@ -48,7 +48,7 @@ public class BehaviorFindPosition extends Behavior { if (this.d && entitycreature.isBaby()) { return false; @@ -51,7 +60,7 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..466180158919c4bf9fde54791511702b return false; } else { return worldserver.getTime() >= this.f; -@@ -56,12 +56,56 @@ public class BehaviorFindPosition extends Behavior { +@@ -56,12 +56,57 @@ public class BehaviorFindPosition extends Behavior { } protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) { @@ -91,6 +100,7 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..466180158919c4bf9fde54791511702b + if (pathentity != null && pathentity.canReach()) { + GlobalPos globalPos = GlobalPos.create(worldserver.getDimensionKey(), pos); + entitycreature.getBehaviorController().setMemory(c, globalPos); ++ this.getPoiAcquisitionEvent().ifPresent((event) -> worldserver.broadcastEntityEffect(entitycreature, event)); + break OUT; + } + if (poiAttempts >= maxPoiAttempts) { @@ -110,7 +120,7 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..466180158919c4bf9fde54791511702b Predicate predicate = (blockposition) -> { BehaviorFindPosition.a behaviorfindposition_a = (BehaviorFindPosition.a) this.g.get(blockposition.asLong()); -@@ -103,6 +147,7 @@ public class BehaviorFindPosition extends Behavior { +@@ -103,6 +148,7 @@ public class BehaviorFindPosition extends Behavior { } } From df30809412f718cbd4191db93de195b8ff0c1ff5 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Wed, 2 Sep 2020 20:44:56 +0300 Subject: [PATCH 3/6] Rebuild patches --- ...565-Optimize-Villagers.patch => 0576-Optimize-Villagers.patch} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Spigot-Server-Patches/{0565-Optimize-Villagers.patch => 0576-Optimize-Villagers.patch} (100%) diff --git a/Spigot-Server-Patches/0565-Optimize-Villagers.patch b/Spigot-Server-Patches/0576-Optimize-Villagers.patch similarity index 100% rename from Spigot-Server-Patches/0565-Optimize-Villagers.patch rename to Spigot-Server-Patches/0576-Optimize-Villagers.patch From edfade22bca42d1ce51457d282ae10b307ad773a Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Tue, 10 Nov 2020 14:37:41 +0200 Subject: [PATCH 4/6] Make it compile --- ...576-Optimize-Villagers.patch => 0595-Optimize-Villagers.patch} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Spigot-Server-Patches/{0576-Optimize-Villagers.patch => 0595-Optimize-Villagers.patch} (100%) diff --git a/Spigot-Server-Patches/0576-Optimize-Villagers.patch b/Spigot-Server-Patches/0595-Optimize-Villagers.patch similarity index 100% rename from Spigot-Server-Patches/0576-Optimize-Villagers.patch rename to Spigot-Server-Patches/0595-Optimize-Villagers.patch From d1ebc6fcd0772296664ad06f3db56425e2f933c9 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Tue, 10 Nov 2020 15:02:22 +0200 Subject: [PATCH 5/6] Amend with asked changes Also renamed VillagePlaceType#getPredicate to getCompletionCondition, more descriptive --- .../0595-Optimize-Villagers.patch | 109 +++++++++++++----- 1 file changed, 79 insertions(+), 30 deletions(-) diff --git a/Spigot-Server-Patches/0595-Optimize-Villagers.patch b/Spigot-Server-Patches/0595-Optimize-Villagers.patch index 6330a91ca002..ff23f904c799 100644 --- a/Spigot-Server-Patches/0595-Optimize-Villagers.patch +++ b/Spigot-Server-Patches/0595-Optimize-Villagers.patch @@ -39,18 +39,27 @@ So we cache that and only rebuild it if professions change, which should be neve a plugin manipulates and adds custom professions, which it will handle by rebuilding. diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -index 63a761ebef80d4af09cdc2682e496d78492c4a3a..bab411b102355bc32ea1d2119604d8d363f6ba66 100644 +index 63a761ebef80d4af09cdc2682e496d78492c4a3a..6bffce90fa887ef173ecd4260fd30a5e6c0feea5 100644 --- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java +++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java -@@ -16,7 +16,7 @@ public class BehaviorFindPosition extends Behavior { - private final VillagePlaceType b; - private final MemoryModuleType c; +@@ -13,12 +13,12 @@ import java.util.stream.Collectors; + + public class BehaviorFindPosition extends Behavior { + +- private final VillagePlaceType b; +- private final MemoryModuleType c; ++ private final VillagePlaceType b; private final VillagePlaceType getPoiType() { return b; } // Paper - OBFHELPER ++ private final MemoryModuleType c; private final MemoryModuleType getTargetMemoryModuleType() { return c; } // Paper - OBFHELPER private final boolean d; - private final Optional e; -+ private final Optional e; private Optional getPoiAcquisitionEvent() { return this.e; } // Paper - OBFHELPER - private long f; - private final Long2ObjectMap g; +- private long f; +- private final Long2ObjectMap g; ++ private final Optional e; private final Optional getPoiAcquisitionEvent() { return this.e; } // Paper - OBFHELPER ++ private long f; private final long getPositionExpireTimeLimit() { return f; } // Paper - OBFHELPER ++ private final Long2ObjectMap g; private Long2ObjectMap getFoundPositionsToExpiry() { return g; } // Paper - OBFHELPER + public BehaviorFindPosition(VillagePlaceType villageplacetype, MemoryModuleType memorymoduletype, MemoryModuleType memorymoduletype1, boolean flag, Optional optional) { + super(a(memorymoduletype, memorymoduletype1)); @@ -48,7 +48,7 @@ public class BehaviorFindPosition extends Behavior { if (this.d && entitycreature.isBaby()) { return false; @@ -68,38 +77,40 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..bab411b102355bc32ea1d2119604d8d3 + this.f = i + 20L + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper VillagePlace villageplace = worldserver.y(); +- this.g.long2ObjectEntrySet().removeIf((entry) -> { +- return !((BehaviorFindPosition.a) entry.getValue()).b(i); + // Paper start - replace implementation completely + BlockPosition blockposition2 = new BlockPosition(entitycreature.locX(), entitycreature.locY(), entitycreature.locZ()); + int dist = 48; + int requiredDist = dist * dist; + int cdist = Math.floorDiv(dist, 16); -+ Predicate predicate = this.b.getPredicate(); ++ Predicate predicate = this.getPoiType().getCompletionCondition(); + int maxPoiAttempts = 4; + int poiAttempts = 0; + OUT: + for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) { + for (int i1 = 0; i1 < 16; i1++) { -+ java.util.Optional section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).asLong()); ++ java.util.Optional section = villageplace.getSection(SectionPosition.from(chunkcoordintpair, i1).asLong()); + if (section == null || !section.isPresent()) continue; -+ for (java.util.Map.Entry> e : section.get().getRecords().entrySet()) { -+ if (!predicate.test(e.getKey())) continue; -+ for (VillagePlaceRecord record : e.getValue()) { ++ for (java.util.Map.Entry> entry : section.get().getRecords().entrySet()) { ++ if (!predicate.test(entry.getKey())) continue; ++ for (VillagePlaceRecord record : entry.getValue()) { + if (!record.hasVacancy()) continue; + + BlockPosition pos = record.getPosition(); + long key = pos.asLong(); -+ if (this.g.containsKey(key)) { ++ if (this.getFoundPositionsToExpiry().containsKey(key)) { + continue; + } + double poiDist = pos.distanceSquared(blockposition2); + if (poiDist <= (double) requiredDist) { -+ this.g.put(key, new BehaviorFindPosition.a(java.util.concurrent.ThreadLocalRandom.current(), (long) (this.f + Math.sqrt(poiDist) * 4))); // use dist instead of 40 to blacklist longer if farther distance ++ this.getFoundPositionsToExpiry().put(key, new BehaviorFindPosition.a(java.util.concurrent.ThreadLocalRandom.current(), (long) (this.getPositionExpireTimeLimit() + Math.sqrt(poiDist) * 4))); // use dist instead of 40 to blacklist longer if farther distance + ++poiAttempts; -+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.b.getValidRange()); ++ PathEntity pathentity = entitycreature.getNavigation().findPathToAny(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.getPoiType().getValidRange()); + + if (pathentity != null && pathentity.canReach()) { + GlobalPos globalPos = GlobalPos.create(worldserver.getDimensionKey(), pos); -+ entitycreature.getBehaviorController().setMemory(c, globalPos); ++ entitycreature.getBehaviorController().setMemory(this.getTargetMemoryModuleType(), globalPos); + this.getPoiAcquisitionEvent().ifPresent((event) -> worldserver.broadcastEntityEffect(entitycreature, event)); + break OUT; + } @@ -112,15 +123,14 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..bab411b102355bc32ea1d2119604d8d3 + } + } + - this.g.long2ObjectEntrySet().removeIf((entry) -> { -- return !((BehaviorFindPosition.a) entry.getValue()).b(i); -+ return entry.getValue().b < f; ++ this.getFoundPositionsToExpiry().long2ObjectEntrySet().removeIf((entry) -> { ++ return entry.getValue().getPreviousAttemptAt() < this.getPositionExpireTimeLimit(); }); + /* Predicate predicate = (blockposition) -> { BehaviorFindPosition.a behaviorfindposition_a = (BehaviorFindPosition.a) this.g.get(blockposition.asLong()); -@@ -103,6 +148,7 @@ public class BehaviorFindPosition extends Behavior { +@@ -103,12 +148,13 @@ public class BehaviorFindPosition extends Behavior { } } @@ -128,6 +138,25 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..bab411b102355bc32ea1d2119604d8d3 } static class a { + + private final Random a; +- private long b; ++ private long b; private final long getPreviousAttemptAt() { return b; } // Paper - OBFHELPER + private long c; + private int d; + +diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java +index 1558c5f8256f50be6850f1d7f70eee3e8ec76496..d97a2f826701d7f0ff36fb5fe6acbbfe8b36ed32 100644 +--- a/src/main/java/net/minecraft/server/NavigationAbstract.java ++++ b/src/main/java/net/minecraft/server/NavigationAbstract.java +@@ -110,6 +110,7 @@ public abstract class NavigationAbstract { + + @Nullable + // Paper start - Add target ++ protected PathEntity findPathToAny(Set set, int i, boolean flag, int j) { return a(set, i, flag, j); } // OBFHELPER + protected PathEntity a(Set set, int i, boolean flag, int j) { + return this.a(set, null, i, flag, j); + } diff --git a/src/main/java/net/minecraft/server/PathEntity.java b/src/main/java/net/minecraft/server/PathEntity.java index c81a5d50c480b064ab60ed6f25f9e2c0bedb6ece..f633796f754fd1b80047033c37a38b099d9b9a9c 100644 --- a/src/main/java/net/minecraft/server/PathEntity.java @@ -141,15 +170,27 @@ index c81a5d50c480b064ab60ed6f25f9e2c0bedb6ece..f633796f754fd1b80047033c37a38b09 return this.h; } diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java -index 04256a95108b8182e8f808e856e0d2b62165e242..b42590586ab68facdb3e25ea91a9e19348019dbf 100644 +index 04256a95108b8182e8f808e856e0d2b62165e242..8c6675db41f2fffdc2fd6f244afd92dc4ad2acc9 100644 --- a/src/main/java/net/minecraft/server/RegionFileSection.java +++ b/src/main/java/net/minecraft/server/RegionFileSection.java -@@ -52,10 +52,13 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab +@@ -25,7 +25,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab - @Nullable + private static final Logger LOGGER = LogManager.getLogger(); + // Paper - nuke IOWorker +- private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); ++ private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); private Long2ObjectMap> getLoadedElements() { return c; } // Paper - OBFHELPER + protected final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); // Paper - private -> protected + private final Function> e; + private final Function f; +@@ -50,12 +50,15 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab + + } + +- @Nullable ++ @Nullable protected Optional getIfLoaded(long i) { return c(i); } @Nullable // Paper - OBFHELPER protected Optional c(long i) { - return (Optional) this.c.get(i); -+ return this.c.getOrDefault(i, Optional.empty()); // Paper ++ return this.getLoadedElements().getOrDefault(i, Optional.empty()); // Paper } + protected final Optional getSection(long i) { return d(i); } // Paper - OBFHELPER @@ -165,7 +206,7 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..b42590586ab68facdb3e25ea91a9e193 } + */ + // If it's an unloaded chunk, well too bad. -+ return this.c(i); ++ return this.getIfLoaded(i); + // Paper end } @@ -184,7 +225,7 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..b42590586ab68facdb3e25ea91a9e193 }); - this.c.put(i1, optional); -+ if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!! ++ if (optional.isPresent()) this.getLoadedElements().put(i1, optional); // Paper - NO!!! optional.ifPresent((object) -> { this.b(i1); if (flag) { @@ -198,10 +239,18 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..b42590586ab68facdb3e25ea91a9e193 } diff --git a/src/main/java/net/minecraft/server/SectionPosition.java b/src/main/java/net/minecraft/server/SectionPosition.java -index f95925f1c5d091f1a129d0437bb6e175c6ac080f..6c8695d659e369e993d959f8b92309953f21ab1f 100644 +index f95925f1c5d091f1a129d0437bb6e175c6ac080f..5ac0c06315ad75e826e21b7e293e725c5192c70d 100644 --- a/src/main/java/net/minecraft/server/SectionPosition.java +++ b/src/main/java/net/minecraft/server/SectionPosition.java -@@ -173,6 +173,7 @@ public class SectionPosition extends BaseBlockPosition { +@@ -19,6 +19,7 @@ public class SectionPosition extends BaseBlockPosition { + return new SectionPosition(blockposition.getX() >> 4, blockposition.getY() >> 4, blockposition.getZ() >> 4); // Paper + } + ++ public static final SectionPosition from(ChunkCoordIntPair chunkPos, int i) { return a(chunkPos, i); } // Paper - OBFHELPER + public static SectionPosition a(ChunkCoordIntPair chunkcoordintpair, int i) { + return new SectionPosition(chunkcoordintpair.x, i, chunkcoordintpair.z); + } +@@ -173,6 +174,7 @@ public class SectionPosition extends BaseBlockPosition { return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count } @@ -259,7 +308,7 @@ index 77c66bc9952542d2444b402896a3d9f622ca2ff9..0f27429b960395130410f4d96ff285a5 return villageplacesection.e; }), VillagePlaceRecord.a(runnable).listOf().fieldOf("Records").forGetter((villageplacesection) -> { diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java -index a5718af9b614ae505067131f04ebb490617d6aa4..18e4c2b6f8616ededba36caf0b76d39a11ae20b2 100644 +index a5718af9b614ae505067131f04ebb490617d6aa4..a9708470c1d27e5f1a612eee84478fea1973311a 100644 --- a/src/main/java/net/minecraft/server/VillagePlaceType.java +++ b/src/main/java/net/minecraft/server/VillagePlaceType.java @@ -14,11 +14,20 @@ import java.util.stream.Collectors; @@ -288,7 +337,7 @@ index a5718af9b614ae505067131f04ebb490617d6aa4..18e4c2b6f8616ededba36caf0b76d39a return this.D; } -+ public final Predicate getPredicate() { return c(); } // Paper - OBFHELPER ++ public final Predicate getCompletionCondition() { return c(); } // Paper - OBFHELPER public Predicate c() { return this.E; } From b4553081f6e72d5c1222b63526a7c74a88e07399 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Tue, 5 Jan 2021 09:48:05 +0200 Subject: [PATCH 6/6] Rebuild patches --- ...595-Optimize-Villagers.patch => 0645-Optimize-Villagers.patch} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Spigot-Server-Patches/{0595-Optimize-Villagers.patch => 0645-Optimize-Villagers.patch} (100%) diff --git a/Spigot-Server-Patches/0595-Optimize-Villagers.patch b/Spigot-Server-Patches/0645-Optimize-Villagers.patch similarity index 100% rename from Spigot-Server-Patches/0595-Optimize-Villagers.patch rename to Spigot-Server-Patches/0645-Optimize-Villagers.patch