[ci skip] Add more identifying patch comments

This commit is contained in:
Nassim Jahnke 2024-01-20 12:50:16 +01:00
parent 8b532bad3a
commit 1b920c7241
43 changed files with 180 additions and 194 deletions

View file

@ -12,15 +12,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.handlingFault = true;
if (this.channel.isOpen()) {
+ net.minecraft.server.level.ServerPlayer player = this.getPlayer(); // Paper
+ net.minecraft.server.level.ServerPlayer player = this.getPlayer(); // Paper - Add API for quit reason
if (throwable instanceof TimeoutException) {
Connection.LOGGER.debug("Timeout", throwable);
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.TIMED_OUT; // Paper
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.TIMED_OUT; // Paper - Add API for quit reason
this.disconnect(Component.translatable("disconnect.timeout"));
} else {
MutableComponent ichatmutablecomponent = Component.translatable("disconnect.genericReason", "Internal Exception: " + throwable);
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper - Add API for quit reason
if (flag) {
Connection.LOGGER.debug("Failed to sent packet", throwable);
if (this.getSending() == PacketFlow.CLIENTBOUND) {
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
public @Nullable String clientBrandName = null; // Paper - Brand name
+ 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 org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
// Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
final Component ichatbasecomponent = io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()); // Paper - Adventure
// CraftBukkit end
+ this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper
+ this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper - Add API for quit reason
this.connection.send(new ClientboundDisconnectPacket(ichatbasecomponent), PacketSendListener.thenRun(() -> {
this.connection.disconnect(ichatbasecomponent);
}));
@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & quit reason
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & Add API for quit reason
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.player = player;
}
+ // Paper start
+ // Paper start - Add PlayerItemCooldownEvent
+ @Override
+ public void addCooldown(Item item, int 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);
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ super.addCooldown(item, event.getCooldown());
+ }
+ }
+ // Paper end
+ // Paper end - Add PlayerItemCooldownEvent
+
@Override
protected void onCooldownStarted(Item item, int duration) {

View file

@ -410,7 +410,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
// Paper start
// Paper start - auto recipe limit
if (!org.bukkit.Bukkit.isPrimaryThread()) {
if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) {
- this.server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]))); // Paper

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static void dropHoneycomb(Level world, BlockPos pos) {
- popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3));
+ popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - conflict on change, item needs to be set below
+ popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - Add PlayerShearBlockEvent; conflict on change, item needs to be set below
}
@Override
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (org.bukkit.inventory.ItemStack itemDrop : event.getDrops()) {
+ popResource(world, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemDrop));
+ }
+ // Paper end
+ // Paper end - Add PlayerShearBlockEvent
itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
entityhuman1.broadcastBreakEvent(hand);
});
@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (!event.callEvent()) {
+ return InteractionResult.PASS;
+ }
+ // Paper end
+ // Paper end - Add PlayerShearBlockEvent
Direction direction = hit.getDirection();
Direction direction2 = direction.getAxis() == Direction.Axis.Y ? player.getDirection().getOpposite() : direction;
world.playSound((Player)null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F);
@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - Add PlayerShearBlockEvent
+ for (org.bukkit.inventory.ItemStack item : event.getDrops()) {
+ ItemEntity itemEntity = new ItemEntity(world, (double) pos.getX() + 0.5D + (double) direction2.getStepX() * 0.65D, (double) pos.getY() + 0.1D, (double) pos.getZ() + 0.5D + (double) direction2.getStepZ() * 0.65D, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item));
+ // Paper end
+ // Paper end - Add PlayerShearBlockEvent
itemEntity.setDeltaMovement(0.05D * (double)direction2.getStepX() + world.random.nextDouble() * 0.02D, 0.05D, 0.05D * (double)direction2.getStepZ() + world.random.nextDouble() * 0.02D);
world.addFreshEntity(itemEntity);
+ } // Paper - Add PlayerShearBlockEvent

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void overrideXp(int experience) {}
+ // Paper start
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ @Override
+ public void processTrade(MerchantOffer recipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
+ if (event == null || event.willIncreaseTradeUses()) {
@ -24,15 +24,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ this.notifyTrade(recipe);
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
+
@Override
public void notifyTrade(MerchantOffer offer) {
- offer.increaseUses();
+ // offer.increaseUses(); // Paper - handled in processTrade
+ // offer.increaseUses(); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
this.ambientSoundTime = -this.getAmbientSoundInterval();
- this.rewardTradeXp(offer);
+ // this.rewardTradeXp(offer); // Paper - handled in processTrade
+ // this.rewardTradeXp(offer); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
if (this.tradingPlayer instanceof ServerPlayer) {
CriteriaTriggers.TRADE.trigger((ServerPlayer) this.tradingPlayer, this, offer.getResult());
}
@ -44,14 +44,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public abstract boolean stillValid(Player player);
protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
+ // Paper start
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ return this.moveItemStackTo(stack, startIndex, endIndex, fromLast, false);
+ }
+ protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean fromLast, boolean isCheck) {
+ if (isCheck) {
+ stack = stack.copy();
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
boolean flag1 = false;
int k = startIndex;
@ -59,27 +59,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
slot = (Slot) this.slots.get(k);
itemstack1 = slot.getItem();
+ // Paper start - clone if only a check
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent; clone if only a check
+ if (isCheck) {
+ itemstack1 = itemstack1.copy();
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
if (!itemstack1.isEmpty() && ItemStack.isSameItemSameTags(stack, itemstack1)) {
int l = itemstack1.getCount() + stack.getCount();
if (l <= stack.getMaxStackSize()) {
stack.setCount(0);
itemstack1.setCount(l);
+ if (!isCheck) { // Paper - dont update if only a check
+ if (!isCheck) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
slot.setChanged();
+ } // Paper
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
flag1 = true;
} else if (itemstack1.getCount() < stack.getMaxStackSize()) {
stack.shrink(stack.getMaxStackSize() - itemstack1.getCount());
itemstack1.setCount(stack.getMaxStackSize());
+ if (!isCheck) { // Paper - dont update if only a check
+ if (!isCheck) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
slot.setChanged();
+ } // Paper
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
flag1 = true;
}
}
@ -87,33 +87,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
slot = (Slot) this.slots.get(k);
itemstack1 = slot.getItem();
+ // Paper start - clone if only a check
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ if (isCheck) {
+ itemstack1 = itemstack1.copy();
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
if (itemstack1.isEmpty() && slot.mayPlace(stack)) {
if (stack.getCount() > slot.getMaxStackSize()) {
+ // Paper start - dont set slot if only check
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ if (isCheck) {
+ stack.shrink(slot.getMaxStackSize());
+ } else {
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
slot.setByPlayer(stack.split(slot.getMaxStackSize()));
+ } // Paper
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
} else {
+ // Paper start - dont set slot if only check
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ if (isCheck) {
+ stack.shrink(stack.getCount());
+ } else {
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
slot.setByPlayer(stack.split(stack.getCount()));
+ } // Paper
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
}
+ if (!isCheck) { // Paper - dont update if only check
+ if (!isCheck) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
slot.setChanged();
+ } // Paper
+ } // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
flag1 = true;
break;
}
@ -126,13 +126,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
itemstack = itemstack1.copy();
if (slot == 2) {
- if (!this.moveItemStackTo(itemstack1, 3, 39, true)) {
+ if (!this.moveItemStackTo(itemstack1, 3, 39, true, true)) { // Paper
+ if (!this.moveItemStackTo(itemstack1, 3, 39, true, true)) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
return ItemStack.EMPTY;
}
- slot1.onQuickCraft(itemstack1, itemstack);
- this.playTradeSound();
+ // slot1.onQuickCraft(itemstack1, itemstack); // Paper - moved to after the non-check moveItemStackTo call
+ // slot1.onQuickCraft(itemstack1, itemstack); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; moved to after the non-check moveItemStackTo call
+ // this.playTradeSound();
} else if (slot != 0 && slot != 1) {
if (slot >= 3 && slot < 30) {
@ -141,7 +141,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return ItemStack.EMPTY;
}
+ if (slot != 2) { // Paper - moved down for slot 2
+ if (slot != 2) { // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; moved down for slot 2
if (itemstack1.isEmpty()) {
slot1.setByPlayer(ItemStack.EMPTY);
} else {
@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
slot1.onTake(player, itemstack1);
+ } // Paper start - handle slot 2
+ } // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent; handle slot 2
+ if (slot == 2) { // is merchant result slot
+ slot1.onTake(player, itemstack1);
+ if (itemstack1.isEmpty()) {
@ -163,7 +163,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.playTradeSound();
+ slot1.set(ItemStack.EMPTY); // itemstack1 should ALWAYS be empty
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
}
return itemstack;
@ -176,9 +176,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void onTake(Player player, ItemStack stack) {
- this.checkTakeAchievements(stack);
+ // this.checkTakeAchievements(stack); // Paper - move to after event is called and not cancelled
+ // this.checkTakeAchievements(stack); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; move to after event is called and not cancelled
MerchantOffer merchantOffer = this.slots.getActiveOffer();
+ // Paper start
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ io.papermc.paper.event.player.PlayerPurchaseEvent event = null;
+ if (merchantOffer != null && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
+ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager abstractVillager) {
@ -196,13 +196,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ this.checkTakeAchievements(stack);
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
if (merchantOffer != null) {
ItemStack itemStack = this.slots.getItem(0);
ItemStack itemStack2 = this.slots.getItem(1);
if (merchantOffer.take(itemStack, itemStack2) || merchantOffer.take(itemStack2, itemStack)) {
- this.merchant.notifyTrade(merchantOffer);
+ this.merchant.processTrade(merchantOffer, event); // Paper
+ this.merchant.processTrade(merchantOffer, event); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent
player.awardStat(Stats.TRADED_WITH_VILLAGER);
this.slots.setItem(0, itemStack);
this.slots.setItem(1, itemStack2);
@ -226,7 +226,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.trades;
}
+ // Paper start
+ // Paper start - Add PlayerTradeEvent and PlayerPurchaseEvent
+ @Override
+ public void processTrade(MerchantOffer merchantRecipe, @javax.annotation.Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent
+ /** Based on {@link net.minecraft.world.entity.npc.AbstractVillager#processTrade(MerchantOffer, io.papermc.paper.event.player.PlayerPurchaseEvent)} */
@ -240,12 +240,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ this.notifyTrade(merchantRecipe);
+ }
+ // Paper end
+ // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent
@Override
public void notifyTrade(MerchantOffer offer) {
// increase recipe's uses
- offer.increaseUses();
+ // offer.increaseUses(); // Paper - handled above in processTrade
+ // offer.increaseUses(); // Paper - Add PlayerTradeEvent and PlayerPurchaseEvent; handled above in processTrade
}
@Override

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings, they can be defined by datapacks so refresh it here
org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings; they can be defined by datapacks so refresh it here
+ new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper - Add ServerResourcesReloadedEvent; fire after everything has been reloaded
}, this);

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 25 Nov 2020 23:20:44 -0800
Subject: [PATCH] Implement TargetHitEvent
Subject: [PATCH] Add TargetHitEvent
diff --git a/src/main/java/net/minecraft/world/level/block/TargetBlock.java b/src/main/java/net/minecraft/world/level/block/TargetBlock.java
@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void onProjectileHit(Level world, BlockState state, BlockHitResult hit, Projectile projectile) {
int i = updateRedstoneOutput(world, state, hit, projectile);
+ // Paper start
+ // Paper start - Add TargetHitEvent
+ }
+ private static void awardTargetHitCriteria(Projectile projectile, BlockHitResult hit, int i) {
+ // Paper end
+ // Paper end - Add TargetHitEvent
Entity entity = projectile.getOwner();
if (entity instanceof ServerPlayer serverPlayer) {
serverPlayer.awardStat(Stats.TARGET_HIT);
@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static int updateRedstoneOutput(LevelAccessor world, BlockState state, BlockHitResult hitResult, Entity entity) {
int i = getRedstoneStrength(hitResult, hitResult.getLocation());
int j = entity instanceof AbstractArrow ? 20 : 8;
+ // Paper start
+ // Paper start - Add TargetHitEvent
+ if (entity instanceof Projectile) {
+ final Projectile projectile = (Projectile) entity;
+ final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, hitResult.getBlockPos());
@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return i;
+ }
+ }
+ // Paper end
+ // Paper end - Add TargetHitEvent
if (!world.getBlockTicks().hasScheduledTick(hitResult.getBlockPos(), state.getBlock())) {
setOutputPower(world, state, i, hitResult.getBlockPos(), j);
}

View file

@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.spawnChance = 25;
- properties.setWanderingTraderSpawnChance(this.spawnChance);
- }
+ // Paper start
+ // Paper start - Add Wandering Trader spawn rate config options
+ 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
@ -37,13 +37,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // this.spawnChance = 25;
+ // properties.setWanderingTraderSpawnChance(this.spawnChance);
+ //}
+ // Paper end
+ // Paper end - Add Wandering Trader spawn rate config options
}
@Override
public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) {
+ // Paper start
+ // Paper start - Add Wandering Trader spawn rate config options
+ if (this.tickDelay == Integer.MIN_VALUE) {
+ this.tickDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
+ this.spawnDelay = world.paperConfig().entities.spawning.wanderingTrader.spawnDayLength;
@ -81,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (this.spawn(world)) {
- this.spawnChance = 25;
+ this.spawnChance = world.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin;
+ // Paper end
+ // Paper end - Add Wandering Trader spawn rate config options
return 1;
} else {
return 0;

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
while (iterator.hasNext()) {
MerchantOffer merchantrecipe = (MerchantOffer) iterator.next();
+ if (merchantrecipe.ignoreDiscounts) continue; // Paper
+ if (merchantrecipe.ignoreDiscounts) continue; // Paper - Add ignore discounts API
merchantrecipe.addToSpecialPriceDiff(-Mth.floor((float) i * merchantrecipe.getPriceMultiplier()));
}
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
while (iterator1.hasNext()) {
MerchantOffer merchantrecipe1 = (MerchantOffer) iterator1.next();
+ if (merchantrecipe1.ignoreDiscounts) continue; // Paper
+ if (merchantrecipe1.ignoreDiscounts) continue; // Paper - Add ignore discounts API
double d0 = 0.3D + 0.0625D * (double) j;
int k = (int) Math.floor(d0 * (double) merchantrecipe1.getBaseCostA().getCount());
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int demand;
public float priceMultiplier;
public int xp;
+ public boolean ignoreDiscounts; // Paper
+ public boolean ignoreDiscounts; // Paper - Add ignore discounts API
// CraftBukkit start
private CraftMerchantRecipe bukkitHandle;
@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, int demand, CraftMerchantRecipe bukkit) {
- this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand);
+ // Paper start - add ignoreDiscounts param
+ // Paper start - Add ignore discounts API
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand, false, bukkit);
+ }
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, boolean ignoreDiscounts, CraftMerchantRecipe bukkit) {
@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, int demand, boolean ignoreDiscounts, CraftMerchantRecipe bukkit) {
+ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand, ignoreDiscounts);
+ // Paper end
+ // Paper end - Add ignore discounts API
this.bukkitHandle = bukkit;
}
// CraftBukkit end
@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.specialPriceDiff = nbt.getInt("specialPrice");
this.demand = nbt.getInt("demand");
+ this.ignoreDiscounts = nbt.getBoolean("Paper.IgnoreDiscounts"); // Paper
+ this.ignoreDiscounts = nbt.getBoolean("Paper.IgnoreDiscounts"); // Paper - Add ignore discounts API
}
public MerchantOffer(ItemStack buyItem, ItemStack sellItem, int maxUses, int merchantExperience, float priceMultiplier) {
@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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
+ // Paper start - Add ignore discounts API
+ this(firstBuyItem, secondBuyItem, sellItem, uses, maxUses, merchantExperience, priceMultiplier, false);
+ }
+ public MerchantOffer(ItemStack firstBuyItem, ItemStack secondBuyItem, ItemStack sellItem, int uses, int maxUses, int merchantExperience, float priceMultiplier, boolean ignoreDiscounts) {
@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ 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
+ // Paper end - Add ignore discounts API
this.rewardExp = true;
this.xp = 1;
this.baseCostA = firstBuyItem;
@ -86,7 +86,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
nbttagcompound.putFloat("priceMultiplier", this.priceMultiplier);
nbttagcompound.putInt("specialPrice", this.specialPriceDiff);
nbttagcompound.putInt("demand", this.demand);
+ nbttagcompound.putBoolean("Paper.IgnoreDiscounts", this.ignoreDiscounts); // Paper
+ nbttagcompound.putBoolean("Paper.IgnoreDiscounts", this.ignoreDiscounts); // Paper - Add ignore discounts API
return nbttagcompound;
}

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 16 Nov 2020 12:01:52 -0800
Subject: [PATCH] Added missing default perms for commands
Subject: [PATCH] Add missing default perms for commands
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 30 Dec 2020 19:43:01 -0500
Subject: [PATCH] Additional Block Material API's
Subject: [PATCH] Additional Block Material API
Faster version for isSolid() that utilizes NMS's state for isSolid instead of the slower
process to do this in the Bukkit API

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
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
+ // Paper start - Custom beacon ranges
+ private final String PAPER_RANGE_TAG = "Paper.Range";
+ private double effectRange = -1;
+
@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public void resetEffectRange() {
+ this.effectRange = -1;
+ }
+ // Paper end
+ // Paper end - Custom beacon ranges
@Nullable
static MobEffect filterEffect(@Nullable MobEffect effect) {
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) {
- BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower);
+ BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper
+ BeaconBlockEntity.applyEffects(world, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper - Custom beacon ranges
BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_AMBIENT);
}
}
@ -48,14 +48,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static List getHumansInRange(Level world, BlockPos blockposition, int i) {
+ // Paper start
+ // Paper start - Custom beacon ranges
+ return BeaconBlockEntity.getHumansInRange(world, blockposition, i, null);
+ }
+ public static List getHumansInRange(Level world, BlockPos blockposition, int i, @Nullable BeaconBlockEntity blockEntity) {
+ // Paper end
+ // Paper end - Custom beacon ranges
{
- double d0 = (double) (i * 10 + 10);
+ double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - custom beacon ranges
+ double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - Custom beacon ranges
AABB axisalignedbb = (new AABB(blockposition)).inflate(d0).expandTowards(0.0D, (double) world.getHeight(), 0.0D);
List<Player> list = world.getEntitiesOfClass(Player.class, axisalignedbb);
@ -63,18 +63,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
private static void applyEffects(Level world, BlockPos pos, int beaconLevel, @Nullable MobEffect primaryEffect, @Nullable MobEffect secondaryEffect) {
+ // Paper start
+ // Paper start - Custom beacon ranges
+ BeaconBlockEntity.applyEffects(world, pos, beaconLevel, primaryEffect, secondaryEffect, null);
+ }
+ private static void applyEffects(Level world, BlockPos pos, int beaconLevel, @Nullable MobEffect primaryEffect, @Nullable MobEffect secondaryEffect, @Nullable BeaconBlockEntity blockEntity) {
+ // Paper end
+ // Paper end - Custom beacon ranges
if (!world.isClientSide && primaryEffect != null) {
double d0 = (double) (beaconLevel * 10 + 10);
byte b0 = BeaconBlockEntity.getAmplification(beaconLevel, primaryEffect, secondaryEffect);
int j = BeaconBlockEntity.getLevel(beaconLevel);
- List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel);
+ List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel, blockEntity); // Paper
+ List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel, blockEntity); // Paper - Custom beacon ranges
BeaconBlockEntity.applyEffect(list, primaryEffect, j, b0, true, pos); // Paper - BeaconEffectEvent
@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
this.lockKey = LockCode.fromTag(nbt);
+ this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper
+ this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper - Custom beacon ranges
}
@Override
@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
this.lockKey.addToTag(nbt);
+ nbt.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper
+ nbt.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges
}
public void setCustomName(@Nullable Component customName) {
@ -103,7 +103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BeaconBlockEntity beacon = (BeaconBlockEntity) tileEntity;
- Collection<Player> nms = BeaconBlockEntity.getHumansInRange(beacon.getLevel(), beacon.getBlockPos(), beacon.levels);
+ Collection<Player> nms = BeaconBlockEntity.getHumansInRange(beacon.getLevel(), beacon.getBlockPos(), beacon.levels, beacon); // Paper
+ Collection<Player> nms = BeaconBlockEntity.getHumansInRange(beacon.getLevel(), beacon.getBlockPos(), beacon.levels, beacon); // Paper - Custom beacon ranges
Collection<LivingEntity> bukkit = new ArrayList<LivingEntity>(nms.size());
for (Player human : nms) {

View file

@ -37,10 +37,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final Int2ObjectSortedMap<Schema> schemas = new Int2ObjectAVLTreeMap<>();
private final List<DataFix> globalList = Lists.newArrayList();
private final IntSortedSet fixerVersions = new IntAVLTreeSet();
+ private final int minDataFixPrecacheVersion; // Paper
+ private final int minDataFixPrecacheVersion; // Paper - Perf: Cache DataFixerUpper Rewrite Rules on demand
public DataFixerBuilder(final int dataVersion) {
+ minDataFixPrecacheVersion = Integer.getInteger("Paper.minPrecachedDatafixVersion", dataVersion+1) * 10; // Paper - default to precache nothing - mojang stores versions * 10 to allow for 'sub versions'
+ minDataFixPrecacheVersion = Integer.getInteger("Paper.minPrecachedDatafixVersion", dataVersion+1) * 10; // Paper - Perf: default to precache nothing - mojang stores versions * 10 to allow for 'sub versions'
this.dataVersion = dataVersion;
}
@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
final IntBidirectionalIterator iterator = fixerUpper.fixerVersions().iterator();
while (iterator.hasNext()) {
final int versionKey = iterator.nextInt();
+ if (versionKey < minDataFixPrecacheVersion) continue; // Paper
+ if (versionKey < minDataFixPrecacheVersion) continue; // Paper - Perf: Cache DataFixerUpper Rewrite Rules on demand
final Schema schema = schemas.get(versionKey);
for (final String typeName : schema.types()) {
if (!requiredTypeNames.contains(typeName)) {

View file

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.getPlayerList().reloadResources();
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
+ org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings, they can be defined by datapacks so refresh it here
+ org.bukkit.craftbukkit.block.data.CraftBlockData.reloadCache(); // Paper - cache block data strings; they can be defined by datapacks so refresh it here
}, this);
if (this.isSameThread()) {
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- private static final Map<Class<? extends Enum<?>>, Enum<?>[]> ENUM_VALUES = new HashMap<>();
+ private static final Map<Class<? extends Enum<?>>, Enum<?>[]> ENUM_VALUES = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - make thread safe
+ private static final Map<Class<? extends Enum<?>>, Enum<?>[]> ENUM_VALUES = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - cache block data strings; make thread safe
/**
* Convert an NMS Enum (usually a BlockStateEnum) to its appropriate Bukkit
@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ stringDataCache.clear();
+ Block.BLOCK_STATE_REGISTRY.forEach(blockData -> stringDataCache.put(blockData.toString(), blockData.createCraftBlockData()));
+ }
+ // Paper end
+ // Paper end - cache block data strings
+
public static CraftBlockData newData(Material material, String data) {
Preconditions.checkArgument(material == null || material.isBlock(), "Cannot get data for not block %s", material);

View file

@ -12,12 +12,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public boolean isPushable() {
+ // Paper start
+ // Paper start - Climbing should not bypass cramming gamerule
+ return isCollidable(false);
+ }
+
+ public boolean isCollidable(boolean ignoreClimbing) {
+ // Paper end
+ // Paper end - Climbing should not bypass cramming gamerule
return false;
}
@ -29,17 +29,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static Predicate<Entity> pushableBy(Entity entity) {
+ // Paper start - ignoreClimbing param
+ // Paper start - Climbing should not bypass cramming gamerule
+ return pushable(entity, false);
+ }
+ public static Predicate<Entity> pushable(Entity entity, boolean ignoreClimbing) {
+ // Paper end
+ // Paper end - Climbing should not bypass cramming gamerule
PlayerTeam scoreboardteam = entity.getTeam();
Team.CollisionRule scoreboardteambase_enumteampush = scoreboardteam == null ? Team.CollisionRule.ALWAYS : scoreboardteam.getCollisionRule();
return (Predicate) (scoreboardteambase_enumteampush == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : EntitySelector.NO_SPECTATORS.and((entity1) -> {
- 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
+ if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
return false;
} else if (entity.level().isClientSide && (!(entity1 instanceof Player) || !((Player) entity1).isLocalPlayer())) {
return false;
@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
// Paper end - don't run getEntities if we're not going to use its result
- List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
+ List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - fix climbing bypassing cramming rule
+ List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - Climbing should not bypass cramming gamerule
if (!list.isEmpty()) {
// Paper - moved up
@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return !this.isRemoved() && this.collides; // CraftBukkit
}
+ // Paper start
+ // Paper start - Climbing should not bypass cramming gamerule
@Override
public boolean isPushable() {
- return this.isAlive() && !this.isSpectator() && !this.onClimbable() && this.collides; // CraftBukkit
@ -70,7 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Override
+ public boolean isCollidable(boolean ignoreClimbing) {
+ return this.isAlive() && !this.isSpectator() && (ignoreClimbing || !this.onClimbable()) && this.collides; // CraftBukkit
+ // Paper end
+ // Paper end - Climbing should not bypass cramming gamerule
}
// CraftBukkit start - collidable API
@ -83,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return false;
}
@ -97,8 +97,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
- return super.isPushable(); // CraftBukkit - collidable API
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ return super.isCollidable(ignoreClimbing); // CraftBukkit - collidable API // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
+ return super.isCollidable(ignoreClimbing); // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
}
@Override
@ -111,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return !this.isVehicle();
}
@ -124,7 +124,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return false;
}
@ -137,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return true;
}
@ -150,7 +150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
- public boolean isPushable() {
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper
+ public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
return true;
}

View file

@ -194,7 +194,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void addDeltaMovement(Vec3 velocity) {
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
}
// Paper end - fix MC-4
// Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {
+ synchronized (this.posLock) { // Paper
this.position = new Vec3(x, y, z);

View file

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public boolean isTicking() {
+ return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this);
+ }
// Paper end
// Paper end - Expose entity id counter
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
void accept(Entity entity, double x, double y, double z);
}
+
+ // Paper start
+ // Paper start - Expose entity id counter
+ public static int nextEntityId() {
+ return ENTITY_COUNTER.incrementAndGet();
+ }
+ // Paper end
+ // Paper end - Expose entity id counter
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
worldserver1 = this.server.getLevel(Level.OVERWORLD);
blockposition = entityplayer1.getSpawnPoint(worldserver1);
- location = CraftLocation.toBukkit(blockposition, worldserver1.getWorld()).add(0.5F, 0.1F, 0.5F);
+ location = CraftLocation.toBukkit(blockposition, worldserver1.getWorld(), worldserver1.levelData.getSpawnAngle(), 0.0F).add(0.5F, 0.1F, 0.5F); // Paper - use world spawn angle
+ location = CraftLocation.toBukkit(blockposition, worldserver1.getWorld(), worldserver1.levelData.getSpawnAngle(), 0.0F).add(0.5F, 0.1F, 0.5F); // Paper - Expose world spawn angle
}
Player respawnPlayer = entityplayer1.getBukkitEntity();

View file

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ captureDrops.add((net.minecraft.world.entity.item.ItemEntity) entity);
+ return true;
+ }
+ // Paper end
+ // Paper end - capture all item additions to the world
// SPIGOT-6415: Don't call spawn event when reason is null. For example when an entity teleports to a new world.
if (spawnReason != null && !CraftEventFactory.doEntityAddEventCalling(this, entity, spawnReason)) {
return false;
@ -30,14 +30,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// return true; // CraftBukkit
}
// CraftBukkit start
+ java.util.List<net.minecraft.world.entity.item.ItemEntity> itemsToDrop = this.level.captureDrops; // Paper - store current list
+ this.level.captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff
+ java.util.List<net.minecraft.world.entity.item.ItemEntity> itemsToDrop = this.level.captureDrops; // Paper - capture all item additions to the world
+ this.level.captureDrops = null; // Paper - capture all item additions to the world; Remove this earlier so that we can actually drop stuff
if (event.isDropItems()) {
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, this.level.captureDrops);
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - use stored ref
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - capture all item additions to the world
}
- this.level.captureDrops = null;
+ //this.level.captureDrops = null; // Paper - move up
+ //this.level.captureDrops = null; // Paper - capture all item additions to the world; move up
// Drop event experience
if (flag && event != null) {

View file

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final GateBehavior.OrderPolicy orderPolicy;
private final GateBehavior.RunningPolicy runningPolicy;
- private final ShufflingList<BehaviorControl<? super E>> behaviors = new ShufflingList<>();
+ private final ShufflingList<BehaviorControl<? super E>> behaviors = new ShufflingList<>(false); // Paper - don't use a clone
+ private final ShufflingList<BehaviorControl<? super E>> behaviors = new ShufflingList<>(false); // Paper - Fix Concurrency issue in ShufflingList during worldgen
private Behavior.Status status = Behavior.Status.STOPPED;
public GateBehavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState, Set<MemoryModuleType<?>> memoriesToForgetWhenStopped, GateBehavior.OrderPolicy order, GateBehavior.RunningPolicy runMode, List<Pair<? extends BehaviorControl<? super E>, Integer>> tasks) {
@ -27,25 +27,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class ShufflingList<U> implements Iterable<U> {
protected final List<ShufflingList.WeightedEntry<U>> entries;
private final RandomSource random = RandomSource.create();
+ private final boolean isUnsafe; // Paper
+ private final boolean isUnsafe; // Paper - Fix Concurrency issue in ShufflingList during worldgen
public ShufflingList() {
+ // Paper start
+ // Paper start - Fix Concurrency issue in ShufflingList during worldgen
+ this(true);
+ }
+ public ShufflingList(boolean isUnsafe) {
+ this.isUnsafe = isUnsafe;
+ // Paper end
+ // Paper end - Fix Concurrency issue in ShufflingList during worldgen
this.entries = Lists.newArrayList();
}
private ShufflingList(List<ShufflingList.WeightedEntry<U>> list) {
+ // Paper start
+ // Paper start - Fix Concurrency issue in ShufflingList during worldgen
+ this(list, true);
+ }
+ private ShufflingList(List<ShufflingList.WeightedEntry<U>> list, boolean isUnsafe) {
+ this.isUnsafe = isUnsafe;
+ // Paper end
+ // Paper end - Fix Concurrency issue in ShufflingList during worldgen
this.entries = Lists.newArrayList(list);
}
@ -58,12 +58,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- });
- this.entries.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight));
- return this;
+ // Paper start - make concurrent safe, work off a clone of the list
+ // Paper start - Fix Concurrency issue in ShufflingList during worldgen
+ List<ShufflingList.WeightedEntry<U>> list = this.isUnsafe ? Lists.newArrayList(this.entries) : this.entries;
+ list.forEach(entry -> entry.setRandom(this.random.nextFloat()));
+ list.sort(Comparator.comparingDouble(ShufflingList.WeightedEntry::getRandWeight));
+ return this.isUnsafe ? new ShufflingList<>(list, this.isUnsafe) : this;
+ // Paper end
+ // Paper end - Fix Concurrency issue in ShufflingList during worldgen
}
public Stream<U> stream() {

View file

@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- this.player.absMoveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
+ this.player.moveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); // Paper - use proper moveTo for teleportation
+ this.player.moveTo(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); // Paper - Fix Entity Teleportation and cancel velocity if teleported
this.lastGoodX = this.awaitingPositionFromClient.x;
this.lastGoodY = this.awaitingPositionFromClient.y;
this.lastGoodZ = this.awaitingPositionFromClient.z;
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.awaitingTeleportTime = this.tickCount;
- this.player.absMoveTo(d0, d1, d2, f, f1);
+ this.player.moveTo(d0, d1, d2, f, f1); // Paper - use proper moveTo for teleportation
+ this.player.moveTo(d0, d1, d2, f, f1); // Paper - Fix Entity Teleportation and cancel velocity if teleported
this.player.connection.send(new ClientboundPlayerPositionPacket(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport));
}
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
+ public boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation
+ public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation
static boolean isLevelAtLeast(CompoundTag tag, int level) {
return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
}
@ -46,13 +46,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public void moveTo(double x, double y, double z, float yaw, float pitch) {
+ // Paper - cancel entity velocity if teleported
+ // Paper - Fix Entity Teleportation and cancel velocity if teleported
+ if (!preserveMotion) {
+ this.deltaMovement = Vec3.ZERO;
+ } else {
+ this.preserveMotion = false;
+ }
+ // Paper end
+ // Paper end - Fix Entity Teleportation and cancel velocity if teleported
this.setPosRaw(x, y, z);
this.setYRot(yaw);
this.setXRot(pitch);
@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return;
}
+ entity.preserveMotion = true; // Paper - preserve entity motion from tag
+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F);
if (entity instanceof Mob) {
Mob entityinsentient = (Mob) entity;

View file

@ -1,9 +1,9 @@
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
Subject: [PATCH] Fix bell block entity 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.
BellBlockEntity 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
@ -13,11 +13,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (blockEntity.ticks >= 50) {
blockEntity.shaking = false;
+ // Paper start
+ // Paper start - Fix bell block entity memory leak
+ if (!blockEntity.resonating) {
+ blockEntity.nearbyEntities.clear();
+ }
+ // Paper end
+ // Paper end - Fix bell block entity memory leak
blockEntity.ticks = 0;
}
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
++blockEntity.resonationTicks;
} else {
bellEffect.run(world, pos, blockEntity.nearbyEntities);
+ blockEntity.nearbyEntities.clear(); // Paper
+ blockEntity.nearbyEntities.clear(); // Paper - Fix bell block entity memory leak
blockEntity.resonating = false;
}
}
@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
}
+ this.nearbyEntities.removeIf(e -> !e.isAlive()); // Paper
+ this.nearbyEntities.removeIf(e -> !e.isAlive()); // Paper - Fix bell block entity memory leak
}
private static boolean areRaidersNearby(BlockPos pos, List<LivingEntity> hearingEntities) {

View file

@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- MinecraftServer.getServer().getPlayerList().reloadResources();
+ // Paper start
+ // Paper start - Fix client lag on advancement loading
+ //MinecraftServer.getServer().getPlayerList().reload();
+ MinecraftServer.getServer().getPlayerList().getPlayers().forEach(player -> {
+ player.getAdvancements().reload(MinecraftServer.getServer().getAdvancements());
+ player.getAdvancements().flushDirty(player);
+ });
+ // Paper end
+ // Paper end - Fix client lag on advancement loading
return bukkit;
}

View file

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 27 Dec 2020 11:31:06 +0000
Subject: [PATCH] Do not crash from invalid ingredient lists in
Subject: [PATCH] Fix crash from invalid ingredient lists in
VillagerAcquireTradeEvent
@ -14,11 +14,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
if (!event.isCancelled()) {
- recipeList.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft());
+ // Paper start
+ // Paper start - Fix crash from invalid ingredient list
+ final CraftMerchantRecipe craftMerchantRecipe = CraftMerchantRecipe.fromBukkit(event.getRecipe());
+ if (craftMerchantRecipe.getIngredients().isEmpty()) return;
+ recipeList.add(craftMerchantRecipe.toMinecraft());
+ // Paper end
+ // Paper end - Fix crash from invalid ingredient list
}
// CraftBukkit end
++j;

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.isEnforceWhitelist()) {
PlayerList playerlist = source.getServer().getPlayerList();
UserWhiteList whitelist = playerlist.getWhiteList();
+ if (!((DedicatedServer)getServer()).getProperties().whiteList.get()) return; // Paper - white list not enabled
+ if (!((DedicatedServer) getServer()).getProperties().whiteList.get()) return; // Paper - whitelist not enabled
List<ServerPlayer> list = Lists.newArrayList(playerlist.getPlayers());
Iterator iterator = list.iterator();

View file

@ -32,9 +32,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ double currDeltaY = toY - fromY;
+ double currDeltaZ = toZ - fromZ;
+ double d10 = Math.max(d6 * d6 + d7 * d7 + d8 * d8, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1);
+ // Paper end - fix large move vectors killing the server
+
+ // Paper start - fix large move vectors killing the server
+ double otherFieldX = d3 - this.vehicleLastGoodX;
+ double otherFieldY = d4 - this.vehicleLastGoodY - 1.0E-6D;
+ double otherFieldZ = d5 - this.vehicleLastGoodZ;
@ -66,8 +63,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ double currDeltaY = toY - prevY;
+ double currDeltaZ = toZ - prevZ;
+ double d10 = Math.max(d6 * d6 + d7 * d7 + d8 * d8, (currDeltaX * currDeltaX + currDeltaY * currDeltaY + currDeltaZ * currDeltaZ) - 1);
+ // Paper end - fix large move vectors killing the server
+ // Paper start - fix large move vectors killing the server
+ double otherFieldX = d0 - this.lastGoodX;
+ double otherFieldY = d1 - this.lastGoodY;
+ double otherFieldZ = d2 - this.lastGoodZ;

View file

@ -36,14 +36,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (MobEffectInstance mobeffect : instantLater) {
+ mobeffect.getEffect().applyInstantenousEffect(entityhuman, entityhuman, user, mobeffect.getAmplifier(), 1.0D);
+ }
+ // Paper end
+ // Paper end - Fix harming potion dupe
if (entityhuman == null || !entityhuman.getAbilities().instabuild) {
+ // Paper start - Fix harming potion dupe
+ if (user.getHealth() <= 0 && !user.level().getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_KEEPINVENTORY)) {
+ user.spawnAtLocation(new ItemStack(Items.GLASS_BOTTLE), 0);
+ return ItemStack.EMPTY;
+ }
+ // Paper end
+ // Paper end - Fix harming potion dupe
if (stack.isEmpty()) {
return new ItemStack(Items.GLASS_BOTTLE);
}

View file

@ -15,14 +15,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
itemstack1 = CraftItemStack.asNMSCopy(result);
// CraftBukkit end
- Containers.dropItemStack(world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), itemstack1);
+ // Paper start
+ // Paper start - Fix item locations dropped from campfires
+ double deviation = 0.05F * RandomSource.GAUSSIAN_SPREAD_FACTOR;
+ while (!itemstack1.isEmpty()) {
+ 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.triangle(0.0D, deviation), world.random.triangle(0.2D, deviation), world.random.triangle(0.0D, deviation));
+ world.addFreshEntity(droppedItem);
+ }
+ // Paper end
+ // Paper end - Fix item locations dropped from campfires
campfire.items.set(i, ItemStack.EMPTY);
world.sendBlockUpdated(pos, state, state, 3);
world.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));

View file

@ -111,12 +111,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerLevel worldserver = entityplayer.serverLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);
@@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
}
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & quit reason
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), leaveMessage, entityplayer.quitReason); // Paper - Adventure & quit reason
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());

View file

@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard {
final Scoreboard board;
+ boolean registeredGlobally = false; // Paper
+ boolean registeredGlobally = false; // Paper - Lazily track plugin scoreboards by default
CraftScoreboard(Scoreboard board) {
this.board = board;
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ net.minecraft.server.MinecraftServer.getServer().server.getScoreboardManager().registerScoreboardForVanilla(this);
+ this.registeredGlobally = true;
+ }
+ // Paper end
+ // Paper end - lazily track plugin scoreboards
net.minecraft.world.scores.Objective objective = this.board.addObjective(name, ((CraftCriteria) criteria).criteria, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName), CraftScoreboardTranslations.fromBukkitRender(renderType), true, null);
return new CraftObjective(this, objective);
}

View file

@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
+ if (recipeSpamPackets.get() > 0) recipeSpamPackets.getAndDecrement(); // Paper
+ if (recipeSpamPackets.get() > 0) recipeSpamPackets.getAndDecrement(); // Paper - auto recipe limit
/* Use thread-safe field access instead
if (this.chatSpamTickCount > 0) {
--this.chatSpamTickCount;
@ -28,14 +28,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) {
+ // Paper start
+ // Paper start - auto recipe limit
+ if (!org.bukkit.Bukkit.isPrimaryThread()) {
+ if (this.recipeSpamPackets.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.recipeSpamLimit) {
+ this.server.scheduleOnMain(() -> this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam", new Object[0]))); // Paper
+ return;
+ }
+ }
+ // Paper end
+ // Paper end - auto recipe limit
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
this.player.resetLastActionTime();
if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.getContainerId() && this.player.containerMenu instanceof RecipeBookMenu) {

View file

@ -17,13 +17,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@VisibleForTesting
static long encode(double value) {
- return Math.round(value * 4096.0D);
+ return Math.round(value * 4096.0D); // Paper - diff on change
+ return Math.round(value * 4096.0D); // Paper - Fix MC-4; diff on change
}
@VisibleForTesting
static double decode(long value) {
- return (double)value / 4096.0D;
+ return (double)value / 4096.0D; // Paper - diff on change
+ return (double)value / 4096.0D; // Paper - Fix MC-4; diff on change
}
public Vec3 decode(long x, long y, long z) {
@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return;
}
// Paper end - rewrite chunk system
+ // Paper start - fix MC-4
+ // Paper start - Fix MC-4
+ if (this instanceof ItemEntity) {
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.fixEntityPositionDesync) {
+ // encode/decode from ClientboundMoveEntityPacket
@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ z = Mth.lfloor(z * 4096.0D) * (1 / 4096.0D);
+ }
+ }
+ // Paper end - fix MC-4
+ // Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {
this.position = new Vec3(x, y, z);
int i = Mth.floor(x);

View file

@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@SuppressWarnings("unused")
public class Dynamic<T> extends DynamicLike<T> {
+ private static final boolean DEBUG_MISSING_KEYS = Boolean.getBoolean("Paper.debugDynamicMissingKeys"); // Paper
+ private static final boolean DEBUG_MISSING_KEYS = Boolean.getBoolean("Paper.debugDynamicMissingKeys"); // Paper - Perf: Skip toString on values like NBT
private final T value;
public Dynamic(final DynamicOps<T> ops) {
@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
final T value = m.get(key);
if (value == null) {
- return DataResult.error(() -> "key missing: " + key + " in " + this.value);
+ return DataResult.error(() -> DEBUG_MISSING_KEYS ? "key missing: " + key + " in " + this.value : "key missing: " + key); // Paper
+ return DataResult.error(() -> DEBUG_MISSING_KEYS ? "key missing: " + key + " in " + this.value : "key missing: " + key); // Paper - Perf: Skip toString on values like NBT
}
return DataResult.success(new Dynamic<>(ops, value));
}));

View file

@ -26,12 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- Map<Target, BlockPos> map = positions.stream().collect(Collectors.toMap((pos) -> {
- return this.nodeEvaluator.getGoal((double)pos.getX(), (double)pos.getY(), (double)pos.getZ());
- }, Function.identity()));
+ // Paper start - remove streams - and optimize collection
+ // Paper start - Perf: remove streams and optimize collection
+ List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
+ for (BlockPos pos : positions) {
+ map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getGoal(pos.getX(), pos.getY(), pos.getZ()), pos));
+ }
+ // Paper end
+ // Paper end - Perf: remove streams and optimize collection
Path path = this.findPath(world.getProfiler(), node, map, followRange, distance, rangeMultiplier);
this.nodeEvaluator.done();
return path;
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Nullable
- private Path findPath(ProfilerFiller profiler, Node startNode, Map<Target, BlockPos> positions, float followRange, int distance, float rangeMultiplier) {
+ // Paper start - optimize collection
+ // Paper start - Perf: remove streams and optimize collection - optimize collection
+ private Path findPath(ProfilerFiller profiler, Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) {
profiler.push("find_path");
profiler.markForCharting(MetricCategory.PATH_FINDING);
@ -73,12 +73,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
target.setReached();
- set3.add(target);
+ entryList.add(entry);
+ // Paper end
+ // Paper end - Perf: remove streams and optimize collection
}
}
- if (!set3.isEmpty()) {
+ if (!entryList.isEmpty()) { // Paper - rename variable
+ if (!entryList.isEmpty()) { // Paper - Perf: remove streams and optimize collection; rename
break;
}
@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
node2.cameFrom = node;
node2.g = g;
- node2.h = this.getBestH(node2, set) * 1.5F;
+ node2.h = this.getBestH(node2, positions) * 1.5F; // Paper - list instead of set
+ node2.h = this.getBestH(node2, positions) * 1.5F; // Paper - Perf: remove streams and optimize collection
if (node2.inOpenSet()) {
this.openSet.changeCost(node2, node2.g + node2.h);
} else {
@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- }).min(Comparator.comparingDouble(Path::getDistToTarget).thenComparingInt(Path::getNodeCount));
- profiler.pop();
- return optional.isEmpty() ? null : optional.get();
+ // Paper start - remove streams - and optimize collection
+ // Paper start - Perf: remove streams and optimize collection
+ Path best = null;
+ boolean entryListIsEmpty = entryList.isEmpty();
+ Comparator<Path> comparator = entryListIsEmpty ? Comparator.comparingInt(Path::getNodeCount)
@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ best = path;
+ }
+ return best;
+ // Paper end
+ // Paper end - Perf: remove streams and optimize collection
}
protected float distance(Node a, Node b) {
@ -121,14 +121,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- private float getBestH(Node node, Set<Target> targets) {
+ private float getBestH(Node node, List<Map.Entry<Target, BlockPos>> targets) { // Paper - optimize collection - Set<Target> -> List<Map.Entry<Target, BlockPos>>
+ private float getBestH(Node node, List<Map.Entry<Target, BlockPos>> targets) { // Paper - Perf: remove streams and optimize collection; Set<Target> -> List<Map.Entry<Target, BlockPos>>
float f = Float.MAX_VALUE;
- for(Target target : targets) {
+ // Paper start - optimize collection
+ // Paper start - Perf: remove streams and optimize collection
+ for (int i = 0, targetsSize = targets.size(); i < targetsSize; i++) {
+ final Target target = targets.get(i).getKey();
+ // Paper end
+ // Paper end - Perf: remove streams and optimize collection
float g = node.distanceTo(target);
target.updateBest(g, node);
f = Math.min(g, f);

View file

@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- 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, Name
double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - custom beacon ranges
double d0 = blockEntity != null ? blockEntity.getEffectRange() : (i * 10 + 10);// Paper - Custom beacon ranges
AABB axisalignedbb = (new AABB(blockposition)).inflate(d0).expandTowards(0.0D, (double) world.getHeight(), 0.0D);
- List<Player> list = world.getEntitiesOfClass(Player.class, axisalignedbb);

View file

@ -12,11 +12,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static void dropChunkStatic(ServerPlayer player, ChunkPos pos) {
player.serverLevel().chunkSource.chunkMap.getVisibleChunkIfPresent(pos.toLong()).removePlayer(player);
player.connection.send(new ClientboundForgetLevelChunkPacket(pos));
+ // Paper start
+ // Paper start - PlayerChunkUnloadEvent
+ if (io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0) {
+ new io.papermc.paper.event.packet.PlayerChunkUnloadEvent(player.getBukkitEntity().getWorld().getChunkAt(pos.longKey), player.getBukkitEntity()).callEvent();
+ }
+ // Paper end
+ // Paper end - PlayerChunkUnloadEvent
}
// Paper end - rewrite player chunk loader

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- if (world.getFluidState(pos).is(FluidTags.WATER)) {
+ if (blockState.getFluidState().is(FluidTags.WATER)) {
+ if (blockState.getFluidState().is(FluidTags.WATER)) { // Paper - Perf: Reduce blockpos allocation from pathfinding
return BlockPathTypes.WATER_BORDER;
}
@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return BlockPathTypes.COCOA;
} else if (!blockState.is(Blocks.WITHER_ROSE) && !blockState.is(Blocks.POINTED_DRIPSTONE)) {
- FluidState fluidState = world.getFluidState(pos);
+ FluidState fluidState = blockState.getFluidState(); // Paper - remove another getFluidState call
+ FluidState fluidState = blockState.getFluidState(); // Paper - Perf: Reduce blockpos allocation from pathfinding
if (fluidState.is(FluidTags.LAVA)) {
return BlockPathTypes.LAVA;
} else if (isBurningBlock(blockState)) {

View file

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entityenderdragon.moveTo((double) this.origin.getX(), (double) (128 + this.origin.getY()), (double) this.origin.getZ(), this.level.random.nextFloat() * 360.0F, 0.0F);
this.level.addFreshEntity(entityenderdragon);
this.dragonUUID = entityenderdragon.getUUID();
+ this.resetSpikeCrystals(); // Paper
+ this.resetSpikeCrystals(); // Paper - Reset ender crystals on dragon spawn
}
return entityenderdragon;

View file

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean captureTreeGeneration = false;
public Map<BlockPos, org.bukkit.craftbukkit.block.CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
- public Map<BlockPos, BlockEntity> capturedTileEntities = new HashMap<>();
+ public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper
+ public Map<BlockPos, BlockEntity> capturedTileEntities = new java.util.LinkedHashMap<>(); // Paper - Retain block place order when capturing blockstates
public List<ItemEntity> captureDrops;
public final it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<SpawnCategory> ticksPerSpawnCategory = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
// Paper start

View file

@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public static final KeyDispatchDataCodec<DensityFunctions.EndIslandDensityFunction> CODEC = KeyDispatchDataCodec.of(MapCodec.unit(new DensityFunctions.EndIslandDensityFunction(0L)));
private static final float ISLAND_THRESHOLD = -0.9F;
private final SimplexNoise islandNoise;
+ // Paper start
+ // Paper start - Perf: Optimize end generation
+ private static final class NoiseCache {
+ public long[] keys = new long[8192];
+ public float[] values = new float[8192];
@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ private static final ThreadLocal<java.util.Map<SimplexNoise, NoiseCache>> noiseCache = ThreadLocal.withInitial(java.util.WeakHashMap::new);
+ // Paper end
+ // Paper end - Perf: Optimize end generation
public EndIslandDensityFunction(long seed) {
RandomSource randomSource = new LegacyRandomSource(seed);
@ -36,14 +36,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
float f = 100.0F - Mth.sqrt((long) x * (long) x + (long) z * (long) z) * 8.0F; // Paper - cast ints to long to avoid integer overflow
f = Mth.clamp(f, -100.0F, 80.0F);
+ NoiseCache cache = noiseCache.get().computeIfAbsent(sampler, noiseKey -> new NoiseCache()); // Paper
+ NoiseCache cache = noiseCache.get().computeIfAbsent(sampler, noiseKey -> new NoiseCache()); // Paper - Perf: Optimize end generation
for(int m = -12; m <= 12; ++m) {
for(int n = -12; n <= 12; ++n) {
long o = (long)(i + m);
long p = (long)(j + n);
- if (o * o + p * p > 4096L && sampler.getValue((double)o, (double)p) < (double)-0.9F) {
- float g = (Mth.abs((float)o) * 3439.0F + Mth.abs((float)p) * 147.0F) % 13.0F + 9.0F;
+ // Paper start - Significantly improve end generation performance by using a noise cache
+ // Paper start - Perf: Optimize end generation by using a noise cache
+ long key = net.minecraft.world.level.ChunkPos.asLong((int) o, (int) p);
+ int index = (int) it.unimi.dsi.fastutil.HashCommon.mix(key) & 8191;
+ float g = Float.MIN_VALUE;
@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ cache.values[index] = g;
+ }
+ if (g != Float.MIN_VALUE) {
+ // Paper end
+ // Paper end - Perf: Optimize end generation
float h = (float)(k - m * 2);
float q = (float)(l - n * 2);
float r = 100.0F - Mth.sqrt(h * h + q * q) * g;

View file

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
EndDragonFight.LOGGER.info("Found that there's a dragon still alive ({})", entityenderdragon);
this.dragonKilled = false;
- if (!flag) {
+ if (!flag && this.level.paperConfig().entities.behavior.shouldRemoveDragon) {
+ if (!flag && this.level.paperConfig().entities.behavior.shouldRemoveDragon) { // Paper - Toggle for removing existing dragon
EndDragonFight.LOGGER.info("But we didn't have a portal, let's remove it.");
entityenderdragon.discard();
this.dragonUUID = null;

View file

@ -12,12 +12,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.tradingPlayer != null;
}
+ // Paper start
+ // Paper start - Villager#resetOffers
+ public void resetOffers() {
+ this.offers = new MerchantOffers();
+ this.updateTrades();
+ }
+ // Paper end
+ // Paper end - Villager#resetOffers
+
@Override
public MerchantOffers getOffers() {
@ -31,10 +31,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.getMerchant().getTrader();
}
+
+ // Paper start
+ // Paper start - Villager#resetOffers
+ @Override
+ public void resetOffers() {
+ getHandle().resetOffers();
+ }
+ // Paper end
+ // Paper end - Villager#resetOffers
}