more patches

This commit is contained in:
Jake Potrebic 2021-06-14 09:58:00 -07:00
parent 1314845ad3
commit b398125ead
46 changed files with 365 additions and 546 deletions

View File

@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -0,0 +0,0 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
Chunk getChunk();
}
/**
- * @return The {@link org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason} that spawned this entity.

View File

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 3 Oct 2020 20:32:25 -0500
Subject: [PATCH] Fix item locations dropped from campfires
Fixes #4259 by not flooring the blockposition among other weirdness
diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
@@ -0,0 +0,0 @@ import net.minecraft.world.Clearable;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.Containers;
import net.minecraft.world.SimpleContainer;
+import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
import net.minecraft.world.item.crafting.RecipeType;
@@ -0,0 +0,0 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable, Ticka
result = blockCookEvent.getResult();
itemstack1 = CraftItemStack.asNMSCopy(result);
// CraftBukkit end
- Containers.dropItemStack(this.level, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), itemstack1);
+ // Paper start
+ ItemEntity droppedItem = new ItemEntity(this.level, blockposition.getX() + 0.5D, blockposition.getY() + 0.5D, blockposition.getZ() + 0.5D, itemstack1.split(this.level.random.nextInt(21) + 10));
+ droppedItem.setDeltaMovement(this.level.random.nextGaussian() * 0.05D, this.level.random.nextGaussian() * 0.05D + 0.2D, this.level.random.nextGaussian() * 0.05D);
+ this.level.addFreshEntity(droppedItem);
+ // Paper end
this.items.set(i, ItemStack.EMPTY);
this.markUpdated();
}

View File

@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: giacomo <32515303+giacomozama@users.noreply.github.com>
Date: Sat, 10 Oct 2020 12:15:33 +0200
Subject: [PATCH] Fixed TileEntityBell memory leak
TileEntityBell has a list of entities (entitiesAtRing) that was not being cleared at the right time, causing leaks whenever a bell would be rung near a crowd of entities.
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity implements TickableBlockEntity
public int ticks;
public boolean shaking;
public Direction clickDirection;
- private List<LivingEntity> nearbyEntities;
- private boolean resonating;
+ private List<LivingEntity> nearbyEntities; private List<LivingEntity> getEntitiesAtRing() { return this.nearbyEntities; } // Paper - OBFHELPER
+ private boolean resonating; private boolean getShouldReveal() { return this.resonating; } // Paper - OBFHELPER
private int resonationTicks;
public BellBlockEntity() {
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity implements TickableBlockEntity
if (this.ticks >= 50) {
this.shaking = false;
+ // Paper start
+ if (!this.getShouldReveal()) {
+ this.getEntitiesAtRing().clear();
+ }
+ // Paper end
this.ticks = 0;
}
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity implements TickableBlockEntity
} else {
this.makeRaidersGlow(this.level);
this.showBellParticles(this.level);
+ this.getEntitiesAtRing().clear(); // Paper
this.resonating = false;
}
}
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity implements TickableBlockEntity
LivingEntity entityliving = (LivingEntity) iterator.next();
if (entityliving.isAlive() && !entityliving.removed && blockposition.closerThan((Position) entityliving.position(), 32.0D)) {
- entityliving.getBrain().setMemory(MemoryModuleType.HEARD_BELL_TIME, (Object) this.level.getGameTime());
+ entityliving.getBrain().setMemory(MemoryModuleType.HEARD_BELL_TIME, this.level.getGameTime()); // Paper - decompile fix
}
}
}
+ this.getEntitiesAtRing().removeIf(e -> !e.isAlive()); // Paper
}
private boolean areRaidersNearby() {

View File

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: chickeneer <emcchickeneer@gmail.com>
Date: Wed, 18 Mar 2020 00:07:46 -0500
Subject: [PATCH] MC-147729: Drop items that are extra from a crafting recipe
diff --git a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
+++ b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
@@ -0,0 +0,0 @@ public class ServerPlaceRecipe<C extends Container> implements PlaceRecipe<Integ
if (j == -1) {
j = this.inventory.getFreeSlot();
}
-
+ // Paper start
+ if (j == -1) {
+ this.inventory.player.drop(itemstack.copy(), false);
+ break;
+ }
+ // Paper end
ItemStack itemstack1 = itemstack.copy();
itemstack1.setCount(1);

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Sat, 25 Apr 2020 17:10:55 -0700
Subject: [PATCH] Reduce blockpos allocation from pathfinding
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
@@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator {
return BlockPathTypes.DANGER_FIRE;
}
- if (iblockaccess.getFluidState(blockposition_mutableblockposition).is((Tag) FluidTags.WATER)) {
+ if (iblockdata.getFluidState().is((Tag) FluidTags.WATER)) { // Paper - remove another getType call
return BlockPathTypes.WATER_BORDER;
}
} // Paper
@@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator {
} else if (iblockdata.is(Blocks.COCOA)) {
return BlockPathTypes.COCOA;
} else {
- FluidState fluid = iblockaccess.getFluidState(blockposition);
+ FluidState fluid = iblockdata.getFluidState(); // Paper - remove another get type call
return fluid.is((Tag) FluidTags.WATER) ? BlockPathTypes.WATER : (fluid.is((Tag) FluidTags.LAVA) ? BlockPathTypes.LAVA : (isBurningBlock(iblockdata) ? BlockPathTypes.DAMAGE_FIRE : (DoorBlock.isWoodenDoor(iblockdata) && !(Boolean) iblockdata.getValue(DoorBlock.OPEN) ? BlockPathTypes.DOOR_WOOD_CLOSED : (block instanceof DoorBlock && material == Material.ORE && !(Boolean) iblockdata.getValue(DoorBlock.OPEN) ? BlockPathTypes.DOOR_IRON_CLOSED : (block instanceof DoorBlock && (Boolean) iblockdata.getValue(DoorBlock.OPEN) ? BlockPathTypes.DOOR_OPEN : (block instanceof BaseRailBlock ? BlockPathTypes.RAIL : (block instanceof LeavesBlock ? BlockPathTypes.LEAVES : (!block.is((Tag) BlockTags.FENCES) && !block.is((Tag) BlockTags.WALLS) && (!(block instanceof FenceGateBlock) || (Boolean) iblockdata.getValue(FenceGateBlock.OPEN)) ? (!iblockdata.isPathfindable(iblockaccess, blockposition, PathComputationType.LAND) ? BlockPathTypes.BLOCKED : BlockPathTypes.OPEN) : BlockPathTypes.FENCE))))))));
}

View File

@ -1,115 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <mail@moep.tv>
Date: Mon, 13 Jan 2020 15:40:32 +0100
Subject: [PATCH] Seed based feature search
This tries to work around the issue where the server will load
surrounding chunks up to a radius of 100 chunks in order to search for
features e.g. when running the /locate command or for treasure maps
(issue #2312).
This is done by backporting Mojang's change in 1.17 which makes it so
that the biome (generated by the seed) is checked first if the feature
can be generated before actually to load the chunk.
Additionally to that the center location of the target chunk is simply
returned if the chunk is not loaded to avoid the sync chunk load.
As this can lead to less precise locations a toggle is provided to
enable the sync loading of the target chunk again.
The main downside of this is that it breaks once the seed or generator
changes but this should usually not happen. A config option to disable
this completely is added though in case that should ever be necessary.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
}
}
+ public boolean seedBasedFeatureSearch = true;
+ public boolean seedBasedFeatureSearchLoadsChunks = false;
+ private void seedBasedFeatureSearch() {
+ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch);
+ seedBasedFeatureSearchLoadsChunks = getBoolean("seed-based-feature-search-loads-chunks", seedBasedFeatureSearchLoadsChunks);
+ log("Feature search is based on seed: " + seedBasedFeatureSearch + ", loads chunks:" + seedBasedFeatureSearchLoadsChunks);
+ }
+
public int maxCollisionsPerEntity;
private void maxEntityCollision() {
maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) );
diff --git a/src/main/java/net/minecraft/world/level/ChunkPos.java b/src/main/java/net/minecraft/world/level/ChunkPos.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/ChunkPos.java
+++ b/src/main/java/net/minecraft/world/level/ChunkPos.java
@@ -0,0 +0,0 @@ public class ChunkPos {
}
}
+ public int getBlockX() { return getMinBlockX(); } // Paper - OBFHELPER
public int getMinBlockX() {
return this.x << 4;
}
+ public int getBlockZ() { return getMinBlockZ(); } // Paper - OBFHELPER
public int getMinBlockZ() {
return this.z << 4;
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return this.profiler;
}
- @Override
- public BiomeManager getBiomeManager() {
+ public BiomeManager getBiomeManager() { return getBiomeManager(); } // Paper - OBFHELPER
+ @Override public BiomeManager getBiomeManager() {
return this.biomeManager;
}
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeManager.java
@@ -0,0 +0,0 @@ public class BiomeManager {
return new BiomeManager(source, this.biomeZoomSeed, this.zoomer);
}
+ public Biome getBiome(BlockPos blockposition) { return getBiome(blockposition); } // Paper - OBFHELPER
public Biome getBiome(BlockPos pos) {
return this.zoomer.getBiome(this.biomeZoomSeed, pos.getX(), pos.getY(), pos.getZ(), this.noiseBiomeSource);
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
@@ -0,0 +0,0 @@ public abstract class StructureFeature<C extends FeatureConfiguration> {
int j2 = i1 + k * l1;
ChunkPos chunkcoordintpair = this.getPotentialFeatureChunk(config, worldSeed, seededrandom, i2, j2);
if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper
- ChunkAccess ichunkaccess = world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS);
+ // Paper start - seed based feature search
+ ChunkAccess ichunkaccess = null;
+ if (structureAccessor.getWorld().paperConfig.seedBasedFeatureSearch) {
+ Biome biomeBase = structureAccessor.getWorld().getBiomeManager().getBiome(new BlockPos(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9));
+ if (!biomeBase.getGenerationSettings().isValidStart(this)) {
+ continue;
+ }
+ if (!structureAccessor.getWorld().paperConfig.seedBasedFeatureSearchLoadsChunks) {
+ ichunkaccess = structureAccessor.getWorld().getChunkIfLoaded(chunkcoordintpair.x, chunkcoordintpair.z);
+ if (ichunkaccess == null) {
+ return chunkcoordintpair.asPosition().add(8, searchStartPos.getY(), 8);
+ }
+ }
+ }
+ if (ichunkaccess == null) {
+ ichunkaccess = world.getChunk(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS);
+ }
+ // Paper end
StructureStart<?> structurestart = structureAccessor.getStartForFeature(SectionPos.of(ichunkaccess.getPos(), 0), this, ichunkaccess);
if (structurestart != null && structurestart.e()) {

View File

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.handlingFault = true;
if (this.channel.isOpen()) {
+ ServerPlayer player = this.getPlayer(); // Paper
+ net.minecraft.server.level.ServerPlayer player = this.getPlayer(); // Paper
if (throwable instanceof TimeoutException) {
Connection.LOGGER.debug("Timeout", throwable);
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.TIMED_OUT; // Paper
@ -23,24 +23,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper
if (flag) {
Connection.LOGGER.debug("Failed to sent packet", throwable);
this.send(new ClientboundDisconnectPacket(chatmessage), (future) -> {
ConnectionProtocol enumprotocol = this.getCurrentProtocol();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
boolean needsChunkCenterUpdate; // Paper - no-tick view distance
+ public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ServerPlayerGameMode interactionManager) {
super(world, world.getSpawn(), world.getSharedSpawnAngle(), profile);
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) {
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
final Component ichatbasecomponent = PaperAdventure.asVanilla(event.reason()); // Paper - Adventure
// CraftBukkit end
@ -56,8 +56,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
}
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())), entityplayer.quitReason); // Paper - quit reason
if (entityplayer.didPlayerJoinEvent) cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(this.cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(this.cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())), entityplayer.quitReason); // Paper - quit reason
if (entityplayer.didPlayerJoinEvent) this.cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());

View File

@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
return getHandle().useItem.asBukkitMirror();
return getHandle().getUseItem().asBukkitMirror();
}
+ // Paper start
@ -21,4 +21,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
@Override
public int getItemUseRemainingTime() {
return getHandle().getItemUseRemainingTime();
return getHandle().getUseItemRemainingTicks();

View File

@ -8,26 +8,14 @@ diff --git a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java b/s
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java
+++ b/src/main/java/net/minecraft/world/item/ServerItemCooldowns.java
@@ -0,0 +0,0 @@
package net.minecraft.world.item;
+import io.papermc.paper.event.player.PlayerItemCooldownEvent; // Paper
import net.minecraft.network.protocol.game.ClientboundCooldownPacket;
import net.minecraft.server.level.ServerPlayer;
public class ServerItemCooldowns extends ItemCooldowns {
- private final ServerPlayer player;
+ private final ServerPlayer player; public ServerPlayer getEntityPlayer() { return player; } // Paper - OBFHELPER
public ServerItemCooldowns(ServerPlayer player) {
@@ -0,0 +0,0 @@ public class ServerItemCooldowns extends ItemCooldowns {
this.player = player;
}
+ // Paper start
+ @Override
+ public void addCooldown(Item item, int duration) {
+ PlayerItemCooldownEvent event = new PlayerItemCooldownEvent(getEntityPlayer().getBukkitEntity(), org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), duration);
+ io.papermc.paper.event.player.PlayerItemCooldownEvent event = new io.papermc.paper.event.player.PlayerItemCooldownEvent(this.player.getBukkitEntity(), org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), duration);
+ if (event.callEvent()) {
+ super.addCooldown(item, event.getCooldown());
+ }

View File

@ -15,10 +15,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
log("The Ender Dragon will be removed if she already exists without a portal.");
}
}
+
+ public int wanderingTraderSpawnMinuteTicks = 1200;
+ public int wanderingTraderSpawnDayTicks = 24000;
+ public int wanderingTraderSpawnChanceFailureIncrement = 25;
@ -31,22 +30,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ wanderingTraderSpawnChanceMin = getInt("wandering-trader.spawn-chance-min", wanderingTraderSpawnChanceMin);
+ wanderingTraderSpawnChanceMax = getInt("wandering-trader.spawn-chance-max", wanderingTraderSpawnChanceMax);
+ }
}
+
public short keepLoadedRange;
private void keepLoadedRange() {
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
@@ -0,0 +0,0 @@ public class WanderingTraderSpawner implements CustomSpawner {
private final Random random = new Random();
private final ServerLevelData serverLevelData;
- private int tickDelay;
- private int spawnDelay;
- private int spawnChance;
+ private int tickDelay; public final int getMinuteTimer() { return this.tickDelay; } public final void setMinuteTimer(int x) { this.tickDelay = x; } // Paper - OBFHELPER
+ private int spawnDelay; public final int getDayTimer() { return this.spawnDelay; } public final void setDayTimer(int x) { this.spawnDelay = x; } // Paper - OBFHELPER
+ private int spawnChance; public final int getSpawnChance() { return this.spawnChance; } public final void setSpawnChance(int x) { this.spawnChance = x; } // Paper - OBFHELPER
public WanderingTraderSpawner(ServerLevelData properties) {
this.serverLevelData = properties;
- this.tickDelay = 1200;
@ -59,14 +52,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- properties.setWanderingTraderSpawnChance(this.spawnChance);
- }
+ // Paper start
+ this.setMinuteTimer(Integer.MIN_VALUE);
+ //this.d = iworlddataserver.v(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
+ //this.e = iworlddataserver.w(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
+ //if (this.d == 0 && this.e == 0) {
+ // this.d = 24000;
+ // iworlddataserver.g(this.d);
+ // this.e = 25;
+ // iworlddataserver.h(this.e);
+ this.tickDelay = Integer.MIN_VALUE;
+ //this.spawnDelay = properties.getWanderingTraderSpawnDelay(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
+ //this.spawnChance = properties.getWanderingTraderSpawnChance(); // Paper - This value is read from the world file only for the first spawn, after which vanilla uses a hardcoded value
+ //if (this.spawnDelay == 0 && this.spawnChance == 0) {
+ // this.spawnDelay = 24000;
+ // properties.setWanderingTraderSpawnDelay(this.spawnDelay);
+ // this.spawnChance = 25;
+ // properties.setWanderingTraderSpawnChance(this.spawnChance);
+ //}
+ // Paper end
@ -75,45 +68,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) {
+ // Paper start
+ if (this.getMinuteTimer() == Integer.MIN_VALUE) {
+ this.setMinuteTimer(world.paperConfig.wanderingTraderSpawnMinuteTicks);
+ this.setDayTimer(world.paperConfig.wanderingTraderSpawnDayTicks);
+ this.setSpawnChance(world.paperConfig.wanderingTraderSpawnChanceMin);
+ if (this.tickDelay == Integer.MIN_VALUE) {
+ this.tickDelay = world.paperConfig.wanderingTraderSpawnMinuteTicks;
+ this.spawnDelay = world.paperConfig.wanderingTraderSpawnDayTicks;
+ this.spawnChance = world.paperConfig.wanderingTraderSpawnChanceMin;
+ }
if (!world.getGameRules().getBoolean(GameRules.RULE_DO_TRADER_SPAWNING)) {
return 0;
- } else if (--this.tickDelay > 0) {
+ } else if (this.getMinuteTimer() - 1 > 0) {
+ this.setMinuteTimer(this.getMinuteTimer() - 1);
+ } else if (this.tickDelay - 1 > 0) {
+ this.tickDelay = this.tickDelay - 1;
return 0;
} else {
- this.tickDelay = 1200;
- this.spawnDelay -= 1200;
- this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay);
- if (this.spawnDelay > 0) {
+ this.setMinuteTimer(world.paperConfig.wanderingTraderSpawnMinuteTicks);
+ this.setDayTimer(getDayTimer() - world.paperConfig.wanderingTraderSpawnMinuteTicks);
+ //this.b.g(this.d); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
+ if (this.getDayTimer() > 0) {
+ this.tickDelay = world.paperConfig.wanderingTraderSpawnMinuteTicks;
+ this.spawnDelay = this.spawnDelay - world.paperConfig.wanderingTraderSpawnMinuteTicks;
+ //this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
if (this.spawnDelay > 0) {
return 0;
} else {
- this.spawnDelay = 24000;
+ this.setDayTimer(world.paperConfig.wanderingTraderSpawnDayTicks);
+ this.spawnDelay = world.paperConfig.wanderingTraderSpawnDayTicks;
if (!world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
return 0;
} else {
- int i = this.spawnChance;
+ int i = this.getSpawnChance();
int i = this.spawnChance;
- this.spawnChance = Mth.clamp(this.spawnChance + 25, 25, 75);
- this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance);
+ this.setSpawnChance(Mth.clamp(i + world.paperConfig.wanderingTraderSpawnChanceFailureIncrement, world.paperConfig.wanderingTraderSpawnChanceMin, world.paperConfig.wanderingTraderSpawnChanceMax));
+ //this.b.h(this.e); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
+ this.spawnChance = Mth.clamp(i + world.paperConfig.wanderingTraderSpawnChanceFailureIncrement, world.paperConfig.wanderingTraderSpawnChanceMin, world.paperConfig.wanderingTraderSpawnChanceMax);
+ //this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
if (this.random.nextInt(100) > i) {
return 0;
} else if (this.spawn(world)) {
- this.spawnChance = 25;
+ this.setSpawnChance(world.paperConfig.wanderingTraderSpawnChanceMin);
+ this.spawnChance = world.paperConfig.wanderingTraderSpawnChanceMin;
+ // Paper end
return 1;
} else {

View File

@ -45,40 +45,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, false, bukkit);
+ }
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, boolean ignoreDiscounts, CraftMerchantRecipe bukkit) {
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, ignoreDiscounts);
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, 0, ignoreDiscounts);
+ // Paper end
this.bukkitHandle = bukkit;
}
// CraftBukkit end
@@ -0,0 +0,0 @@ public class MerchantOffer {
this.specialPriceDiff = nbttagcompound.getInt("specialPrice");
this.demand = nbttagcompound.getInt("demand");
+ this.ignoreDiscounts = nbttagcompound.getBoolean("Paper.IgnoreDiscounts"); // Paper
this.specialPriceDiff = nbt.getInt("specialPrice");
this.demand = nbt.getInt("demand");
+ this.ignoreDiscounts = nbt.getBoolean("Paper.IgnoreDiscounts"); // Paper
}
public MerchantOffer(ItemStack buyItem, ItemStack sellItem, int maxUses, int rewardedExp, float priceMultiplier) {
public MerchantOffer(ItemStack buyItem, ItemStack sellItem, int maxUses, int merchantExperience, float priceMultiplier) {
@@ -0,0 +0,0 @@ public class MerchantOffer {
}
public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int rewardedExp, float priceMultiplier) {
- this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, rewardedExp, priceMultiplier, 0);
public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier) {
- this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, 0);
+ // Paper start - add ignoreDiscounts param
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, rewardedExp, priceMultiplier, false);
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, false);
+ }
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, int k, float f, boolean ignoreDiscounts) {
+ this(itemstack, itemstack1, itemstack2, i, j, k, f, 0, ignoreDiscounts);
+ public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, boolean ignoreDiscounts) {
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, 0, ignoreDiscounts);
}
public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, int k, float f, int l) {
+ this(itemstack, itemstack1, itemstack2, i, j, k, f, l, false);
public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, int demandBonus) {
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, demandBonus, false);
+ }
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, int k, float f, int l, boolean ignoreDiscounts) {
+ public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, int demandBonus, boolean ignoreDiscounts) {
+ this.ignoreDiscounts = ignoreDiscounts;
+ // Paper end
this.rewardExp = true;
this.xp = 1;
this.baseCostA = itemstack;
this.baseCostA = firstBuyItem;
@@ -0,0 +0,0 @@ public class MerchantOffer {
nbttagcompound.putFloat("priceMultiplier", this.priceMultiplier);
nbttagcompound.putInt("specialPrice", this.specialPriceDiff);

View File

@ -8,8 +8,8 @@ diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEnt
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Tick
return (hasSecondaryEffect()) ? CraftPotionUtil.toBukkit(new MobEffectInstance(this.secondaryPower, getLevelCb(), getAmplification(), true, true)) : null;
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider {
return (BeaconBlockEntity.hasSecondaryEffect(this.levels, this.primaryPower, this.secondaryPower)) ? CraftPotionUtil.toBukkit(new MobEffectInstance(this.secondaryPower, BeaconBlockEntity.getLevel(this.levels), BeaconBlockEntity.getAmplification(this.levels, this.primaryPower, this.secondaryPower), true, true)) : null;
}
// CraftBukkit end
+ // Paper start - add field/methods for custom range
@ -33,37 +33,39 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end
public BeaconBlockEntity() {
super(BlockEntityType.BEACON);
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Tick
public BeaconBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.BEACON, pos, state);
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider {
}
public List getHumansInRange() {
public static List getHumansInRange(Level world, BlockPos blockposition, int i) {
+ // Paper start
+ return BeaconBlockEntity.getHumansInRange(world, blockposition, i, null);
+ }
+ public static List getHumansInRange(Level world, BlockPos blockposition, int i, @Nullable BeaconBlockEntity blockEntity) {
+ // Paper end
{
- double d0 = (double) (this.levels * 10 + 10);
+ // Paper - custom beacon ranges
+ double d0 = this.getEffectRange();
- double d0 = (double) (i * 10 + 10);
+ double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - custom beacon ranges
AABB axisalignedbb = (new AABB(this.worldPosition)).inflate(d0).expandTowards(0.0D, (double) this.level.getMaxBuildHeight(), 0.0D);
List<net.minecraft.world.entity.player.Player> list = this.level.getEntitiesOfClass(net.minecraft.world.entity.player.Player.class, axisalignedbb);
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Tick
this.secondaryPower = MobEffect.byId(tag.getInt("Secondary"));
this.levels = tag.getInt("Levels"); // SPIGOT-5053, use where available
// CraftBukkit end
+ // Paper
+ this.effectRange = tag.contains(PAPER_RANGE_TAG, 6) ? tag.getDouble(PAPER_RANGE_TAG) : -1;
+
if (tag.contains("CustomName", 8)) {
this.name = Component.Serializer.fromJson(tag.getString("CustomName"));
AABB axisalignedbb = (new AABB(blockposition)).inflate(d0).expandTowards(0.0D, (double) world.getHeight(), 0.0D);
List<Player> list = world.getEntitiesOfClass(Player.class, axisalignedbb);
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider {
}
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Tick
if (this.name != null) {
tag.putString("CustomName", Component.Serializer.toJson(this.name));
}
+ // Paper
+ tag.putDouble(PAPER_RANGE_TAG, this.effectRange);
this.lockKey.addToTag(tag);
return tag;
this.lockKey = LockCode.fromTag(nbt);
+ this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper
}
@Override
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider {
}
this.lockKey.addToTag(nbt);
+ nbt.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper
return nbt;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
@ -73,6 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.getSnapshot().lockKey = (key == null) ? LockCode.NO_LOCK : new LockCode(key);
}
+
+ // Paper start
+ @Override
+ public double getEffectRange() {
+ return this.getSnapshot().getEffectRange();
@ -87,4 +90,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public void resetEffectRange() {
+ this.getSnapshot().resetEffectRange();
+ }
+ // Paper end
}

View File

@ -9,20 +9,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
wanderingTraderSpawnChanceMin = getInt("wandering-trader.spawn-chance-min", wanderingTraderSpawnChanceMin);
wanderingTraderSpawnChanceMax = getInt("wandering-trader.spawn-chance-max", wanderingTraderSpawnChanceMax);
}
+
+ public boolean fixClimbingBypassingCrammingRule = false;
+ private void fixClimbingBypassingCrammingRule() {
+ fixClimbingBypassingCrammingRule = getBoolean("fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule);
+ }
}
+
public short keepLoadedRange;
private void keepLoadedRange() {
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
public boolean isPushable() {
@ -53,8 +55,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Team.CollisionRule scoreboardteambase_enumteampush = scoreboardteambase == null ? Team.CollisionRule.ALWAYS : scoreboardteambase.getCollisionRule();
return (Predicate) (scoreboardteambase_enumteampush == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : EntitySelector.NO_SPECTATORS.and((entity1) -> {
- if (!entity1.canCollideWithCb(entity) || !entity.canCollideWithCb(entity1)) { // CraftBukkit - collidable API
+ if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWithCb(entity) || !entity.canCollideWithCb(entity1)) { // CraftBukkit - collidable API // Paper - isCollidable
- if (!entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API
+ if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API // Paper - isCollidable
return false;
} else if (entity.level.isClientSide && (!(entity1 instanceof Player) || !((Player) entity1).isLocalPlayer())) {
return false;
@ -62,25 +64,17 @@ diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
-import co.aikar.timings.MinecraftTimings; // Paper
public abstract class LivingEntity extends Entity {
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
return;
}
// Paper - end don't run getEntities if we're not going to use its result
// Paper end - don't run getEntities if we're not going to use its result
- List<Entity> list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this));
+ List<Entity> list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushable(this, level.paperConfig.fixClimbingBypassingCrammingRule)); // Paper - fix climbing bypassing cramming rule
if (!list.isEmpty()) {
// Paper - move up
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
return !this.removed && this.collides; // CraftBukkit
return !this.isRemoved() && this.collides; // CraftBukkit
}
+ // Paper start

View File

@ -16,19 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ location = new Location(worldserver1.getWorld(), (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.1F), (double) ((float) blockposition.getZ() + 0.5F), worldserver1.levelData.getSpawnAngle(), 0.0F); // Paper - use world spawn angle
}
Player respawnPlayer = cserver.getPlayer(entityplayer1);
diff --git a/src/main/java/net/minecraft/world/level/storage/LevelData.java b/src/main/java/net/minecraft/world/level/storage/LevelData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/storage/LevelData.java
+++ b/src/main/java/net/minecraft/world/level/storage/LevelData.java
@@ -0,0 +0,0 @@ public interface LevelData {
int getZSpawn();
+ default float getSpawnAngle() { return getSpawnAngle(); } // Paper - OBFHELPER
float getSpawnAngle();
long getGameTime();
Player respawnPlayer = this.cserver.getPlayer(entityplayer1);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@ -36,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
@Override
public Location getSpawnLocation() {
BlockPos spawn = world.getSpawn();
BlockPos spawn = this.world.getSharedSpawnPos();
- return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
+ return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ(), world.levelData.getSpawnAngle(), 0.0F); // Paper - expose world spawn angle
}

View File

@ -8,12 +8,12 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
public Stream<Entity> getSelfAndPassengers() {
- return Stream.concat(Stream.of(this), this.passengers.stream().flatMap(Entity::getSelfAndPassengers));
+ return Stream.concat(Stream.of(this), com.google.common.collect.ImmutableList.copyOf(this.passengers).stream().flatMap(Entity::getSelfAndPassengers)); // Paper
private Stream<Entity> getIndirectPassengersStream() {
- return this.passengers.stream().flatMap(Entity::getSelfAndPassengers);
+ return ImmutableList.copyOf(this.passengers).stream().flatMap(Entity::getSelfAndPassengers); // Paper
}
public boolean hasOnePlayerPassenger() {
@Override

View File

@ -14,6 +14,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.toNMS(particle, data), true, (float) x, (float) y, (float) z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count);
+ ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(CraftParticle.toNMS(particle, data), true, x, y, z, (float) offsetX, (float) offsetY, (float) offsetZ, (float) extra, count); // Paper - Fix x/y/z coordinate precision loss
getHandle().connection.send(packetplayoutworldparticles);
this.getHandle().connection.send(packetplayoutworldparticles);
}

View File

@ -22,14 +22,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ public final void reload(ServerAdvancementManager advancementDataWorld) { this.reload(advancementDataWorld); } // Paper - OBFHELPER
public void reload(ServerAdvancementManager advancementLoader) {
this.stopListening();
this.advancements.clear();
@@ -0,0 +0,0 @@ public class PlayerAdvancements {
}
+ public final void sendUpdateIfNeeded(ServerPlayer entityPlayer) { this.flushDirty(entityPlayer); } // Paper - OBFHELPER
public void flushDirty(ServerPlayer player) {
if (this.isFirstPacket || !this.visibilityChanged.isEmpty() || !this.progressChanged.isEmpty()) {

View File

@ -9,24 +9,24 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (entity != this.player && entity.getControllingPassenger() == this.player && entity == this.lastVehicle) {
ServerLevel worldserver = this.player.getLevel();
- double d0 = entity.getX();
- double d1 = entity.getY();
- double d2 = entity.getZ();
- double d3 = packet.getX();
- double d4 = packet.getY();
- double d5 = packet.getZ();
+ double d0 = entity.getX();double fromX = d0; // Paper - OBFHELPER
+ double d1 = entity.getY();double fromY = d1; // Paper - OBFHELPER
+ double d2 = entity.getZ();double fromZ = d2; // Paper - OBFHELPER
+ double d3 = packet.getX();double toX = d3; // Paper - OBFHELPER
+ double d4 = packet.getY();double toY = d4; // Paper - OBFHELPER
+ double d5 = packet.getZ();double toZ = d5; // Paper - OBFHELPER
float f = packet.getYRot();
float f1 = packet.getXRot();
- double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX());
- double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY());
- double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ());
+ double d0 = entity.getX();final double fromX = d0; // Paper - OBFHELPER
+ double d1 = entity.getY();final double fromY = d1; // Paper - OBFHELPER
+ double d2 = entity.getZ();final double fromZ = d2; // Paper - OBFHELPER
+ double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX());final double toX = d3; // Paper - OBFHELPER
+ double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY());final double toY = d4; // Paper - OBFHELPER
+ double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ());final double toZ = d5; // Paper - OBFHELPER
float f = Mth.wrapDegrees(packet.getYRot());
float f1 = Mth.wrapDegrees(packet.getXRot());
double d6 = d3 - this.vehicleFirstGoodX;
double d7 = d4 - this.vehicleFirstGoodY;
double d8 = d5 - this.vehicleFirstGoodZ;
@ -41,18 +41,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start - handle custom speeds and skipped ticks
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
double d2 = this.player.getZ();
double d3 = this.player.getY();
double d4 = packet.getX(this.player.getX());double toX = d4; // Paper - OBFHELPER
- double d5 = packet.getY(this.player.getY());
+ double d5 = packet.getY(this.player.getY());double toY = d5; // Paper - OBFHELPER
double d6 = packet.getZ(this.player.getZ());double toZ = d6; // Paper - OBFHELPER
float f = packet.getYRot(this.player.yRot);
float f1 = packet.getXRot(this.player.xRot);
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
double d8 = d5 - this.firstGoodY;
double d9 = d6 - this.firstGoodZ;
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
float prevPitch = this.player.getXRot();
// CraftBukkit end
double d3 = this.player.getX(); final double toX = d3; // Paper - OBFHELPER
- double d4 = this.player.getY();
+ double d4 = this.player.getY(); final double toY = d4; // Paper - OBFHELPER
double d5 = this.player.getZ(); final double toZ = d5; // Paper - OBFHELPER
double d6 = this.player.getY();
double d7 = d0 - this.firstGoodX;
double d8 = d1 - this.firstGoodY;
double d9 = d2 - this.firstGoodZ;
double d10 = this.player.getDeltaMovement().lengthSqr();
- double d11 = d7 * d7 + d8 * d8 + d9 * d9;
+ // Paper start - fix large move vectors killing the server

View File

@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 3 Oct 2020 20:32:25 -0500
Subject: [PATCH] Fix item locations dropped from campfires
Fixes #4259 by not flooring the blockposition among other weirdness
diff --git a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/CampfireBlockEntity.java
@@ -0,0 +0,0 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable {
result = blockCookEvent.getResult();
itemstack1 = CraftItemStack.asNMSCopy(result);
// CraftBukkit end
- Containers.dropItemStack(world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), itemstack1);
+ // Paper start
+ net.minecraft.world.entity.item.ItemEntity droppedItem = new net.minecraft.world.entity.item.ItemEntity(world, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, itemstack1.split(world.random.nextInt(21) + 10));
+ droppedItem.setDeltaMovement(world.random.nextGaussian() * 0.05D, world.random.nextGaussian() * 0.05D + 0.2D, world.random.nextGaussian() * 0.05D);
+ world.addFreshEntity(droppedItem);
+ // Paper end
campfire.items.set(i, ItemStack.EMPTY);
world.sendBlockUpdated(pos, state, state, 3);
}

View File

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: giacomo <32515303+giacomozama@users.noreply.github.com>
Date: Sat, 10 Oct 2020 12:15:33 +0200
Subject: [PATCH] Fixed TileEntityBell memory leak
TileEntityBell has a list of entities (entitiesAtRing) that was not being cleared at the right time, causing leaks whenever a bell would be rung near a crowd of entities.
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BellBlockEntity.java
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity {
if (blockEntity.ticks >= 50) {
blockEntity.shaking = false;
+ // Paper start
+ if (!blockEntity.resonating) {
+ blockEntity.nearbyEntities.clear();
+ }
+ // Paper end
blockEntity.ticks = 0;
}
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity {
++blockEntity.resonationTicks;
} else {
bellEffect.run(world, pos, blockEntity.nearbyEntities);
+ blockEntity.nearbyEntities.clear(); // Paper
blockEntity.resonating = false;
}
}
@@ -0,0 +0,0 @@ public class BellBlockEntity extends BlockEntity {
}
}
+ this.nearbyEntities.removeIf(e -> !e.isAlive()); // Paper
}
private static boolean areRaidersNearby(BlockPos pos, List<LivingEntity> hearingEntities) {

View File

@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour {
return this.getBlock().is(block);
return this.getBlock() == block;
}
- public FluidState getFluidState() {
@ -72,20 +72,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return this.isTicking; // Paper - moved into init
}
public SoundType getSoundType() {
public long getSeed(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/material/FluidState.java b/src/main/java/net/minecraft/world/level/material/FluidState.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/material/FluidState.java
+++ b/src/main/java/net/minecraft/world/level/material/FluidState.java
@@ -0,0 +0,0 @@ public final class FluidState extends StateHolder<Fluid, FluidState> {
public static final Codec<FluidState> CODEC = codec((Codec) Registry.FLUID, Fluid::defaultFluidState).stable();
public static final int AMOUNT_MAX = 9;
public static final int AMOUNT_FULL = 8;
+ // Paper start
+ protected final boolean isEmpty;
+ // Paper end
public FluidState(Fluid fluid, ImmutableMap<Property<?>, Comparable<?>> propertiesMap, MapCodec<FluidState> mapcodec) {
super(fluid, propertiesMap, mapcodec);
public FluidState(Fluid fluid, ImmutableMap<Property<?>, Comparable<?>> propertiesMap, MapCodec<FluidState> codec) {
super(fluid, propertiesMap, codec);
+ this.isEmpty = fluid.isEmpty(); // Paper - moved from isEmpty()
}

View File

@ -9,60 +9,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/entity/LightningBolt.java
+++ b/src/main/java/net/minecraft/world/entity/LightningBolt.java
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
private int life;
private static final int START_LIFE = 2;
private static final double DAMAGE_RADIUS = 3.0D;
private static final double DETECTION_RADIUS = 15.0D;
- private int life;
+ public int life; // Paper - private -> public
public long seed;
- private int flashes;
+ private int flashes; public int getFlashCount() { return flashes; } public void setFlashCount(int flashes) { this.flashes = flashes; } // Paper - OBFHELPER
+ public int flashes; // Paper - private -> public
public boolean visualOnly;
@Nullable
private ServerPlayer cause;
@@ -0,0 +0,0 @@ public class LightningBolt extends Entity {
this.visualOnly = cosmetic;
}
+ // Paper start
+ public int getLifeTicks() {
+ return life;
+ }
+
+ public void setLifeTicks(int lifeTicks) {
+ this.life = lifeTicks;
+ }
+ // Paper end
+
@Override
public SoundSource getSoundSource() {
return SoundSource.WEATHER;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
@@ -0,0 +0,0 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike
return spigot;
return this.spigot;
}
// Spigot end
+
+ // Paper start
+ @Override
+ public int getFlashCount() {
+ return getHandle().getFlashCount();
+ return getHandle().flashes;
+ }
+
+ @Override
+ public void setFlashCount(int flashes) {
+ com.google.common.base.Preconditions.checkArgument(flashes >= 0, "Flashes has to be a positive number!");
+ getHandle().setFlashCount(flashes);
+ getHandle().flashes = flashes;
+ }
+
+ @Override
+ public int getLifeTicks() {
+ return getHandle().getLifeTicks();
+ return getHandle().life;
+ }
+
+ @Override
+ public void setLifeTicks(int lifeTicks) {
+ getHandle().setLifeTicks(lifeTicks);
+ getHandle().life = lifeTicks;
+ }
+ // Paper end
}

View File

@ -9,11 +9,10 @@ diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockState.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/state/BlockState.java
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockState.java
@@ -0,0 +0,0 @@ public class BlockState extends BlockBehaviour.BlockStateBase {
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.properties.Property;
public class BlockState extends BlockBehaviour.BlockStateBase {
public static final Codec<BlockState> CODEC = codec(Registry.BLOCK, Block::defaultBlockState).stable();
public static final Codec<BlockState> CODEC = codec((Codec) Registry.BLOCK, Block::defaultBlockState).stable();
+
+ // Paper start - optimise getType calls
+ org.bukkit.Material cachedMaterial;
+
@ -25,9 +24,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return this.cachedMaterial;
+ }
+ // Paper end - optimise getType calls
+
public BlockState(Block block, ImmutableMap<Property<?>, Comparable<?>> propertyMap, MapCodec<BlockState> mapcodec) {
super(block, propertyMap, mapcodec);
public BlockState(Block block, ImmutableMap<Property<?>, Comparable<?>> propertyMap, MapCodec<BlockState> codec) {
super(block, propertyMap, codec);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -35,10 +33,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
@@ -0,0 +0,0 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
public Material getBlockType(int x, int y, int z) {
CraftChunk.validateChunkCoordinates(x, y, z);
this.validateChunkCoordinates(x, y, z);
- return CraftMagicNumbers.getMaterial(blockids[y >> 4].get(x, y & 0xF, z).getBlock());
+ return blockids[y >> 4].get(x, y & 0xF, z).getBukkitMaterial(); // Paper - optimise getType calls
- return CraftMagicNumbers.getMaterial(this.blockids[this.getSectionIndex(y)].get(x, y & 0xF, z).getBlock());
+ return this.blockids[this.getSectionIndex(y)].get(x, y & 0xF, z).getBukkitMaterial(); // Paper - optimise getType calls
}
@Override
@ -50,8 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Material getType() {
- return CraftMagicNumbers.getMaterial(world.getBlockState(position).getBlock());
+ return world.getBlockState(position).getBukkitMaterial(); // Paper - optimise getType calls
- return CraftMagicNumbers.getMaterial(this.world.getBlockState(position).getBlock());
+ return this.world.getBlockState(this.position).getBukkitMaterial(); // Paper - optimise getType calls
}
@Override
@ -63,8 +61,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Material getType() {
- return CraftMagicNumbers.getMaterial(data.getBlock());
+ return data.getBukkitMaterial(); // Paper - optimise getType calls
- return CraftMagicNumbers.getMaterial(this.data.getBlock());
+ return this.data.getBukkitMaterial(); // Paper - optimise getType calls
}
public void setFlag(int flag) {
@ -76,8 +74,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Material getMaterial() {
- return CraftMagicNumbers.getMaterial(state.getBlock());
+ return state.getBukkitMaterial(); // Paper - optimise getType calls
- return CraftMagicNumbers.getMaterial(this.state.getBlock());
+ return this.state.getBukkitMaterial(); // Paper - optimise getType calls
}
public BlockState getState() {
@ -89,8 +87,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public Material getType(int x, int y, int z) {
- return CraftMagicNumbers.getMaterial(getTypeId(x, y, z).getBlock());
+ return getTypeId(x, y, z).getBukkitMaterial(); // Paper - optimise getType calls
- return CraftMagicNumbers.getMaterial(this.getTypeId(x, y, z).getBlock());
+ return this.getTypeId(x, y, z).getBukkitMaterial(); // Paper - optimise getType calls
}
@Override

View File

@ -8,14 +8,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.entity.ai.attributes.Attributes;
+import net.minecraft.world.entity.projectile.FireworkRocketEntity;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
throw new RuntimeException("Unknown settings type");
@ -29,11 +21,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ net.minecraft.world.item.ItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(firework);
+ net.minecraft.world.level.Level world = ((CraftWorld) getWorld()).getHandle();
+ FireworkRocketEntity entity = new FireworkRocketEntity(world, item, getHandle());
+ net.minecraft.world.entity.projectile.FireworkRocketEntity entity = new net.minecraft.world.entity.projectile.FireworkRocketEntity(world, item, getHandle());
+ return world.addFreshEntity(entity)
+ ? (org.bukkit.entity.Firework) entity.getBukkitEntity()
+ : null;
+ }
// Paper end
// Spigot start
@Override

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Sat, 25 Apr 2020 17:10:55 -0700
Subject: [PATCH] Reduce blockpos allocation from pathfinding
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
@@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator {
return BlockPathTypes.DANGER_FIRE;
}
- if (world.getFluidState(pos).is(FluidTags.WATER)) {
+ if (blockState.getFluidState().is(FluidTags.WATER)) {
return BlockPathTypes.WATER_BORDER;
}
} // Paper
@@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator {
} else if (blockState.is(Blocks.COCOA)) {
return BlockPathTypes.COCOA;
} else {
- FluidState fluidState = world.getFluidState(pos);
+ FluidState fluidState = blockState.getFluidState(); // Paper - remove another get type call
if (fluidState.is(FluidTags.LAVA)) {
return BlockPathTypes.LAVA;
} else if (isBurningBlock(blockState)) {

View File

@ -15,10 +15,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -0,0 +0,0 @@ public class EndDragonFight {
entityenderdragon.moveTo(0.0D, 128.0D, 0.0D, this.level.random.nextFloat() * 360.0F, 0.0F);
this.level.addFreshEntity(entityenderdragon);
this.dragonUUID = entityenderdragon.getUUID();
enderDragon.moveTo(0.0D, 128.0D, 0.0D, this.level.random.nextFloat() * 360.0F, 0.0F);
this.level.addFreshEntity(enderDragon);
this.dragonUUID = enderDragon.getUUID();
+ this.resetSpikeCrystals(); // Paper
return entityenderdragon;
return enderDragon;
}

View File

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <mail@moep.tv>
Date: Mon, 13 Jan 2020 15:40:32 +0100
Subject: [PATCH] Seed based feature search
This tries to work around the issue where the server will load
surrounding chunks up to a radius of 100 chunks in order to search for
features e.g. when running the /locate command or for treasure maps
(issue #2312).
This is done by backporting Mojang's change in 1.17 which makes it so
that the biome (generated by the seed) is checked first if the feature
can be generated before actually to load the chunk.
Additionally to that the center location of the target chunk is simply
returned if the chunk is not loaded to avoid the sync chunk load.
As this can lead to less precise locations a toggle is provided to
enable the sync loading of the target chunk again.
The main downside of this is that it breaks once the seed or generator
changes but this should usually not happen. A config option to disable
this completely is added though in case that should ever be necessary.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
}
}
+ public boolean seedBasedFeatureSearch = true;
+ public boolean seedBasedFeatureSearchLoadsChunks = false;
+ private void seedBasedFeatureSearch() {
+ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch);
+ seedBasedFeatureSearchLoadsChunks = getBoolean("seed-based-feature-search-loads-chunks", seedBasedFeatureSearchLoadsChunks);
+ log("Feature search is based on seed: " + seedBasedFeatureSearch + ", loads chunks:" + seedBasedFeatureSearchLoadsChunks);
+ }
+
public int maxCollisionsPerEntity;
private void maxEntityCollision() {
maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) );
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/StructureFeature.java
@@ -0,0 +0,0 @@ public abstract class StructureFeature<C extends FeatureConfiguration> {
if (!world.getWorldBorder().isChunkInBounds(chunkPos.x, chunkPos.z)) { continue; } // Paper
boolean bl3 = world.getBiomeManager().getPrimaryBiomeAtChunk(chunkPos).getGenerationSettings().isValidStart(this);
if (bl3) {
- ChunkAccess chunkAccess = world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.STRUCTURE_STARTS);
+ // Paper start - seed based feature search
+ ChunkAccess chunkAccess = null;
+ if (structureAccessor.getWorld().paperConfig.seedBasedFeatureSearch) {
+ Biome biomeBase = structureAccessor.getWorld().getBiomeManager().getBiome(new BlockPos(chunkPos.getMinBlockX() + 9, 0, chunkPos.getMinBlockZ() + 9));
+ if (!biomeBase.getGenerationSettings().isValidStart(this)) {
+ continue;
+ }
+ if (!structureAccessor.getWorld().paperConfig.seedBasedFeatureSearchLoadsChunks) {
+ chunkAccess = structureAccessor.getWorld().getChunkIfLoaded(chunkPos.x, chunkPos.z);
+ if (chunkAccess == null) {
+ return chunkPos.getWorldPosition().offset(8, searchStartPos.getY(), 8);
+ }
+ }
+ }
+ if (chunkAccess == null) {
+ chunkAccess = world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.STRUCTURE_STARTS);
+ }
+ // Paper end
StructureStart<?> structureStart = structureAccessor.getStartForFeature(SectionPos.bottomOf(chunkAccess), this, chunkAccess);
if (structureStart != null && structureStart.isValid()) {
if (skipExistingChunks && structureStart.canBeReferenced()) {

View File

@ -15,19 +15,6 @@ diff --git a/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java
+++ b/src/main/java/net/minecraft/world/level/biome/TheEndBiomeSource.java
@@ -0,0 +0,0 @@ package net.minecraft.world.level.biome;
import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
+import it.unimi.dsi.fastutil.HashCommon; // Paper
import java.util.List;
import net.minecraft.core.Registry;
import net.minecraft.resources.RegistryLookupCodec;
import net.minecraft.util.Mth;
+import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
@@ -0,0 +0,0 @@ public class TheEndBiomeSource extends BiomeSource {
private final Biome midlands;
private final Biome islands;
@ -44,34 +31,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
public TheEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
this(biomeRegistry, seed, (Biome) biomeRegistry.lifecycle(Biomes.THE_END), (Biome) biomeRegistry.lifecycle(Biomes.END_HIGHLANDS), (Biome) biomeRegistry.lifecycle(Biomes.END_MIDLANDS), (Biome) biomeRegistry.lifecycle(Biomes.SMALL_END_ISLANDS), (Biome) biomeRegistry.lifecycle(Biomes.END_BARRENS));
this(biomeRegistry, seed, biomeRegistry.getOrThrow(Biomes.THE_END), biomeRegistry.getOrThrow(Biomes.END_HIGHLANDS), biomeRegistry.getOrThrow(Biomes.END_MIDLANDS), biomeRegistry.getOrThrow(Biomes.SMALL_END_ISLANDS), biomeRegistry.getOrThrow(Biomes.END_BARRENS));
@@ -0,0 +0,0 @@ public class TheEndBiomeSource extends BiomeSource {
float f = 100.0F - Mth.sqrt((long) i * (long) i + (long) j * (long) j) * 8.0F; // Paper - cast ints to long to avoid integer overflow
f = Mth.clamp(f, -100.0F, 80.0F);
+ NoiseCache cache = noiseCache.get().computeIfAbsent(noisegenerator3handler, m -> new NoiseCache()); // Paper
for (int k1 = -12; k1 <= 12; ++k1) {
for (int l1 = -12; l1 <= 12; ++l1) {
long i2 = (long) (k + k1);
long j2 = (long) (l + l1);
- if (i2 * i2 + j2 * j2 > 4096L && noisegenerator3handler.getValue((double) i2, (double) j2) < -0.8999999761581421D) {
- float f1 = (Mth.abs((float) i2) * 3439.0F + Mth.abs((float) j2) * 147.0F) % 13.0F + 9.0F;
+ NoiseCache cache = noiseCache.get().computeIfAbsent(simplexNoise, noiseKey -> new NoiseCache()); // Paper
for(int o = -12; o <= 12; ++o) {
for(int p = -12; p <= 12; ++p) {
long q = (long)(k + o);
long r = (long)(l + p);
- if (q * q + r * r > 4096L && simplexNoise.getValue((double)q, (double)r) < (double)-0.9F) {
- float g = (Mth.abs((float)q) * 3439.0F + Mth.abs((float)r) * 147.0F) % 13.0F + 9.0F;
+ // Paper start - Significantly improve end generation performance by using a noise cache
+ long key = ChunkPos.asLong((int) i2, (int) j2);
+ int index = (int) HashCommon.mix(key) & 8191;
+ float f1 = Float.MIN_VALUE;
+ long key = net.minecraft.world.level.ChunkPos.asLong((int) q, (int) q);
+ int index = (int) it.unimi.dsi.fastutil.HashCommon.mix(key) & 8191;
+ float g = Float.MIN_VALUE;
+ if (cache.keys[index] == key) {
+ f1 = cache.values[index];
+ g = cache.values[index];
+ } else {
+ if (i2 * i2 + j2 * j2 > 4096L && noisegenerator3handler.getValue((double) i2, (double) j2) < -0.8999999761581421D) {
+ f1 = (Mth.abs((float) i2) * 3439.0F + Mth.abs((float) j2) * 147.0F) % 13.0F + 9.0F;
+ if (q * q + r * r > 4096L && simplexNoise.getValue((double)q, (double)r) < (double)-0.9F) {
+ g = (Mth.abs((float) q) * 3439.0F + Mth.abs((float) r) * 147.0F) % 13.0F + 9.0F;
+ }
+ cache.keys[index] = key;
+ cache.values[index] = f1;
+ cache.values[index] = g;
+ }
+ if (f1 != Float.MIN_VALUE) {
+ if (g != Float.MIN_VALUE) {
+ // Paper end
float f2 = (float) (i1 - k1 * 2);
float f3 = (float) (j1 - l1 * 2);
float f4 = 100.0F - Mth.sqrt(f2 * f2 + f3 * f3) * f1;
float h = (float)(m - o * 2);
float s = (float)(n - p * 2);
float t = 100.0F - Mth.sqrt(h * h + s * s) * g;

View File

@ -9,10 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
log("Using vanilla redstone algorithm.");
}
}
+
+ public boolean shouldRemoveDragon = false;
+ private void shouldRemoveDragon() {
+ shouldRemoveDragon = getBoolean("should-remove-dragon", shouldRemoveDragon);
@ -20,17 +19,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ log("The Ender Dragon will be removed if she already exists without a portal.");
+ }
+ }
}
+
public short keepLoadedRange;
private void keepLoadedRange() {
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -0,0 +0,0 @@ public class EndDragonFight {
this.dragonUUID = entityenderdragon.getUUID();
EndDragonFight.LOGGER.info("Found that there's a dragon still alive ({})", entityenderdragon);
this.dragonUUID = enderDragon.getUUID();
LOGGER.info("Found that there's a dragon still alive ({})", (Object)enderDragon);
this.dragonKilled = false;
- if (!flag) {
+ if (!flag && this.level.paperConfig.shouldRemoveDragon) { // Paper
EndDragonFight.LOGGER.info("But we didn't have a portal, let's remove it.");
entityenderdragon.remove();
- if (!bl) {
+ if (!bl && this.level.paperConfig.shouldRemoveDragon) {
LOGGER.info("But we didn't have a portal, let's remove it.");
enderDragon.discard();
this.dragonUUID = null;

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
@@ -0,0 +0,0 @@ public abstract class AbstractVillager extends AgableMob implements Npc, Merchan
@@ -0,0 +0,0 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
return this.tradingPlayer != null;
}
@ -22,21 +22,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public MerchantOffers getOffers() {
if (this.offers == null) {
@@ -0,0 +0,0 @@ public abstract class AbstractVillager extends AgableMob implements Npc, Merchan
return this.level;
}
+ protected final void updateTrades() { updateTrades(); } // Paper - OBFHELPER
protected abstract void updateTrades();
protected void addOffersFromItemListings(MerchantOffers recipeList, VillagerTrades.ItemListing[] pool, int count) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java
@@ -0,0 +0,0 @@ public class CraftAbstractVillager extends CraftAgeable implements AbstractVilla
public HumanEntity getTrader() {
return getMerchant().getTrader();
return this.getMerchant().getTrader();
}
+
+ // Paper start