diff --git a/SHIT_TO_CHECK.md b/SHIT_TO_CHECK.md index 024d8cc9a..98771cea3 100644 --- a/SHIT_TO_CHECK.md +++ b/SHIT_TO_CHECK.md @@ -5,4 +5,5 @@ * Mini: "MC-50319": fix if still works * Mini: I definetly dropped a patch I didnt want to drop, we need to go thru in the end and see if all patches are still in, lol * Make sure the flat bedrock setting doesn't do anything stupid -* Check DataBits foreach \ No newline at end of file +* Check DataBits foreach +* Update MobGoalHelper \ No newline at end of file diff --git a/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch b/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch index 356defd04..436e2e8ff 100644 --- a/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch +++ b/Spigot-Server-Patches/Add-PlayerAttackEntityCooldownResetEvent.patch @@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); if (damagesource.getEntity() instanceof EntityHuman) { -- ((EntityHuman) damagesource.getEntity()).ey(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired +- ((EntityHuman) damagesource.getEntity()).resetAttackCooldown(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired + // Paper start - PlayerAttackEntityCooldownResetEvent + if (damagesource.getEntity() instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) damagesource.getEntity(); @@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((EntityHuman) damagesource.getEntity()).resetCooldown(); + } + // Paper end -+ } if (event.isCancelled()) { return false; diff --git a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch index e5523e226..1d2990ac3 100644 --- a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch +++ b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch @@ -37,23 +37,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -0,0 +0,0 @@ public final class IEntitySelector { - public static final Predicate f = (entity) -> { + public static final Predicate g = (entity) -> { return !entity.isSpectator(); }; + public static Predicate isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper - public static Predicate a(double d0, double d1, double d2, double d3) { - double d4 = d3 * d3; + // Paper start + public static final Predicate affectsSpawning = (entity) -> { diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java +++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java -@@ -0,0 +0,0 @@ public class MobSpawnerPhantom { +@@ -0,0 +0,0 @@ public class MobSpawnerPhantom implements MobSpawner { while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); - if (!entityhuman.isSpectator()) { + if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper - BlockPosition blockposition = new BlockPosition(entityhuman); + BlockPosition blockposition = entityhuman.getChunkCoordinates(); - if (!worldserver.worldProvider.f() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) { + if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) { diff --git a/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch b/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch index ef2016f31..b070d2810 100644 --- a/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch +++ b/Spigot-Server-Patches/Add-tick-times-API-and-mspt-command.patch @@ -91,19 +91,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant -Date: Sun, 19 Apr 2020 12:25:20 +0200 -Subject: [PATCH] Allow sleeping players to float - -This change lets players who are in their bed have a position which is above -ground for a longer period of time. This is because of the server not setting -their position to the ground/exit location when entering the bed, resulting in -the server believing they're still in the air. - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - this.player.setLocation(this.l, this.m, this.n, this.player.yaw, this.player.pitch); - ++this.e; - this.processedMovePackets = this.receivedMovePackets; -- if (this.B) { -+ if (this.B && !this.player.isSleeping()) { // Paper - #3176 Allow sleeping players to float - if (++this.C > 80) { - PlayerConnection.LOGGER.warn("{} was kicked for floating too long!", this.player.getDisplayName().getString()); - this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage); // Paper - use configurable kick message diff --git a/Spigot-Server-Patches/Broadcast-join-message-to-console.patch b/Spigot-Server-Patches/Broadcast-join-message-to-console.patch index 9ca906ecd..58ea9674f 100644 --- a/Spigot-Server-Patches/Broadcast-join-message-to-console.patch +++ b/Spigot-Server-Patches/Broadcast-join-message-to-console.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (joinMessage != null && joinMessage.length() > 0) { - for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { -- server.getPlayerList().sendAll(new PacketPlayOutChat(line)); +- server.getPlayerList().sendAll(new PacketPlayOutChat(line, ChatMessageType.SYSTEM, SystemUtils.b)); - } + // Paper start - Removed sendAll for loop and broadcasted to console also + server.getPlayerList().sendMessage(CraftChatMessage.fromString(joinMessage)); diff --git a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch index 4abf65846..533cad888 100644 --- a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch +++ b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch @@ -9,9 +9,9 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World { - private final Queue entitiesToAdd = Queues.newArrayDeque(); +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { public final List players = Lists.newArrayList(); // Paper - private -> public + public final ChunkProviderServer chunkProvider; // Paper - public boolean tickingEntities; + // Paper start + List afterEntityTickingTasks = Lists.newArrayList(); @@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end private final MinecraftServer server; - private final WorldNBTStorage dataManager; + public final WorldDataServer worldDataServer; // CraftBukkit - type public boolean savingDisabled; -@@ -0,0 +0,0 @@ public class WorldServer extends World { +@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed { timings.entityTick.stopTiming(); // Spigot this.tickingEntities = false; @@ -42,4 +42,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end this.getMinecraftServer().midTickLoadChunks(); // Paper - try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings + Entity entity2; diff --git a/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch index b79282d73..9ad6a06d8 100644 --- a/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch +++ b/Spigot-Server-Patches/Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch @@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/ChunkMapDistance.java +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { - long i = sectionposition.u().pair(); + long i = sectionposition.r().pair(); ObjectSet objectset = (ObjectSet) this.c.get(i); - objectset.remove(entityplayer); @@ -19,5 +19,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully. + if (objectset == null || objectset.isEmpty()) { // Paper this.c.remove(i); - this.f.b(i, Integer.MAX_VALUE, false); - this.g.b(i, Integer.MAX_VALUE, false); + this.f.update(i, Integer.MAX_VALUE, false); + this.g.update(i, Integer.MAX_VALUE, false); diff --git a/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch index 124b393bf..da24b2112 100644 --- a/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch +++ b/Spigot-Server-Patches/Don-t-fire-BlockFade-on-worldgen-threads.patch @@ -9,11 +9,20 @@ diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/n index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/BlockFire.java +++ b/src/main/java/net/minecraft/server/BlockFire.java -@@ -0,0 +0,0 @@ public class BlockFire extends Block { +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { // CraftBukkit start -+ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a((IBlockAccess) generatoraccess, blockposition).set(BlockFire.AGE, iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation - if (!iblockdata.canPlace(generatoraccess, blockposition)) { ++ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation + if (!this.canPlace(iblockdata, generatoraccess, blockposition)) { CraftBlockState blockState = CraftBlockState.getBlockState(generatoraccess, blockposition); blockState.setData(Blocks.AIR.getBlockData()); +@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract { + return blockState.getHandle(); + } + } +- return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)); ++ return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)); // Paper - diff on change, see "don't fire events in world generation" + // CraftBukkit end + } + diff --git a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch index 33a19ad58..875b09ea4 100644 --- a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch +++ b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch @@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.serverStatisticManager = minecraftserver.getPlayerList().getStatisticManager(this); this.advancementDataPlayer = minecraftserver.getPlayerList().f(this); - this.H = 1.0F; -- this.a(worldserver); -+ //this.a(worldserver); // Paper - don't move to spawn on login, only first join + this.G = 1.0F; +- this.b(worldserver); ++ //this.b(worldserver); // Paper - don't move to spawn on login, only first join this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper @@ -26,28 +26,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // CraftBukkit end -+ public void moveToSpawn(WorldServer worldserver) { a(worldserver); } // Paper - OBFHELPER - private void a(WorldServer worldserver) { ++ public final void moveToSpawn(WorldServer worldserver) { b(worldserver); } // Paper - OBFHELPER + private void b(WorldServer worldserver) { BlockPosition blockposition = worldserver.getSpawn(); @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - position = new Vec3D(world.getSpawn()); + position = Vec3D.a(((WorldServer) world).getSpawn()); } this.world = world; - this.setPosition(position.getX(), position.getY(), position.getZ()); + this.setPositionRaw(position.getX(), position.getY(), position.getZ()); // Paper - don't register to chunks yet } - this.dimension = ((WorldServer) this.world).getWorldProvider().getDimensionManager(); this.playerInteractManager.a((WorldServer) world); + } diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { - NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit"); - s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; + worldserver1 = worldserver; } -+ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are.... - // CraftBukkit end - entityplayer.spawnIn(worldserver); ++ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are.... ++ + entityplayer.spawnIn(worldserver1); + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); + String s1 = "local"; diff --git a/Spigot-Server-Patches/Don-t-tick-dead-players.patch b/Spigot-Server-Patches/Don-t-tick-dead-players.patch index 01acdc680..b9e63c162 100644 --- a/Spigot-Server-Patches/Don-t-tick-dead-players.patch +++ b/Spigot-Server-Patches/Don-t-tick-dead-players.patch @@ -14,8 +14,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void playerTick() { try { -- if (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this))) { -+ if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn) +- if (!this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { ++ if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn) super.tick(); } diff --git a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch index 0d34b0489..2251aae28 100644 --- a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -53,8 +53,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Either.left(chunk); }); }, (runnable) -> { -- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error -+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // CraftBukkit - decompile error // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request. +- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); ++ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request. }); completablefuture1.thenAcceptAsync((either) -> { diff --git a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index ab15c7d97..74b6d19d1 100644 --- a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).supressTrackerForLogin) return; // Delay adding to tracker until after list packets // Paper end if (!(entity instanceof EntityComplexPart)) { - if (!(entity instanceof EntityLightning)) { + EntityTypes entitytypes = entity.getEntityType(); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java diff --git a/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch b/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch index b9b0c35c5..b302e074b 100644 --- a/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch +++ b/Spigot-Server-Patches/Fix-numerous-item-duplication-issues-and-teleport-is.patch @@ -36,17 +36,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit start @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @Nullable - public Entity teleportTo(DimensionManager dimensionmanager, BlockPosition location) { + public Entity teleportTo(WorldServer worldserver, BlockPosition location) { // CraftBukkit end + // Paper start - fix bad state entities causing dupes + if (!isAlive() || !valid) { -+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + dimensionmanager + ":" + location, new Throwable()); ++ LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable()); + return null; + } + // Paper end - if (!this.world.isClientSide && !this.dead) { + if (this.world instanceof WorldServer && !this.dead) { this.world.getMethodProfiler().enter("changeDimension"); - MinecraftServer minecraftserver = this.getMinecraftServer(); + // CraftBukkit start @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke entity.bukkitEntity = this.getBukkitEntity(); @@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!itemstack.isEmpty()) { - drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops + drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe - this.handItems.set(i, ItemStack.a); + this.handItems.set(i, ItemStack.b); } } @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { @@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!itemstack.isEmpty()) { - drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops + drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe - this.armorItems.set(i, ItemStack.a); + this.armorItems.set(i, ItemStack.b); } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java diff --git a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch index c59d66e27..62fecb8ad 100644 --- a/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch +++ b/Spigot-Server-Patches/Implement-Brigadier-Mojang-API.patch @@ -40,8 +40,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 -public class CommandListenerWrapper implements ICompletionProvider { +public class CommandListenerWrapper implements ICompletionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper - public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player", new Object[0])); - public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity", new Object[0])); + public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player")); + public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity")); @@ -0,0 +0,0 @@ public class CommandListenerWrapper implements ICompletionProvider { return this.g; } @@ -73,19 +73,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { - ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); + ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); - this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { -- if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer -- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error -+ // Paper start -+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); -+ suggestEvent.setCancelled(suggestions.isEmpty()); -+ if (!suggestEvent.callEvent()) return; -+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper -+ // Paper end - }); - }); // Paper - This needs to be on main + this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { +- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer +- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions)); ++ // Paper start ++ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); ++ suggestEvent.setCancelled(suggestions.isEmpty()); ++ if (!suggestEvent.callEvent()) return; ++ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper ++ // Paper end + }); + }); } @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { @@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestEvent.getSuggestions())); } // Paper end - async tab completion - + } diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java diff --git a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch index 355a7d356..95d0b0363 100644 --- a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch +++ b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch @@ -787,13 +787,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } }; private final Map c = new EnumMap(PathfinderGoal.Type.class); -- private final Set d = Sets.newLinkedHashSet();private Set getTasks() { return d; }// Paper - OBFHELPER -+ private final Set d = Sets.newLinkedHashSet();public Set getTasks() { return d; }// Paper - OBFHELPER - private final GameProfilerFiller e; +- private final Set d = Sets.newLinkedHashSet(); private Set getTasks() { return d; }// Paper - OBFHELPER ++ private final Set d = Sets.newLinkedHashSet(); public final Set getTasks() { return d; }// Paper - OBFHELPER // Paper - private -> public + private final Supplier e; private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { - this.e = gameprofilerfiller; + this.e = supplier; } - public void a(int i, PathfinderGoal pathfindergoal) { @@ -811,11 +811,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { PathfinderGoalWrapped goalWrapped = iterator.next(); @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { - this.e.exit(); + gameprofilerfiller.exit(); } -+ public Stream getExecutingGoals() {return c();} // Paper - OBFHELPER - public Stream c() { ++ public final Stream getExecutingGoals() { return d(); } // Paper - OBFHELPER + public Stream d() { return this.d.stream().filter(PathfinderGoalWrapped::g); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java diff --git a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch index c27a59fd8..eac1cd199 100644 --- a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch +++ b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch @@ -89,14 +89,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { - private static final Map b = ImmutableMap.builder().put(EntityPose.STANDING, EntityHuman.bp).put(EntityPose.SLEEPING, EntityHuman.ap).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build(); + private static final Map b = ImmutableMap.builder().put(EntityPose.STANDING, EntityHuman.bo).put(EntityPose.SLEEPING, EntityHuman.ao).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build(); private static final DataWatcherObject c = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c); private static final DataWatcherObject d = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.b); -- protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); -+ protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject getSkinPartsWatcher() { return bq; } // Paper - OBFHELPER - protected static final DataWatcherObject br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); +- protected static final DataWatcherObject bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); ++ protected static final DataWatcherObject bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject getSkinPartsWatcher() { return bp; } // Paper - OBFHELPER + protected static final DataWatcherObject bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); + protected static final DataWatcherObject br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); protected static final DataWatcherObject bs = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); - protected static final DataWatcherObject bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -108,19 +108,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; // Paper import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Either; - import io.netty.util.concurrent.Future; + import com.mojang.serialization.DataResult; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public int lastSentExp = -99999999; public int invulnerableTicks = 60; - private EnumChatVisibility ch; -- private boolean ci = true; -+ private boolean ci = true; public boolean hasChatColorsEnabled() { return this.ci; } // Paper - OBFHELPER - private long cj = SystemUtils.getMonotonicMillis(); + private EnumChatVisibility cf; +- private boolean cg = true; ++ private boolean cg = true; public boolean hasChatColorsEnabled() { return this.cg; } // Paper - OBFHELPER + private long ch = SystemUtils.getMonotonicMillis(); private Entity spectatedEntity; public boolean worldChangeInvuln; @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - } + public String locale = null; // CraftBukkit - lowercase // Paper - default to null public void a(PacketPlayInSettings packetplayinsettings) { + new PlayerClientOptionsChangeEvent(getBukkitEntity(), packetplayinsettings.getLocale(), packetplayinsettings.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packetplayinsettings.getChatVisibility().name()), packetplayinsettings.hasChatColorsEnabled(), new com.destroystokyo.paper.PaperSkinParts(packetplayinsettings.getSkinParts()), packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event // CraftBukkit start @@ -130,15 +130,19 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayInSettings.java b/src/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInSettings.java +++ b/src/main/java/net/minecraft/server/PacketPlayInSettings.java +@@ -0,0 +0,0 @@ import java.io.IOException; + + public class PacketPlayInSettings implements Packet { + +- public String locale; ++ public String locale; public String getLocale() { return this.locale; } // Paper - OBFHELPER + public int viewDistance; + private EnumChatVisibility c; + private boolean d; @@ -0,0 +0,0 @@ public class PacketPlayInSettings implements Packet { packetlistenerplayin.a(this); } -+ public String getLocale() { return b(); } // Paper - OBFHELPER - public String b() { - return this.a; - } - + public EnumChatVisibility getChatVisibility() { return d(); } // Paper - OBFHELPER public EnumChatVisibility d() { return this.c; @@ -166,14 +170,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 import com.destroystokyo.paper.Title; import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; -@@ -0,0 +0,0 @@ import net.minecraft.server.BlockPosition; - import net.minecraft.server.ChatComponentText; - import net.minecraft.server.Container; - import net.minecraft.server.Entity; -+import net.minecraft.server.EntityHuman; - import net.minecraft.server.EntityLiving; - import net.minecraft.server.EntityPlayer; - import net.minecraft.server.EnumColor; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setViewDistance(int viewDistance) { throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO diff --git a/Spigot-Server-Patches/Improved-Watchdog-Support.patch b/Spigot-Server-Patches/Improved-Watchdog-Support.patch index 1486a45c9..d22f25f74 100644 --- a/Spigot-Server-Patches/Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/Improved-Watchdog-Support.patch @@ -71,11 +71,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer - long l = SystemUtils.getMonotonicNanos() - i; - String s2 = String.format(Locale.ROOT, "%.3fs", (double) l / 1.0E9D); + long j = SystemUtils.getMonotonicNanos() - i; + String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); -- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); -+ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); // Paper moved to after init +- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); ++ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); // Paper moved to after init if (dedicatedserverproperties.announcePlayerAchievements != null) { ((GameRules.GameRuleBoolean) this.getGameRules().get(GameRules.ANNOUNCE_ADVANCEMENTS)).a(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this); } @@ -91,8 +91,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void stop() { super.stop(); -- SystemUtils.f(); -+ //SystemUtils.f(); // Paper - moved into super +- SystemUtils.h(); ++ //SystemUtils.h(); // Paper - moved into super } @Override @@ -105,21 +105,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 r0.run(); } catch (Exception exception) { + if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper - IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bi(), exception); + IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bh(), exception); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant resourcePackRepository; - @Nullable - private ResourcePackSourceFolder resourcePackFolder; -+ public volatile Thread shutdownThread; // Paper - public CommandDispatcher commandDispatcher; - private final CraftingManager craftingManager; - private final TagRegistry tagRegistry; @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant S a(Function function) { + AtomicReference atomicreference = new AtomicReference(); + Thread thread = new Thread(() -> { +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant public + boolean flag = this.chunkMapDistance.a(this.playerChunkMap); + boolean flag1 = this.playerChunkMap.b(); + diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/Entity.java @@ -12,18 +25,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.pitch = MathHelper.a(f1, -90.0F, 90.0F) % 360.0F; this.lastYaw = this.yaw; this.lastPitch = this.pitch; -- world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit -+ if (valid) world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit // Paper +- world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit ++ if (valid) world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit // Paper } - public void setPositionRotation(BlockPosition blockposition, float f, float f1) { + public void c(Vec3D vec3d) { diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + private static final Logger LOGGER = LogManager.getLogger(); - public String locale = null; // CraftBukkit - lowercase // Paper - default to null public PlayerConnection playerConnection; + public NetworkManager networkManager; // Paper public final MinecraftServer server; @@ -45,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } // Paper end } else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) { -- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); +- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId()); + EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper if (entityplayer == null) { @@ -54,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } this.networkManager.sendPacket(new PacketLoginOutSuccess(this.i)); -- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); +- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId()); + EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper if (entityplayer != null) { @@ -140,15 +153,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; - } + }String lastKnownName = s; // Paper - if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are.... // CraftBukkit end + if (nbttagcompound != null) { @@ -0,0 +0,0 @@ public abstract class PlayerList { entityplayer.B().a(entityplayer); - this.sendScoreboard(worldserver.getScoreboard(), entityplayer); + this.sendScoreboard(worldserver1.getScoreboard(), entityplayer); this.server.invalidatePingSample(); + // Paper start - async load spawn in chunk + WorldServer finalWorldserver = worldserver; ++ WorldServer finalWorldserver1 = worldserver1; + int chunkX = loc.getBlockX() >> 4; + int chunkZ = loc.getBlockZ() >> 4; + final ChunkCoordIntPair pos = new ChunkCoordIntPair(chunkX, chunkZ); @@ -165,7 +179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }).thenAccept(chunk -> { + playerconnection.playerJoinReady = () -> { + postChunkLoadJoin( -+ entityplayer, finalWorldserver, networkmanager, playerconnection, ++ entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection, + nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName + ); + //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair()); @@ -186,7 +200,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }); + } + -+ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { ++ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) { + pendingPlayers.remove(entityplayer.getUniqueID(), entityplayer); + if (!networkmanager.isConnected()) { + return; @@ -196,6 +210,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ChatMessage chatmessage; if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) { +@@ -0,0 +0,0 @@ public abstract class PlayerList { + entityplayer.supressTrackerForLogin = true; + worldserver.addPlayerJoin(entityplayer); + this.server.getBossBattleCustomData().a(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer); +- mountSavedVehicle(entityplayer, worldserver, nbttagcompound); ++ mountSavedVehicle(entityplayer, worldserver, worldserver1, nbttagcompound); + // Paper end + // CraftBukkit start + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); @@ -0,0 +0,0 @@ public abstract class PlayerList { } entityplayer.sentListPacket = true; @@ -211,7 +234,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + ((WorldServer)entityplayer.world).getChunkProvider().playerChunkMap.addEntity(entityplayer); // track entity now onPlayerJoinFinish(entityplayer, worldserver, s1); } - private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { +- private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) { ++ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NBTTagCompound nbttagcompound) { + // Paper end + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); @@ -0,0 +0,0 @@ public abstract class PlayerList { protected void savePlayerFile(EntityPlayer entityplayer) { @@ -242,7 +269,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end // CraftBukkit start - // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); + // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); @@ -0,0 +0,0 @@ public abstract class PlayerList { cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); // CraftBukkit end diff --git a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch index 8c4e734e6..cf1ca82dd 100644 --- a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch +++ b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch @@ -81,17 +81,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // Paper end - this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping + final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); if (optional.isPresent()) { @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.timings.chunkTicks.startTiming(); // Spigot // Paper - this.world.a(chunk, k); - this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper -+ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper + this.world.timings.chunkTicks.startTiming(); // Spigot // Paper + this.world.a(chunk, k); + this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper ++ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper + } } } - }); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { super.executeTask(runnable); } @@ -154,7 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public boolean canSleepForTick() { // Paper // CraftBukkit start if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken - return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.ac ? this.ab : this.nextTick); + return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.X ? this.W : this.nextTick); @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance if (flag1) { - ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error + ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -125,8 +125,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + boolean needsChunkCenterUpdate; // Paper - no-tick view distance + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { - super((World) worldserver, gameprofile); - playerinteractmanager.player = this; + super(worldserver, worldserver.getSpawn(), gameprofile); + this.spawnDimension = World.OVERWORLD; diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java @@ -306,7 +306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + player.needsChunkCenterUpdate = false; + // Paper end - no-tick view distance } - + // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -367,18 +367,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return Either.left(chunk); }); }, (runnable) -> { -- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error -+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again) +- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); ++ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again) }); return completablefuture1; } @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } // Paper } -- protected void setViewDistance(int i) { + protected void setViewDistance(int i) { - int j = MathHelper.clamp(i + 1, 3, 33); -+ public final void setViewDistance(int i) { // Paper - public + 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) { @@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return Stream.empty(); + } + // all current cases are inlined so we wont hit this code, it's just in case plugins or future updates use it -+ List players = new ArrayList<>(); ++ List players = new java.util.ArrayList<>(); + Object[] backingSet = inRange.getBackingSet(); + + if (flag) { // flag -> border only @@ -542,7 +540,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final void sendChunk(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { this.a(entityplayer, apacket, chunk); } // Paper - OBFHELPER private void a(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { if (apacket[0] == null) { - apacket[0] = new PacketPlayOutMapChunk(chunk, 65535); + apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ); PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair()); @@ -557,23 +555,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { - // CraftBukkit - getType() + // Spigot - view distance networkmanager.queueImmunity = true; // Paper -- playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.spigotConfig.viewDistance, flag1, !flag)); -+ playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag)); // Paper - no-tick view distance +- playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1.getSeed()), worlddata.isHardcore(), this.server.E(), this.s, worldserver1.getTypeKey(), worldserver1.getDimensionKey(), this.getMaxPlayers(), worldserver.spigotConfig.viewDistance, flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); ++ playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1.getSeed()), worlddata.isHardcore(), this.server.E(), this.s, worldserver1.getTypeKey(), worldserver1.getDimensionKey(), this.getMaxPlayers(), worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); @@ -0,0 +0,0 @@ public abstract class PlayerList { - WorldData worlddata = worldserver.getWorldData(); - - entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getType(), WorldData.c(worldserver.getWorldData().getSeed()), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); -- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.spigotConfig.viewDistance)); // Spigot -+ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Paper - no-tick view distance - entityplayer1.spawnIn(worldserver); + // CraftBukkit start + WorldData worlddata = worldserver1.getWorldData(); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver1.getTypeKey(), worldserver1.getDimensionKey(), BiomeManager.a(worldserver1.getSeed()), entityplayer1.playerInteractManager.getGameMode(), entityplayer1.playerInteractManager.c(), worldserver1.isDebugWorld(), worldserver1.isFlatWorld(), flag)); +- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.spigotConfig.viewDistance)); // Spigot ++ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Spigot // Paper - no-tick view distance + entityplayer1.spawnIn(worldserver1); entityplayer1.dead = false; - entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch)); + entityplayer1.playerConnection.teleport(new Location(worldserver1.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch)); @@ -0,0 +0,0 @@ public abstract class PlayerList { public void a(int i) { diff --git a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch index 12459568c..e809bb728 100644 --- a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch +++ b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch @@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List into) { ++ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List into, Predicate predicate) { + // copied from getEntities + int min = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); + int max = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); @@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Entity entity1 = entities[i]; + if (entity1.shouldBeRemoved) continue; // Paper + -+ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb)) { ++ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entity1))) { + into.add(entity1); + + if (!(entity1 instanceof EntityEnderDragon)) { @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + for (int i1 = 0; i1 < l; ++i1) { + EntityComplexPart entitycomplexpart = aentitycomplexpart[i1]; + -+ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb)) { ++ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) { + into.add(entitycomplexpart); + } + } @@ -106,9 +106,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + Boolean hardCollides = cachedOverrides.get(this.getClass()); + if (hardCollides == null) { + try { -+ Object getHardCollisionBoxMethod = Entity.class.getMethod("au"); ++ Object getHardCollisionBoxMethod = Entity.class.getMethod("ay"); + Object getHardCollisionBoxEntityMethod = Entity.class.getMethod("j", Entity.class); -+ if (!this.getClass().getMethod("au").equals(getHardCollisionBoxMethod)) { ++ if (!this.getClass().getMethod("ay").equals(getHardCollisionBoxMethod)) { + hardCollides = Boolean.TRUE; + } else if (!this.getClass().getMethod("j", Entity.class).equals(getHardCollisionBoxEntityMethod)) { + hardCollides = Boolean.TRUE; @@ -140,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public void checkDespawn() {} -+ public final EntityComplexPart[] getComplexParts() { return this.eo(); } // Paper - OBFHELPER - public EntityComplexPart[] eo() { ++ public final EntityComplexPart[] getComplexParts() { return this.eK(); } // Paper - OBFHELPER + public EntityComplexPart[] eK() { return this.children; } diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -149,34 +149,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -0,0 +0,0 @@ public interface IEntityAccess { - return this.b(oclass, axisalignedbb, IEntitySelector.f); + return this.b(oclass, axisalignedbb, IEntitySelector.g); } + // Paper start - optimise hard collision + /** + * Not guaranteed to only return hard colliding entites + */ -+ default List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { ++ default List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + return this.getEntities(entity, axisalignedbb); + } + // Paper end - optimise hard collision + - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + default Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { if (axisalignedbb.a() < 1.0E-7D) { return Stream.empty(); } else { AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); -- Stream stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { // Paper - decompile fix -+ Stream stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision - return !set.contains(entity1); - }).filter((entity1) -> { - return entity == null || !entity.isSameVehicle(entity1); - }).flatMap((entity1) -> { -- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); -+ return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override - }).filter(Objects::nonNull); - return stream.filter(axisalignedbb1::c).map(VoxelShapes::a); +- return this.getEntities(entity, axisalignedbb1, predicate.and((entity1) -> { ++ // Paper start ++ Predicate effectivePredicate = predicate.and((entity1) -> { + return entity == null || !entity.isSameVehicle(entity1); +- })).stream().flatMap((entity1) -> { ++ }); ++ ++ return ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb, effectivePredicate) : this.getHardCollidingEntities(entity, axisalignedbb1, effectivePredicate)).stream().flatMap((entity1) -> { + if (entity != null) { +- AxisAlignedBB axisalignedbb2 = entity.j(entity1); ++ AxisAlignedBB axisalignedbb2 = entity.j(entity1); // Paper - diff on change, hard collision box method + + if (axisalignedbb2 != null && axisalignedbb2.c(axisalignedbb1)) { + return Stream.of(entity1.ay(), axisalignedbb2); + } + } + +- return Stream.of(entity1.ay()); ++ return Stream.of(entity1.ay()); // Paper - diff on change, hard collision box method + }).filter(Objects::nonNull).map(VoxelShapes::a); + } + } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/World.java @@ -187,7 +199,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - optimise hard collision handling + @Override -+ public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { ++ public List getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + // copied from below + List list = Lists.newArrayList(); + int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); @@ -195,14 +207,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); + int l = MathHelper.floor((axisalignedbb.maxZ + 2.0D) / 16.0D); + -+ ChunkProviderServer chunkProvider = ((ChunkProviderServer)this.chunkProvider); ++ ChunkProviderServer chunkProvider = ((WorldServer)this).getChunkProvider(); + + for (int i1 = i; i1 <= j; ++i1) { + for (int j1 = k; j1 <= l; ++j1) { + Chunk chunk = chunkProvider.getChunkAtIfLoadedMainThread(i1, j1); + + if (chunk != null) { -+ chunk.getHardCollidingEntities(entity, axisalignedbb, list); ++ chunk.getHardCollidingEntities(entity, axisalignedbb, list, predicate); + } + } + } diff --git a/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch b/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch index 7fd7aa4d5..0f3108799 100644 --- a/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch +++ b/Spigot-Server-Patches/Optimize-ChunkProviderServer-s-chunk-level-checking-.patch @@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean a(Entity entity) { - long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4); - -- return this.a(i, PlayerChunk::b); +- return this.a(i, (Function>>) PlayerChunk::b); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // entity ticking + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity)); @@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final boolean isEntityTickingChunk(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } // Paper - OBFHELPER @Override public boolean a(ChunkCoordIntPair chunkcoordintpair) { -- return this.a(chunkcoordintpair.pair(), PlayerChunk::b); +- return this.a(chunkcoordintpair.pair(), (Function>>) PlayerChunk::b); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // is entity ticking ready + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(chunkcoordintpair)); @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public boolean a(BlockPosition blockposition) { - long i = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4); - -- return this.a(i, PlayerChunk::a); +- return this.a(i, (Function>>) PlayerChunk::a); // CraftBukkit - decompile error + // Paper start - optimize is ticking ready type functions + // is ticking ready + PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(blockposition)); @@ -48,15 +48,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimize is ticking ready type functions } - public boolean b(Entity entity) { -- long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4); -- -- return this.a(i, PlayerChunk::c); -+ // Paper start - optimize is ticking ready type functions -+ // is full chunk ready -+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity)); -+ return playerChunk != null && playerChunk.isFullChunkReady(); -+ // Paper end - optimize is ticking ready type functions - } - private boolean a(long i, Function>> function) { diff --git a/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch b/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch index 2cd9d1192..570df4963 100644 --- a/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch +++ b/Spigot-Server-Patches/Optimize-Collision-to-not-load-chunks.patch @@ -32,57 +32,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { } - default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + try { if (entity != null) entity.collisionLoadChunks = true; // Paper - return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty); + return this.d(entity, axisalignedbb, predicate).allMatch(VoxelShape::isEmpty); + } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper } - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { -@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess { - } - - while (cursorposition.a()) { -- int k1 = cursorposition.b(); -- int l1 = cursorposition.c(); -- int i2 = cursorposition.d(); -+ int k1 = cursorposition.b();int x = k1; // Paper -+ int l1 = cursorposition.c();int y = l1; // Paper -+ int i2 = cursorposition.d();int z = i2; // Paper - int j2 = cursorposition.e(); - - if (j2 != 3) { -- int k2 = k1 >> 4; -- int l2 = i2 >> 4; -- IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2); -- -- if (iblockaccess != null) { -- blockposition_mutableblockposition.d(k1, l1, i2); -- IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); -+ // Paper start - ensure we don't load chunks -+ //int k2 = k1 >> 4; -+ //int l2 = i2 >> 4; -+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14; -+ blockposition_mutableblockposition.setValues(x, y, z); -+ -+ boolean isRegionLimited = ICollisionAccess.this instanceof RegionLimitedWorldAccess; -+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks) -+ ? ICollisionAccess.this.getType(blockposition_mutableblockposition) -+ : ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition) -+ ); -+ if (iblockdata == null) { -+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { -+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))); -+ consumer.accept(voxelshape3); -+ return true; -+ } -+ } else { -+ //blockposition_mutableblockposition.d(k1, l1, i2); // moved up -+ //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up -+ // Paper end - - if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { - VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); + Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java @@ -92,9 +48,77 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 // CraftBukkit end + worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper - while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { + while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) { entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ()); } +diff --git a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java ++++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java +@@ -0,0 +0,0 @@ import javax.annotation.Nullable; + public class VoxelShapeSpliterator extends AbstractSpliterator { + + @Nullable +- private final Entity a; ++ private final Entity a; final Entity getEntity() { return this.a; } // Paper - OBFHELPER + private final AxisAlignedBB b; + private final VoxelShapeCollision c; + private final CursorPosition d; +- private final BlockPosition.MutableBlockPosition e; ++ private final BlockPosition.MutableBlockPosition e; final BlockPosition.MutableBlockPosition getMutablePos() { return this.e; } // Paper - OBFHELPER + private final VoxelShape f; +- private final ICollisionAccess g; ++ private final ICollisionAccess g; final ICollisionAccess getCollisionAccess() { return this.g; } // Paper - OBFHELPER + private boolean h; + private final BiPredicate i; + +@@ -0,0 +0,0 @@ public class VoxelShapeSpliterator extends AbstractSpliterator { + boolean a(Consumer consumer) { + while (true) { + if (this.d.a()) { +- int i = this.d.b(); +- int j = this.d.c(); +- int k = this.d.d(); ++ int i = this.d.b(); final int x = i; ++ int j = this.d.c(); final int y = j; ++ int k = this.d.d(); final int z = k; + int l = this.d.e(); + + if (l == 3) { + continue; + } + +- IBlockAccess iblockaccess = this.a(i, k); +- +- if (iblockaccess == null) { ++ // Paper start - ensure we don't load chunks ++ Entity entity = this.getEntity(); ++ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = this.getMutablePos(); ++ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14; ++ blockposition_mutableblockposition.setValues(x, y, z); ++ ++ boolean isRegionLimited = this.getCollisionAccess() instanceof RegionLimitedWorldAccess; ++ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks) ++ ? this.getCollisionAccess().getType(blockposition_mutableblockposition) ++ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition) ++ ); ++ ++ if (iblockdata == null) { ++ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { ++ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))); ++ consumer.accept(voxelshape3); ++ return true; ++ } + continue; + } +- +- this.e.d(i, j, k); +- IBlockData iblockdata = iblockaccess.getType(this.e); ++ // Paper - moved up ++ // Paper end + + if (!this.i.test(iblockdata, this.e) || l == 1 && !iblockdata.d() || l == 2 && !iblockdata.a(Blocks.MOVING_PISTON)) { + continue; diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/VoxelShapes.java @@ -107,5 +131,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper + if (iblockdata == null) return 0.0D; // Paper - if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { + if ((k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) { d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0); diff --git a/Spigot-Server-Patches/Optimize-Pathfinding.patch b/Spigot-Server-Patches/Optimize-Pathfinding.patch index 94c11c7ee..d35d9e3aa 100644 --- a/Spigot-Server-Patches/Optimize-Pathfinding.patch +++ b/Spigot-Server-Patches/Optimize-Pathfinding.patch @@ -17,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - protected PathEntity c; + protected PathEntity c; protected final PathEntity getCurrentPath() { return this.c; } // Paper - OBFHELPER protected double d; - private final AttributeInstance p; protected int e; + protected int f; @@ -0,0 +0,0 @@ public abstract class NavigationAbstract { return this.a(this.a(d0, d1, d2, 1), d3); } diff --git a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index 1bc10e94d..7525f1162 100644 --- a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -64,9 +64,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 entityPlayer.playerNaturallySpawnedEvent.callEvent(); }; // Paper end -- this.playerChunkMap.f().forEach((playerchunk) -> { +- this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no... + this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); if (optional.isPresent()) { diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java @@ -124,8 +124,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public final WorldServer world; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { - super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer); + 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); - this.visibleChunks = this.updatingChunks.clone(); + //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning this.pendingUnload = new Long2ObjectLinkedOpenHashMap(); diff --git a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch index 44fdb9491..a53602822 100644 --- a/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch +++ b/Spigot-Server-Patches/Optimize-isOutsideRange-to-use-distance-maps.patch @@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); - private final ChunkMapDistance.a e = new ChunkMapDistance.a(); + private final ChunkMapDistance.a ticketLevelTracker = new ChunkMapDistance.a(); - private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); -+ public static final int MOB_SPAWN_RANGE = 8; //private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used ++ public static final int MOB_SPAWN_RANGE = 8; // private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); // Paper start use a queue, but still keep unique requirement public final java.util.Queue pendingChunkUpdates = new java.util.ArrayDeque() { @@ -34,24 +34,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.f.a(); + //this.f.a(); // Paper - no longer used this.g.a(); - int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE); + int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE); boolean flag = i != 0; @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { ((ObjectSet) this.c.computeIfAbsent(i, (j) -> { return new ObjectOpenHashSet(); })).add(entityplayer); -- this.f.b(i, 0, true); -+ //this.f.b(i, 0, true); // Paper - no longer used - this.g.b(i, 0, true); +- this.f.update(i, 0, true); ++ //this.f.update(i, 0, true); // Paper - no longer used + this.g.update(i, 0, true); } @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully. if (objectset == null || objectset.isEmpty()) { // Paper this.c.remove(i); -- this.f.b(i, Integer.MAX_VALUE, false); -+ //this.f.b(i, Integer.MAX_VALUE, false); // Paper - no longer used - this.g.b(i, Integer.MAX_VALUE, false); +- this.f.update(i, Integer.MAX_VALUE, false); ++ //this.f.update(i, Integer.MAX_VALUE, false); // Paper - no longer used + this.g.update(i, Integer.MAX_VALUE, false); } @@ -0,0 +0,0 @@ public abstract class ChunkMapDistance { @@ -116,37 +116,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - optimize isOutisdeRange this.world.getMethodProfiler().enter("pollingChunks"); int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED); - BlockPosition blockposition = this.world.getSpawn(); + boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - - this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings this.world.getMethodProfiler().exit(); + //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper + //Collections.shuffle(list); // Paper - //Paper start - call player naturally spawn event - int chunkRange = world.spigotConfig.mobSpawnRange; - chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange; - chunkRange = Math.min(chunkRange, 8); -- for (EntityPlayer entityPlayer : this.world.players) { +- for (EntityPlayer entityPlayer : this.world.getPlayers()) { - entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); - entityPlayer.playerNaturallySpawnedEvent.callEvent(); - }; - // Paper end -+ // Paper - replaced by above ++ // Paper - moved up final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping - Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + Optional optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { - this.world.getMethodProfiler().exit(); - ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + Chunk chunk = (Chunk) optional1.get(); + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + +- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) { ++ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange + chunk.setInhabitedTime(chunk.getInhabitedTime() + j); +- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot ++ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange + SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2); + } -- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) { -+ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange - // Paper end - chunk.setInhabitedTime(chunk.getInhabitedTime() + j); -- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot -+ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange - this.world.getMethodProfiler().enter("spawner"); - this.world.timings.mobSpawn.startTiming(); // Spigot - EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java @@ -158,8 +157,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { - super((World) worldserver, gameprofile); - playerinteractmanager.player = this; + super(worldserver, worldserver.getSpawn(), gameprofile); + this.spawnDimension = World.OVERWORLD; diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java @@ -196,8 +195,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps; - final int[] entityTrackerTrackRanges; + return MinecraftServer.getServer().applyTrackingRangeScale(vanilla); + } // Paper end - use distance map to optimise tracker + // Paper start - optimise PlayerChunkMap#isOutsideRange + // A note about the naming used here: @@ -242,16 +241,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, ChunkMapDistance.MOB_SPAWN_RANGE); + // Paper end - optimise PlayerChunkMap#isOutsideRange } - + // Paper end @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.mailboxWorldGen = this.p.a(threadedmailbox, false); this.mailboxMain = this.p.a(mailbox, false); - this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false)); + this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false)); - this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); + this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper this.l = supplier; - this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper + this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper this.setViewDistance(i); @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets); diff --git a/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch b/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch deleted file mode 100644 index cdccb6f23..000000000 --- a/Spigot-Server-Patches/Remove-streams-from-MinecraftKey.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Mon, 6 Apr 2020 18:06:24 -0700 -Subject: [PATCH] Remove streams from MinecraftKey - -They produce a lot of garbage. - -diff --git a/src/main/java/net/minecraft/server/MinecraftKey.java b/src/main/java/net/minecraft/server/MinecraftKey.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/MinecraftKey.java -+++ b/src/main/java/net/minecraft/server/MinecraftKey.java -@@ -0,0 +0,0 @@ public class MinecraftKey implements Comparable { - } - - private static boolean c(String s) { -- return s.chars().allMatch((i) -> { -- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; -- }); -+ // Paper start - remove streams -+ for (int index = 0, len = s.length(); index < len; ++index) { -+ int i = (int)s.charAt(index); -+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; // this is copied from the replaced code. -+ if (!condition) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - remove streams - } - - private static boolean d(String s) { -- return s.chars().allMatch((i) -> { -- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; -- }); -+ // Paper start - remove streams -+ for (int index = 0, len = s.length(); index < len; ++index) { -+ int i = (int)s.charAt(index); -+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; // this is copied from the replaced code. -+ if (!condition) { -+ return false; -+ } -+ } -+ return true; -+ // Paper end - remove streams - } - - public static class a implements JsonDeserializer, JsonSerializer { diff --git a/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch b/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch index 40aaee329..00a42bae8 100644 --- a/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch +++ b/Spigot-Server-Patches/Remove-streams-from-Mob-AI-System.patch @@ -66,11 +66,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Iterator; // Paper - remove streams from pathfindergoalselector import java.util.Map; import java.util.Set; - import java.util.stream.Stream; + import java.util.function.Supplier; @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { private final Map c = new EnumMap(PathfinderGoal.Type.class); - private final Set d = Sets.newLinkedHashSet();private Set getTasks() { return d; }// Paper - OBFHELPER - private final GameProfilerFiller e; + private final Set d = Sets.newLinkedHashSet(); private Set getTasks() { return d; }// Paper - OBFHELPER + private final Supplier e; - private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); + private final EnumSet f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. + private final OptimizedSmallEnumSet goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector @@ -104,8 +104,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector + public void doTick() { - this.e.enter("goalCleanup"); -- this.c().filter((pathfindergoalwrapped) -> { + GameProfilerFiller gameprofilerfiller = (GameProfilerFiller) this.e.get(); + + gameprofilerfiller.enter("goalCleanup"); +- this.d().filter((pathfindergoalwrapped) -> { - boolean flag; - - if (pathfindergoalwrapped.g()) { @@ -138,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.c.remove(pathfindergoal_type); @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { }); - this.e.exit(); - this.e.enter("goalUpdate"); + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalUpdate"); - this.d.stream().filter((pathfindergoalwrapped) -> { - return !pathfindergoalwrapped.g(); - }).filter((pathfindergoalwrapped) -> { @@ -203,9 +205,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + wrappedGoal.c(); + } + // Paper end - remove streams from pathfindergoalselector - this.e.exit(); - this.e.enter("goalTick"); -- this.c().forEach(PathfinderGoalWrapped::e); + gameprofilerfiller.exit(); + gameprofilerfiller.enter("goalTick"); +- this.d().forEach(PathfinderGoalWrapped::e); + // Paper start - remove streams from pathfindergoalselector + for (Iterator iterator = this.d.iterator(); iterator.hasNext();) { + PathfinderGoalWrapped wrappedGoal = iterator.next(); @@ -214,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - remove streams from pathfindergoalselector - this.e.exit(); + gameprofilerfiller.exit(); } @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { diff --git a/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch b/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch index b6c4f8b6d..691c930c1 100644 --- a/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch +++ b/Spigot-Server-Patches/Restrict-vanilla-teleport-command-to-valid-locations.patch @@ -10,15 +10,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/CommandTeleport.java +++ b/src/main/java/net/minecraft/server/CommandTeleport.java @@ -0,0 +0,0 @@ public class CommandTeleport { - } - private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) { + private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) throws CommandSyntaxException { + BlockPosition blockposition = new BlockPosition(d0, d1, d2); + // Paper start - Don't allow teleport command to invalid locations + if (d0 <= -30000000 || d2 <= -30000000 || d0 > 30000000 || d2 > 30000000 || d1 > 30000000 || d1 <= -30000000) { // Copy/pasta from BaseBlockPosition#isValidLocation + org.bukkit.Bukkit.getLogger().warning("Refused to teleport " + entity.getName() + " to " + d0 + ", " + d1 + ", " + d2); + return; + } + // Paper end - if (entity instanceof EntityPlayer) { - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(d0, d1, d2)); + if (!World.k(blockposition)) { + throw CommandTeleport.a.create(); diff --git a/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch index b5c1702cd..15817fc88 100644 --- a/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch +++ b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch @@ -36,13 +36,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -0,0 +0,0 @@ public class EntityTrackerEntry { - this.r = entity.onGround; + this.r = entity.isOnGround(); } + public final void tick() { this.a(); } // Paper - OBFHELPER public void a() { List list = this.tracker.getPassengers(); +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0); + this.entityTrackerTrackRanges[ordinal] = trackRange; @@ -166,12 +183,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = MathHelper.floor(entityplayer.locZ()) >> 4; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker - this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); -- playerchunkmap_entitytracker.track(this.world.getPlayers()); -+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players - if (entity instanceof EntityPlayer) { - EntityPlayer entityplayer = (EntityPlayer) entity; + entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); +- playerchunkmap_entitytracker.track(this.world.getPlayers()); ++ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { entity.tracker = null; // Paper - We're no longer tracked @@ -321,6 +338,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/spigotmc/TrackingRange.java +++ b/src/main/java/org/spigotmc/TrackingRange.java @@ -0,0 +0,0 @@ public class TrackingRange + return config.miscTrackingRange; + } else + { +- if (entity instanceof EntityEnderDragon) return ((WorldServer)(entity.getWorld())).getChunkProvider().playerChunkMap.getLoadViewDistance(); // Paper - enderdragon is exempt ++ if (entity instanceof EntityEnderDragon) return defaultRange; // Paper - enderdragon is exempt return config.otherTrackingRange; } } @@ -337,8 +359,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + switch (entity.activationType) { + case RAIDER: + case MONSTER: ++ case FLYING_MONSTER: + return TrackingRangeType.MONSTER; + case WATER: ++ case VILLAGER: + case ANIMAL: + return TrackingRangeType.ANIMAL; + case MISC: diff --git a/Spigot-Server-Patches/Villager-Restocks-API.patch b/Spigot-Server-Patches/Villager-Restocks-API.patch index 5a828d88f..3bc317aec 100644 --- a/Spigot-Server-Patches/Villager-Restocks-API.patch +++ b/Spigot-Server-Patches/Villager-Restocks-API.patch @@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/server/EntityVillager.java @@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - return optional.isPresent() && optional1.isPresent() ? i - ((MinecraftSerializableLong) optional.get()).a() < 24000L && i - ((MinecraftSerializableLong) optional1.get()).a() < 36000L : false; + return optional.isPresent() ? i - (Long) optional.get() < 24000L : false; } + + // Paper start