diff --git a/patches/server/0001-Tuinity-Server-Changes.patch b/patches/server/0001-Tuinity-Server-Changes.patch index 5ea981b30..166fec33d 100644 --- a/patches/server/0001-Tuinity-Server-Changes.patch +++ b/patches/server/0001-Tuinity-Server-Changes.patch @@ -454,12 +454,12 @@ index 9ba379b7e3ee3bc8c6d2c8ec46213c404c73d682..e83e4241a56fe131a75fe21cc1518992 - https://papermc.io + Tuinity-Server + https://github.com/Spottedleaf/Tuinity - + @@ -19,16 +19,16 @@ - + - com.destroystokyo.paper - paper-parent @@ -468,7 +468,7 @@ index 9ba379b7e3ee3bc8c6d2c8ec46213c404c73d682..e83e4241a56fe131a75fe21cc1518992 dev-SNAPSHOT ../pom.xml - + - com.destroystokyo.paper @@ -517,10 +517,10 @@ index 9ba379b7e3ee3bc8c6d2c8ec46213c404c73d682..e83e4241a56fe131a75fe21cc1518992 + compile + - + @@ -173,15 +183,15 @@ - + - paper-${minecraft.version} @@ -545,12 +545,12 @@ index 884b59d478aa7de49906520e77866a7949bed19d..68ab5ccb2fcfe1de0503c9336572f28e @@ -43,6 +43,9 @@ public final class MinecraftTimings { public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); - + + public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Tuinity - add timings for scoreboard search + public static final Timing distanceManagerTick = Timings.ofSafe("Distance Manager Tick"); // Tuinity - add timings for distance manager + private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); - + private MinecraftTimings() {} diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java index e33e889c291d37a821a4fbd40d9aac7bb079de0d..5dfa0658838c4801cdf260eae8b98163f729e5af 100644 @@ -564,7 +564,7 @@ index e33e889c291d37a821a4fbd40d9aac7bb079de0d..5dfa0658838c4801cdf260eae8b98163 + pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)), // Tuinity - add config to timings report + pair("tuinity", mapAsJSON(Bukkit.spigot().getTuinityConfig(), null)) // Tuinity - add config to timings report )); - + new TimingsExport(listeners, parent, history).start(); diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java index dee00aac05f1acf050f05d4db557a08dd0f301c8..52c0ab1ce46e1f3233ef746d9bc699356fa9fae4 100644 @@ -576,16 +576,16 @@ index dee00aac05f1acf050f05d4db557a08dd0f301c8..52c0ab1ce46e1f3233ef746d9bc69935 if (config.getBoolean("enabled", true)) { - Metrics metrics = new Metrics("Paper", serverUUID, logFailedRequests, Bukkit.getLogger()); + Metrics metrics = new Metrics("Tuinity", serverUUID, logFailedRequests, Bukkit.getLogger()); // Tuinity - we have our own bstats page - + metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { String minecraftVersion = Bukkit.getVersion(); @@ -603,7 +603,7 @@ public class Metrics { - + metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size())); metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() || PaperConfig.isProxyOnlineMode() ? "online" : "offline")); - metrics.addCustomChart(new Metrics.SimplePie("paper_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); + metrics.addCustomChart(new Metrics.SimplePie("tuinity_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); // Tuinity - we have our own bstats page - + metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { Map> map = new HashMap<>(); diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java @@ -595,7 +595,7 @@ index 0abfe19e204d20af0f8dedbeedb0ef98dfe9d3c8..1a876336384198bad2a25c018be5f241 @@ -186,6 +186,44 @@ public class PaperCommand extends Command { } } - + + private void starlightFixLight(EntityPlayer sender, WorldServer world, LightEngineThreaded lightengine, int radius) { + long start = System.nanoTime(); + LinkedHashSet chunks = new LinkedHashSet<>(MCUtil.getSpiralOutChunks(sender.getChunkCoordinates(), radius)); // getChunkCoordinates is actually just bad mappings, this function rets position as blockpos @@ -649,7 +649,7 @@ index 0abfe19e204d20af0f8dedbeedb0ef98dfe9d3c8..1a876336384198bad2a25c018be5f241 @@ -207,6 +245,13 @@ public class PaperCommand extends Command { net.minecraft.server.WorldServer world = (WorldServer) handle.world; LightEngineThreaded lightengine = world.getChunkProvider().getLightEngine(); - + + // Tuinity start - rewrite light engine + if (com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) { + this.starlightFixLight(handle, world, lightengine, radius); @@ -673,10 +673,10 @@ index 49a38c6608b652ff48ef4eaca0dd3ccb1ba570e3..255bbd6e48b95c70fad02ba692c64c75 + String[] parts = serverVersion.substring("git-Tuinity-".length()).split("[-\\s]"); // Tuinity + String updateMessage = getUpdateStatusMessage("Spottedleaf/Tuinity", GITHUB_BRANCH_NAME, parts[0]); // Tuinity String history = getHistory(); - + return history != null ? history + "\n" + updateMessage : updateMessage; @@ -49,13 +49,10 @@ public class PaperVersionFetcher implements VersionFetcher { - + private static String getUpdateStatusMessage(@Nonnull String repo, @Nonnull String branch, @Nonnull String versionInfo) { int distance; - try { @@ -688,7 +688,7 @@ index 49a38c6608b652ff48ef4eaca0dd3ccb1ba570e3..255bbd6e48b95c70fad02ba692c64c75 distance = fetchDistanceFromGitHub(repo, branch, versionInfo); - } + // Tuinity - we don't have jenkins setup - + switch (distance) { case -1: diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java @@ -697,14 +697,14 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 +++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java @@ -186,6 +186,7 @@ public final class PaperTickList extends TickListServer { // extend to avo } - + public void onChunkSetTicking(final int chunkX, final int chunkZ) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list chunk ticking update"); // Tuinity - soft async catcher final ArrayList> pending = this.pendingChunkTickLoad.remove(MCUtil.getCoordinateKey(chunkX, chunkZ)); if (pending == null) { return; @@ -268,6 +269,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override protected void nextTick() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list tick"); // Tuinity - soft async catcher @@ -712,12 +712,12 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 if (this.currentTick != this.world.getTime()) { if (!this.warnedAboutDesync) { @@ -280,6 +282,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public void tick() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list tick"); // Tuinity - soft async catcher final ChunkProviderServer chunkProvider = this.world.getChunkProvider(); - + this.world.getMethodProfiler().enter("cleaning"); @@ -307,6 +310,7 @@ public final class PaperTickList extends TickListServer { // extend to avo if (toTick.tickState == STATE_TICKING) { @@ -729,14 +729,14 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 toTick.tickState = STATE_SCHEDULED; @@ -424,6 +428,7 @@ public final class PaperTickList extends TickListServer { // extend to avo } - + public void schedule(final BlockPosition pos, final T data, final long targetTick, final TickListPriority priority) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list schedule"); // Tuinity - soft async catcher final NextTickListEntry entry = new NextTickListEntry<>(pos, data, targetTick, priority); if (this.excludeFromScheduling.test(entry.getData())) { return; @@ -479,6 +484,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public List> getEntriesInBoundingBox(final StructureBoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get in bounding box"); // Tuinity - soft async catcher @@ -744,7 +744,7 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above } @@ -535,6 +541,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public void copy(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list copy"); // Tuinity - soft async catcher @@ -752,7 +752,7 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 List> list = this.getEntriesInBoundingBox(structureboundingbox, false, false); Iterator> iterator = list.iterator(); @@ -554,6 +561,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public List> getEntriesInChunk(ChunkCoordIntPair chunkPos, boolean removeReturned, boolean excludeTicked) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get"); // Tuinity - soft async catcher @@ -760,21 +760,21 @@ index e7624948ea4aa1a07d84ed3d295cfe2dd354fd14..77df6888803093ad9527d276033f2ed7 // not at ticking status, and ticking status requires neighbours loaded // so with this method we will reduce scheduler churning @@ -585,6 +593,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public NBTTagList serialize(ChunkCoordIntPair chunkcoordintpair) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list serialize"); // Tuinity - soft async catcher // start copy from TickListServer // TODO check on update List> list = this.getEntriesInChunk(chunkcoordintpair, false, true); - + @@ -594,6 +603,7 @@ public final class PaperTickList extends TickListServer { // extend to avo - + @Override public int getTotalScheduledEntries() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("async tick list get size"); // Tuinity - soft async catcher // good thing this is only used in debug reports // TODO check on update int ret = 0; - + diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java index 103576715ef6ae4df4b216ae9ae31b6fb1086bd5..e8fdbe7b8d8192a3247d98534e78ede7a7314a91 100644 --- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java @@ -797,7 +797,7 @@ index cb993ca102402d9c19ea9fa04e5db09c21205896..849686f7b2a8b0044f7cd14c8c2e401e --- a/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java +++ b/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java @@ -34,10 +34,10 @@ public class BoolArgumentType implements ArgumentType { - + @Override public CompletableFuture listSuggestions(final CommandContext context, final SuggestionsBuilder builder) { - if ("true".startsWith(builder.getRemaining().toLowerCase())) { @@ -819,7 +819,7 @@ index bc0024adb804ac055a4f8afb7f85d00ec13931e9..0343f6663c450c3f0d9c57d817eef9c9 private final String remaining; + private String remainingLowercase; public final String getRemainingLowercase() { return this.remainingLowercase == null ? this.remainingLowercase = this.remaining.toLowerCase() : this.remainingLowercase; } // Tuinity private final List result = new ArrayList<>(); - + public SuggestionsBuilder(final String input, final int start) { + // Tuinity start + this(input, start, null); @@ -836,20 +836,20 @@ index 7720578796e28d28e8c0c9aa40155cd205c17d54..e5db29d4cadb5702c7d06b0b6e2d0558 +++ b/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java @@ -20,11 +20,11 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; - + public class LiteralCommandNode extends CommandNode { - private final String literal; + private final String literal; private final String literalLower; // Tuinity - + public LiteralCommandNode(final String literal, final Command command, final Predicate requirement, final CommandNode redirect, final RedirectModifier modifier, final boolean forks) { super(command, requirement, redirect, modifier, forks); - this.literal = literal; + this.literal = literal; this.literalLower = this.literal.toLowerCase(); // Tuinity } - + public String getLiteral() { @@ -66,7 +66,7 @@ public class LiteralCommandNode extends CommandNode { - + @Override public CompletableFuture listSuggestions(final CommandContext context, final SuggestionsBuilder builder) { - if (literal.toLowerCase().startsWith(builder.getRemaining().toLowerCase())) { @@ -5271,7 +5271,7 @@ index 0000000000000000000000000000000000000000..63dfad42c372a33b35c585aaa7ed24d8 + tickWorldsInParallel = TuinityConfig.getBoolean("tick-worlds-in-parallel", false); + tickThreads = TuinityConfig.getInt("server-tick-threads", 1); // will be 4 in the future + }*/ -+ ++ + public static int delayChunkUnloadsBy; + + private static void delayChunkUnloadsBy() { @@ -7726,7 +7726,7 @@ index ed9b2f9adfecdc6d1b9925579ec510657adde11f..5c3d5b22b833d9f835e17803295b8789 @@ -13,6 +13,157 @@ public class AxisAlignedBB { public final double maxY; public final double maxZ; - + + // Tuinity start + public final boolean isEmpty() { + return (this.maxX - this.minX) < MCUtil.COLLISION_EPSILON && (this.maxY - this.minY) < MCUtil.COLLISION_EPSILON && (this.maxZ - this.minZ) < MCUtil.COLLISION_EPSILON; @@ -7884,7 +7884,7 @@ index ed9b2f9adfecdc6d1b9925579ec510657adde11f..5c3d5b22b833d9f835e17803295b8789 @@ -185,6 +336,7 @@ public class AxisAlignedBB { return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); } - + + public final AxisAlignedBB offset(double d0, double d1, double d2) { return this.d(d0, d1, d2); } // Tuinity - OBFHELPER public AxisAlignedBB d(double d0, double d1, double d2) { return new AxisAlignedBB(this.minX + d0, this.minY + d1, this.minZ + d2, this.maxX + d0, this.maxY + d1, this.maxZ + d2); @@ -7892,7 +7892,7 @@ index ed9b2f9adfecdc6d1b9925579ec510657adde11f..5c3d5b22b833d9f835e17803295b8789 @@ -193,6 +345,7 @@ public class AxisAlignedBB { return new AxisAlignedBB(this.minX + (double) blockposition.getX(), this.minY + (double) blockposition.getY(), this.minZ + (double) blockposition.getZ(), this.maxX + (double) blockposition.getX(), this.maxY + (double) blockposition.getY(), this.maxZ + (double) blockposition.getZ()); } - + + public final AxisAlignedBB offset(Vec3D vec3d) { return this.b(vec3d); } // Tuinity - OBFHELPER public AxisAlignedBB c(Vec3D vec3d) { return this.d(vec3d.x, vec3d.y, vec3d.z); @@ -7900,7 +7900,7 @@ index ed9b2f9adfecdc6d1b9925579ec510657adde11f..5c3d5b22b833d9f835e17803295b8789 @@ -212,6 +365,7 @@ public class AxisAlignedBB { return this.e(vec3d.x, vec3d.y, vec3d.z); } - + + public final boolean contains(double d0, double d1, double d2) { return this.e(d0, d1, d2); } // Tuinity - OBFHELPER public boolean e(double d0, double d1, double d2) { return d0 >= this.minX && d0 < this.maxX && d1 >= this.minY && d1 < this.maxY && d2 >= this.minZ && d2 < this.maxZ; @@ -7919,35 +7919,35 @@ index 6b655b744d31d9660c7521ab596b27bcd92f4d58..e811295b4d6afcd920f60e0ce5440e43 + protected int a; // Paper - OBFHELPER // Tuinity - private->protected - diff on change, this is the x coordinate - Also revert the decision to expose set on an immutable type + protected int b; // Paper - OBFHELPER // Tuinity - private->protected - diff on change, this is the y coordinate - Also revert the decision to expose set on an immutable type + protected int e; // Paper - OBFHELPER // Tuinity - private->protected - diff on change, this is the z coordinate - Also revert the decision to expose set on an immutable type - + // Paper start public boolean isValidLocation() { @@ -71,15 +71,15 @@ public class BaseBlockPosition implements Comparable { return this.e; } - + - public void o(int i) { // Paper - protected -> public + protected void o_unused(int i) { // Paper - protected -> public // Tuinity - not needed here - Also revert the decision to expose set on an immutable type this.a = i; } - + - public void p(int i) { // Paper - protected -> public + protected void p_unused(int i) { // Paper - protected -> public // Tuinity - not needed here - Also revert the decision to expose set on an immutable type this.b = i; } - + - public void q(int i) { // Paper - protected -> public + protected void q_unused(int i) { // Paper - protected -> public // Tuinity - not needed here - Also revert the decision to expose set on an immutable type this.e = i; } - + diff --git a/src/main/java/net/minecraft/server/Behavior.java b/src/main/java/net/minecraft/server/Behavior.java index 65af976527133ee5c2f52e411e19c4f7f06df3ef..0b9d469a92decfb0632805791868ef7faa88c535 100644 --- a/src/main/java/net/minecraft/server/Behavior.java +++ b/src/main/java/net/minecraft/server/Behavior.java @@ -7,7 +7,7 @@ import java.util.Map.Entry; public abstract class Behavior { - + protected final Map, MemoryStatus> a; - private Behavior.Status b; + private Behavior.Status b; public final Behavior.Status getStatus() { return this.b; } // Tuinity - OBFHELPER @@ -7961,7 +7961,7 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..8d445e9c0875db6cf45e4d8bcfce7cd3 @@ -55,6 +55,227 @@ public class BehaviorFindPosition extends Behavior { } } - + + // Tuinity - remove streams entirely for poi search + // the only intentional vanilla diff is that this function will NOT load in poi data, anything else is a bug! + protected static Set findNearestPoi(VillagePlace poiStorage, @@ -8193,7 +8193,7 @@ index 63a761ebef80d4af09cdc2682e496d78492c4a3a..8d445e9c0875db6cf45e4d8bcfce7cd3 - Set set = (Set) villageplace.b(this.b.c(), predicate, entitycreature.getChunkCoordinates(), 48, VillagePlace.Occupancy.HAS_SPACE).limit(5L).collect(Collectors.toSet()); + Set set = findNearestPoi(villageplace, this.b.c(), predicate, entitycreature.getChunkCoordinates(), 48, VillagePlace.Occupancy.HAS_SPACE, 5); // Tuinity - remove streams entirely for poi search PathEntity pathentity = entitycreature.getNavigation().a(set, this.b.d()); - + if (pathentity != null && pathentity.j()) { @@ -84,7 +305,7 @@ public class BehaviorFindPosition extends Behavior { villageplace.a(this.b.c(), (blockposition1) -> { @@ -8214,11 +8214,11 @@ index 46e910581210421c8699637431804dc2f43eb4a6..fb967bc03f58fab8cec2732b1890108f private final BehaviorGate.Execution d; - private final WeightedList> e = new WeightedList<>(false); // Paper - don't use a clone + private final WeightedList> e = new WeightedList<>(false); protected final WeightedList> getList() { return this.e; } // Paper - don't use a clone // Tuinity - OBFHELPER - + public BehaviorGate(Map, MemoryStatus> map, Set> set, BehaviorGate.Order behaviorgate_order, BehaviorGate.Execution behaviorgate_execution, List, Integer>> list) { super(map); @@ -26,11 +26,17 @@ public class BehaviorGate extends Behavior { - + @Override protected boolean b(WorldServer worldserver, E e0, long i) { - return this.e.c().filter((behavior) -> { @@ -8238,10 +8238,10 @@ index 46e910581210421c8699637431804dc2f43eb4a6..fb967bc03f58fab8cec2732b1890108f + return false; + // Tuinity end - remove streams } - + @Override @@ -46,20 +52,28 @@ public class BehaviorGate extends Behavior { - + @Override protected void d(WorldServer worldserver, E e0, long i) { - this.e.c().filter((behavior) -> { @@ -8259,7 +8259,7 @@ index 46e910581210421c8699637431804dc2f43eb4a6..fb967bc03f58fab8cec2732b1890108f + } + // Tuinity end - remove streams } - + @Override protected void c(WorldServer worldserver, E e0, long i) { - this.e.c().filter((behavior) -> { @@ -8277,7 +8277,7 @@ index 46e910581210421c8699637431804dc2f43eb4a6..fb967bc03f58fab8cec2732b1890108f + } + // Tuinity end - remove streams BehaviorController behaviorcontroller = e0.getBehaviorController(); - + this.b.forEach(behaviorcontroller::removeMemory); // Paper - decomp fix @@ -79,21 +93,29 @@ public class BehaviorGate extends Behavior { RUN_ONE { @@ -8318,22 +8318,22 @@ index 46e910581210421c8699637431804dc2f43eb4a6..fb967bc03f58fab8cec2732b1890108f + // Tuinity end - remove streams } }; - + diff --git a/src/main/java/net/minecraft/server/BehaviorLookInteract.java b/src/main/java/net/minecraft/server/BehaviorLookInteract.java index a33303c31881b6391723e16a06d7841d48679958..ce57e6a4acac97d6da82202094306e7e91f1c87e 100644 --- a/src/main/java/net/minecraft/server/BehaviorLookInteract.java +++ b/src/main/java/net/minecraft/server/BehaviorLookInteract.java @@ -7,7 +7,7 @@ import java.util.function.Predicate; public class BehaviorLookInteract extends Behavior { - + private final EntityTypes b; - private final int c; + private final int c; private final int getMaxRange() { return this.c; } // Tuinity - OBFHELPER private final Predicate d; private final Predicate e; - + @@ -29,7 +29,20 @@ public class BehaviorLookInteract extends Behavior { - + @Override public boolean a(WorldServer worldserver, EntityLiving entityliving) { - return this.e.test(entityliving) && this.b(entityliving).stream().anyMatch(this::a); @@ -8352,12 +8352,12 @@ index a33303c31881b6391723e16a06d7841d48679958..ce57e6a4acac97d6da82202094306e7e + return false; + // Tuinity end - remove streams } - + @Override @@ -37,16 +50,28 @@ public class BehaviorLookInteract extends Behavior { super.a(worldserver, entityliving, i); BehaviorController behaviorcontroller = entityliving.getBehaviorController(); - + - behaviorcontroller.getMemory(MemoryModuleType.VISIBLE_MOBS).ifPresent((list) -> { - list.stream().filter((entityliving1) -> { - return entityliving1.h((Entity) entityliving) <= (double) this.c; @@ -8386,7 +8386,7 @@ index a33303c31881b6391723e16a06d7841d48679958..ce57e6a4acac97d6da82202094306e7e + } + // Tuinity end - remove streams } - + + private final boolean canTarget(EntityLiving entityliving) { return this.a(entityliving); } // Tuinity - OBFHELPER private boolean a(EntityLiving entityliving) { return this.b.equals(entityliving.getEntityType()) && this.d.test(entityliving); @@ -8396,9 +8396,9 @@ index 1f334d63282bd5c23dc3b275a220f09e60c34537..829d4a7508e1656dbdc912096b7eafcf --- a/src/main/java/net/minecraft/server/BlockBase.java +++ b/src/main/java/net/minecraft/server/BlockBase.java @@ -295,21 +295,23 @@ public abstract class BlockBase { - + public abstract static class BlockData extends IBlockDataHolder { - + - private final int b; - private final boolean e; + private final int b; public final int getEmittedLight() { return this.b; } // Tuinity - OBFHELPER @@ -8420,7 +8420,7 @@ index 1f334d63282bd5c23dc3b275a220f09e60c34537..829d4a7508e1656dbdc912096b7eafcf + protected BlockBase.BlockData.Cache a; protected final BlockBase.BlockData.Cache getShapeCache() { return this.a; } // Tuinity - OBFHELPER + public PathType staticPathType; // Tuinity - cache static path types + public PathType neighbourOverridePathType; // Tuinity - cache static path types - + protected BlockData(Block block, ImmutableMap, Comparable> immutablemap, MapCodec mapcodec) { super(block, immutablemap, mapcodec); @@ -328,6 +330,7 @@ public abstract class BlockBase { @@ -8434,7 +8434,7 @@ index 1f334d63282bd5c23dc3b275a220f09e60c34537..829d4a7508e1656dbdc912096b7eafcf @@ -343,12 +346,62 @@ public abstract class BlockBase { protected Fluid fluid; // Paper end - + + // Tuinity start - micro the hell out of this call + protected boolean shapeExceedsCube = true; + public final boolean shapeExceedsCube() { @@ -8491,30 +8491,30 @@ index 1f334d63282bd5c23dc3b275a220f09e60c34537..829d4a7508e1656dbdc912096b7eafcf + } + } + // Tuinity end - optimise culling shape cache for light - + } - + @@ -372,10 +425,12 @@ public abstract class BlockBase { return this.a != null ? this.a.g : this.getBlock().b(this.p(), iblockaccess, blockposition); } - + + public final int getOpacity(IBlockAccess iblockaccess, BlockPosition blockposition) { return this.b(iblockaccess, blockposition); } // Tuinity - OBFHELPER public int b(IBlockAccess iblockaccess, BlockPosition blockposition) { return this.a != null ? this.a.h : this.getBlock().f(this.p(), iblockaccess, blockposition); } - + + public final VoxelShape getCullingFace(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return this.a(iblockaccess, blockposition, enumdirection); } // Tuinity - OBFHELPER public VoxelShape a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return this.a != null && this.a.i != null ? this.a.i[enumdirection.ordinal()] : VoxelShapes.a(this.c(iblockaccess, blockposition), enumdirection); } @@ -385,7 +440,7 @@ public abstract class BlockBase { } - + public final boolean d() { // Paper - return this.a == null || this.a.c; + return this.shapeExceedsCube; // Tuinity - moved into shape cache init } - + public final boolean e() { // Paper @@ -675,9 +730,9 @@ public abstract class BlockBase { private static final int f = EnumBlockSupport.values().length; @@ -8534,7 +8534,7 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd +++ b/src/main/java/net/minecraft/server/BlockPosition.java @@ -449,10 +449,10 @@ public class BlockPosition extends BaseBlockPosition { } - + public final BlockPosition.MutableBlockPosition setValues(int i, int j, int k) { return d(i, j, k);} // Paper - OBFHELPER - public BlockPosition.MutableBlockPosition d(int i, int j, int k) { - this.o(i); @@ -8546,10 +8546,10 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + ((BaseBlockPosition)this).e = k; // Tuinity - force inline return this; } - + @@ -462,12 +462,18 @@ public class BlockPosition extends BaseBlockPosition { } - + public final BlockPosition.MutableBlockPosition setValues(final BaseBlockPosition baseblockposition) { return this.g(baseblockposition); } // Paper - OBFHELPER - public BlockPosition.MutableBlockPosition g(BaseBlockPosition baseblockposition) { - return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); @@ -8559,7 +8559,7 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + ((BaseBlockPosition)this).e = baseblockposition.e; // Tuinity - force inline + return this; } - + - public BlockPosition.MutableBlockPosition g(long i) { - return this.d(b(i), c(i), d(i)); + public final BlockPosition.MutableBlockPosition g(long i) { // Tuinity @@ -8568,12 +8568,12 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + ((BaseBlockPosition)this).e = (int)((i << 26) >> 38); // Tuinity - force inline + return this; } - + public BlockPosition.MutableBlockPosition a(EnumAxisCycle enumaxiscycle, int i, int j, int k) { @@ -482,8 +488,11 @@ public class BlockPosition extends BaseBlockPosition { return this.d(baseblockposition.getX() + i, baseblockposition.getY() + j, baseblockposition.getZ() + k); } - + - public BlockPosition.MutableBlockPosition c(EnumDirection enumdirection) { - return this.c(enumdirection, 1); + public final BlockPosition.MutableBlockPosition c(EnumDirection enumdirection) { // Tuinity @@ -8582,12 +8582,12 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + ((BaseBlockPosition)this).e += enumdirection.getAdjacentZ(); // Tuinity - force inline + return this; } - + public BlockPosition.MutableBlockPosition c(EnumDirection enumdirection, int i) { @@ -511,21 +520,30 @@ public class BlockPosition extends BaseBlockPosition { } } - + - /* // Paper start - comment out useless overrides @Override - @Override - public void o(int i) { @@ -8603,7 +8603,7 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + public final void setZ(int value) { + ((BaseBlockPosition)this).e = value; } - + - @Override - public void p(int i) { - super.p(i); @@ -8614,7 +8614,7 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd + public final void p(int i) { + ((BaseBlockPosition)this).b = i; } - + - public void q(int i) { - super.q(i); + public final void q(int i) { @@ -8622,7 +8622,7 @@ index 2d887af902a33b0e28d8f0a6ac2e59c815a7856e..2291135eaef64c403183724cb6e413cd } - */ // Paper end + // Tuinity end - + @Override public BlockPosition immutableCopy() { diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java @@ -8632,7 +8632,7 @@ index 3bcd63a754538ccfc5965207a8fc79faa31925c0..68d6fb69a0c1b98b3c11b6d80783faaa @@ -91,6 +91,197 @@ public class Chunk implements IChunkAccess { private final int[] inventoryEntityCounts = new int[16]; // Paper end - + + // Tuinity start - optimise hard collision handling + final com.destroystokyo.paper.util.maplist.EntityList[] hardCollidingEntities = new com.destroystokyo.paper.util.maplist.EntityList[16]; + @@ -8828,7 +8828,7 @@ index 3bcd63a754538ccfc5965207a8fc79faa31925c0..68d6fb69a0c1b98b3c11b6d80783faaa this.sections = new ChunkSection[16]; this.e = Maps.newHashMap(); @@ -298,6 +489,12 @@ public class Chunk implements IChunkAccess { - + public Chunk(World world, ProtoChunk protochunk) { this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.getInhabitedTime(), protochunk.getSections(), (Consumer) null); + // Tuinity start - copy over protochunk light @@ -8838,7 +8838,7 @@ index 3bcd63a754538ccfc5965207a8fc79faa31925c0..68d6fb69a0c1b98b3c11b6d80783faaa + this.setBlockEmptinessMap(protochunk.getBlockEmptinessMap()); + // Tuinity end - copy over protochunk light Iterator iterator = protochunk.y().iterator(); - + while (iterator.hasNext()) { @@ -594,8 +791,8 @@ public class Chunk implements IChunkAccess { entity.chunkX = this.loc.x; @@ -8861,9 +8861,9 @@ index 3bcd63a754538ccfc5965207a8fc79faa31925c0..68d6fb69a0c1b98b3c11b6d80783faaa } if (entity instanceof EntityItem) { @@ -946,6 +1143,7 @@ public class Chunk implements IChunkAccess { - + } - + + public final void getEntities(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { this.a(oclass, axisalignedbb, list, predicate); } // Tuinity - OBFHELPER public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -8874,7 +8874,7 @@ index 8eecdcde510661ec3a13a25a04ba394f6b6dc012..ab1085091fefea3a3fa15f7028bec050 +++ b/src/main/java/net/minecraft/server/ChunkCache.java @@ -1,5 +1,6 @@ package net.minecraft.server; - + +import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; @@ -8882,7 +8882,7 @@ index 8eecdcde510661ec3a13a25a04ba394f6b6dc012..ab1085091fefea3a3fa15f7028bec050 @@ -12,6 +13,156 @@ public class ChunkCache implements IBlockAccess, ICollisionAccess { protected boolean d; protected final World e; protected final World getWorld() { return e; } // Paper - OBFHELPER - + + // Tuinity start - optimise pathfinder collision detection + @Override + public boolean getCubes(Entity entity) { @@ -9063,9 +9063,9 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); // Paper start use a queue, but still keep unique requirement @@ -53,6 +53,47 @@ public abstract class ChunkMapDistance { - + PlayerChunkMap chunkMap; // Paper - + + // Tuinity start - delay chunk unloads + private long nextUnloadId; // delay chunk unloads + private final Long2ObjectOpenHashMap> delayedChunks = new Long2ObjectOpenHashMap<>(); @@ -9112,12 +9112,12 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 Mailbox mailbox = Mailbox.a("player ticket throttler", executor1::execute); @@ -65,21 +106,45 @@ public abstract class ChunkMapDistance { } - + protected void purgeTickets() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async purge tickets"); // Tuinity ++this.currentTick; ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); - + + // Tuinity start - delay chunk unloads + int[] tempLevel = new int[] { PlayerChunkMap.GOLDEN_TICKET + 1 }; + Entry>>[] entryPass = new Entry[1]; @@ -9139,7 +9139,7 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 while (objectiterator.hasNext()) { - Entry>> entry = (Entry) objectiterator.next(); + Entry>> entry = (Entry) objectiterator.next(); entryPass[0] = entry; // Tuinity - only allocate lambda once - + - if ((entry.getValue()).removeIf((ticket) -> { // CraftBukkit - decompile error - return ticket.b(this.currentTick); - })) { @@ -9151,18 +9151,18 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 + // Tuinity end - delay chunk unloads this.ticketLevelTracker.update(entry.getLongKey(), getLowestTicketLevel((ArraySetSorted) entry.getValue()), false); } - + if (((ArraySetSorted) entry.getValue()).isEmpty()) { objectiterator.remove(); } + + tempLevel[0] = PlayerChunkMap.GOLDEN_TICKET + 1; // Tuinity - reset } - + } @@ -98,6 +163,7 @@ public abstract class ChunkMapDistance { protected abstract PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k); - + public boolean a(PlayerChunkMap playerchunkmap) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot tick ChunkMapDistance off of the main-thread");// Tuinity //this.f.a(); // Paper - no longer used @@ -9198,11 +9198,11 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 - // Paper end + // Tuinity end - delay chunk unloads } - + if (arraysetsorted.isEmpty()) { @@ -370,6 +420,7 @@ public abstract class ChunkMapDistance { } - + private ArraySetSorted> e(long i) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async tickets compute"); // Tuinity return (ArraySetSorted) this.tickets.computeIfAbsent(i, (j) -> { @@ -9210,27 +9210,27 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..7f3887b0894aca0f972922f434382646 }); @@ -387,6 +438,7 @@ public abstract class ChunkMapDistance { } - + public void a(SectionPosition sectionposition, EntityPlayer entityplayer) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async player add"); // Tuinity long i = sectionposition.r().pair(); - + ((ObjectSet) this.c.computeIfAbsent(i, (j) -> { @@ -397,6 +449,7 @@ public abstract class ChunkMapDistance { } - + public void b(SectionPosition sectionposition, EntityPlayer entityplayer) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async player remove"); // Tuinity long i = sectionposition.r().pair(); ObjectSet objectset = (ObjectSet) this.c.get(i); if (objectset == null) return; // CraftBukkit - SPIGOT-6208 @@ -447,6 +500,7 @@ public abstract class ChunkMapDistance { - + // CraftBukkit start public void removeAllTicketsFor(TicketType ticketType, int ticketLevel, T ticketIdentifier) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async ticket remove"); // Tuinity Ticket target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier); - + for (java.util.Iterator>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) { diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112bccfa8c3 100644 @@ -9239,7 +9239,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 @@ -22,6 +22,12 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; // Paper import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - + +// Tuinity start +import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator; @@ -9247,19 +9247,19 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 +// Tuinity end + public class ChunkProviderServer extends IChunkProvider { - + private static final List b = ChunkStatus.a(); static final List getPossibleChunkStatuses() { return ChunkProviderServer.b; } // Paper - OBFHELPER @@ -112,7 +118,7 @@ public class ChunkProviderServer extends IChunkProvider { return (Chunk)this.getChunkAt(x, z, ChunkStatus.FULL, true); } - + - private long chunkFutureAwaitCounter; + long chunkFutureAwaitCounter; // Tuinity - private -> package private - + public void getEntityTickingChunkAsync(int x, int z, java.util.function.Consumer onLoad) { if (Thread.currentThread() != this.serverThread) { @@ -174,9 +180,9 @@ public class ChunkProviderServer extends IChunkProvider { - + try { if (onLoad != null) { - playerChunkMap.callbackExecutor.execute(() -> { @@ -9273,7 +9273,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 @@ -201,6 +207,165 @@ public class ChunkProviderServer extends IChunkProvider { } // Paper end - rewrite ticklistserver - + + // Tuinity start + // this will try to avoid chunk neighbours for lighting + public final IChunkAccess getFullStatusChunkAt(int chunkX, int chunkZ) { @@ -9439,7 +9439,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 @@ -544,6 +709,8 @@ public class ChunkProviderServer extends IChunkProvider { Arrays.fill(this.cacheChunk, (Object) null); } - + + private long syncLoadCounter; // Tuinity - prevent plugin unloads from removing our ticket + private CompletableFuture> getChunkFutureMainThread(int i, int j, ChunkStatus chunkstatus, boolean flag) { @@ -9483,30 +9483,30 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 @@ -599,8 +777,8 @@ public class ChunkProviderServer extends IChunkProvider { return !this.a(playerchunk, k); } - + - @Override - public IBlockAccess c(int i, int j) { + public final IBlockAccess getFeaturesReadyChunk(int x, int z) { return this.c(x, z); } // Tuinity - OBFHELPER + @Override public IBlockAccess c(int i, int j) { // Tuinity - OBFHELPER long k = ChunkCoordIntPair.pair(i, j); PlayerChunk playerchunk = this.getChunk(k); - + @@ -637,6 +815,8 @@ public class ChunkProviderServer extends IChunkProvider { - + public boolean tickDistanceManager() { // Paper - private -> public if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper + if (this.playerChunkMap.unloadingPlayerChunk) { MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Tuinity + co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Tuinity - add timings for distance manager boolean flag = this.chunkMapDistance.a(this.playerChunkMap); boolean flag1 = this.playerChunkMap.b(); - + @@ -646,6 +826,7 @@ public class ChunkProviderServer extends IChunkProvider { this.clearCache(); return true; } + } finally { co.aikar.timings.MinecraftTimings.distanceManagerTick.stopTiming(); } // Tuinity - add timings for distance manager } - + public final boolean isInEntityTickingChunk(Entity entity) { return this.a(entity); } // Paper - OBFHELPER @@ -734,7 +915,7 @@ public class ChunkProviderServer extends IChunkProvider { this.world.getMethodProfiler().enter("purge"); @@ -9550,13 +9550,13 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 this.world.getMethodProfiler().exit(); - Optional optional1 = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + // Tuinity - + - if (optional1.isPresent()) { - Chunk chunk = (Chunk) optional1.get(); + if (true) { // Tuinity + // Tuinity ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); - + if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange @@ -845,11 +1030,15 @@ public class ChunkProviderServer extends IChunkProvider { this.world.timings.chunkTicks.startTiming(); // Spigot // Paper @@ -9579,7 +9579,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 @@ -861,7 +1050,25 @@ public class ChunkProviderServer extends IChunkProvider { this.world.getMethodProfiler().exit(); } - + + // Tuinity start - controlled flush for entity tracker packets + List disabledFlushes = new java.util.ArrayList<>(this.world.getPlayers().size()); + for (EntityPlayer player : this.world.getPlayers()) { @@ -9600,7 +9600,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 + } + // Tuinity end - controlled flush for entity tracker packets } - + private void a(long i, Consumer consumer) { @@ -1001,51 +1208,18 @@ public class ChunkProviderServer extends IChunkProvider { ChunkProviderServer.this.world.getMethodProfiler().c("runTask"); @@ -9642,7 +9642,7 @@ index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..fdbf984e64f135abfdee465d76eb1112 - } - // Paper end + // Tuinity - replace logic - + @Override protected boolean executeNext() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot execute chunk tasks off-main thread");// Tuinity @@ -9662,9 +9662,9 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -24,6 +24,14 @@ public class ChunkRegionLoader { - + private static final Logger LOGGER = LogManager.getLogger(); - + + // Tuinity start + // TODO: Check on update + public static long getLastWorldSaveTime(NBTTagCompound chunkData) { @@ -9679,7 +9679,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 @@ -56,6 +64,13 @@ public class ChunkRegionLoader { private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); // Paper end - + + // Tuinity start - rewrite light engine + private static final int STARLIGHT_LIGHT_VERSION = 4; + @@ -9706,11 +9706,11 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 + com.tuinity.tuinity.chunk.light.SWMRNibbleArray[] skyNibbles = com.tuinity.tuinity.chunk.light.StarLightEngine.getFilledEmptyLight(worldserver); // Tuinity - replace light impl + final int minSection = com.tuinity.tuinity.util.WorldUtil.getMinLightSection(worldserver); + final int maxSection = com.tuinity.tuinity.util.WorldUtil.getMaxLightSection(worldserver); - + if (flag) { tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main @@ -119,6 +138,7 @@ public class ChunkRegionLoader { - + if (flag) { if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) { + if (com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine && canUseBlockLight) blockNibbles[b0 - minSection] = new com.tuinity.tuinity.chunk.light.SWMRNibbleArray(nbttagcompound2.getByteArray("BlockLight").clone()); // Tuinity - replace light impl @@ -9719,7 +9719,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 tasksToExecuteOnMain.add(() -> { @@ -128,13 +148,14 @@ public class ChunkRegionLoader { } - + if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) { + if (com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine && canUseSkyLight) skyNibbles[b0 - minSection] = new com.tuinity.tuinity.chunk.light.SWMRNibbleArray(nbttagcompound2.getByteArray("SkyLight").clone()); // Tuinity - replace light impl // Paper start - delay this task since we're executing off-main @@ -9732,7 +9732,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 + } else if (flag2 && nbttagcompound2.getBoolean(UNINITIALISED_SKYLIGHT_TAG)) skyNibbles[b0 - minSection] = new com.tuinity.tuinity.chunk.light.SWMRNibbleArray(); // Tuinity - replace light impl } } - + @@ -173,8 +194,12 @@ public class ChunkRegionLoader { object = new Chunk(worldserver.getMinecraftWorld(), chunkcoordintpair, biomestorage, chunkconverter, (TickList) object1, (TickList) object2, j, achunksection, // Paper start - fix massive nbt memory leak due to lambda. move lambda into a container method to not leak scope. Only clone needed NBT keys. createLoadEntitiesConsumer(new SafeNBTCopy(nbttagcompound1, "TileEntities", "Entities", "ChunkBukkitValues")) // Paper - move CB Chunk PDC into here @@ -9743,13 +9743,13 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 ProtoChunk protochunk = new ProtoChunk(chunkcoordintpair, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, worldserver); // Paper - Anti-Xray - Add parameter + protochunk.setBlockNibbles(blockNibbles); // Tuinity - replace light impl + protochunk.setSkyNibbles(skyNibbles); // Tuinity - replace light impl - + protochunk.a(biomestorage); object = protochunk; @@ -353,15 +378,20 @@ public class ChunkRegionLoader { NibbleArray[] blockLight = new NibbleArray[17 - (-1)]; NibbleArray[] skyLight = new NibbleArray[17 - (-1)]; - + + // Tuinity start - rewrite light impl + final int minSection = com.tuinity.tuinity.util.WorldUtil.getMinLightSection(world); + final int maxSection = com.tuinity.tuinity.util.WorldUtil.getMaxLightSection(world); @@ -9760,7 +9760,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 - NibbleArray skyArray = lightenginethreaded.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkPos, i)); + NibbleArray blockArray = com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? (!lightenginethreaded.hasBlockLight ? null : (chunk.getBlockNibbles()[i - minSection].isAllZero() ? new NibbleArray() : chunk.getBlockNibbles()[i - minSection].toVanillaNibble())) : lightenginethreaded.a(EnumSkyBlock.BLOCK).a(SectionPosition.a(chunkPos, i)); // Tuinity - chunk might not be loaded + NibbleArray skyArray = com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? (!lightenginethreaded.hasSkyLight ? null : (chunk.getSkyNibbles()[i - minSection].isAllZero() ? new NibbleArray() : chunk.getSkyNibbles()[i - minSection].toVanillaNibble())) : lightenginethreaded.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkPos, i)); // Tuinity - chunk might not be loaded - + // copy data for safety - if (blockArray != null) { + if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine && blockArray != null) { // Tuinity - data already copied @@ -9770,7 +9770,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 + if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine && skyArray != null) { // Tuinity - data already copied skyArray = skyArray.copy(); } - + @@ -396,15 +426,19 @@ public class ChunkRegionLoader { } public static NBTTagCompound saveChunk(WorldServer worldserver, IChunkAccess ichunkaccess, AsyncSaveData asyncsavedata) { @@ -9782,7 +9782,7 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); NBTTagCompound nbttagcompound = new NBTTagCompound(); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - + nbttagcompound.setInt("DataVersion", SharedConstants.getGameVersion().getWorldVersion()); - nbttagcompound.set("Level", nbttagcompound1); + nbttagcompound.set("Level", nbttagcompound1); // Tuinity - diff on change @@ -9806,28 +9806,28 @@ index f51bf71c8d6eef3c054ac64765709794fcfad5ee..076d6c1e1cc049dd312ecb30518e7b25 nibblearray1 = asyncsavedata.skyLight[i + 1]; // +1 to offset the -1 starting index @@ -444,12 +478,12 @@ public class ChunkRegionLoader { } - + if (nibblearray != null && !nibblearray.c()) { - nbttagcompound2.setByteArray("BlockLight", nibblearray.asBytesPoolSafe().clone()); // Paper + nbttagcompound2.setByteArray("BlockLight", com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? nibblearray.asBytes() : nibblearray.asBytesPoolSafe().clone()); // Paper // Tuinity - data is already cloned } - + if (nibblearray1 != null && !nibblearray1.c()) { - nbttagcompound2.setByteArray("SkyLight", nibblearray1.asBytesPoolSafe().clone()); // Paper - } + nbttagcompound2.setByteArray("SkyLight", com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? nibblearray1.asBytes() : nibblearray1.asBytesPoolSafe().clone()); // Paper // Tuinity - data is already cloned + } else if (nibblearray1 != null && com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) nbttagcompound2.setBoolean(UNINITIALISED_SKYLIGHT_TAG, true); // Tuinity - store uninitialised tags - + nbttaglist.add(nbttagcompound2); } @@ -457,7 +491,7 @@ public class ChunkRegionLoader { - + nbttagcompound1.set("Sections", nbttaglist); if (flag) { - nbttagcompound1.setBoolean("isLightOn", true); + nbttagcompound1.setBoolean("isLightOn", com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? false : true); if (com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) nbttagcompound1.setInt(STARLIGHT_VERSION_TAG, STARLIGHT_LIGHT_VERSION); // Tuinity } - + BiomeStorage biomestorage = ichunkaccess.getBiomeIndex(); diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java index e52df8096e399c84ff8a2637fdd65ea57d9001d0..33b8f4e0f09fdc41c8ea48b6ed77af199136ab92 100644 @@ -9839,13 +9839,13 @@ index e52df8096e399c84ff8a2637fdd65ea57d9001d0..33b8f4e0f09fdc41c8ea48b6ed77af19 private short e; - final DataPaletteBlock blockIds; // Paper - package-private + public final DataPaletteBlock blockIds; // Paper - package-private // Tuinity - public - + final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper - + @@ -96,6 +96,7 @@ public class ChunkSection { return iblockdata1; } - + + public final boolean isFullOfAir() { return this.c(); } // Tuinity - OBFHELPER public boolean c() { return this.nonEmptyBlockCount == 0; @@ -9860,7 +9860,7 @@ index f6c9bdbf52d773d7aa601125b887b347163f9328..51ea295d66312c95685b9fe4ee502a02 private final ChunkStatus.Type y; - private final EnumSet z; + private final EnumSet z; public final HeightMap.Type[] heightMaps; // Tuinity - + private static CompletableFuture> a(ChunkStatus chunkstatus, LightEngineThreaded lightenginethreaded, IChunkAccess ichunkaccess) { boolean flag = a(chunkstatus, ichunkaccess); @@ -171,7 +171,7 @@ public class ChunkStatus { @@ -9871,7 +9871,7 @@ index f6c9bdbf52d773d7aa601125b887b347163f9328..51ea295d66312c95685b9fe4ee502a02 + this.z = enumset; this.heightMaps = new java.util.ArrayList<>(this.z).toArray(new HeightMap.Type[0]); // Tuinity this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1; } - + diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java index 95ef96286855624590b72d69514b0fc0e08fddba..73163b417af7e522a4509bf9c1ab56d6499be622 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java @@ -9879,11 +9879,11 @@ index 95ef96286855624590b72d69514b0fc0e08fddba..73163b417af7e522a4509bf9c1ab56d6 @@ -163,6 +163,7 @@ public class DataPaletteBlock implements DataPaletteExpandable { return this.a(j << 8 | k << 4 | i); // Paper - inline } - + + public final T rawGet(int index) { return this.a(index); } // Tuinity - OBFHELPER protected T a(int i) { T t0 = this.h.a(this.a.a(i)); - + diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java index 5504facd2e453238caa71d98743be5416d4dd4fe..ecff0657e5666ddc2e6a5c3111bfb2b8dd2b78d3 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java @@ -9893,17 +9893,17 @@ index 5504facd2e453238caa71d98743be5416d4dd4fe..ecff0657e5666ddc2e6a5c3111bfb2b8 com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now // Paper end + com.tuinity.tuinity.config.TuinityConfig.init((java.io.File) options.valueOf("tuinity-settings")); // Tuinity - Server Config - + this.setPVP(dedicatedserverproperties.pvp); this.setAllowFlight(dedicatedserverproperties.allowFlight); @@ -357,7 +358,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } - + if (this.q != null) { - this.q.b(); + //this.q.b(); // Tuinity - do not wait for AWT, causes deadlock with sigint handler (AWT shutdown will properly clear our resources anyways) } - + if (this.remoteControlListener != null) { diff --git a/src/main/java/net/minecraft/server/EULA.java b/src/main/java/net/minecraft/server/EULA.java index 550232cb3819138b3bae0fa1c51429485e8bc593..229c3b0f0c650b501f31147adaa17194af57fedd 100644 @@ -9911,7 +9911,7 @@ index 550232cb3819138b3bae0fa1c51429485e8bc593..229c3b0f0c650b501f31147adaa17194 +++ b/src/main/java/net/minecraft/server/EULA.java @@ -70,7 +70,7 @@ public class EULA { Properties properties = new Properties(); - + properties.setProperty("eula", "false"); - properties.store(outputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).\nYou also agree that tacos are tasty, and the best food in the world."); // Paper - fix lag; + properties.store(outputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula)."); // Paper - fix lag; // Tuinity - Tacos are disgusting @@ -9934,7 +9934,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d @@ -207,6 +207,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } // CraftBukkit end - + + // Tuinity start + public final AxisAlignedBB getBoundingBoxAt(double x, double y, double z) { + double widthHalf = (double)this.size.width / 2.0; @@ -9945,11 +9945,11 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d + // Paper start - optimise entity tracking final org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = org.spigotmc.TrackingRange.getTrackingRangeType(this); - + @@ -222,6 +230,41 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } // Paper end - optimise entity tracking - + + // Tuinity start + /** + * Overriding this field will cause memory leaks. @@ -9991,7 +9991,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d @@ -591,7 +634,39 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.onGround; } - + + // Tuinity start - detailed watchdog information + private Vec3D moveVector; + private double moveStartX; @@ -10030,16 +10030,16 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d this.recalcPosition(); @@ -619,7 +694,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // Paper end - + vec3d = this.a(vec3d, enummovetype); - Vec3D vec3d1 = this.g(vec3d); + Vec3D vec3d1 = this.performCollision(vec3d); // Tuinity - optimise collisions - + if (vec3d1.g() > 1.0E-7D) { this.a(this.getBoundingBox().c(vec3d1)); @@ -710,7 +785,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } - + try { - this.checkBlockCollisions(); + this.checkBlockCollisions(this.fireTicks <= 0); // Tuinity - move fire checking into method here @@ -10048,7 +10048,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision"); @@ -722,11 +797,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke float f2 = this.getBlockSpeedFactor(); - + this.setMot(this.getMot().d((double) f2, 1.0D, (double) f2)); - if (this.world.c(this.getBoundingBox().shrink(0.001D)).noneMatch((iblockdata1) -> { - return iblockdata1.a((Tag) TagsBlock.FIRE) || iblockdata1.a(Blocks.LAVA); @@ -10056,11 +10056,11 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d - this.setFireTicks(-this.getMaxFireTicks()); - } + // Tuinity - move into checkBlockCollisions - + if (this.aG() && this.isBurning()) { this.playSound(SoundEffects.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); @@ -735,6 +806,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - + this.world.getMethodProfiler().exit(); } + // Tuinity start - detailed watchdog information @@ -10071,12 +10071,12 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d + } + // Tuinity end - detailed watchdog information } - + protected BlockPosition ap() { @@ -815,6 +893,137 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return d0; } - + + // Tuinity start - optimise entity movement + private static double performCollisionsX(AxisAlignedBB currentBoundingBox, double value, List potentialCollisions) { + for (int i = 0, len = potentialCollisions.size(); i < len; ++i) { @@ -10214,14 +10214,14 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d @@ -850,6 +1059,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return vec3d1; } - + + public static double getXZSquared(Vec3D vec3d) { return Entity.c(vec3d); } // Tuinity - OBFHELPER public static double c(Vec3D vec3d) { return vec3d.x * vec3d.x + vec3d.z * vec3d.z; } @@ -962,18 +1172,34 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } - + protected void checkBlockCollisions() { + // Tuinity start + this.checkBlockCollisions(false); @@ -10233,7 +10233,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d BlockPosition blockposition = new BlockPosition(axisalignedbb.minX + 0.001D, axisalignedbb.minY + 0.001D, axisalignedbb.minZ + 0.001D); BlockPosition blockposition1 = new BlockPosition(axisalignedbb.maxX - 0.001D, axisalignedbb.maxY - 0.001D, axisalignedbb.maxZ - 0.001D); BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - + if (this.world.areChunksLoadedBetween(blockposition, blockposition1)) { - for (int i = blockposition.getX(); i <= blockposition1.getX(); ++i) { - for (int j = blockposition.getY(); j <= blockposition1.getY(); ++j) { @@ -10245,7 +10245,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d + // Tuinity end - reorder iteration to more cache aware blockposition_mutableblockposition.d(i, j, k); IBlockData iblockdata = this.world.getType(blockposition_mutableblockposition); - + + // Tuinity start - move fire checking in here - reuse getType from this method + if (checkFire) { + if (!inFire && (iblockdata.a(TagsBlock.FIRE) || iblockdata.a(Blocks.LAVA))) { @@ -10267,12 +10267,12 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d + } + // Tuinity end - move fire checking in here - reuse getType from this method } - + } @@ -1358,6 +1589,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return d3 * d3 + d4 * d4 + d5 * d5; } - + + public final double getDistanceSquared(Entity other) { return this.h(other); } // Tuinity - OBFHELPER public double h(Entity entity) { return this.e(entity.getPositionVector()); @@ -10280,7 +10280,7 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d @@ -1945,9 +2177,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke float f1 = this.size.width * 0.8F; AxisAlignedBB axisalignedbb = AxisAlignedBB.g((double) f1, 0.10000000149011612D, (double) f1).d(this.locX(), this.getHeadY(), this.locZ()); - + - return this.world.b(this, axisalignedbb, (iblockdata, blockposition) -> { + return ((WorldServer)this.world).collidesWithAnyBlockOrWorldBorder(this, axisalignedbb, false, false, (iblockdata, blockposition) -> { // Tuinity - use optimised method return iblockdata.o(this.world, blockposition); @@ -10288,48 +10288,48 @@ index d8787985ab4c94e9808332c15b3d16d4b52ba195..2b76b5a70280def08f239ff387407a9d + }); // Tuinity - use optimised method } } - + @@ -1955,11 +2187,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return EnumInteractionResult.PASS; } - + - public boolean j(Entity entity) { + public final boolean hardCollidesWith(Entity other) { return this.j(other); } // Tuinity - OBFHELPER + public boolean j(Entity entity) { // Tuinity - diff on change, hard colliding entities override this return entity.aZ() && !this.isSameVehicle(entity); } - + - public boolean aZ() { + public final boolean collisionBoxIsHard() { return this.aZ(); } // Tuinity - OBFHELPER + public boolean aZ() {// Tuinity - diff on change, hard colliding entities override this return false; } - + @@ -2850,7 +3084,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.recursiveStream().forEach((entity) -> { worldserver.chunkCheck(entity); entity.az = true; - Iterator iterator = entity.passengers.iterator(); + Iterator iterator = new java.util.ArrayList<>(entity.passengers).iterator(); // Tuinity - copy list to guard against CME - + while (iterator.hasNext()) { Entity entity1 = (Entity) iterator.next(); @@ -3308,12 +3542,16 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.locBlock; } - + + public final Object posLock = new Object(); // Tuinity - log detailed entity tick information + public Vec3D getMot() { return this.mot; } - + public void setMot(Vec3D vec3d) { + synchronized (this.posLock) { // Tuinity this.mot = vec3d; + } // Tuinity } - + public void setMot(double d0, double d1, double d2) { @@ -3368,7 +3606,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } @@ -10347,23 +10347,23 @@ index 1e7f5957d879d1ba8cf2b29cf9397b8e204e4381..f983516b89cdf7ce7fdea8f5a5b1a29d +++ b/src/main/java/net/minecraft/server/EntityArrow.java @@ -173,8 +173,10 @@ public abstract class EntityArrow extends IProjectile { // Paper end - + if (object != null && !flag) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, (MovingObjectPosition) object)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly this.a((MovingObjectPosition) object); this.impulse = true; + } // Tuinity - implement cancellation properly } - + if (movingobjectpositionentity == null || this.getPierceLevel() <= 0) { diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java index 8bc8dcf7dfe79c5522bc715ad60aeaab4b1d85da..675083e3952779e43bf8cc3175ad70458a79e49c 100644 --- a/src/main/java/net/minecraft/server/EntityCat.java +++ b/src/main/java/net/minecraft/server/EntityCat.java @@ -292,7 +292,7 @@ public class EntityCat extends EntityTameableAnimal { - + WorldServer worldserver = worldaccess.getMinecraftWorld(); - + - if (worldserver instanceof WorldServer && ((WorldServer) worldserver).getStructureManager().a(this.getChunkCoordinates(), true, StructureGenerator.SWAMP_HUT).e()) { + if (worldserver instanceof WorldServer && ((WorldServer) worldserver).getStructureManager().getStructureStarts(this.getChunkCoordinates(), true, StructureGenerator.SWAMP_HUT, worldaccess).e()) { // Tuinity - fix deadlock on chunk gen this.setCatType(10); @@ -10375,12 +10375,12 @@ index 0840fdf3585407ec317f0326359619220c64db78..6b9b64539d2272070b523ed6b927de02 +++ b/src/main/java/net/minecraft/server/EntityFireball.java @@ -67,7 +67,9 @@ public abstract class EntityFireball extends IProjectile { // Paper end - + if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled + if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly this.a(movingobjectposition); + } // Tuinity - implement cancellation properly - + // CraftBukkit start - Fire ProjectileHitEvent if (this.dead) { diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java @@ -10389,14 +10389,14 @@ index a646dc9f030ad1f76ba2b7bb1bc7897cd34b648c..dd18eabd7104995f0e6a8ecb279a3872 +++ b/src/main/java/net/minecraft/server/EntityFireworks.java @@ -124,8 +124,10 @@ public class EntityFireworks extends IProjectile { MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a); - + if (!this.noclip) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly this.a(movingobjectposition); this.impulse = true; + } // Tuinity - implement cancellation properly } - + this.x(); diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java index e97c7794e86c0518bcec0a0370bffbeab20e2623..0816ab54bc99bcf29356b56516e83759a3f2988f 100644 @@ -10405,12 +10405,12 @@ index e97c7794e86c0518bcec0a0370bffbeab20e2623..0816ab54bc99bcf29356b56516e83759 @@ -226,7 +226,9 @@ public class EntityFishingHook extends IProjectile { private void m() { MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a); - + + if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly this.a(movingobjectposition); + } // Tuinity - implement cancellation properly } - + @Override diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java index a88521745f9f9b6935a61db52db915ea483af227..8a5e2806e68e5f4431fd9563fae780861e87632f 100644 @@ -10428,7 +10428,7 @@ index a88521745f9f9b6935a61db52db915ea483af227..8a5e2806e68e5f4431fd9563fae78086 + entityhuman = ((WorldServer)this.world).playersAffectingSpawning.isEmpty() ? null : ((WorldServer)this.world).playersAffectingSpawning.get(0); + } + // Tuinity end - optimise checkDespawn - + if (entityhuman != null) { double d0 = entityhuman.h((Entity) this); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java @@ -10436,7 +10436,7 @@ index f41aaa7623c052b9f4044898d1bdee898c03057a..d99cecc4075338d7b8f154ab94d8ac04 --- a/src/main/java/net/minecraft/server/EntityItem.java +++ b/src/main/java/net/minecraft/server/EntityItem.java @@ -526,7 +526,7 @@ public class EntityItem extends Entity { - + // Paper start - fix MC-4 public void setPositionRaw(double x, double y, double z) { - if (com.destroystokyo.paper.PaperConfig.fixEntityPositionDesync) { @@ -10458,7 +10458,7 @@ index b7a362bd9c5e9dae909b863335bae3a94d404a16..87b66c284208f12e9e7cd1c9950ada8d + this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.pushable(this, world.paperConfig.fixClimbingBypassingCrammingRule), list); // Paper - fix climbing bypassing cramming rule + try { + // Tuinity end - reduce memory allocation from collideNearby - + if (!list.isEmpty()) { // Paper - move up @@ -2908,6 +2912,9 @@ public abstract class EntityLiving extends Entity { @@ -10468,22 +10468,22 @@ index b7a362bd9c5e9dae909b863335bae3a94d404a16..87b66c284208f12e9e7cd1c9950ada8d + } finally { // Tuinity start - reduce memory allocation from collideNearby + com.tuinity.tuinity.util.CachedLists.returnTempGetEntitiesList(list); + } // Tuinity end - reduce memory allocation from collideNearby - + } - + diff --git a/src/main/java/net/minecraft/server/EntityLlamaSpit.java b/src/main/java/net/minecraft/server/EntityLlamaSpit.java index 7636a51a7ef0aa05b5b2aaa9d17e7b551dedac96..480a02a8f6ec7110f9af8f2037fdc09a7a54ef01 100644 --- a/src/main/java/net/minecraft/server/EntityLlamaSpit.java +++ b/src/main/java/net/minecraft/server/EntityLlamaSpit.java @@ -19,7 +19,9 @@ public class EntityLlamaSpit extends IProjectile { MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a); - + if (movingobjectposition != null) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // CraftBukkit - Call event // Paper - make cancellable // Tuinity - implement cancellation properly this.a(movingobjectposition); + } // Tuinity - implement cancellation properly } - + double d0 = this.locX() + vec3d.x; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index a9a409eebabae11ab84cf9bcced1f9a030b4a479..173a210392d71cdfc551f095dc0d9c9040d22d3f 100644 @@ -10492,7 +10492,7 @@ index a9a409eebabae11ab84cf9bcced1f9a030b4a479..173a210392d71cdfc551f095dc0d9c90 @@ -528,6 +528,185 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } } - + + /* // TODO remove debug + this.networkManager.disableAutomaticFlush(); + @@ -10693,9 +10693,9 @@ index 23017b5486530bcf76b3934cfa8621e8b4772b27..a4d94385ede0303417d676155c2c0b22 --- a/src/main/java/net/minecraft/server/EntityShulkerBullet.java +++ b/src/main/java/net/minecraft/server/EntityShulkerBullet.java @@ -206,7 +206,7 @@ public class EntityShulkerBullet extends IProjectile { - + MovingObjectPosition movingobjectposition = ProjectileHelper.a((Entity) this, this::a); - + - if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { + if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS && org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) { // Tuinity - implement cancellation properly this.a(movingobjectposition); @@ -10706,17 +10706,17 @@ index 3960a975e74ed81c45819fe5e0f01c6c18252982..81869215876d10a84ab27c0e6f41963c --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -74,6 +74,7 @@ public class EntityTrackerEntry { - + public final void tick() { this.a(); } // Paper - OBFHELPER public void a() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Tracker update"); // Tuinity List list = this.tracker.getPassengers(); - + if (!list.equals(this.p)) { @@ -156,7 +157,7 @@ public class EntityTrackerEntry { // Paper end - remove allocation of Vec3D here boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; - + - if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.isOnGround()) { + if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.isOnGround() && !(com.tuinity.tuinity.config.TuinityConfig.sendFullPosForHardCollidingEntities && this.tracker.hardCollides())) { // Tuinity - send full pos for hard colliding entities to prevent collision problems due to desync if ((!flag2 || !flag3) && !(this.tracker instanceof EntityArrow)) { @@ -10729,14 +10729,14 @@ index 05b0090ae36cf61f67e26aad478df30c89f31941..30ba21ac1bced18a9d0946b7c3ed5597 @@ -170,8 +170,8 @@ public enum EnumDirection implements INamable { return EnumDirection.q[MathHelper.a(i % EnumDirection.q.length)]; } - + - @Nullable - public static EnumDirection a(int i, int j, int k) { + @Nullable public static EnumDirection from(int i, int j, int k) { return a(i, j, k); } // Tuinity - OBFHELPER + @Nullable public static EnumDirection a(int i, int j, int k) { return (EnumDirection) EnumDirection.r.get(BlockPosition.a(i, j, k)); } - + diff --git a/src/main/java/net/minecraft/server/HeightMap.java b/src/main/java/net/minecraft/server/HeightMap.java index 068b92c5c4ae112771757626ea75694e59f3d255..476da43b9f0ef35b4985f88e4784b1f8c5222af3 100644 --- a/src/main/java/net/minecraft/server/HeightMap.java @@ -10744,7 +10744,7 @@ index 068b92c5c4ae112771757626ea75694e59f3d255..476da43b9f0ef35b4985f88e4784b1f8 @@ -101,6 +101,7 @@ public class HeightMap { } } - + + public final int get(int x, int z) { return this.a(x, z); } // Tuinity - OBFHELPER public int a(int i, int j) { return this.a(c(i, j)); @@ -10757,11 +10757,11 @@ index 068b92c5c4ae112771757626ea75694e59f3d255..476da43b9f0ef35b4985f88e4784b1f8 + private static final Map k = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // Tuinity - decompile fix HeightMap.Type[] aheightmap_type = values(); int i = aheightmap_type.length; - + @@ -149,7 +150,7 @@ public class HeightMap { - + }); - + - private Type(String s, HeightMap.Use heightmap_use, Predicate predicate) { + private Type(String s, HeightMap.Use heightmap_use, Predicate predicate) { // Tuinity - decompile fix this.h = s; @@ -10787,7 +10787,7 @@ index 180b6b58dc5663158db84b6f1257591439b48c31..eb0d794b7275af7f860e7c7b85a9e3b2 @@ -24,6 +24,36 @@ public interface IChunkAccess extends IBlockAccess, IStructureAccess { } // Paper end - + + // Tuinity start + default com.tuinity.tuinity.chunk.light.SWMRNibbleArray[] getBlockNibbles() { + throw new UnsupportedOperationException(this.getClass().getName()); @@ -10824,18 +10824,18 @@ index 180b6b58dc5663158db84b6f1257591439b48c31..eb0d794b7275af7f860e7c7b85a9e3b2 @@ -122,6 +152,7 @@ public interface IChunkAccess extends IBlockAccess, IStructureAccess { @Nullable NBTTagCompound j(BlockPosition blockposition); - + + default Stream getLightSources() { return this.m(); } // Tuinity - OBFHELPER Stream m(); - + TickList n(); @@ -142,7 +173,9 @@ public interface IChunkAccess extends IBlockAccess, IStructureAccess { return ashortlist[i]; } - + + default boolean isLit() { return this.r(); } // Tuinity - OBFHELPER boolean r(); - + + default void setLit(boolean lit) { this.b(lit); } // Tuinity - OBFHELPER void b(boolean flag); } @@ -10845,7 +10845,7 @@ index 582a5695bac7d078e3022b8ee70c512c0680d992..5601088cd5024a40e8296bab979f43de +++ b/src/main/java/net/minecraft/server/IChunkLoader.java @@ -21,7 +21,7 @@ public class IChunkLoader implements AutoCloseable { protected final RegionFileCache regionFileCache; - + public IChunkLoader(File file, DataFixer datafixer, boolean flag) { - this.regionFileCache = new RegionFileCache(file, flag); // Paper - nuke IOWorker + this.regionFileCache = new RegionFileCache(file, flag, true); // Paper - nuke IOWorker // Tuinity @@ -10858,7 +10858,7 @@ index 25e54a1fadc5d31fb250a3f47524b4f345fc8cc6..cce0ac8a36bef3b9e5a2b95e0c3dd137 +++ b/src/main/java/net/minecraft/server/ICollisionAccess.java @@ -28,6 +28,11 @@ public interface ICollisionAccess extends IBlockAccess { } - + default boolean b(AxisAlignedBB axisalignedbb) { + // Tuinity start - allow overriding in WorldServer + return this.getCubes(axisalignedbb); @@ -10870,7 +10870,7 @@ index 25e54a1fadc5d31fb250a3f47524b4f345fc8cc6..cce0ac8a36bef3b9e5a2b95e0c3dd137 }); @@ -46,6 +51,11 @@ public interface ICollisionAccess extends IBlockAccess { } - + default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + // Tuinity start - allow overriding in WorldServer + return this.getCubes(entity, axisalignedbb, predicate); @@ -10887,7 +10887,7 @@ index 2639c17b7f6100533f33124f9e49990cd303d161..93f2ac996904ddefed04704e554209d0 @@ -55,16 +55,26 @@ public interface IEntityAccess { return this.b(oclass, axisalignedbb, IEntitySelector.g); } - + + // Tuinity start - optimise hard collision + /** + * Not guaranteed to only return hard colliding entities @@ -10903,57 +10903,57 @@ index 2639c17b7f6100533f33124f9e49990cd303d161..93f2ac996904ddefed04704e554209d0 } else { - AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); + AxisAlignedBB axisalignedbb1 = axisalignedbb.g(-1.0E-7D); // Tuinity - to comply with vanilla intersection rules, expand by -epsilon so we only get stuff we definitely collide with. expanding by +epsilon gives us stuff we don't collide with, which will screw over callers in some cases. - + - return this.getEntities(entity, axisalignedbb1, predicate.and((entity1) -> { + if (predicate == null) predicate = (e) -> true; // Tuinity - allow nullable + predicate = predicate.and((entity1) -> { // Tuinity - optimise entity hard collisions // Tuinity - allow nullable boolean flag; - + - if (entity1.getBoundingBox().c(axisalignedbb1)) { + if (true || entity1.getBoundingBox().c(axisalignedbb1)) { // Tuinity - always true, wtf did they think this.getEntities(entity, axisalignedbb1) does? label25: { if (entity == null) { @@ -82,7 +92,7 @@ public interface IEntityAccess { - + flag = false; return flag; - })).stream().map(Entity::getBoundingBox).map(VoxelShapes::a); + }); return ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb1, predicate) : this.getHardCollidingEntities(entity, axisalignedbb1, predicate)).stream().map(Entity::getBoundingBox).map(VoxelShapes::a); // Tuinity - optimise entity hard collisions } } - + @@ -204,12 +214,12 @@ public interface IEntityAccess { } - + @Nullable - default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { + default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" return this.a(this.a(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix } - + @Nullable - default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { + default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" return this.a(this.b(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix } - + diff --git a/src/main/java/net/minecraft/server/ILightAccess.java b/src/main/java/net/minecraft/server/ILightAccess.java index be5384ee41290b24b0c419c3e8f4553db34b2399..df28f7a6bf4c650a22ddf046eae4d5e8ca5879a9 100644 --- a/src/main/java/net/minecraft/server/ILightAccess.java +++ b/src/main/java/net/minecraft/server/ILightAccess.java @@ -4,9 +4,10 @@ import javax.annotation.Nullable; - + public interface ILightAccess { - + - @Nullable - IBlockAccess c(int i, int j); + default @Nullable IBlockAccess getFeaturesReadyChunk(int i, int j) { return this.c(i, j); } // Tuinity - OBFHELPER + @Nullable IBlockAccess c(int i, int j); - + + default void markLightSectionDirty(EnumSkyBlock enumskyblock, SectionPosition sectionposition) { this.a(enumskyblock, sectionposition); } // Tuinity - OBFHELPER default void a(EnumSkyBlock enumskyblock, SectionPosition sectionposition) {} - + IBlockAccess getWorld(); diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java index bbc089b41fcbe0141f13591db2cb44b9e688cac4..dc9f2a1a132b3a7925bd62aa1da0512afd90b8b1 100644 @@ -10961,12 +10961,12 @@ index bbc089b41fcbe0141f13591db2cb44b9e688cac4..dc9f2a1a132b3a7925bd62aa1da0512a +++ b/src/main/java/net/minecraft/server/IProjectile.java @@ -118,7 +118,7 @@ public abstract class IProjectile extends Entity { } - + protected void a(MovingObjectPosition movingobjectposition) { - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition)) return; // CraftBukkit - Call event // Paper - make cancellable + // Tuinity - proper cancellation requires moving this into the caller (see method overrides) - TODO this unfortunately means we need to manually inspect each call on update MovingObjectPosition.EnumMovingObjectType movingobjectposition_enummovingobjecttype = movingobjectposition.getType(); - + if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.ENTITY) { diff --git a/src/main/java/net/minecraft/server/LightEngineGraphSection.java b/src/main/java/net/minecraft/server/LightEngineGraphSection.java index 13d067f48647dea63ef1bf3a2a3e0868074ba75f..04afd7f285db2f281a038e0be6f557b8a692936b 100644 @@ -10975,10 +10975,10 @@ index 13d067f48647dea63ef1bf3a2a3e0868074ba75f..04afd7f285db2f281a038e0be6f557b8 @@ -74,8 +74,10 @@ public abstract class LightEngineGraphSection extends LightEngineGraph { return i == Long.MAX_VALUE ? this.b(j) : k + 1; } - + + public final int getSource(long coordinate) { return this.b(coordinate); } // Tuinity - OBFHELPER protected abstract int b(long i); - + + public final void update(long coordinate, int level, boolean flag) { this.b(coordinate, level, flag); } // Tuinity - OBFHELPER public void b(long i, int j, boolean flag) { this.a(Long.MAX_VALUE, i, j, flag); @@ -10998,21 +10998,21 @@ index b98e60772bad7e06845b50fdc11e98c0ea775d3d..e0bbfe1422cbad811ecb43d7436380d8 private final LongSet o = new LongOpenHashSet(); private final LongSet p = new LongOpenHashSet(); @@ -247,7 +248,7 @@ public abstract class LightEngineStorage> e - + this.p.clear(); this.j = false; - ObjectIterator objectiterator = this.i.long2ObjectEntrySet().iterator(); + ObjectIterator objectiterator = this.i_synchronized_map_real.long2ObjectEntrySet().fastIterator(); // Tuinity - use fast iterator to reduce entry creation - + Entry entry; long j; @@ -284,7 +285,7 @@ public abstract class LightEngineStorage> e } - + this.n.clear(); - objectiterator = this.i.long2ObjectEntrySet().iterator(); + objectiterator = this.i_synchronized_map_real.long2ObjectEntrySet().fastIterator(); // Tuinity - use fast iterator to reduce entry creation; - + while (objectiterator.hasNext()) { entry = (Entry) objectiterator.next(); diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java @@ -11020,7 +11020,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 --- a/src/main/java/net/minecraft/server/LightEngineThreaded.java +++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java @@ -2,6 +2,11 @@ package net.minecraft.server; - + import com.mojang.datafixers.util.Pair; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; // Paper +// Tuinity start @@ -11033,13 +11033,13 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 import it.unimi.dsi.fastutil.objects.ObjectListIterator; @@ -15,11 +20,12 @@ import org.apache.logging.log4j.Logger; public class LightEngineThreaded extends LightEngine implements AutoCloseable { - + private static final Logger LOGGER = LogManager.getLogger(); - private final ThreadedMailbox b; + private final ThreadedMailbox b; private ThreadedMailbox getExecutor() { return this.b; } // Tuinity - OBFHELPER // Paper start private static final int MAX_PRIORITIES = PlayerChunkMap.GOLDEN_TICKET + 2; - + private boolean isChunkLightStatus(long pair) { + if (true) return true; // Tuinity - viewing ticket levels async can result in the viewing of transient levels, and LIGHT ticket isn't guaranteed to exist for all loading chunks thanks to really dumb unloading behaviors with the chunk system PlayerChunk playerChunk = playerChunkMap.getVisibleChunk(pair); @@ -11048,7 +11048,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 @@ -156,13 +162,218 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { private volatile int f = 5; private final AtomicBoolean g = new AtomicBoolean(); - + + // Tuinity start - replace light engine impl + protected final com.tuinity.tuinity.chunk.light.StarLightInterface theLightEngine; + public final boolean hasBlockLight; @@ -11230,7 +11230,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 + } + }, this.playerChunkMap.mainInvokingExecutor); } - + + // override things from superclass + + @Override @@ -11262,12 +11262,12 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 + // Tuinity end - replace light engine impl + public void close() {} - + @Override @@ -179,6 +390,15 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { public void a(BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.immutableCopy(); - + + // Tuinity start - replace light engine impl + if (this.theLightEngine != null) { + this.scheduleLightWorkTask(blockposition1.getX() >> 4, blockposition1.getZ() >> 4, LightEngineThreaded.Update.POST_UPDATE, () -> { @@ -11282,7 +11282,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 }, () -> { @@ -187,6 +407,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { } - + protected void a(ChunkCoordIntPair chunkcoordintpair) { + // Tuinity start - replace light impl + if (this.theLightEngine != null) { @@ -11293,7 +11293,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 return 0; }, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { @@ -211,6 +436,14 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - + @Override public void a(SectionPosition sectionposition, boolean flag) { + // Tuinity start - replace light engine impl @@ -11308,7 +11308,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 return 0; }, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { @@ -222,6 +455,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - + @Override public void a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + // Tuinity start - replace light impl @@ -11320,7 +11320,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 super.a(chunkcoordintpair, flag); }, () -> { @@ -231,6 +469,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - + @Override public void a(EnumSkyBlock enumskyblock, SectionPosition sectionposition, @Nullable NibbleArray nibblearray, boolean flag) { + // Tuinity start - replace light impl @@ -11334,13 +11334,13 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 @@ -240,6 +483,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { })); } - + + private void scheduleTask(int x, int z, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { this.a(x, z, lightenginethreaded_update, runnable); } // Tuinity - OBFHELPER private void a(int i, int j, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { this.a(i, j, this.d.c(ChunkCoordIntPair.pair(i, j)), lightenginethreaded_update, runnable); } @@ -252,6 +496,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { - + @Override public void b(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + // Tuinity start - replace light impl @@ -11354,7 +11354,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 @@ -264,6 +513,35 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { public CompletableFuture a(IChunkAccess ichunkaccess, boolean flag) { ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - + + // Tuinity start - replace light engine + if (this.theLightEngine != null) { + // make the completion of this future only depend on pre-update execution @@ -11389,7 +11389,7 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 long pair = chunkcoordintpair.pair(); @@ -311,7 +589,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { } - + public void queueUpdate() { - if ((!this.queue.isEmpty() || super.a()) && this.g.compareAndSet(false, true)) { // Paper + if ((!this.queue.isEmpty() || (this.theLightEngine == null && super.a())) && this.g.compareAndSet(false, true)) { // Paper // Tuinity - replace light impl @@ -11433,14 +11433,14 @@ index 2f9c97dd4e1d705a87772d18c7ab4883a876af08..001ac05cf26237eec8a77c476e678ff6 + //final long end = System.nanoTime(); // TODO remove debug + //System.out.println("Block updates took " + (end - start) * 1.0e-6 + "ms"); // TODO remove debug } - + public void a(int i) { diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java index c61cd50df0c81f7ab12bd0c955fd6f07f2b02e64..d987483255195c0bde713a92676baced1eaff2b3 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java @@ -234,7 +234,7 @@ public class LoginListener implements PacketLoginInListener { - + s = (new BigInteger(MinecraftEncryption.a("", this.server.getKeyPair().getPublic(), this.loginKey))).toString(16); this.g = LoginListener.EnumProtocolState.AUTHENTICATING; - this.networkManager.a(cipher, cipher1); @@ -11454,7 +11454,7 @@ index ff74be14512a947e81b62d53e616131ca7d7f609..e79e773f2219f9a9ae076fcbc8108b79 +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -38,6 +38,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; - + public final class MCUtil { + public static final double COLLISION_EPSILON = 1.0E-7; // Tuinity - Just in case mojang changes this... public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor( @@ -11463,7 +11463,7 @@ index ff74be14512a947e81b62d53e616131ca7d7f609..e79e773f2219f9a9ae076fcbc8108b79 @@ -221,6 +222,63 @@ public final class MCUtil { return getBlockKey(getBlockCoordinate(entity.locX()), getBlockCoordinate(entity.locY()), getBlockCoordinate(entity.locZ())); } - + + // Tuinity start + + static final int SECTION_X_BITS = 22; @@ -11551,7 +11551,7 @@ index ccf2d0b090f0c360dfc7886bb0726e099acec42c..1768554b00ea0b7a57ebbed1f0bc5d8f // We've just obliterated the main thread, this will prevent stop from dying when removing players @@ -952,6 +954,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant // Spigot - Spigot > // CraftBukkit - cb > vanilla! + return "Tuinity"; // Tuinity //Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! } - + public CrashReport b(CrashReport crashreport) { diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java index 1558c5f8256f50be6850f1d7f70eee3e8ec76496..b92ca4a6de01f3f86367fb8dfe3591b08a3e9218 100644 @@ -11770,7 +11770,7 @@ index 1558c5f8256f50be6850f1d7f70eee3e8ec76496..b92ca4a6de01f3f86367fb8dfe3591b0 @@ -30,6 +30,13 @@ public abstract class NavigationAbstract { private final Pathfinder s; public Pathfinder getPathfinder() { return this.s; } // Paper - OBFHELPER private boolean t; - + + // Tuinity start + public boolean isViableForPathRecalculationChecking() { + return !this.needsPathRecalculation() && @@ -11782,23 +11782,23 @@ index 1558c5f8256f50be6850f1d7f70eee3e8ec76496..b92ca4a6de01f3f86367fb8dfe3591b0 this.g = Vec3D.ORIGIN; this.h = BaseBlockPosition.ZERO; @@ -85,7 +92,7 @@ public abstract class NavigationAbstract { - + @Nullable public PathEntity a(Stream stream, int i) { - return this.a((Set) stream.collect(Collectors.toSet()), 8, false, i); + return this.a((Set) stream.collect(Collectors.toSet()), 8, false, i); // Tuinity - diff on change, inlined into SensorNearestBed } - + @Nullable @@ -393,7 +400,7 @@ public abstract class NavigationAbstract { } - + public void b(BlockPosition blockposition) { - if (this.c != null && !this.c.c() && this.c.e() != 0) { + if (this.c != null && !this.c.c() && this.c.e() != 0) { // Tuinity - diff on change - needed for isViableForPathRecalculationChecking() PathPoint pathpoint = this.c.d(); Vec3D vec3d = new Vec3D(((double) pathpoint.a + this.a.locX()) / 2.0D, ((double) pathpoint.b + this.a.locY()) / 2.0D, ((double) pathpoint.c + this.a.locZ()) / 2.0D); - + diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b32c162cf6 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java @@ -11806,16 +11806,16 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 @@ -27,6 +27,8 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; - + +import io.netty.util.concurrent.AbstractEventExecutor; // Tuinity + public class NetworkManager extends SimpleChannelInboundHandler> { - + private static final Logger LOGGER = LogManager.getLogger(); @@ -71,6 +73,39 @@ public class NetworkManager extends SimpleChannelInboundHandler> { EnumProtocol protocol; // Paper end - + + // Tuinity start - allow controlled flushing + volatile boolean canFlush = true; + private final java.util.concurrent.atomic.AtomicInteger packetWrites = new java.util.concurrent.atomic.AtomicInteger(); @@ -11855,7 +11855,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 @@ -145,8 +180,63 @@ public class NetworkManager extends SimpleChannelInboundHandler> { if (MinecraftServer.getServer().isDebugging()) throwable.printStackTrace(); // Spigot } - + + // Tuinity start - packet limiter + protected final Object PACKET_LIMIT_LOCK = new Object(); + protected final com.tuinity.tuinity.util.IntervalledCounter allPacketCounts = com.tuinity.tuinity.config.TuinityConfig.allPacketsLimit != null ? new com.tuinity.tuinity.util.IntervalledCounter( @@ -11926,7 +11926,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 } // write the packets to the queue, then flush - antixray hooks there already @@ -248,6 +338,14 @@ public class NetworkManager extends SimpleChannelInboundHandler> { - + private void dispatchPacket(Packet packet, @Nullable GenericFutureListener> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER private void b(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { + // Tuinity start - add flush parameter @@ -11939,14 +11939,14 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 + // Tuinity end - add flush parameter EnumProtocol enumprotocol = EnumProtocol.a(packet); EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get(); - + @@ -270,7 +368,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { try { // Paper end - + - ChannelFuture channelfuture = this.channel.writeAndFlush(packet); + ChannelFuture channelfuture = (flush) ? this.channel.writeAndFlush(packet) : this.channel.write(packet); // Tuinity - add flush parameter - + if (genericfuturelistener != null) { channelfuture.addListener(genericfuturelistener); @@ -290,39 +388,83 @@ public class NetworkManager extends SimpleChannelInboundHandler> { @@ -11967,7 +11967,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 + if (enumprotocol != enumprotocol1) { + this.setProtocol(enumprotocol); + } - + - // Paper start - if (!isConnected()) { - packet.onPacketDispatchFinish(player, null); @@ -12019,7 +12019,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 + if (enumprotocol != enumprotocol1) { + this.setProtocol(enumprotocol); + } - + - channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - // Paper start - } catch (Exception e) { @@ -12061,7 +12061,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 + this.channel.eventLoop().execute(choice1 != null ? choice1 : choice2); + // Tuinity end - optimise packets that are not flushed } - + } @@ -345,6 +487,8 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } @@ -12074,13 +12074,13 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 java.util.Iterator iterator = this.packetQueue.iterator(); @@ -352,16 +496,22 @@ public class NetworkManager extends SimpleChannelInboundHandler> { NetworkManager.QueuedPacket queued = iterator.next(); // poll -> peek - + // Fix NPE (Spigot bug caused by handleDisconnection()) - if (queued == null) { + if (false && queued == null) { // Tuinity - diff on change, this logic is redundant: iterator guarantees ret of an element - on change, hook the flush logic here return true; } - + Packet packet = queued.getPacket(); if (!packet.isReady()) { + // Tuinity start - make only one flush call per sendPacketQueue() call @@ -12100,7 +12100,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 @@ -438,10 +588,16 @@ public class NetworkManager extends SimpleChannelInboundHandler> { return this.channel instanceof LocalChannel || this.channel instanceof LocalServerChannel; } - + - public void a(Cipher cipher, Cipher cipher1) { + public void a(javax.crypto.SecretKey secretkey) { // Tuinity this.n = true; @@ -12115,7 +12115,7 @@ index fb1e3c705b8abee13695762cdfd0e9f1bfdb5ad8..6a0ec0105399066dede622b45c9471b3 + } + // Tuinity end } - + public boolean isConnected() { diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java index 4085426af03f032cf405bdfd1e40a8e5dc27c1d1..348d16ddec3b4da0b6b4e4f49916b966005b5259 100644 @@ -12135,8 +12135,8 @@ index 4085426af03f032cf405bdfd1e40a8e5dc27c1d1..348d16ddec3b4da0b6b4e4f49916b966 // Paper end - @Nullable protected byte[] a; + @Nullable protected byte[] a; public final byte[] justGiveMeTheFuckingByteArrayNoCleanerBullshitJesusFuckingChrist() { return this.a; } - - + + public NibbleArray() {} @@ -74,7 +75,7 @@ public class NibbleArray { } @@ -12148,22 +12148,22 @@ index 4085426af03f032cf405bdfd1e40a8e5dc27c1d1..348d16ddec3b4da0b6b4e4f49916b966 // Paper end if (abyte.length != 2048) { @@ -162,7 +163,7 @@ public class NibbleArray { - + public NibbleArray copy() { return this.b(); } // Paper - OBFHELPER public NibbleArray b() { - return this.a == null ? new NibbleArray() : new NibbleArray(this.a); // Paper - clone in ctor + return this.a == null ? new NibbleArray() : new NibbleArray(com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? this.a.clone() : this.a); // Paper - clone in ctor // Tuinity - no longer clone in constructor } - + public String toString() { diff --git a/src/main/java/net/minecraft/server/PacketCompressor.java b/src/main/java/net/minecraft/server/PacketCompressor.java index 3cdd07cad85ef2d2c4b6c27a55a878695b4a7b12..50b2a8dfbdd0fe60e295d7c7214d7c99bcbeb19a 100644 --- a/src/main/java/net/minecraft/server/PacketCompressor.java +++ b/src/main/java/net/minecraft/server/PacketCompressor.java @@ -7,14 +7,18 @@ import java.util.zip.Deflater; - + public class PacketCompressor extends MessageToByteEncoder { - + - private final byte[] a = new byte[8192]; - private final Deflater b; + // Tuinity start - use Velocity natives @@ -12171,7 +12171,7 @@ index 3cdd07cad85ef2d2c4b6c27a55a878695b4a7b12..50b2a8dfbdd0fe60e295d7c7214d7c99 +// private final Deflater b; private int c; + private final com.velocitypowered.natives.compression.VelocityCompressor compressor; - + public PacketCompressor(int i) { this.c = i; - this.b = new Deflater(); @@ -12179,7 +12179,7 @@ index 3cdd07cad85ef2d2c4b6c27a55a878695b4a7b12..50b2a8dfbdd0fe60e295d7c7214d7c99 + this.compressor = com.velocitypowered.natives.util.Natives.compress.get().create(-1); } + // Tuinity end - + protected void encode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, ByteBuf bytebuf1) throws Exception { int i = bytebuf.readableBytes(); @@ -24,24 +28,46 @@ public class PacketCompressor extends MessageToByteEncoder { @@ -12224,9 +12224,9 @@ index 3cdd07cad85ef2d2c4b6c27a55a878695b4a7b12..50b2a8dfbdd0fe60e295d7c7214d7c99 - this.b.reset(); + // Tuinity end } - + } - + + // Tuinity start + @Override + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception { @@ -12247,15 +12247,15 @@ index 23c850be0155c1ece807d244117a196488f0a13b..4bab19a52b400071e69b06b940ab6432 --- a/src/main/java/net/minecraft/server/PacketDecompressor.java +++ b/src/main/java/net/minecraft/server/PacketDecompressor.java @@ -10,13 +10,17 @@ import java.util.zip.Inflater; - + public class PacketDecompressor extends ByteToMessageDecoder { - + - private final Inflater a; + // Tuinity start - use Velocity natives + //private final Inflater a; + private final com.velocitypowered.natives.compression.VelocityCompressor compressor; private int b; - + public PacketDecompressor(int i) { this.b = i; - this.a = new Inflater(); @@ -12263,13 +12263,13 @@ index 23c850be0155c1ece807d244117a196488f0a13b..4bab19a52b400071e69b06b940ab6432 + this.compressor = com.velocitypowered.natives.util.Natives.compress.get().create(-1); } + // Tuinity end - + protected void decode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, List list) throws Exception { if (bytebuf.readableBytes() != 0) { @@ -34,20 +38,41 @@ public class PacketDecompressor extends ByteToMessageDecoder { throw new DecoderException("Badly compressed packet - size of " + i + " is larger than protocol maximum of " + 2097152); } - + - byte[] abyte = new byte[packetdataserializer.readableBytes()]; - - packetdataserializer.readBytes(abyte); @@ -12303,10 +12303,10 @@ index 23c850be0155c1ece807d244117a196488f0a13b..4bab19a52b400071e69b06b940ab6432 +// this.a.reset(); + // Tuinity end } - + } } - + + // Tuinity start + @Override + public void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { @@ -12322,21 +12322,21 @@ index c85f291c5b22a8e85c7556b220cba698701748f2..771cc0f4fa98be294abba65c83442205 --- a/src/main/java/net/minecraft/server/PacketDecrypter.java +++ b/src/main/java/net/minecraft/server/PacketDecrypter.java @@ -8,13 +8,24 @@ import javax.crypto.Cipher; - + public class PacketDecrypter extends MessageToMessageDecoder { - + - private final PacketEncryptionHandler a; + // Tuinity start + private final com.velocitypowered.natives.encryption.VelocityCipher cipher; + //private final PacketEncryptionHandler a; - + - public PacketDecrypter(Cipher cipher) { - this.a = new PacketEncryptionHandler(cipher); + public PacketDecrypter(javax.crypto.SecretKey key /* Cipher cipher */) throws java.security.GeneralSecurityException { + //this.a = new PacketEncryptionHandler(cipher); + this.cipher = com.velocitypowered.natives.util.Natives.cipher.get().forDecryption(key); } - + protected void decode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, List list) throws Exception { - list.add(this.a.a(channelhandlercontext, bytebuf)); + ByteBuf compatible = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(channelhandlercontext.alloc(), cipher, bytebuf).slice(); @@ -12357,24 +12357,24 @@ index e35369476839e9622520af1027d7478aa6d1b037..aba14794cc4cb114fea17bb92816ac29 @@ -5,15 +5,38 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; import javax.crypto.Cipher; - + -public class PacketEncrypter extends MessageToByteEncoder { +// Tuinity start +// We rewrite this class as the Velocity natives support in-place encryption +import io.netty.handler.codec.MessageToMessageEncoder; // An unfortunate import, but this is required to fix a compiler error +public class PacketEncrypter extends MessageToMessageEncoder { - + - private final PacketEncryptionHandler a; + private final com.velocitypowered.natives.encryption.VelocityCipher cipher; + //private final PacketEncryptionHandler a; - + - public PacketEncrypter(Cipher cipher) { - this.a = new PacketEncryptionHandler(cipher); + public PacketEncrypter(javax.crypto.SecretKey key /* Cipher cipher */) throws java.security.GeneralSecurityException { + // this.a = new PacketEncryptionHandler(cipher); + this.cipher = com.velocitypowered.natives.util.Natives.cipher.get().forEncryption(key); } - + - protected void encode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, ByteBuf bytebuf1) throws Exception { - this.a.a(bytebuf, bytebuf1); +// protected void encode(ChannelHandlerContext channelhandlercontext, ByteBuf bytebuf, ByteBuf bytebuf1) throws Exception { @@ -12404,13 +12404,13 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 --- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java @@ -26,12 +26,12 @@ public class PacketPlayOutLightUpdate implements Packet { - + @Override public void onPacketDispatch(EntityPlayer player) { - remainingSends.incrementAndGet(); + if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) remainingSends.incrementAndGet(); } - + @Override public void onPacketDispatchFinish(EntityPlayer player, ChannelFuture future) { - if (remainingSends.decrementAndGet() <= 0) { @@ -12419,13 +12419,13 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 MCUtil.scheduleTask(5, () -> { if (remainingSends.get() == 0) { @@ -44,7 +44,7 @@ public class PacketPlayOutLightUpdate implements Packet { - + @Override public boolean hasFinishListener() { - return true; + return !com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine; // Tuinity - replace light impl } - + // Paper end @@ -54,8 +54,8 @@ public class PacketPlayOutLightUpdate implements Packet { this.a = chunkcoordintpair.x; @@ -12435,7 +12435,7 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 - this.h = Lists.newArrayList();cleaner2 = MCUtil.registerListCleaner(this, this.h, NibbleArray::releaseBytes); // Paper + this.g = Lists.newArrayList();if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) cleaner1 = MCUtil.registerListCleaner(this, this.g, NibbleArray::releaseBytes); // Paper // Tuinity - purge cleaner usage + this.h = Lists.newArrayList();if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) cleaner2 = MCUtil.registerListCleaner(this, this.h, NibbleArray::releaseBytes); // Paper // Tuinity - purge cleaner usage - + for (int i = 0; i < 18; ++i) { NibbleArray nibblearray = lightengine.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkcoordintpair, -1 + i)); @@ -66,7 +66,7 @@ public class PacketPlayOutLightUpdate implements Packet { @@ -12446,7 +12446,7 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 + this.g.add(com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? nibblearray.asBytes() : nibblearray.getCloneIfSet()); // Paper // Tuinity - don't clone again } } - + @@ -75,7 +75,7 @@ public class PacketPlayOutLightUpdate implements Packet { this.f |= 1 << i; } else { @@ -12464,7 +12464,7 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 - this.h = Lists.newArrayList();cleaner2 = MCUtil.registerListCleaner(this, this.h, NibbleArray::releaseBytes); // Paper + this.g = Lists.newArrayList();if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) cleaner1 = MCUtil.registerListCleaner(this, this.g, NibbleArray::releaseBytes); // Paper // Tuinity - purge cleaner usage + this.h = Lists.newArrayList();if (!com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine) cleaner2 = MCUtil.registerListCleaner(this, this.h, NibbleArray::releaseBytes); // Paper // Tuinity - purge cleaner usage - + for (int k = 0; k < 18; ++k) { NibbleArray nibblearray; @@ -97,7 +97,7 @@ public class PacketPlayOutLightUpdate implements Packet { @@ -12496,17 +12496,17 @@ index b9276928a58d56ca9aac95d262d8555522946bd7..d5a8036b764699a70a69b7dc3d45ea6d - private List g; + private List g; private List getTileEntityData() { return this.g; } // Tuinity - OBFHELPER private boolean h; - + // Paper start - Async-Anti-Xray - Set the ready flag to true @@ -31,7 +31,9 @@ public class PacketPlayOutMapChunk implements Packet { - + // Paper start private final java.util.List extraPackets = new java.util.ArrayList<>(); - private static final int TE_LIMIT = Integer.getInteger("Paper.excessiveTELimit", 750); + private static final int TE_LIMIT = Integer.getInteger("tuinity.excessive-te-limit", 750); // Tuinity - handle oversized chunk data packets more robustly + private static final int TE_SPLIT_LIMIT = Math.max(4096 + 1, Integer.getInteger("tuinity.te-split-limit", 15_000)); // Tuinity - handle oversized chunk data packets more robustly + private boolean mustSplit; // Tuinity - handle oversized chunk data packets more robustly - + @Override public java.util.List getExtraPackets() { @@ -40,7 +42,7 @@ public class PacketPlayOutMapChunk implements Packet { @@ -12554,7 +12554,7 @@ index b9276928a58d56ca9aac95d262d8555522946bd7..d5a8036b764699a70a69b7dc3d45ea6d iterator = chunk.getTileEntities().entrySet().iterator(); @@ -82,8 +69,16 @@ public class PacketPlayOutMapChunk implements Packet { int j = blockposition.getY() >> 4; - + if (this.f() || (i & 1 << j) != 0) { + // Tuinity start - improve oversized chunk data packet handling + ++totalTileEntities; @@ -12611,12 +12611,12 @@ index b9276928a58d56ca9aac95d262d8555522946bd7..d5a8036b764699a70a69b7dc3d45ea6d + } + // Tuinity end - improve oversized chunk data packet handling } - + // Paper start - Async-Anti-Xray - Getter and Setter for the ready flag @@ -188,7 +218,7 @@ public class PacketPlayOutMapChunk implements Packet { for (int l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; - + - if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { + if ((!this.mustSplit && chunksection != Chunk.a) && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { // Tuinity - improve oversized chunk data packet handling j |= 1 << k; @@ -12625,7 +12625,7 @@ index b9276928a58d56ca9aac95d262d8555522946bd7..d5a8036b764699a70a69b7dc3d45ea6d @@ -205,7 +235,7 @@ public class PacketPlayOutMapChunk implements Packet { for (int l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; - + - if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { + if ((!this.mustSplit && chunksection != Chunk.a) && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { j += chunksection.j(); @@ -12636,13 +12636,13 @@ index fb37f5b500c52f915b4536e5ec35552b75056046..52a2d3db7da3596bfdd6fd51147cc93b --- a/src/main/java/net/minecraft/server/PathType.java +++ b/src/main/java/net/minecraft/server/PathType.java @@ -4,6 +4,8 @@ public enum PathType { - + BLOCKED(-1.0F), OPEN(0.0F), WALKABLE(0.0F), WALKABLE_DOOR(0.0F), TRAPDOOR(0.0F), FENCE(-1.0F), LAVA(-1.0F), WATER(8.0F), WATER_BORDER(8.0F), RAIL(0.0F), UNPASSABLE_RAIL(-1.0F), DANGER_FIRE(8.0F), DAMAGE_FIRE(16.0F), DANGER_CACTUS(8.0F), DAMAGE_CACTUS(-1.0F), DANGER_OTHER(8.0F), DAMAGE_OTHER(-1.0F), DOOR_OPEN(0.0F), DOOR_WOOD_CLOSED(-1.0F), DOOR_IRON_CLOSED(-1.0F), BREACH(4.0F), LEAVES(-1.0F), STICKY_HONEY(8.0F), COCOA(0.0F); - + + PathType belowOverride; // Tuinity + private final float y; - + private PathType(float f) { diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java b/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java index 475c0764b97b056f17720f37b1ca3eb1a2375334..9f48d476c05dbeabbfe3c650ce4ad33ec691a56a 100644 @@ -12654,7 +12654,7 @@ index 475c0764b97b056f17720f37b1ca3eb1a2375334..9f48d476c05dbeabbfe3c650ce4ad33e } else { - Optional optional = worldserver.y().c(VillagePlaceType.b, this::a, blockposition1, 10, VillagePlace.Occupancy.IS_OCCUPIED); + Optional optional = Optional.ofNullable(BehaviorFindPosition.findAnyFirstPoi(worldserver.y(), VillagePlaceType.b, this::a, blockposition1, 10, VillagePlace.Occupancy.IS_OCCUPIED)); // Tuinity - remove streams here - + return !optional.isPresent() ? Double.NEGATIVE_INFINITY : -((BlockPosition) optional.get()).j(blockposition); } @@ -59,7 +59,7 @@ public class PathfinderGoalMoveThroughVillage extends PathfinderGoal { @@ -12663,7 +12663,7 @@ index 475c0764b97b056f17720f37b1ca3eb1a2375334..9f48d476c05dbeabbfe3c650ce4ad33e } else { - Optional optional = worldserver.y().c(VillagePlaceType.b, this::a, new BlockPosition(vec3d), 10, VillagePlace.Occupancy.IS_OCCUPIED); + Optional optional = Optional.ofNullable(BehaviorFindPosition.findAnyFirstPoi(worldserver.y(), VillagePlaceType.b, this::a, new BlockPosition(vec3d), 10, VillagePlace.Occupancy.IS_OCCUPIED)); // Tuinity - remove streams here - + if (!optional.isPresent()) { return false; diff --git a/src/main/java/net/minecraft/server/PathfinderNormal.java b/src/main/java/net/minecraft/server/PathfinderNormal.java @@ -12673,7 +12673,7 @@ index 74e81e1e4aea6f74b14a84231ddeb7f2fb845ae7..33804e68931e8b4145b896eedeab79bd @@ -421,6 +421,12 @@ public class PathfinderNormal extends PathfinderAbstract { if (pathtype == PathType.OPEN && j >= 1) { PathType pathtype1 = b(iblockaccess, blockposition_mutableblockposition.d(i, j - 1, k)); - + + // Tuinity start - reduce pathfinder branches + if (pathtype1.belowOverride != null) { + pathtype = pathtype1.belowOverride; @@ -12689,7 +12689,7 @@ index 74e81e1e4aea6f74b14a84231ddeb7f2fb845ae7..33804e68931e8b4145b896eedeab79bd } + original1.belowOverride = pathtype; } // Tuinity - reduce pathfinder branches } - + if (pathtype == PathType.WALKABLE) { @@ -462,22 +469,29 @@ public class PathfinderNormal extends PathfinderAbstract { pathtype = PathType.BLOCKED; @@ -12707,17 +12707,17 @@ index 74e81e1e4aea6f74b14a84231ddeb7f2fb845ae7..33804e68931e8b4145b896eedeab79bd - return PathType.DANGER_CACTUS; + return iblockdata.neighbourOverridePathType = PathType.DANGER_CACTUS; // Tuinity - reduce pathfinder branching } - + if (iblockdata.a(Blocks.SWEET_BERRY_BUSH)) { - return PathType.DANGER_OTHER; + return iblockdata.neighbourOverridePathType = PathType.DANGER_OTHER; // Tuinity - reduce pathfinder branching } - + if (a(iblockdata)) { - return PathType.DANGER_FIRE; + return iblockdata.neighbourOverridePathType = PathType.DANGER_FIRE; // Tuinity - reduce pathfinder branching } - + if (iblockdata.getFluid().a((Tag) TagsFluid.WATER)) { // Paper - remove another getType call - return PathType.WATER_BORDER; + return iblockdata.neighbourOverridePathType = PathType.WATER_BORDER; // Tuinity - reduce pathfinder branching @@ -12746,7 +12746,7 @@ index 74e81e1e4aea6f74b14a84231ddeb7f2fb845ae7..33804e68931e8b4145b896eedeab79bd + // Tuinity end - reduce pathfinder branches Block block = iblockdata.getBlock(); Material material = iblockdata.getMaterial(); - + diff --git a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java index 253377c6238594de1f76cafcbf8223592e4d3f6b..3ebe3d0dc4c2c6aee6ea349006a74cbe5aa8e78f 100644 --- a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java @@ -12754,7 +12754,7 @@ index 253377c6238594de1f76cafcbf8223592e4d3f6b..3ebe3d0dc4c2c6aee6ea349006a74cbe @@ -51,6 +51,7 @@ public class PathfinderTargetCondition { return this; } - + + public final boolean test(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { return this.a(entityliving, entityliving1); } // Tuinity - OBFHELPER public boolean a(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { if (entityliving == entityliving1) { @@ -12779,18 +12779,18 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 @@ -366,7 +372,7 @@ public class PlayerChunk { if (!blockposition.isValidLocation()) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks Chunk chunk = this.getSendingChunk(); // Paper - no-tick view distance - + - if (chunk != null) { + if (chunk != null && (blockposition.getY() >= 0 && blockposition.getY() <= 255)) { // Tuinity - updates cannot happen in sections that don't exist byte b0 = (byte) SectionPosition.a(blockposition.getY()); - + if (b0 < 0 || b0 >= this.dirtyBlocks.length) return; // CraftBukkit - SPIGOT-6086, SPIGOT-6296 @@ -381,13 +387,14 @@ public class PlayerChunk { - + public void a(EnumSkyBlock enumskyblock, int i) { Chunk chunk = this.getSendingChunk(); // Paper - no-tick view distance + if (this.getAvailableChunkNow() != null) this.getAvailableChunkNow().setNeedsSaving(true); // Tuinity - always mark as needing saving - + if (chunk != null) { chunk.setNeedsSaving(true); if (enumskyblock == EnumSkyBlock.SKY) { @@ -12800,7 +12800,7 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 - this.r |= 1 << i - -1; + this.r |= 1 << (i - -1); // Tuinity - fix mojang oopsie } - + } @@ -425,7 +432,7 @@ public class PlayerChunk { this.a(world, blockposition, iblockdata); @@ -12809,19 +12809,19 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 - if (chunksection == null) chunksection = new ChunkSection(sectionposition.getY(), chunk, world, true); // Paper - make a new chunk section if none was found + //if (chunksection == null) chunksection = new ChunkSection(sectionposition.getY(), chunk, world, true); // Paper - make a new chunk section if none was found // Tuinity - handled better by spigot PacketPlayOutMultiBlockChange packetplayoutmultiblockchange = new PacketPlayOutMultiBlockChange(sectionposition, shortset, chunksection, this.x); - + this.a(packetplayoutmultiblockchange, false); @@ -508,6 +515,7 @@ public class PlayerChunk { // Paper end - per player view distance } - + + public final CompletableFuture> getOrCreateFuture(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { return this.a(chunkstatus, playerchunkmap); } // Tuinity - OBFHELPER public CompletableFuture> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { int i = chunkstatus.c(); CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(i); @@ -563,6 +571,7 @@ public class PlayerChunk { } - + protected void a(PlayerChunkMap playerchunkmap) { + com.tuinity.tuinity.util.TickThread.ensureTickThread("Async ticket level update"); // Tuinity ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel); @@ -12848,7 +12848,7 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 // note: Here is a very good place to add callbacks to logic waiting on this. Chunk fullChunk = either.left().get(); @@ -668,7 +679,8 @@ public class PlayerChunk { - + if (!flag4 && flag5) { // Paper start - cache ticking ready status - this.tickingFuture = playerchunkmap.a(this); ensureMain(this.tickingFuture).thenAccept((either) -> { // Paper - ensure main @@ -12864,7 +12864,7 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 + // Tuinity start - ticking chunk set + PlayerChunk.this.chunkMap.world.getChunkProvider().tickingChunks.add(tickingChunk); + // Tuinity end - ticking chunk set - + } }); @@ -688,6 +703,12 @@ public class PlayerChunk { @@ -12878,11 +12878,11 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 + } + // Tuinity end - ticking chunk set } - + boolean flag6 = playerchunk_state.isAtLeast(PlayerChunk.State.ENTITY_TICKING); @@ -699,13 +720,16 @@ public class PlayerChunk { } - + // Paper start - cache ticking ready status - this.entityTickingFuture = playerchunkmap.b(this.location); ensureMain(this.entityTickingFuture).thenAccept((either) -> { // Paper ensureMain + this.entityTickingFuture = playerchunkmap.b(this.location); this.entityTickingFuture.thenAccept((either) -> { // Paper ensureMain // Tuinity - always completed on main @@ -12891,13 +12891,13 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 // note: Here is a very good place to add callbacks to logic waiting on this. Chunk entityTickingChunk = either.left().get(); PlayerChunk.this.isEntityTickingReady = true; - + - + // Tuinity start - entity ticking chunk set + PlayerChunk.this.chunkMap.world.getChunkProvider().entityTickingChunks.add(entityTickingChunk); + // Tuinity end - entity ticking chunk set - - + + } @@ -717,6 +741,12 @@ public class PlayerChunk { if (flag6 && !flag7) { @@ -12910,7 +12910,7 @@ index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..3127fc9dd87e82243e167862cae83ac8 + } + // Tuinity end - entity ticking chunk set } - + // Paper start - raise IO/load priority if priority changes, use our preferred priority @@ -742,7 +772,8 @@ public class PlayerChunk { // CraftBukkit start @@ -12937,7 +12937,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 - private java.util.ArrayDeque queued = new java.util.ArrayDeque<>(); + // Tuinity start - revert paper's change + private Runnable queued; - + @Override public void execute(Runnable runnable) { AsyncCatcher.catchOp("Callback Executor execute"); @@ -12951,7 +12951,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + queued = runnable; } + // Tuinity end - revert paper's change - + @Override public void run() { AsyncCatcher.catchOp("Callback Executor run"); @@ -12976,7 +12976,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + // Tuinity start - optimise checkDespawn + public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; + // Tuinity end - optimise checkDespawn - + void addPlayerToDistanceMaps(EntityPlayer player) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity int chunkX = MCUtil.getChunkCoordinate(player.locX()); @@ -12990,7 +12990,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + this.playerGeneralAreaMap.add(player, chunkX, chunkZ, 33); + // Tuinity end - optimise checkDespawn } - + void removePlayerFromDistanceMaps(EntityPlayer player) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity // Paper start - use distance map to optimise tracker @@ -13004,7 +13004,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + this.playerGeneralAreaMap.remove(player); + // Tuinity end - optimise checkDespawn } - + void updateMaps(EntityPlayer player) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity int chunkX = MCUtil.getChunkCoordinate(player.locX()); @@ -13019,7 +13019,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + // Tuinity end - optimise checkDespawn } // Paper end - + + // Tuinity start + public static enum RegionData implements com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.RegionDataCreator { + // Tuinity start - optimise notify() @@ -13047,7 +13047,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 public PlayerChunkMap(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i, boolean flag) { super(new File(convertable_conversionsession.a(worldserver.getDimensionKey()), "region"), datafixer, flag); @@ -310,9 +345,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - + this.worldLoadListener = worldloadlistener; // Paper start - use light thread + String threadName = ((WorldDataServer)this.world.getWorldData()).getName() + " - Light"; // Tuinity - make sure playerchunkmap instance is not retained by the thread factory @@ -13086,7 +13086,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 // Paper start - Chunk Prioritization public void queueHolderUpdate(PlayerChunk playerchunk) { @@ -756,6 +812,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - + @Nullable private PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Chunk holder update"); // Tuinity @@ -13101,40 +13101,40 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + this.dataRegionManager.addChunk(playerchunk.location.x, playerchunk.location.z); // Tuinity } + this.getVillagePlace().dequeueUnload(playerchunk.location.pair()); // Tuinity - unload POI data - + this.updatingChunks.put(i, playerchunk); this.updatingChunksModified = true; @@ -904,7 +964,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - + } - + - private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more + static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more // Tuinity - private -> package private - + protected void unloadChunks(BooleanSupplier booleansupplier) { GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); @@ -970,7 +1030,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } - + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z, - poiData, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); + poiData, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); // Tuinity - use normal priority - + if (!chunk.isNeedsSaving()) { return; @@ -1004,7 +1064,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { asyncSaveData = ChunkRegionLoader.getAsyncSaveData(this.world, chunk); } - + - this.world.asyncChunkTaskManager.scheduleChunkSave(chunkPos.x, chunkPos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY, + this.world.asyncChunkTaskManager.scheduleChunkSave(chunkPos.x, chunkPos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, // Tuinity - use normal priority asyncSaveData, chunk); - + chunk.setLastSaved(this.world.getTime()); @@ -1012,6 +1072,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } // Paper end - + + boolean unloadingPlayerChunk = false; // Tuinity - do not allow ticket level changes while unloading chunks + private void a(long i, PlayerChunk playerchunk) { @@ -13164,24 +13164,24 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + if (removed) this.dataRegionManager.removeChunk(playerchunk.location.x, playerchunk.location.z); // Tuinity + if (removed) this.getVillagePlace().queueUnload(playerchunk.location.pair(), MinecraftServer.currentTickLong + 1); // Tuinity - unload POI data + } finally { this.unloadingPlayerChunk = unloadingBefore; } // Tuinity - do not allow ticket level changes while unloading chunks - + } }; @@ -1059,6 +1132,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } - + protected boolean b() { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update visibleChunks off of the main thread"); // Tuinity if (!this.updatingChunksModified) { return false; } else { @@ -1134,6 +1208,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - + this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); chunkHolder.tasks.forEach(Runnable::run); + this.getVillagePlace().dequeueUnload(chunkcoordintpair.pair()); // Tuinity // Paper end - + if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async @@ -1246,9 +1321,13 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -13193,7 +13193,7 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + }, this.mainInvokingExecutor); + // Tuinity end - force competion on the main thread } - + + protected final void removeLightTicket(ChunkCoordIntPair chunkcoordintpair) { this.c(chunkcoordintpair); } // Tuinity - OBFHELPER protected void c(ChunkCoordIntPair chunkcoordintpair) { this.executor.a(SystemUtils.a(() -> { @@ -13207,23 +13207,23 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 - }); + }, this.executor); // Tuinity - queue to execute immediately so this doesn't delay chunk unloading } - + public int c() { @@ -1498,6 +1575,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } - + public void setViewDistance(int i) { // Paper - public + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update view distance off of the main thread"); // Tuinity int j = MathHelper.clamp(i + 1, 3, 33); // Paper - diff on change, these make the lower view distance limit 2 and the upper 32 - + if (j != this.viewDistance) { @@ -1511,6 +1589,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - + // Paper start - no-tick view distance public final void setNoTickViewDistance(int viewDistance) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update view distance off of the main thread"); // Tuinity viewDistance = viewDistance == -1 ? -1 : MathHelper.clamp(viewDistance, 2, 32); - + this.noTickViewDistance = viewDistance; @@ -1626,7 +1705,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { @@ -13243,8 +13243,8 @@ index 49008cdec739b19409fdaf1b0ed806a6c0e93200..2c2becef8b56d7e5e998976222df85d2 + return this.pendingUnload.get(ChunkCoordIntPair.pair(chunkX, chunkZ)); + } + // Tuinity end - - + + // Paper start - async io @@ -2037,22 +2121,25 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { private final void processTrackQueue() { @@ -13291,7 +13291,7 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -419,7 +419,9 @@ public class PlayerConnection implements PacketListenerPlayIn { speed *= 2f; // TODO: Get the speed of the vehicle instead of the player - + // Paper start - Prevent moving into unloaded chunks - if (player.world.paperConfig.preventMovingIntoUnloadedChunks && worldserver.getChunkIfLoadedImmediately((int) Math.floor(packetplayinvehiclemove.getX()) >> 4, (int) Math.floor(packetplayinvehiclemove.getZ()) >> 4) == null) { + if (player.world.paperConfig.preventMovingIntoUnloadedChunks // Tuinity - improve this check @@ -13303,29 +13303,29 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 @@ -432,12 +434,14 @@ public class PlayerConnection implements PacketListenerPlayIn { return; } - + - boolean flag = worldserver.getCubes(entity, entity.getBoundingBox().shrink(0.0625D)); + //boolean flag = worldserver.getCubes(entity, entity.getBoundingBox().shrink(0.0625D)); // Tuinity - replace with different checks + AxisAlignedBB oldBox = entity.getBoundingBox(); // Tuinity - copy from player movement packet - + d6 = d3 - this.v; d7 = d4 - this.w - 1.0E-6D; d8 = d5 - this.x; entity.move(EnumMoveType.PLAYER, new Vec3D(d6, d7, d8)); + boolean didCollide = toX != entity.locX() || toY != entity.locY() || toZ != entity.locZ(); // Tuinity - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be... double d11 = d7; - + d6 = d3 - entity.locX(); @@ -451,16 +455,25 @@ public class PlayerConnection implements PacketListenerPlayIn { boolean flag1 = false; - + if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot - flag1 = true; + flag1 = true; // Tuinity - diff on change, this should be moved wrongly PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", entity.getDisplayName().getString(), this.player.getDisplayName().getString(), Math.sqrt(d10)); } Location curPos = this.getPlayer().getLocation(); // Spigot - + entity.setLocation(d3, d4, d5, f, f1); player.setLocation(d3, d4, d5, this.player.yaw, this.player.pitch); // CraftBukkit - boolean flag2 = worldserver.getCubes(entity, entity.getBoundingBox().shrink(0.0625D)); @@ -13348,7 +13348,7 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity)); @@ -546,7 +559,32 @@ public class PlayerConnection implements PacketListenerPlayIn { } - + private boolean a(Entity entity) { - return entity.world.a(entity.getBoundingBox().g(0.0625D).b(0.0D, -0.55D, 0.0D)).allMatch(BlockBase.BlockData::isAir); + // Tuinity start - stop using streams, this is already a known fixed problem in Entity#move @@ -13378,11 +13378,11 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 + return true; + // Tuinity end - stop using streams, this is already a known fixed problem in Entity#move } - + @Override @@ -1068,7 +1106,7 @@ public class PlayerConnection implements PacketListenerPlayIn { } - + if (this.teleportPos != null) { - if (this.e - this.A > 20) { + if (false && this.e - this.A > 20) { // Tuinity - this will greatly screw with clients with > 1000ms RTT @@ -13401,15 +13401,15 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 @@ -1155,7 +1193,7 @@ public class PlayerConnection implements PacketListenerPlayIn { } } - + - AxisAlignedBB axisalignedbb = this.player.getBoundingBox(); + AxisAlignedBB axisalignedbb = this.player.getBoundingBox(); // Tuinity - diff on change, should be old AABB - + d7 = d4 - this.o; d8 = d5 - this.p; @@ -1194,6 +1232,7 @@ public class PlayerConnection implements PacketListenerPlayIn { } - + this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); + boolean didCollide = toX != this.player.locX() || toY != this.player.locY() || toZ != this.player.locZ(); // Tuinity - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be... this.player.setOnGround(packetplayinflying.b()); // CraftBukkit - SPIGOT-5810, SPIGOT-5835: reset by this.player.move @@ -13417,13 +13417,13 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 if (this.teleportPos != null) { @@ -1213,12 +1252,23 @@ public class PlayerConnection implements PacketListenerPlayIn { boolean flag1 = false; - + if (!this.player.H() && d11 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.playerInteractManager.isCreative() && this.player.playerInteractManager.getGameMode() != EnumGamemode.SPECTATOR) { // Spigot - flag1 = true; + flag1 = true; // Tuinity - diff on change, this should be moved wrongly PlayerConnection.LOGGER.warn("{} moved wrongly!", this.player.getDisplayName().getString()); } - + this.player.setLocation(d4, d5, d6, f, f1); - if (!this.player.noclip && !this.player.isSleeping() && (flag1 && worldserver.getCubes(this.player, axisalignedbb) || this.a((IWorldReader) worldserver, axisalignedbb))) { + // Tuinity start - optimise out extra getCubes @@ -13444,7 +13444,7 @@ index 87b1ff21957d5d708209257e569785aeaf191181..4185ec46435ddf48d9e25c4d71ac4e14 @@ -1305,6 +1355,26 @@ public class PlayerConnection implements PacketListenerPlayIn { } } - + + // Tuinity start - optimise out extra getCubes + private boolean hasNewCollision(final WorldServer world, final Entity entity, final AxisAlignedBB oldBox, final AxisAlignedBB newBox) { + final List collisions = com.tuinity.tuinity.util.CachedLists.getTempCollisionList(); @@ -13475,7 +13475,7 @@ index 8c7080777b370f97e1291dfedde5b419290f39cc..7fff1b3e4eda519851b714502d33122c @@ -13,10 +13,30 @@ public class PlayerConnectionUtils { ensureMainThread(packet, t0, (IAsyncTaskHandler) worldserver.getMinecraftServer()); } - + + // Tuinity start - detailed watchdog information + private static final java.util.concurrent.ConcurrentLinkedDeque packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>(); + private static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong(); @@ -13513,7 +13513,7 @@ index 8c7080777b370f97e1291dfedde5b419290f39cc..7fff1b3e4eda519851b714502d33122c + packetProcessing.pop(); + } + // Tuinity end - detailed watchdog information - + }); throw CancelledPacketHandleException.INSTANCE; diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java @@ -13535,7 +13535,7 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 + private int l; private final int getHasDestroyedTooFastStartTick() { return this.l; } // Tuinity - OBFHELPER + private long hasDestroyedTooFastStartTime; // Tuinity - lag compensate block breaking private int m; - + + // Tuinity start - lag compensate block breaking + private int getTimeDiggingLagCompensate() { + int lagCompensated = (int)((System.nanoTime() - this.lastDigTime) / (50L * 1000L * 1000L)); @@ -13559,7 +13559,7 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 } else { - float f = this.a(iblockdata, this.k, this.l); + float f = this.updateBlockBreakAnimation(iblockdata, this.k, this.getTimeDiggingTooFastLagCompensate()); // Tuinity - lag compensate destroying blocks - + if (f >= 1.0F) { this.j = false; @@ -104,7 +119,7 @@ public class PlayerInteractManager { @@ -13570,9 +13570,9 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 + this.updateBlockBreakAnimation(iblockdata, this.h, this.getTimeDiggingLagCompensate()); // Tuinity - lag compensate destroying blocks } } - + @@ -112,6 +127,12 @@ public class PlayerInteractManager { - + private float a(IBlockData iblockdata, BlockPosition blockposition, int i) { int j = this.currentTick - i; + // Tuinity start - change i (startTime) to totalTime @@ -13583,19 +13583,19 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 + // Tuinity end float f = iblockdata.getDamage(this.player, this.player.world, blockposition) * (float) (j + 1); int k = (int) (f * 10.0F); - + @@ -179,7 +200,7 @@ public class PlayerInteractManager { return; } - + - this.lastDigTick = this.currentTick; + this.lastDigTick = this.currentTick; this.lastDigTime = System.nanoTime(); // Tuinity - lag compensate block breaking float f = 1.0F; - + iblockdata = this.world.getType(blockposition); @@ -232,12 +253,12 @@ public class PlayerInteractManager { int j = (int) (f * 10.0F); - + this.world.a(this.player.getId(), blockposition, j); - this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "actual start of destroying")); + if (!com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "actual start of destroying")); // Tuinity - on lagging servers this can cause the client to think it's only just started to destroy a block when it already has/will @@ -13605,7 +13605,7 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 if (blockposition.equals(this.h)) { - int k = this.currentTick - this.lastDigTick; + int k = this.getTimeDiggingLagCompensate(); // Tuinity - lag compensate block breaking - + iblockdata = this.world.getType(blockposition); if (!iblockdata.isAir()) { @@ -254,12 +275,18 @@ public class PlayerInteractManager { @@ -13617,7 +13617,7 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 } } } - + + // Tuinity start - this can cause clients on a lagging server to think they're not currently destroying a block + if (com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); @@ -13630,15 +13630,15 @@ index 114e986e5132e5e4bb42d0f08a067429bce53ba6..05656ea8448aa569e8dd480461e2d5f7 if (!Objects.equals(this.h, blockposition) && !BlockPosition.ZERO.equals(this.h)) { @@ -271,7 +298,7 @@ public class PlayerInteractManager { } - + this.world.a(this.player.getId(), blockposition, -1); - this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "aborted destroying")); + if (!com.tuinity.tuinity.config.TuinityConfig.lagCompensateBlockBreaking) this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true, "aborted destroying")); // Tuinity - this can cause clients on a lagging server to think they stopped destroying a block they're currently destroying } - + } @@ -281,7 +308,13 @@ public class PlayerInteractManager { - + public void a(BlockPosition blockposition, PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype, String s) { if (this.breakBlock(blockposition)) { + // Tuinity start - this can cause clients on a lagging server to think they're not currently destroying a block @@ -13657,7 +13657,7 @@ index 1eb44877e7384ae0a028a12b832684126b8d50ec..eabd1aa2b740bcb6db40be300cd6daf5 +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -98,6 +98,7 @@ public abstract class PlayerList { } - + public void a(NetworkManager networkmanager, EntityPlayer entityplayer) { + entityplayer.isRealPlayer = true; // Paper // Tuinity - this is a better place to write this that works and isn't overriden by plugins EntityPlayer prev = pendingPlayers.put(entityplayer.getUniqueID(), entityplayer);// Paper @@ -13665,13 +13665,13 @@ index 1eb44877e7384ae0a028a12b832684126b8d50ec..eabd1aa2b740bcb6db40be300cd6daf5 disconnectPendingPlayer(prev); @@ -637,7 +638,7 @@ public abstract class PlayerList { SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); - + EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(World.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(World.OVERWORLD))); - entity.isRealPlayer = true; // Paper + // Tuinity - some plugins (namely protocolsupport) bypass this logic completely! So this needs to be moved. Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress()); - + diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java index 5b0cd414ca1949ab53b289f7159f18da07d21f14..d8b759874545293764690b2ba08a4bd7605c76ae 100644 --- a/src/main/java/net/minecraft/server/ProtoChunk.java @@ -13679,7 +13679,7 @@ index 5b0cd414ca1949ab53b289f7159f18da07d21f14..d8b759874545293764690b2ba08a4bd7 @@ -48,6 +48,54 @@ public class ProtoChunk implements IChunkAccess { private volatile boolean u; final World world; // Paper - Anti-Xray - Add world // Paper - private -> default - + + // Tuinity start - rewrite light engine + protected volatile com.tuinity.tuinity.chunk.light.SWMRNibbleArray[] blockNibbles = com.tuinity.tuinity.chunk.light.StarLightEngine.getFilledEmptyLight(); + protected volatile com.tuinity.tuinity.chunk.light.SWMRNibbleArray[] skyNibbles = com.tuinity.tuinity.chunk.light.StarLightEngine.getFilledEmptyLight(); @@ -13734,14 +13734,14 @@ index 5b0cd414ca1949ab53b289f7159f18da07d21f14..d8b759874545293764690b2ba08a4bd7 @@ -173,20 +221,17 @@ public class ProtoChunk implements IChunkAccess { ChunkSection chunksection = this.a(j >> 4); IBlockData iblockdata1 = chunksection.setType(i & 15, j & 15, k & 15, iblockdata); - + - if (this.g.b(ChunkStatus.FEATURES) && iblockdata != iblockdata1 && (iblockdata.b((IBlockAccess) this, blockposition) != iblockdata1.b((IBlockAccess) this, blockposition) || iblockdata.f() != iblockdata1.f() || iblockdata.e() || iblockdata1.e())) { + if ((com.tuinity.tuinity.config.TuinityConfig.useNewLightEngine ? (this.g.b(ChunkStatus.LIGHT) && this.isLit()) : (this.g.b(ChunkStatus.FEATURES))) && iblockdata != iblockdata1 && (iblockdata.b((IBlockAccess) this, blockposition) != iblockdata1.b((IBlockAccess) this, blockposition) || iblockdata.f() != iblockdata1.f() || iblockdata.e() || iblockdata1.e())) { // Tuinity - move block updates to only happen after lighting occurs LightEngine lightengine = this.e(); - + lightengine.a(blockposition); } - + - EnumSet enumset = this.getChunkStatus().h(); + HeightMap.Type[] enumset = this.getChunkStatus().heightMaps; // Tuinity - reduce iterator creation EnumSet enumset1 = null; @@ -13749,17 +13749,17 @@ index 5b0cd414ca1949ab53b289f7159f18da07d21f14..d8b759874545293764690b2ba08a4bd7 - - HeightMap.Type heightmap_type; + // Tuinity - reduce iterator creation - + - while (iterator.hasNext()) { - heightmap_type = (HeightMap.Type) iterator.next(); + for (HeightMap.Type heightmap_type : enumset) { // Tuinity - reduce iterator creation HeightMap heightmap = (HeightMap) this.f.get(heightmap_type); - + if (heightmap == null) { @@ -202,10 +247,9 @@ public class ProtoChunk implements IChunkAccess { HeightMap.a(this, enumset1); } - + - iterator = enumset.iterator(); - - while (iterator.hasNext()) { @@ -13769,15 +13769,15 @@ index 5b0cd414ca1949ab53b289f7159f18da07d21f14..d8b759874545293764690b2ba08a4bd7 + // Tuinity end - reduce iterator creation ((HeightMap) this.f.get(heightmap_type)).a(i & 15, j, k & 15, iblockdata); } - + diff --git a/src/main/java/net/minecraft/server/ProtoChunkExtension.java b/src/main/java/net/minecraft/server/ProtoChunkExtension.java index 300cbb8b01d94e7eb0cded0c8e118103c416d4b6..2d7c86c9a323fb7294607ee5685cef8f9ef52794 100644 --- a/src/main/java/net/minecraft/server/ProtoChunkExtension.java +++ b/src/main/java/net/minecraft/server/ProtoChunkExtension.java @@ -8,7 +8,50 @@ import javax.annotation.Nullable; - + public class ProtoChunkExtension extends ProtoChunk { - + - private final Chunk a; + private final Chunk a; public final Chunk getWrappedChunk() { return this.a; } // Tuinity - OBFHELPER + @@ -13823,7 +13823,7 @@ index 300cbb8b01d94e7eb0cded0c8e118103c416d4b6..2d7c86c9a323fb7294607ee5685cef8f + } + + // Tuinity end - rewrite light engine - + public ProtoChunkExtension(Chunk chunk) { super(chunk.getPos(), ChunkConverter.a, chunk.world); // Paper - Anti-Xray - Add parameter diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java @@ -13854,7 +13854,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 @VisibleForTesting protected final RegionFileBitSet freeSectors; public final File file; // Paper - + + // Tuinity start - try to recover from RegionFile header corruption + private static long roundToSectors(long bytes) { + long sectors = bytes >>> 12; // 4096 = 2^12 @@ -14191,11 +14191,11 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 + // Tuinity end + public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper - + // Paper start - Cache chunk status @@ -65,11 +401,22 @@ public class RegionFile implements AutoCloseable { // Paper end - + public RegionFile(File file, File file1, boolean flag) throws IOException { + // Tuinity start - add can recalc flag this(file.toPath(), file1.toPath(), RegionFileCompression.b, flag); @@ -14204,7 +14204,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 + this(file.toPath(), file1.toPath(), RegionFileCompression.b, flag, canRecalcHeader); + // Tuinity end - add can recalc flag + } - + public RegionFile(java.nio.file.Path java_nio_file_path, java.nio.file.Path java_nio_file_path1, RegionFileCompression regionfilecompression, boolean flag) throws IOException { + // Tuinity start - add can recalc flag + this(java_nio_file_path, java_nio_file_path1, regionfilecompression, flag, false); @@ -14219,16 +14219,16 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 @@ -97,14 +444,16 @@ public class RegionFile implements AutoCloseable { RegionFile.LOGGER.warn("Region file {} has truncated header: {}", java_nio_file_path, i); } - + - long j = Files.size(java_nio_file_path); + final long j = Files.size(java_nio_file_path); final long regionFileSize = j; - + + boolean needsHeaderRecalc = false; // Tuinity - recalculate header on header corruption + boolean hasBackedUp = false; // Tuinity - recalculate header on header corruption for (int k = 0; k < 1024; ++k) { - int l = this.h.get(k); + int l = this.h.get(k); final int headerLocation = k; // Tuinity - we expect this to be the header location - + if (l != 0) { - int i1 = b(l); - int j1 = a(l); @@ -14243,7 +14243,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 } + sectorLength = j1; // Tuinity - diff on change, we expect this to be sector length of region // Spigot end - + if (i1 < 2) { RegionFile.LOGGER.warn("Region file {} has invalid sector at index: {}; sector {} overlaps with header", java_nio_file_path, k, i1); - this.h.put(k, 0); @@ -14309,18 +14309,18 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 + } + // Tuinity end } - + } } - + + private final java.nio.file.Path getOversizedChunkPath(ChunkCoordIntPair chunkcoordintpair) { return this.e(chunkcoordintpair); } // Tuinity - OBFHELPER private java.nio.file.Path e(ChunkCoordIntPair chunkcoordintpair) { - String s = "c." + chunkcoordintpair.x + "." + chunkcoordintpair.z + ".mcc"; + String s = "c." + chunkcoordintpair.x + "." + chunkcoordintpair.z + ".mcc"; // Tuinity - diff on change - + return this.e.resolve(s); } - + + // Tuinity start + private static ChunkCoordIntPair getOversizedChunkPair(File file) { + String fileName = file.getName(); @@ -14363,7 +14363,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 } else { int i1 = bytebuffer.getInt(); @@ -170,6 +597,12 @@ public class RegionFile implements AutoCloseable { - + if (i1 == 0) { RegionFile.LOGGER.warn("Chunk {} is allocated, but stream is missing", chunkcoordintpair); + // Tuinity start - recalculate header on regionfile corruption @@ -14386,7 +14386,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 + } + // Tuinity end - recalculate header on regionfile corruption } - + - return this.a(chunkcoordintpair, b(b0)); + // Tuinity start - recalculate header on regionfile corruption + DataInputStream ret = this.a(chunkcoordintpair, b(b0)); @@ -14429,7 +14429,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 } @@ -347,10 +812,15 @@ public class RegionFile implements AutoCloseable { } - + private ByteBuffer b() { + // Tuinity start - add compressionType param + return this.getOversizedChunkHolderData(this.getRegionFileCompression()); @@ -14437,7 +14437,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 + private ByteBuffer getOversizedChunkHolderData(RegionFileCompression compressionType) { + // Tuinity end ByteBuffer bytebuffer = ByteBuffer.allocate(5); - + bytebuffer.putInt(1); - bytebuffer.put((byte) (this.f.a() | 128)); + bytebuffer.put((byte) (compressionType.compressionTypeId() | 128)); // Tuinity - replace with compressionType @@ -14447,7 +14447,7 @@ index 1751fb6934d9242e475c1a44b2a4a1ade6987766..1ffa213a819f9d39488ca3599f77e771 @@ -387,6 +857,7 @@ public class RegionFile implements AutoCloseable { }; } - + + private final void flushHeader() throws IOException { this.b(); } // Tuinity - OBFHELPER private void c() throws IOException { ((java.nio.Buffer) this.g).position(0); @@ -14457,24 +14457,24 @@ index 1ebdf73cc927405bc536dc74a5118d2a086db0e5..cfa3ecb031b59ec677f016ecdea92d16 --- a/src/main/java/net/minecraft/server/RegionFileBitSet.java +++ b/src/main/java/net/minecraft/server/RegionFileBitSet.java @@ -4,18 +4,42 @@ import java.util.BitSet; - + public class RegionFileBitSet { - + - private final BitSet a = new BitSet(); + private final BitSet a = new BitSet(); private final BitSet getBitset() { return this.a; } // Tuinity - OBFHELPER - + public RegionFileBitSet() {} - + + public final void allocate(int from, int length) { this.a(from, length); } // Tuinity - OBFHELPER public void a(int i, int j) { this.a.set(i, i + j); } - + + public final void free(int from, int length) { this.b(from, length); } // Tuinity - OBFHELPER public void b(int i, int j) { this.a.clear(i, i + j); } - + + // Tuinity start + public final void copyFrom(RegionFileBitSet other) { + BitSet thisBitset = this.getBitset(); @@ -14499,7 +14499,7 @@ index 1ebdf73cc927405bc536dc74a5118d2a086db0e5..cfa3ecb031b59ec677f016ecdea92d16 + public final int allocateNewSpace(final int requiredLength) { return this.a(requiredLength); } // Tuinity - OBFHELPER public int a(int i) { int j = 0; - + diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java index d64f7ad925e5f40740a58ceee0845ac2db5419f2..8b341c14e7082fc96a464f2386a3dedea31ec59c 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java @@ -14509,7 +14509,7 @@ index d64f7ad925e5f40740a58ceee0845ac2db5419f2..8b341c14e7082fc96a464f2386a3dede private final File b; private final boolean c; + private final boolean isChunkData; // Tuinity - + RegionFileCache(File file, boolean flag) { + // Tuinity start - add isChunkData param + this(file, flag, false); @@ -14520,7 +14520,7 @@ index d64f7ad925e5f40740a58ceee0845ac2db5419f2..8b341c14e7082fc96a464f2386a3dede this.b = file; this.c = flag; } - + + // Tuinity start + public static ChunkCoordIntPair getRegionFileCoordinates(File file) { + String fileName = file.getName(); @@ -14545,19 +14545,19 @@ index d64f7ad925e5f40740a58ceee0845ac2db5419f2..8b341c14e7082fc96a464f2386a3dede + } + // Tuinity end + - + // Paper start public synchronized RegionFile getRegionFileIfLoaded(ChunkCoordIntPair chunkcoordintpair) { // Paper - synchronize for async io @@ -54,9 +85,9 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final this.b.mkdirs(); } - + - File file = new File(this.b, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); + File file = new File(this.b, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Tuinity - diff on change if (existingOnly && !file.exists()) return null; // CraftBukkit - RegionFile regionfile1 = new RegionFile(file, this.b, this.c); + RegionFile regionfile1 = new RegionFile(file, this.b, this.c, this.isChunkData); // Tuinity - allow for chunk regionfiles to regen header - + this.cache.putAndMoveToFirst(i, regionfile1); // Paper start @@ -145,6 +176,13 @@ public class RegionFileCache implements AutoCloseable { // Paper - no final @@ -14591,15 +14591,15 @@ index d64f7ad925e5f40740a58ceee0845ac2db5419f2..8b341c14e7082fc96a464f2386a3dede + // Tuinity end - recover from corrupt regionfile header return nbttagcompound; } - + diff --git a/src/main/java/net/minecraft/server/RegionFileCompression.java b/src/main/java/net/minecraft/server/RegionFileCompression.java index 3382d678e68e559b8d3cb9dced4fce24206cd38f..3b7894256dc8daa81be35f845cb5f8de02d7cb00 100644 --- a/src/main/java/net/minecraft/server/RegionFileCompression.java +++ b/src/main/java/net/minecraft/server/RegionFileCompression.java @@ -13,7 +13,7 @@ import javax.annotation.Nullable; - + public class RegionFileCompression { - + - private static final Int2ObjectMap d = new Int2ObjectOpenHashMap(); + private static final Int2ObjectMap d = new Int2ObjectOpenHashMap(); static final Int2ObjectMap getCompressionTypes() { return RegionFileCompression.d; } // Tuinity - OBFHELPER public static final RegionFileCompression a = a(new RegionFileCompression(1, GZIPInputStream::new, GZIPOutputStream::new)); @@ -14608,18 +14608,18 @@ index 3382d678e68e559b8d3cb9dced4fce24206cd38f..3b7894256dc8daa81be35f845cb5f8de @@ -36,8 +36,8 @@ public class RegionFileCompression { return regionfilecompression; } - + - @Nullable - public static RegionFileCompression a(int i) { + @Nullable public static RegionFileCompression getByType(int type) { return RegionFileCompression.a(type); } // Tuinity - OBFHELPER + @Nullable public static RegionFileCompression a(int i) { // Tuinity - OBFHELPER return (RegionFileCompression) RegionFileCompression.d.get(i); } - + @@ -45,6 +45,7 @@ public class RegionFileCompression { return RegionFileCompression.d.containsKey(i); } - + + public final int compressionTypeId() { return this.a(); } // Tuinity - OBFHELPER public int a() { return this.e; @@ -14627,7 +14627,7 @@ index 3382d678e68e559b8d3cb9dced4fce24206cd38f..3b7894256dc8daa81be35f845cb5f8de @@ -53,6 +54,7 @@ public class RegionFileCompression { return (OutputStream) this.g.wrap(outputstream); } - + + public final InputStream wrap(InputStream inputstream) throws IOException { return this.a(inputstream); } // Tuinity - OBFHELPER public InputStream a(InputStream inputstream) throws IOException { return (InputStream) this.f.wrap(inputstream); @@ -14637,7 +14637,7 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..79a11d17a2822b192dec5981d0344ae6 --- a/src/main/java/net/minecraft/server/RegionFileSection.java +++ b/src/main/java/net/minecraft/server/RegionFileSection.java @@ -25,8 +25,8 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab - + private static final Logger LOGGER = LogManager.getLogger(); // Paper - nuke IOWorker - private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); @@ -14648,9 +14648,9 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..79a11d17a2822b192dec5981d0344ae6 private final Function f; private final DataFixer g; @@ -50,8 +50,42 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab - + } - + - @Nullable - protected Optional c(long i) { + // Tuinity start - actually unload POI data @@ -14691,19 +14691,19 @@ index 04256a95108b8182e8f808e856e0d2b62165e242..79a11d17a2822b192dec5981d0344ae6 + @Nullable protected Optional c(long i) { // Tuinity - OBFHELPER return (Optional) this.c.get(i); } - + @@ -150,6 +184,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab }); } } + if (this instanceof VillagePlace) { ((VillagePlace)this).queueUnload(chunkcoordintpair.pair(), MinecraftServer.currentTickLong + 1); } // Tuinity - unload POI data - + } - + @@ -221,6 +256,7 @@ public class RegionFileSection extends RegionFileCache implements AutoCloseab return dynamic.get("DataVersion").asInt(1945); } - + + public final void writeDirtyData(ChunkCoordIntPair chunkcoordintpair) { this.a(chunkcoordintpair); } // Tuinity - OBFHELPER public void a(ChunkCoordIntPair chunkcoordintpair) { if (!this.d.isEmpty()) { @@ -14713,14 +14713,14 @@ index f95925f1c5d091f1a129d0437bb6e175c6ac080f..0bb3ad0bffc04eba38cd827eaf5c63e8 --- a/src/main/java/net/minecraft/server/SectionPosition.java +++ b/src/main/java/net/minecraft/server/SectionPosition.java @@ -7,7 +7,7 @@ import java.util.stream.StreamSupport; - + public class SectionPosition extends BaseBlockPosition { - + - private SectionPosition(int i, int j, int k) { + public SectionPosition(int i, int j, int k) { // Tuinity - private -> public super(i, j, k); } - + diff --git a/src/main/java/net/minecraft/server/SensorNearestBed.java b/src/main/java/net/minecraft/server/SensorNearestBed.java index ad3609f2b884f64f1a1a449036cece49a46e933e..d3d28f97f9d2f969a182aec5e0947b6969d2939c 100644 --- a/src/main/java/net/minecraft/server/SensorNearestBed.java @@ -14733,11 +14733,11 @@ index ad3609f2b884f64f1a1a449036cece49a46e933e..d3d28f97f9d2f969a182aec5e0947b69 - PathEntity pathentity = entityinsentient.getNavigation().a(stream, VillagePlaceType.r.d()); + Set set = BehaviorFindPosition.findPoi(villageplace, VillagePlaceType.r.c(), predicate, entityinsentient.getChunkCoordinates(), 48, VillagePlace.Occupancy.ANY, Integer.MAX_VALUE); // Tuinity - remove streams + PathEntity pathentity = entityinsentient.getNavigation().a(set, 8, false, VillagePlaceType.r.d()); // this.a((Set) stream.collect(Collectors.toSet()), 8, false, i) // Tuinity - remove streams - + if (pathentity != null && pathentity.j()) { BlockPosition blockposition = pathentity.m(); Optional optional = villageplace.c(blockposition); - + if (optional.isPresent()) { - entityinsentient.getBehaviorController().setMemory(MemoryModuleType.NEAREST_BED, (Object) blockposition); + entityinsentient.getBehaviorController().setMemory(MemoryModuleType.NEAREST_BED, blockposition); // Tuinity - decompile fix @@ -14749,7 +14749,7 @@ index 2e747158d48ab28ac1611990cc97aa4a9e30b30e..1de170b9fe6f2888da6dcf0151aaf1f8 --- a/src/main/java/net/minecraft/server/SensorNearestItems.java +++ b/src/main/java/net/minecraft/server/SensorNearestItems.java @@ -18,20 +18,23 @@ public class SensorNearestItems extends Sensor { - + protected void a(WorldServer worldserver, EntityInsentient entityinsentient) { BehaviorController behaviorcontroller = entityinsentient.getBehaviorController(); - List list = worldserver.a(EntityItem.class, entityinsentient.getBoundingBox().grow(8.0D, 4.0D, 8.0D), (entityitem) -> { @@ -14758,7 +14758,7 @@ index 2e747158d48ab28ac1611990cc97aa4a9e30b30e..1de170b9fe6f2888da6dcf0151aaf1f8 + List list = worldserver.a(EntityItem.class, entityinsentient.getBoundingBox().grow(8.0D, 4.0D, 8.0D), (EntityItem item) -> { + return entityinsentient.i(item.getItemStack()) && item.a((Entity)entityinsentient, 9.0D); // copied from removed code, make sure to update - move here so we sort less }); - + - entityinsentient.getClass(); - list.sort(Comparator.comparingDouble(entityinsentient::h)); - Stream stream = list.stream().filter((entityitem) -> { @@ -14781,7 +14781,7 @@ index 2e747158d48ab28ac1611990cc97aa4a9e30b30e..1de170b9fe6f2888da6dcf0151aaf1f8 + + Optional optional = Optional.ofNullable(nearest); + // Tuinity end - remove streams - + behaviorcontroller.setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, optional); } diff --git a/src/main/java/net/minecraft/server/SensorNearestLivingEntities.java b/src/main/java/net/minecraft/server/SensorNearestLivingEntities.java @@ -14791,7 +14791,7 @@ index f6568a54ab85bc3a682f6fbb19dda7a783625bbe..4005df5ef3dec956a54feff539db2e63 @@ -21,10 +21,17 @@ public class SensorNearestLivingEntities extends Sensor { list.sort(Comparator.comparingDouble(entityliving::h)); BehaviorController behaviorcontroller = entityliving.getBehaviorController(); - + - behaviorcontroller.setMemory(MemoryModuleType.MOBS, (Object) list); - behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_MOBS, list.stream().filter((entityliving1) -> { - return a(entityliving, entityliving1); @@ -14808,14 +14808,14 @@ index f6568a54ab85bc3a682f6fbb19dda7a783625bbe..4005df5ef3dec956a54feff539db2e63 + behaviorcontroller.setMemory(MemoryModuleType.VISIBLE_MOBS, visible); + // Tuinity end - remove streams } - + @Override diff --git a/src/main/java/net/minecraft/server/SensorNearestPlayers.java b/src/main/java/net/minecraft/server/SensorNearestPlayers.java index 904a6d5ac61d2ac81f1057068383e9ab432852db..c8e43a9f2a23178fdef52375b7204b90b28ac20b 100644 --- a/src/main/java/net/minecraft/server/SensorNearestPlayers.java +++ b/src/main/java/net/minecraft/server/SensorNearestPlayers.java @@ -19,22 +19,30 @@ public class SensorNearestPlayers extends Sensor { - + @Override protected void a(WorldServer worldserver, EntityLiving entityliving) { - Stream stream = worldserver.getPlayers().stream().filter(IEntitySelector.g).filter((entityplayer) -> { @@ -14828,7 +14828,7 @@ index 904a6d5ac61d2ac81f1057068383e9ab432852db..c8e43a9f2a23178fdef52375b7204b90 + List nearby = (List)worldserver.getNearbyPlayers(entityliving, 16.0, IEntitySelector.g); + nearby.sort((e1, e2) -> Double.compare(entityliving.getDistanceSquared(e1), entityliving.getDistanceSquared(e2))); BehaviorController behaviorcontroller = entityliving.getBehaviorController(); - + - behaviorcontroller.setMemory(MemoryModuleType.NEAREST_PLAYERS, (Object) list); - List list1 = (List) list.stream().filter((entityhuman) -> { - return a(entityliving, (EntityLiving) entityhuman); @@ -14865,13 +14865,13 @@ index a367bbfde4fbfeca6d01dec49c05f5e185aab43a..794b33a13b7f11b973caf085b0bded9b --- a/src/main/java/net/minecraft/server/SensorVillagerBabies.java +++ b/src/main/java/net/minecraft/server/SensorVillagerBabies.java @@ -17,11 +17,23 @@ public class SensorVillagerBabies extends Sensor { - + @Override protected void a(WorldServer worldserver, EntityLiving entityliving) { - entityliving.getBehaviorController().setMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES, (Object) this.a(entityliving)); + entityliving.getBehaviorController().setMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES, this.a(entityliving)); // Tuinity - decompile fix } - + private List a(EntityLiving entityliving) { - return (List) this.c(entityliving).stream().filter(this::b).collect(Collectors.toList()); + // Tuinity start - remove streams @@ -14888,7 +14888,7 @@ index a367bbfde4fbfeca6d01dec49c05f5e185aab43a..794b33a13b7f11b973caf085b0bded9b + return ret; + // Tuinity end - remove streams } - + private boolean b(EntityLiving entityliving) { diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java index 5f4dacf9c93c2495a07df2647fe0411f796da6af..0668d383db1f3a81d1053954d72678c7ac5aecec 100644 @@ -14897,7 +14897,7 @@ index 5f4dacf9c93c2495a07df2647fe0411f796da6af..0668d383db1f3a81d1053954d72678c7 @@ -74,6 +74,11 @@ public class ServerConnection { ServerConnection.LOGGER.info("Using default channel type"); } - + + // Tuinity start - indicate Velocity natives in use + ServerConnection.LOGGER.info("Tuinity: Using " + com.velocitypowered.natives.util.Natives.compress.getLoadedVariant() + " compression from Velocity."); + ServerConnection.LOGGER.info("Tuinity: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity."); @@ -14911,7 +14911,7 @@ index f199368a6d78b0cd52f11ca2c8509d729b918852..2598ae3710d46c2cfd2be5d6be2a56e5 --- a/src/main/java/net/minecraft/server/StructureManager.java +++ b/src/main/java/net/minecraft/server/StructureManager.java @@ -35,8 +35,13 @@ public class StructureManager { - + // Paper start - remove structure streams public java.util.List> getFeatureStarts(SectionPosition sectionPosition, StructureGenerator structureGenerator) { + // Tuinity start - add world parameter @@ -14927,7 +14927,7 @@ index f199368a6d78b0cd52f11ca2c8509d729b918852..2598ae3710d46c2cfd2be5d6be2a56e5 if (structurestart != null && structurestart.e()) { @@ -65,8 +70,12 @@ public class StructureManager { } - + public StructureStart a(BlockPosition blockposition, boolean flag, StructureGenerator structuregenerator) { + // Tuinity start - add world parameter + return this.getStructureStarts(blockposition,flag, structuregenerator, null); @@ -14945,7 +14945,7 @@ index e41cb8613efc86499dfe3be36c9130ab6dc9b89e..c19ffb925a02d123da8a5c77186e6105 +++ b/src/main/java/net/minecraft/server/Ticket.java @@ -5,17 +5,17 @@ import java.util.Objects; public final class Ticket implements Comparable> { - + private final TicketType a; - private final int b; + private int b; public final void setTicketLevel(final int value) { this.b = value; } // Tuinity - remove final, add set OBFHELPER @@ -14955,7 +14955,7 @@ index e41cb8613efc86499dfe3be36c9130ab6dc9b89e..c19ffb925a02d123da8a5c77186e6105 public int priority = 0; // Paper - public long delayUnloadBy; // Paper + boolean isCached; // Tuinity - delay chunk unloads, this defends against really stupid plugins - + protected Ticket(TicketType tickettype, int i, T t0) { this.a = tickettype; this.b = i; @@ -14963,17 +14963,17 @@ index e41cb8613efc86499dfe3be36c9130ab6dc9b89e..c19ffb925a02d123da8a5c77186e6105 - this.delayUnloadBy = tickettype.loadPeriod; // Paper + // Tuinity - delay chunk unloads } - + public int compareTo(Ticket ticket) { @@ -64,8 +64,9 @@ public final class Ticket implements Comparable> { this.d = i; } - + + protected final boolean isExpired(long time) { return this.b(time); } // Tuinity - OBFHELPER protected boolean b(long i) { - long j = delayUnloadBy; // Paper + long j = this.a.b(); // Tuinity - delay chunk unloads - + return j != 0L && i - this.d > j; } diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java @@ -14989,7 +14989,7 @@ index 5c789b25f1df2eae8ea8ceb4ba977ba336fe6d5e..3c964f26592fc84bb5fc11c60808d11c + public static final TicketType REQUIRED_LOAD = a("required_load", Long::compareTo); // Tuinity - make sure getChunkAt does not fail + public static final TicketType LIGHT_UPDATE = a("light_update", Comparator.comparingLong(ChunkCoordIntPair::pair)); // Tuinity - ensure chunks stay loaded for lighting + public static final TicketType CHUNK_RELIGHT = a("chunk_relight", Long::compareTo); // Tuinity - ensure chunk stays loaded for relighting - + + // Tuinity start - delay chunk unloads + boolean delayUnloadViable = true; + static { @@ -15011,7 +15011,7 @@ index aa1b18ffa1e2b7f865f63b7df81d8f3b3d5aa966..3f9ba8ef2ae4f870c1567454fcb66788 @@ -49,6 +49,11 @@ public class UserCache { private final File g; private final AtomicLong h = new AtomicLong(); - + + // Tuinity start + protected final java.util.concurrent.locks.ReentrantLock stateLock = new java.util.concurrent.locks.ReentrantLock(); + protected final java.util.concurrent.locks.ReentrantLock lookupLock = new java.util.concurrent.locks.ReentrantLock(); @@ -15022,32 +15022,32 @@ index aa1b18ffa1e2b7f865f63b7df81d8f3b3d5aa966..3f9ba8ef2ae4f870c1567454fcb66788 this.g = file; @@ -56,6 +61,7 @@ public class UserCache { } - + private void a(UserCache.UserCacheEntry usercache_usercacheentry) { + try { this.stateLock.lock(); // Tuinity - allow better concurrency GameProfile gameprofile = usercache_usercacheentry.a(); - + usercache_usercacheentry.a(this.d()); @@ -70,6 +76,7 @@ public class UserCache { if (uuid != null) { this.d.put(uuid, usercache_usercacheentry); } + } finally { this.stateLock.unlock(); } // Tuinity - allow better concurrency - + } - + @@ -107,7 +114,7 @@ public class UserCache { } - + public void saveProfile(GameProfile gameprofile) { a(gameprofile); } // Paper - OBFHELPER - public synchronized void a(GameProfile gameprofile) { // Paper - synchronize + public void a(GameProfile gameprofile) { // Paper - synchronize // Tuinity - allow better concurrency Calendar calendar = Calendar.getInstance(); - + calendar.setTime(new Date()); @@ -124,8 +131,9 @@ public class UserCache { } - + @Nullable - public synchronized GameProfile getProfile(String s) { // Paper - synchronize + public GameProfile getProfile(String s) { // Paper - synchronize // Tuinity start - allow better concurrency @@ -15055,10 +15055,10 @@ index aa1b18ffa1e2b7f865f63b7df81d8f3b3d5aa966..3f9ba8ef2ae4f870c1567454fcb66788 + boolean stateLocked = true; try { this.stateLock.lock(); // Tuinity - allow better concurrency UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.c.get(s1); boolean flag = false; - + @@ -139,10 +147,14 @@ public class UserCache { GameProfile gameprofile; - + if (usercache_usercacheentry != null) { + stateLocked = false; this.stateLock.unlock(); // Tuinity - allow better concurrency usercache_usercacheentry.a(this.d()); @@ -15073,30 +15073,30 @@ index aa1b18ffa1e2b7f865f63b7df81d8f3b3d5aa966..3f9ba8ef2ae4f870c1567454fcb66788 flag = false; @@ -154,6 +166,7 @@ public class UserCache { } - + return gameprofile; + } finally { if (stateLocked) { this.stateLock.unlock(); } } // Tuinity - allow better concurrency } - + // Paper start @@ -287,7 +300,9 @@ public class UserCache { } - + private Stream a(int i) { + try { this.stateLock.lock(); // Tuinity - allow better concurrency return ImmutableList.copyOf(this.d.values()).stream().sorted(Comparator.comparing(UserCache.UserCacheEntry::c).reversed()).limit((long) i); + } finally { this.stateLock.unlock(); } // Tuinity - allow better concurrency } - + private static JsonElement a(UserCache.UserCacheEntry usercache_usercacheentry, DateFormat dateformat) { diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java index 7f05587d42b7cdb09552277ec2e467f0edf06f10..5af554870bcf36e47aef43b966b141b9eda6c4d5 100644 --- a/src/main/java/net/minecraft/server/Vec3D.java +++ b/src/main/java/net/minecraft/server/Vec3D.java @@ -4,7 +4,7 @@ import java.util.EnumSet; - + public class Vec3D implements IPosition { - + - public static final Vec3D ORIGIN = new Vec3D(0.0D, 0.0D, 0.0D); + public static final Vec3D ORIGIN = new Vec3D(0.0D, 0.0D, 0.0D); public static Vec3D getZeroVector() { return Vec3D.ORIGIN; } // Tuinity - OBFHELPER public final double x; @@ -15105,7 +15105,7 @@ index 7f05587d42b7cdb09552277ec2e467f0edf06f10..5af554870bcf36e47aef43b966b141b9 @@ -61,6 +61,7 @@ public class Vec3D implements IPosition { return this.add(-d0, -d1, -d2); } - + + public final Vec3D add(Vec3D vec3d) { return this.e(vec3d); } // Tuinity - OBFHELPER public Vec3D e(Vec3D vec3d) { return this.add(vec3d.x, vec3d.y, vec3d.z); @@ -15113,12 +15113,12 @@ index 7f05587d42b7cdb09552277ec2e467f0edf06f10..5af554870bcf36e47aef43b966b141b9 @@ -109,10 +110,12 @@ public class Vec3D implements IPosition { return new Vec3D(this.x * d0, this.y * d1, this.z * d2); } - + + public final double magnitude() { return this.f(); } // Tuinity - OBFHELPER public double f() { return (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } - + + public final double magnitudeSquared() { return this.g(); } // Tuinity - OBFHELPER public double g() { return this.x * this.x + this.y * this.y + this.z * this.z; @@ -15136,9 +15136,9 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 import it.unimi.dsi.fastutil.longs.LongSet; import java.io.File; @@ -22,8 +23,24 @@ import java.util.stream.Stream; - + public class VillagePlace extends RegionFileSection { - + - private final VillagePlace.a a = new VillagePlace.a(); - private final LongSet b = new LongOpenHashSet(); + // Tuinity start - unload poi data @@ -15159,9 +15159,9 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 + // Tuinity end - unload poi data + + private final LongSet b = new LongOpenHashSet(); private final LongSet getLoadedChunks() { return this.b; } // Tuinity - OBFHELPER - + private final WorldServer world; // Paper - + @@ -34,9 +51,124 @@ public class VillagePlace extends RegionFileSection { public VillagePlace(File file, DataFixer datafixer, boolean flag, WorldServer world) { super(file, VillagePlaceSection::a, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK, flag); @@ -15169,7 +15169,7 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 + if (world == null) { throw new IllegalStateException("world must be non-null"); }// Tuinity - require non-null // Paper end - add world parameter } - + + // Tuinity start - actually unload POI data + private final java.util.TreeSet queuedUnloads = new java.util.TreeSet<>(); + private final Long2ObjectOpenHashMap queuedUnloadsByCoordinate = new Long2ObjectOpenHashMap<>(); @@ -15289,18 +15289,18 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 } @@ -140,10 +272,11 @@ public class VillagePlace extends RegionFileSection { } - + public int a(SectionPosition sectionposition) { - this.a.a(); - return this.a.c(sectionposition.s()); + this.villageDistanceTracker.propagateUpdates(); // Tuinity - replace distance tracking util + return convertBetweenLevels(this.villageDistanceTracker.getLevel(MCUtil.getSectionKey(sectionposition))); // Tuinity - replace distance tracking util } - + + private boolean isSectionDistanceTrackerSource(long section) { return this.f(section); } // Tuinity - OBFHELPER private boolean f(long i) { Optional optional = this.c(i); - + @@ -159,7 +292,7 @@ public class VillagePlace extends RegionFileSection { super.a(booleansupplier); } else { @@ -15308,7 +15308,7 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 - while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean()) { + while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean() && !this.world.isSavingDisabled()) { // Tuinity - unload POI data - don't write to disk if saving is disabled ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).r(); - + NBTTagCompound data; @@ -167,22 +300,27 @@ public class VillagePlace extends RegionFileSection { data = this.getData(chunkcoordintpair); @@ -15327,29 +15327,29 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 - this.a.a(); + this.villageDistanceTracker.propagateUpdates(); // Tuinity - replace distance tracking until } - + @Override protected void a(long i) { super.a(i); - this.a.b(i, this.a.b(i), false); + this.updateDistanceTracking(i); // Tuinity - move to new distance tracking util } - + @Override protected void b(long i) { - this.a.b(i, this.a.b(i), false); + this.updateDistanceTracking(i); // Tuinity - move to new distance tracking util } - + public void a(ChunkCoordIntPair chunkcoordintpair, ChunkSection chunksection) { @@ -247,7 +385,7 @@ public class VillagePlace extends RegionFileSection { - + @Override protected int b(long i) { - return VillagePlace.this.f(i) ? 0 : 7; + return VillagePlace.this.f(i) ? 0 : 7; // Tuinity - unload poi data - diff on change, this specifies the source level to use for distance tracking } - + @Override @@ -292,7 +430,7 @@ public class VillagePlace extends RegionFileSection { if (this.world != null && Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { @@ -15363,7 +15363,7 @@ index 6a0f07b13eef5560dfc7c7b39618c0b825533aec..fce9967912628c232fe41ccc17fe2296 @@ -311,6 +449,7 @@ public class VillagePlace extends RegionFileSection { this.d = predicate; } - + + public final Predicate getPredicate() { return this.a(); } // Tuinity - OBFHELPER public Predicate a() { return this.d; @@ -15373,9 +15373,9 @@ index 0b40c2f4dada7d8432e3f91e9cf206c2bda3b24b..6eaf9fc9cc93f79a497b07a3549d459b --- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java +++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java @@ -6,7 +6,7 @@ import java.util.Objects; - + public class VillagePlaceRecord { - + - private final BlockPosition a; + private final BlockPosition a; public final BlockPosition getPosition() { return this.a; } // Tuinity - OBFHELPER private final VillagePlaceType b; @@ -15386,14 +15386,14 @@ index b86963aa34b5ae479f924c5a52afc5b5b66dba76..943a437ff27162eae09211c28bdc0d14 --- a/src/main/java/net/minecraft/server/VillagePlaceSection.java +++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java @@ -23,12 +23,12 @@ public class VillagePlaceSection { - + private static final Logger LOGGER = LogManager.getLogger(); private final Short2ObjectMap b; - private final Map> c; + private final Map> c; public final Map> getData() { return this.c; } // Tuinity - OBFHELPER private final Runnable d; private boolean e; - + public static Codec a(Runnable runnable) { - Codec codec = RecordCodecBuilder.create((instance) -> { + Codec codec = RecordCodecBuilder.create((instance) -> { // Tuinity - decompile fix @@ -15405,27 +15405,27 @@ index eb926b74e17fb2f88c1d6ce2fb546541f8e6e274..e3b72922e2dfad07f3452ec5ee2af379 --- a/src/main/java/net/minecraft/server/VoxelShape.java +++ b/src/main/java/net/minecraft/server/VoxelShape.java @@ -8,11 +8,11 @@ import javax.annotation.Nullable; - + public abstract class VoxelShape { - + - protected final VoxelShapeDiscrete a; + protected final VoxelShapeDiscrete a; public final VoxelShapeDiscrete getShape() { return this.a; } // Tuinity - OBFHELPER @Nullable private VoxelShape[] b; - + - VoxelShape(VoxelShapeDiscrete voxelshapediscrete) { + protected VoxelShape(VoxelShapeDiscrete voxelshapediscrete) { // Tuinity this.a = voxelshapediscrete; } - + @@ -48,9 +48,16 @@ public abstract class VoxelShape { - + public final VoxelShape offset(double x, double y, double z) { return this.a(x, y, z); } // Paper - OBFHELPER public VoxelShape a(double d0, double d1, double d2) { - return (VoxelShape) (this.isEmpty() ? VoxelShapes.a() : new VoxelShapeArray(this.a, new DoubleListOffset(this.a(EnumDirection.EnumAxis.X), d0), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Y), d1), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Z), d2))); + return (VoxelShape) (this.isEmpty() ? VoxelShapes.a() : new VoxelShapeArray(this.a, new DoubleListOffset(this.a(EnumDirection.EnumAxis.X), d0), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Y), d1), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Z), d2))); // Tuinity - diff on change, copied into VoxelShapeArray override } - + + // Tuinity start - optimise multi-aabb shapes + public boolean intersects(final AxisAlignedBB axisalingedbb) { + return VoxelShapes.applyOperation(this, new com.tuinity.tuinity.voxel.AABBVoxelShape(axisalingedbb), OperatorBoolean.AND); @@ -15435,15 +15435,15 @@ index eb926b74e17fb2f88c1d6ce2fb546541f8e6e274..e3b72922e2dfad07f3452ec5ee2af379 + public final VoxelShape simplify() { return this.c(); } // Tuinity - OBFHELPER public VoxelShape c() { VoxelShape[] avoxelshape = new VoxelShape[]{VoxelShapes.a()}; - + @@ -70,6 +77,7 @@ public abstract class VoxelShape { }, true); } - + + public final List getBoundingBoxesRepresentation() { return this.d(); } // Tuinity - OBFHELPER public List d() { List list = Lists.newArrayList(); - + diff --git a/src/main/java/net/minecraft/server/VoxelShapeArray.java b/src/main/java/net/minecraft/server/VoxelShapeArray.java index 3c29cb1452cde1308f630bfcb82876ef19057e8f..c14b7bd63e3917bc5f495655c40d8825a8d2062f 100644 --- a/src/main/java/net/minecraft/server/VoxelShapeArray.java @@ -15453,13 +15453,13 @@ index 3c29cb1452cde1308f630bfcb82876ef19057e8f..c14b7bd63e3917bc5f495655c40d8825 import it.unimi.dsi.fastutil.doubles.DoubleList; import java.util.Arrays; +import java.util.List; - + public final class VoxelShapeArray extends VoxelShape { - + @@ -10,11 +11,25 @@ public final class VoxelShapeArray extends VoxelShape { private final DoubleList c; private final DoubleList d; - + + // Tuinity start - optimise multi-aabb shapes + static final AxisAlignedBB[] EMPTY = new AxisAlignedBB[0]; + final AxisAlignedBB[] boundingBoxesRepresentation; @@ -15472,7 +15472,7 @@ index 3c29cb1452cde1308f630bfcb82876ef19057e8f..c14b7bd63e3917bc5f495655c40d8825 protected VoxelShapeArray(VoxelShapeDiscrete voxelshapediscrete, double[] adouble, double[] adouble1, double[] adouble2) { this(voxelshapediscrete, (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble, voxelshapediscrete.b() + 1)), (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble1, voxelshapediscrete.c() + 1)), (DoubleList) DoubleArrayList.wrap(Arrays.copyOf(adouble2, voxelshapediscrete.d() + 1))); } - + VoxelShapeArray(VoxelShapeDiscrete voxelshapediscrete, DoubleList doublelist, DoubleList doublelist1, DoubleList doublelist2) { + // Tuinity start - optimise multi-aabb shapes + this(voxelshapediscrete, doublelist, doublelist1, doublelist2, null, null, 0.0, 0.0, 0.0); @@ -15499,7 +15499,7 @@ index 3c29cb1452cde1308f630bfcb82876ef19057e8f..c14b7bd63e3917bc5f495655c40d8825 + } + // Tuinity end - optimise multi-aabb shapes } - + @Override @@ -42,4 +69,63 @@ public final class VoxelShapeArray extends VoxelShape { throw new IllegalArgumentException(); @@ -15571,19 +15571,19 @@ index e841611bb7c36dffec44bb9e74a0a9657a113263..259605daabb18aedb15d56c78e6553ae +++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java @@ -91,7 +91,7 @@ public class VoxelShapeSpliterator extends AbstractSpliterator { VoxelShape voxelshape = iblockdata.b((IBlockAccess) this.g, this.e, this.c); - + if (voxelshape == VoxelShapes.b()) { - if (!this.b.a((double) i, (double) j, (double) k, (double) i + 1.0D, (double) j + 1.0D, (double) k + 1.0D)) { + if (!this.b.voxelShapeIntersect((double) i, (double) j, (double) k, (double) i + 1.0D, (double) j + 1.0D, (double) k + 1.0D)) { // Tuinity - keep vanilla behavior for voxelshape intersection - See comment in AxisAlignedBB continue; } - + diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe64cc2e79 100644 --- a/src/main/java/net/minecraft/server/VoxelShapes.java +++ b/src/main/java/net/minecraft/server/VoxelShapes.java @@ -17,18 +17,101 @@ public final class VoxelShapes { - + voxelshapebitset.a(0, 0, 0, true, true); return new VoxelShapeCube(voxelshapebitset); - }); @@ -15598,12 +15598,12 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe + return voxelshape == getEmptyShape() || voxelshape.isEmpty(); + } + // Tuinity end - optimise voxelshapes - + public static final VoxelShape empty() {return a();} // Paper - OBFHELPER public static VoxelShape a() { return VoxelShapes.c; } - + + static final com.tuinity.tuinity.voxel.AABBVoxelShape optimisedFullCube = new com.tuinity.tuinity.voxel.AABBVoxelShape(new AxisAlignedBB(0, 0, 0, 1.0, 1.0, 1.0)); // Tuinity - optimise voxelshape + + // Tuinity start - optimise voxelshapes @@ -15685,7 +15685,7 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe - return VoxelShapes.b; + return VoxelShapes.optimisedFullCube; // Tuinity - optimise voxelshape } - + public static VoxelShape create(double d0, double d1, double d2, double d3, double d4, double d5) { @@ -67,7 +150,7 @@ public final class VoxelShapes { return new VoxelShapeCube(voxelshapebitset); @@ -15695,9 +15695,9 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe + return new com.tuinity.tuinity.voxel.AABBVoxelShape(axisalignedbb); // Tuinity - optimise VoxelShapes for single AABB shapes } } - + @@ -132,6 +215,20 @@ public final class VoxelShapes { - + public static final boolean applyOperation(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { return VoxelShapes.c(voxelshape, voxelshape1, operatorboolean); } // Paper - OBFHELPER public static boolean c(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { + // Tuinity start - optimise voxelshape @@ -15720,7 +15720,7 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe @@ -314,8 +411,52 @@ public final class VoxelShapes { } } - + + public static boolean combinationOccludes(VoxelShape voxelshape, VoxelShape voxelshape1) { return b(voxelshape, voxelshape1); } // Tuinity - OBFHELPER public static boolean b(VoxelShape voxelshape, VoxelShape voxelshape1) { - return voxelshape != b() && voxelshape1 != b() ? (voxelshape.isEmpty() && voxelshape1.isEmpty() ? false : !c(b(), b(voxelshape, voxelshape1, OperatorBoolean.OR), OperatorBoolean.ONLY_FIRST)) : true; @@ -15769,30 +15769,30 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..636bbbc42466cb54c300352f400464fe + public static boolean b_rare(VoxelShape voxelshape, VoxelShape voxelshape1) { + return (voxelshape != b() || voxelshape != getFullUnoptimisedCube()) && (voxelshape1 != b() || voxelshape1 != getFullUnoptimisedCube()) ? ((voxelshape == VoxelShapes.getEmptyShape() || voxelshape.isEmpty()) && (voxelshape1 == VoxelShapes.getEmptyShape() || voxelshape1.isEmpty()) ? false : !c(b(), b(voxelshape, voxelshape1, OperatorBoolean.OR), OperatorBoolean.ONLY_FIRST)) : true; // Tuinity - optimise call by checking against more constant shapes } - + @VisibleForTesting diff --git a/src/main/java/net/minecraft/server/WeightedList.java b/src/main/java/net/minecraft/server/WeightedList.java index 5d9d58411f2fad9d5da703f964d269b4a7c2b205..f0fdfd6891e59891e7370a2d682b65c647b28e9e 100644 --- a/src/main/java/net/minecraft/server/WeightedList.java +++ b/src/main/java/net/minecraft/server/WeightedList.java @@ -14,7 +14,7 @@ import java.util.stream.Stream; - + public class WeightedList { - + - protected final List> list; // Paper - decompile conflict + protected final List> list; public final List> getList() { return this.list; } // Paper - decompile conflict // Tuinity - OBFHELPER private final Random b; private final boolean isUnsafe; // Paper - + @@ -74,7 +74,7 @@ public class WeightedList { - + public static class a { - + - private final T a; + private final T a; public final T getValue() { return this.a; } // Tuinity - OBFHELPER private final int b; private double c; - + diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda5f985b78 100644 --- a/src/main/java/net/minecraft/server/World.java @@ -15800,7 +15800,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda @@ -94,6 +94,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper public final ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray - + + public final com.tuinity.tuinity.config.TuinityConfig.WorldConfig tuinityConfig; // Tuinity - Server Config + public final co.aikar.timings.WorldTimingsHandler timings; // Paper @@ -15809,7 +15809,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda @@ -121,10 +123,39 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return typeKey; } - + + // Tuinity start - optimise checkDespawn + public final List getNearbyPlayers(Entity source, double maxRange, Predicate predicate) { + Chunk chunk = source.getCurrentChunk(); @@ -15847,7 +15847,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda this.world = new CraftWorld((WorldServer) this, gen, env); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit @@ -286,6 +317,15 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - + @Override public final Chunk getChunkAt(int i, int j) { // Paper - final to help inline + // Tuinity start - make sure loaded chunks get the inlined variant of this function @@ -15861,9 +15861,9 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda + // Tuinity end - make sure loaded chunks get the inlined variant of this function return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL, true); // Paper - avoid a method jump } - + @@ -360,6 +400,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - + @Override public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) { + org.spigotmc.AsyncCatcher.catchOp("set type call"); // Tuinity @@ -15871,7 +15871,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda if (this.captureTreeGeneration) { // Paper start @@ -461,6 +502,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - + // CraftBukkit start - Split off from above in order to directly send client and physic updates public void notifyAndUpdatePhysics(BlockPosition blockposition, Chunk chunk, IBlockData oldBlock, IBlockData newBlock, IBlockData actualBlock, int i, int j) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Async notify and update"); // Tuinity @@ -15889,7 +15889,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda @@ -1078,10 +1121,44 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return this.getChunkAt(i, j, ChunkStatus.FULL, false); } - + + // Tuinity start - optimise hard collision handling + @Override + public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { @@ -15934,7 +15934,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); @@ -1137,7 +1214,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper - + if (chunk != null) { - chunk.a(oclass, axisalignedbb, list, predicate); + chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class @@ -15943,7 +15943,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda } @@ -1160,7 +1237,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper - + if (chunk != null) { - chunk.a(oclass, axisalignedbb, list, predicate); + chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class @@ -15953,7 +15953,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda @@ -1168,6 +1245,106 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return list; } - + + // Tuinity start + @Override + public T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { @@ -16056,7 +16056,7 @@ index f5ab99156ce5429e63976183cbf115d5340a83a1..93c0c3376c3cb2fe416c8ae3e740ffda + @Nullable public abstract Entity getEntity(int i); - + diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java index f011869880fedae4b69e505491e8bdbc5f51dfba..0d10d317cd0b60fc0866ae505c7fd71fa886c48b 100644 --- a/src/main/java/net/minecraft/server/WorldBorder.java @@ -16064,7 +16064,7 @@ index f011869880fedae4b69e505491e8bdbc5f51dfba..0d10d317cd0b60fc0866ae505c7fd71f @@ -47,11 +47,59 @@ public class WorldBorder { return axisalignedbb.maxX > this.e() && axisalignedbb.minX < this.g() && axisalignedbb.maxZ > this.f() && axisalignedbb.minZ < this.h(); } - + + // Tuinity start - optimise collisions + // determines whether we are almost colliding with the world border + // for clear collisions, this rets false @@ -16115,7 +16115,7 @@ index f011869880fedae4b69e505491e8bdbc5f51dfba..0d10d317cd0b60fc0866ae505c7fd71f public double a(Entity entity) { return this.b(entity.locX(), entity.locZ()); } - + public final VoxelShape asVoxelShape(){ return c();} // Paper - OBFHELPER + public final VoxelShape getCollisionShape() { return this.c(); } // Tuinity - OBFHELPER public VoxelShape c() { @@ -16124,22 +16124,22 @@ index f011869880fedae4b69e505491e8bdbc5f51dfba..0d10d317cd0b60fc0866ae505c7fd71f @@ -67,18 +115,22 @@ public class WorldBorder { return Math.min(d6, d3); } - + + public final double getMinX() { return this.e(); } // Tuinity - OBFHELPER public double e() { return this.j.a(); } - + + public final double getMinZ() { return this.f(); } // Tuinity - OBFHELPER public double f() { return this.j.c(); } - + + public final double getMaxX() { return this.g(); } // Tuinity - OBFHELPER public double g() { return this.j.b(); } - + + public final double getMaxZ() { return this.h(); } // Tuinity - OBFHELPER public double h() { return this.j.d(); @@ -16153,9 +16153,9 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end +import it.unimi.dsi.fastutil.ints.IntArrayList; // Tuinity - + public class WorldServer extends World implements GeneratorAccessSeed { - + public static final BlockPosition a = new BlockPosition(100, 50, 0); private static final Logger LOGGER = LogManager.getLogger(); - public final Int2ObjectMap entitiesById = new Int2ObjectLinkedOpenHashMap(); @@ -16175,7 +16175,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 @@ -206,6 +207,111 @@ public class WorldServer extends World implements GeneratorAccessSeed { } // Paper end - rewrite ticklistserver - + + // Tuinity start + public final boolean areChunksLoadedForMove(AxisAlignedBB axisalignedbb) { + // copied code from collision methods, so that we can guarantee that they wont load chunks (we don't override @@ -16287,7 +16287,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 @@ -266,6 +372,251 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper } - + + // Tuinity start - optimise collision + public boolean collidesWithAnyBlockOrWorldBorder(@Nullable Entity entity, AxisAlignedBB axisalignedbb, boolean loadChunks, + boolean collidesWithUnloaded) { @@ -16537,7 +16537,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 @Override protected TileEntity getTileEntity(BlockPosition pos, boolean validate) { @@ -319,6 +670,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { - + public void doTick(BooleanSupplier booleansupplier) { GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); + // Tuinity start - optimise checkDespawn @@ -16548,13 +16548,13 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + } + } + // Tuinity end - optimise checkDespawn - + this.ticking = true; gameprofilerfiller.enter("world border"); @@ -468,7 +827,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } timings.scheduledBlocks.stopTiming(); // Paper - + - this.getMinecraftServer().midTickLoadChunks(); // Paper + // Tuinity - replace logic gameprofilerfiller.exitEnter("raid"); @@ -16571,11 +16571,11 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 boolean flag3 = true || !this.players.isEmpty() || !this.getForceLoadedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players @@ -493,13 +852,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { } - + this.tickingEntities = true; - ObjectIterator objectiterator = this.entitiesById.int2ObjectEntrySet().iterator(); + com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet.Iterator objectiterator = this.entitiesForIteration.iterator(); // Tuinity - + org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot while (objectiterator.hasNext()) { @@ -16583,7 +16583,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 - Entity entity = (Entity) entry.getValue(); + Entity entity = (Entity) objectiterator.next(); // Tuinity Entity entity1 = entity.getVehicle(); - + /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed @@ -515,6 +873,15 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("checkDespawn"); @@ -16599,7 +16599,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + } + // Tuinity end - optimise notify() } - + gameprofilerfiller.exit(); @@ -535,14 +902,22 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("remove"); @@ -16616,11 +16616,11 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + this.removeNavigatorsFromData(entity); } + // Tuinity end - optimise notify() - + gameprofilerfiller.exit(); } timings.entityTick.stopTiming(); // Spigot - + + objectiterator.finishedIterating(); // Tuinity this.tickingEntities = false; // Paper start @@ -16631,22 +16631,22 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 // Paper end - this.getMinecraftServer().midTickLoadChunks(); // Paper + // Tuinity - replace logic - + Entity entity2; - + @@ -564,7 +939,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } - + timings.tickEntities.stopTiming(); // Spigot - this.getMinecraftServer().midTickLoadChunks(); // Paper + // Tuinity - replace logic this.tickBlockEntities(); } - + @@ -810,7 +1185,26 @@ public class WorldServer extends World implements GeneratorAccessSeed { - + } - + + // Tuinity start - log detailed entity tick information + static final java.util.concurrent.ConcurrentLinkedDeque currentlyTickingEntities = new java.util.concurrent.ConcurrentLinkedDeque<>(); + @@ -16672,7 +16672,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 } else { @@ -863,6 +1257,11 @@ public class WorldServer extends World implements GeneratorAccessSeed { //} finally { timer.stopTiming(); } // Paper - timings - move up - + } + // Tuinity start - log detailed entity tick information + } finally { @@ -16680,7 +16680,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + } + // Tuinity end - log detailed entity tick information } - + public void a(Entity entity, Entity entity1) { @@ -921,6 +1320,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { int i = MathHelper.floor(entity.locX() / 16.0D); @@ -16692,13 +16692,13 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + int newRegionX = i >> com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.REGION_CHUNK_SIZE_SHIFT; + int newRegionZ = k >> com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.REGION_CHUNK_SIZE_SHIFT; + // Tuinity end - + if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { // Paper start - remove entity if its in a chunk more correctly. @@ -930,6 +1335,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { } // Paper end - + + // Tuinity start + if (oldRegionX != newRegionX || oldRegionZ != newRegionZ) { + this.removeNavigatorsFromData(entity); @@ -16718,19 +16718,19 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + } + // Tuinity end } - + this.getMethodProfiler().exit(); @@ -1298,7 +1714,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { Entity entity = (Entity) iterator.next(); - + if (!(entity instanceof EntityPlayer)) { - if (this.tickingEntities) { + if (false && this.tickingEntities) { // Tuinity throw (IllegalStateException) SystemUtils.c((Throwable) (new IllegalStateException("Removing entity while ticking!"))); } - + @@ -1326,6 +1742,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { - + public void unregisterEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot + this.entitiesForIteration.remove(entity); // Tuinity @@ -16759,7 +16759,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + this.removeNavigatorsFromData(entity); // Tuinity - optimise notify() entity.valid = false; // CraftBukkit } - + + // Tuinity start - optimise notify() + void removeNavigatorsIfNotPathingFromRegion(Entity entity) { + com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.RegionSection section = @@ -16868,12 +16868,12 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 int i = aentitycomplexpart.length; @@ -1429,6 +1938,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; - + this.entitiesById.put(entitycomplexpart.getId(), entitycomplexpart); + this.entitiesForIteration.add(entitycomplexpart); // Tuinity } } - + @@ -1453,12 +1963,16 @@ public class WorldServer extends World implements GeneratorAccessSeed { // this.getChunkProvider().addEntity(entity); // Paper - moved down below valid=true // CraftBukkit start - SPIGOT-5278 @@ -16896,7 +16896,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 this.getChunkProvider().addEntity(entity); // Paper - from above to be below valid=true @@ -1474,7 +1988,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } - + public void removeEntity(Entity entity) { - if (this.tickingEntities) { + if (false && this.tickingEntities) { // Tuinity @@ -16904,7 +16904,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 } else { this.removeEntityFromChunk(entity); @@ -1570,14 +2084,33 @@ public class WorldServer extends World implements GeneratorAccessSeed { - + @Override public void notify(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) { + org.spigotmc.AsyncCatcher.catchOp("notify call"); // Tuinity @@ -16912,7 +16912,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 if(this.paperConfig.updatePathfindingOnBlockUpdate) { // Paper - option to disable pathfinding updates VoxelShape voxelshape = iblockdata.getCollisionShape(this, blockposition); VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition); - + if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) { + // Tuinity start - optimise notify() + com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.Region region = this.getChunkProvider().playerChunkMap.dataRegionManager.getRegion(blockposition.getX() >> 4, blockposition.getZ() >> 4); @@ -16935,7 +16935,7 @@ index cf7d94aabab600822eb5e27f38690b06456d5fcc..43740b9b2d2c4a5b6bfe6061841ec4e4 + com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet.Iterator iterator = navigators.iterator(); + // Tuinity end - optimise notify() + try { // Tuinity end - + while (iterator.hasNext()) { // CraftBukkit start - fix SPIGOT-6362 @@ -1596,7 +2129,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {