Work work work work

This commit is contained in:
Bjarne Koll 2024-10-23 20:50:46 +02:00
parent 0bb4d1d660
commit 4db250389e
No known key found for this signature in database
GPG key ID: 27F6CCCF55D2EE62
22 changed files with 229 additions and 239 deletions

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Mon, 28 Jun 2021 18:16:52 -0700
Subject: [PATCH] Fix return value of Block#applyBoneMeal always being false
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 54fb380a6896731a18c0100722d12099e590cbc9..9c8aac69f01db647e20d49d272ccc107a7edceaf 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -558,7 +558,7 @@ public class CraftBlock implements Block {
}
}
- return result == InteractionResult.SUCCESS && (event == null || !event.isCancelled());
+ return result == InteractionResult.CONSUME && (event == null || !event.isCancelled()); // Paper - CONSUME is returned on success server-side (see BoneMealItem.applyBoneMeal and InteractionResult.sidedSuccess(boolean))
}
@Override

View file

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 8 Jul 2019 00:13:36 -0700
Subject: [PATCH] Use getChunkIfLoadedImmediately in places
This prevents us from hitting chunk loads for chunks at or less-than
ticket level 33 (yes getChunkIfLoaded will actually perform a chunk
load in that case).
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 355b60f8d0d600973da673db5a954345f3a0094d..83f3f05ffe61d77417bce50ce7ae6a8671605e9e 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -234,7 +234,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
public LevelChunk getChunkIfLoaded(int x, int z) {
- return this.chunkSource.getChunk(x, z, false);
+ return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index aff89d2e3274b91238989fc1e7d8c119c2a3c097..560777a99b58c4f82cc0e8fb087de04a564163b5 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -180,6 +180,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public CraftServer getCraftServer() {
return (CraftServer) Bukkit.getServer();
}
+ // Paper start - Use getChunkIfLoadedImmediately
+ @Override
+ public boolean hasChunk(int chunkX, int chunkZ) {
+ return this.getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+ // Paper end - Use getChunkIfLoadedImmediately
+
public abstract ResourceKey<LevelStem> getTypeKey();
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index 13b34e89bd3e55df1bb1d4d0cf013bafae43f502..df6c97be1b278c97a20390be5d3e60f429383702 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
@@ -56,7 +56,7 @@ public class GameEventDispatcher {
for (int l1 = j; l1 <= i1; ++l1) {
for (int i2 = l; i2 <= k1; ++i2) {
- LevelChunk chunk = this.level.getChunkSource().getChunkNow(l1, i2);
+ LevelChunk chunk = (LevelChunk) this.level.getChunkIfLoadedImmediately(l1, i2); // Paper - Use getChunkIfLoadedImmediately
if (chunk != null) {
for (int j2 = k; j2 <= j1; ++j2) {

View file

@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 9 Jul 2021 13:50:48 -0700
Subject: [PATCH] Fix commands from signs not firing command events
This patch changes sign command logic so that `run_command` click events:
- are logged to the console
- fire PlayerCommandPreprocessEvent
- work with double-slash commands like `//wand`
- sends failure messages to the player who clicked the sign
diff --git a/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
new file mode 100644
index 0000000000000000000000000000000000000000..01a2bc1feec808790bb93618ce46adb9bea5a9c8
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
@@ -0,0 +1,42 @@
+package io.papermc.paper.commands;
+
+import net.minecraft.commands.CommandSource;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.network.chat.Component;
+import org.bukkit.command.CommandSender;
+
+import java.util.UUID;
+
+public class DelegatingCommandSource implements CommandSource {
+
+ private final CommandSource delegate;
+
+ public DelegatingCommandSource(CommandSource delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void sendSystemMessage(Component message) {
+ delegate.sendSystemMessage(message);
+ }
+
+ @Override
+ public boolean acceptsSuccess() {
+ return delegate.acceptsSuccess();
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return delegate.acceptsFailure();
+ }
+
+ @Override
+ public boolean shouldInformAdmins() {
+ return delegate.shouldInformAdmins();
+ }
+
+ @Override
+ public CommandSender getBukkitSender(CommandSourceStack wrapper) {
+ return delegate.getBukkitSender(wrapper);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
index 3339130f3a02e6e395bcd8e3047b35f6f4eca9a9..a34c2fc6ac1418a89d789b8945ca3dad57f64151 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -274,7 +274,17 @@ public class SignBlockEntity extends BlockEntity {
ClickEvent chatclickable = chatmodifier.getClickEvent();
if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
- player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(player, world, pos), chatclickable.getValue());
+ // Paper start - Fix commands from signs not firing command events
+ String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent((org.bukkit.entity.Player) player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) CraftBlock.at(this.level, this.worldPosition).getState(), front ? Side.FRONT : Side.BACK);
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), world, pos), event.getMessage());
+ // Paper end - Fix commands from signs not firing command events
flag1 = true;
}
}
@@ -314,8 +324,23 @@ public class SignBlockEntity extends BlockEntity {
String s = player == null ? "Sign" : player.getName().getString();
Object object = player == null ? Component.literal("Sign") : player.getDisplayName();
- // CraftBukkit - commandSource
- return new CommandSourceStack(this.commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player);
+ // Paper start - Fix commands from signs not firing command events
+ CommandSource commandSource = this.level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) {
+ @Override
+ public void sendSystemMessage(Component message) {
+ if (player instanceof final ServerPlayer serverPlayer) {
+ serverPlayer.sendSystemMessage(message);
+ }
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return true;
+ }
+ } : this.commandSource;
+ // Paper end - Fix commands from signs not firing command events
+ // CraftBukkit - this
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel) world, 2, s, (Component) object, world.getServer(), player); // Paper - Fix commands from signs not firing command events
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index d113e54a30db16e2ad955170df6030d15de530d6..21b6f90cf5bd7087d1a0f512289d971f2c3e1afa 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -61,7 +61,7 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
CommandSender sender = context.getSource().getBukkitSender();
try {
- return this.server.dispatchCommand(sender, context.getInput()) ? 1 : 0;
+ return this.server.dispatchCommand(sender, context.getRange().get(context.getInput())) ? 1 : 0; // Paper - Fix commands from signs not firing command events; actually use the StringRange from context
} catch (CommandException ex) {
sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
this.server.getLogger().log(Level.SEVERE, null, ex);

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 12 Mar 2021 19:22:21 -0800
Subject: [PATCH] Add PlayerArmSwingEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index f4d92374f7865a39a0442d79eb5f146ed4bd2b52..c8ab002ddfcea910f916ee503e930085f6c5cb5a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2423,7 +2423,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
} // Paper end - Call interact event
// Arm swing animation
- PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packet.getHand() == InteractionHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
+ io.papermc.paper.event.player.PlayerArmSwingEvent event = new io.papermc.paper.event.player.PlayerArmSwingEvent(this.getCraftPlayer(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(packet.getHand())); // Paper - Add PlayerArmSwingEvent
this.cserver.getPluginManager().callEvent(event);
if (event.isCancelled()) return;

View file

@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:19:41 -0700
Subject: [PATCH] Fix kick event leave message not being sent
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 7bcb3ef3cb498114428782848e0370ac2497ccdc..99a634760cd04d5e3182254b1d0b817baf1cf87a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -318,7 +318,6 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
public boolean joining = true;
public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
- public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
public boolean isRealPlayer; // Paper
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 59d20fd62e850a38380d877cef95ed69cb46ecbd..fc242acade3ff06c9213428cde103cf078216382 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -116,6 +116,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@Override
public void onDisconnect(DisconnectionDetails info) {
+ // Paper start - Fix kick event leave message not being sent
+ this.onDisconnect(info, null);
+ }
+ public void onDisconnect(DisconnectionDetails info, @Nullable net.kyori.adventure.text.Component quitMessage) {
+ // Paper end - Fix kick event leave message not being sent
if (this.isSingleplayerOwner()) {
ServerCommonPacketListenerImpl.LOGGER.info("Stopping singleplayer server as player logged out");
this.server.halt(false);
@@ -386,18 +391,17 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
// Do not kick the player
return;
}
- this.player.kickLeaveMessage = event.getLeaveMessage(); // CraftBukkit - SPIGOT-3034: Forward leave message to PlayerQuitEvent
// Send the possibly modified leave message
- this.disconnect0(new DisconnectionDetails(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()), disconnectionInfo.report(), disconnectionInfo.bugReportLink())); // Paper - Adventure
+ this.disconnect0(new DisconnectionDetails(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()), disconnectionInfo.report(), disconnectionInfo.bugReportLink()), event.leaveMessage()); // Paper - Adventure & use kick event leave message
}
- private void disconnect0(DisconnectionDetails disconnectiondetails) {
+ private void disconnect0(DisconnectionDetails disconnectiondetails, @Nullable net.kyori.adventure.text.Component leaveMessage) { // Paper - use kick event leave message
// CraftBukkit end
this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper - Add API for quit reason
this.connection.send(new ClientboundDisconnectPacket(disconnectiondetails.reason()), PacketSendListener.thenRun(() -> {
this.connection.disconnect(disconnectiondetails);
}));
- this.onDisconnect(disconnectiondetails); // CraftBukkit - fire quit instantly
+ this.onDisconnect(disconnectiondetails, leaveMessage); // CraftBukkit - fire quit instantly // Paper - use kick event leave message
this.connection.setReadOnly();
MinecraftServer minecraftserver = this.server;
Connection networkmanager = this.connection;
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index c8ab002ddfcea910f916ee503e930085f6c5cb5a..e9e5b35cd09fe50ce4f2116ca5c38137408105bf 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1907,6 +1907,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void onDisconnect(DisconnectionDetails info) {
+ // Paper start - Fix kick event leave message not being sent
+ this.onDisconnect(info, null);
+ }
+ @Override
+ public void onDisconnect(DisconnectionDetails info, @Nullable net.kyori.adventure.text.Component quitMessage) {
+ // Paper end - Fix kick event leave message not being sent
// CraftBukkit start - Rarely it would send a disconnect line twice
if (this.processedDisconnect) {
return;
@@ -1915,11 +1921,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// CraftBukkit end
ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString());
- this.removePlayerFromWorld();
- super.onDisconnect(info);
+ this.removePlayerFromWorld(quitMessage); // Paper - Fix kick event leave message not being sent
+ super.onDisconnect(info, quitMessage); // Paper - Fix kick event leave message not being sent
}
+ // Paper start - Fix kick event leave message not being sent
private void removePlayerFromWorld() {
+ this.removePlayerFromWorld(null);
+ }
+
+ private void removePlayerFromWorld(@Nullable net.kyori.adventure.text.Component quitMessage) {
+ // Paper end - Fix kick event leave message not being sent
this.chatMessageChain.close();
// CraftBukkit start - Replace vanilla quit message handling with our own.
/*
@@ -1929,7 +1941,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player.disconnect();
// Paper start - Adventure
- net.kyori.adventure.text.Component quitMessage = this.server.getPlayerList().remove(this.player);
+ quitMessage = quitMessage == null ? this.server.getPlayerList().remove(this.player) : this.server.getPlayerList().remove(this.player, quitMessage); // Paper - pass in quitMessage to fix kick message not being used
if ((quitMessage != null) && !quitMessage.equals(net.kyori.adventure.text.Component.empty())) {
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false);
// Paper end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 3ec8d38ca514048d94d24424d2132a90c10f529f..55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -511,6 +511,11 @@ public abstract class PlayerList {
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component
+ // Paper start - Fix kick event leave message not being sent
+ return this.remove(entityplayer, 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())));
+ }
+ public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
+ // Paper end - Fix kick event leave message not being sent
ServerLevel worldserver = entityplayer.serverLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Sun, 20 Jun 2021 16:35:42 +0100
Subject: [PATCH] Don't apply cramming damage to players
It does not make a lot of sense to damage players if they get crammed,
especially as the usecase of teleporting lots of players to the same
location isn't too uncommon and killing all those players isn't
really what one would expect to happen.
For those who really want it a config option is provided.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 99a634760cd04d5e3182254b1d0b817baf1cf87a..94cc69ed1ccbcfcc8f431762fef641c313b2f634 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1814,7 +1814,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
@Override
public boolean isInvulnerableTo(ServerLevel world, DamageSource source) {
- return super.isInvulnerableTo(world, source) || this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL);
+ return super.isInvulnerableTo(world, source) || (this.isChangingDimension() && !source.is(DamageTypes.ENDER_PEARL)) || (!this.level().paperConfig().collisions.allowPlayerCrammingDamage && source.is(DamageTypes.CRAMMING)); // Paper - disable player cramming;
}
@Override

View file

@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Mon, 28 Jun 2021 22:38:29 +0100
Subject: [PATCH] Rate options and timings for sensors and behaviors
This adds config options to specify the tick rate for sensors
and behaviors of different entity types as well as timings
for those in order to be able to have some metrics as to which
ones might need tweaking.
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
index 4bd813161a5d76a83cdbd0a9209b9ea9e60ffe1b..e2764186bd6b838ed5cd86c15597a08d079ef984 100644
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -115,6 +115,14 @@ public final class MinecraftTimings {
return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
}
+ public static Timing getBehaviorTimings(String type) {
+ return Timings.ofSafe("## Behavior - " + type);
+ }
+
+ public static Timing getSensorTimings(String type, int rate) {
+ return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")");
+ }
+
/**
* Get a named timer for the specified tile entity type to track type specific timings.
* @param entity
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
index f639cafa64d98a001e622882c647701547f5c3ac..9379dd4056018b52c93ed4888dcdc94579bd9691 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
@@ -14,6 +14,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
private long endTimestamp;
private final int minDuration;
private final int maxDuration;
+ // Paper start - configurable behavior tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end - configurable behavior tick rate and timings
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) {
this(requiredMemoryState, 60);
@@ -27,6 +31,15 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
this.minDuration = minRunTime;
this.maxDuration = maxRunTime;
this.entryCondition = requiredMemoryState;
+ // Paper start - configurable behavior tick rate and timings
+ String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
+ // Paper end - configurable behavior tick rate and timings
}
@Override
@@ -36,11 +49,19 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final boolean tryStart(ServerLevel world, E entity, long time) {
+ // Paper start - configurable behavior tick rate and timings
+ int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1);
+ if (tickRate > -1 && time < this.endTimestamp + tickRate) {
+ return false;
+ }
+ // Paper end - configurable behavior tick rate and timings
if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) {
this.status = Behavior.Status.RUNNING;
int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
this.endTimestamp = time + (long)i;
+ this.timing.startTiming(); // Paper - behavior timings
this.start(world, entity, time);
+ this.timing.stopTiming(); // Paper - behavior timings
return true;
} else {
return false;
@@ -52,11 +73,13 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final void tickOrStop(ServerLevel world, E entity, long time) {
+ this.timing.startTiming(); // Paper - behavior timings
if (!this.timedOut(time) && this.canStillUse(world, entity, time)) {
this.tick(world, entity, time);
} else {
this.doStop(world, entity, time);
}
+ this.timing.stopTiming(); // Paper - behavior timings
}
protected void tick(ServerLevel world, E entity, long time) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
index 4d451f6cb5862411848bb9b6b5692ab512dcaa25..8bc7979fb9c2a796921a2a279b78294809f2ed03 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
@@ -29,8 +29,21 @@ public abstract class Sensor<E extends LivingEntity> {
.ignoreInvisibilityTesting();
private final int scanRate;
private long timeToTick;
+ // Paper start - configurable sensor tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end
public Sensor(int senseInterval) {
+ // Paper start - configurable sensor tick rate and timings
+ String key = io.papermc.paper.util.MappingEnvironment.reobf() ? io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()) : this.getClass().getName();
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval);
+ // Paper end
this.scanRate = senseInterval;
this.timeToTick = (long)RANDOM.nextInt(senseInterval);
}
@@ -41,9 +54,13 @@ public abstract class Sensor<E extends LivingEntity> {
public final void tick(ServerLevel world, E entity) {
if (--this.timeToTick <= 0L) {
- this.timeToTick = (long)this.scanRate;
+ // Paper start - configurable sensor tick rate and timings
+ this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate);
+ this.timing.startTiming();
this.updateTargetingConditionRanges(entity);
+ // Paper end
this.doTick(world, entity);
+ this.timing.stopTiming(); // Paper - sensor timings
}
}

View file

@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 20 Jul 2021 21:25:35 -0700
Subject: [PATCH] Add missing forceDrop toggles
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
index 4ec1f881c05d96d72814ac3dffd3b4bef40c1bce..c34cb8c918e400636856317cc58356d2677e1d52 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
@@ -86,7 +86,9 @@ public class WorkAtComposter extends WorkAtPoi {
simpleContainer.removeItemType(Items.WHEAT, m);
ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l));
if (!itemStack.isEmpty()) {
+ villager.forceDrops = true; // Paper - Add missing forceDrop toggles
villager.spawnAtLocation(world, itemStack, 0.5F);
+ villager.forceDrops = false; // Paper - Add missing forceDrop toggles
}
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
index 705c26ceff9371b09311bd7fa796c0efde7ebfee..4f04170b3ec4ff59358e10ccfd0799af3ab590c3 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
@@ -540,7 +540,9 @@ public class Panda extends Animal {
if (world1 instanceof ServerLevel worldserver) {
if (worldserver.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
this.dropFromGiftLootTable(worldserver, BuiltInLootTables.PANDA_SNEEZE, this::spawnAtLocation);
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
}
}
@@ -664,7 +666,9 @@ public class Panda extends Animal {
ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack1.isEmpty() && !player.hasInfiniteMaterials()) {
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
this.spawnAtLocation(worldserver, itemstack1);
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
}
this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1));
@@ -942,7 +946,9 @@ public class Panda extends Animal {
ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack.isEmpty()) {
+ Panda.this.forceDrops = true; // Paper - Add missing forceDrop toggles
Panda.this.spawnAtLocation(getServerLevel(Panda.this.level()), itemstack);
+ Panda.this.forceDrops = false; // Paper - Add missing forceDrop toggles
Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10;
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
index ec733e71e41a4c89ed9f35ad1d9d4fa912160d27..15a49e3541c8b45db5e472a64fa0cb94c5a72f67 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -323,9 +323,11 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
protected void finishConversion(ServerLevel world) {
PiglinAi.cancelAdmiring(world, this);
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
this.inventory.removeAllItems().forEach((itemstack) -> {
this.spawnAtLocation(world, itemstack);
});
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
super.finishConversion(world);
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index 42b1bd58c6e2c3bd1170171eabfefe315202f340..55868c82bf8bd61ce3494aa9f363c20c88ec6aa6 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -273,7 +273,9 @@ public class PiglinAi {
private static void holdInOffhand(ServerLevel world, Piglin piglin, ItemStack stack) {
if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(world, piglin.getItemInHand(InteractionHand.OFF_HAND));
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
}
piglin.holdInOffHand(stack);
@@ -333,7 +335,9 @@ public class PiglinAi {
protected static void cancelAdmiring(ServerLevel world, Piglin piglin) {
if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+ piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
piglin.spawnAtLocation(world, piglin.getOffhandItem());
+ piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
}
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
index 4b9b961b1b910775788f85b13ee48abcc474daca..69a0a8aa7eec0a68a1460f6d6a4b604963b884c4 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
@@ -233,7 +233,9 @@ public abstract class Raider extends PatrollingMonster {
double d0 = (double) this.getEquipmentDropChance(enumitemslot);
if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) {
+ this.forceDrops = true; // Paper - Add missing forceDrop toggles
this.spawnAtLocation(world, itemstack1);
+ this.forceDrops = false; // Paper - Add missing forceDrop toggles
}
this.onItemPickup(itemEntity);

View file

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 22 Jun 2021 23:15:44 -0400
Subject: [PATCH] Stinger API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 00db6ba96bda7ceaae8bc69a6b3a42e7a3929485..9870222cc1c46bcc37f9d3d44881606f2b9d038e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -384,6 +384,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public boolean isInvulnerable() {
return this.getHandle().isInvulnerableTo((ServerLevel) this.getHandle().level(), this.getHandle().damageSources().generic());
}
+ // Paper start - Bee Stinger API
+ @Override
+ public int getBeeStingerCooldown() {
+ return getHandle().removeStingerTime;
+ }
+
+ @Override
+ public void setBeeStingerCooldown(int ticks) {
+ getHandle().removeStingerTime = ticks;
+ }
+
+ @Override
+ public int getBeeStingersInBody() {
+ return getHandle().getStingerCount();
+ }
+
+ @Override
+ public void setBeeStingersInBody(int count) {
+ Preconditions.checkArgument(count >= 0, "New bee stinger amount must be >= 0");
+ getHandle().setStingerCount(count);
+ }
+
+ @Override
+ public void setNextBeeStingerRemoval(final int ticks) {
+ Preconditions.checkArgument(ticks >= 0, "New amount of ticks before next bee stinger removal must be >= 0");
+ this.getHandle().removeStingerTime = ticks;
+ }
+
+ @Override
+ public int getNextBeeStingerRemoval() {
+ return this.getHandle().removeStingerTime;
+ }
+ // Paper end - Bee Stinger API
@Override
public void damage(double amount) {

View file

@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: underscore11code <minecrafter11mrt@gmail.com>
Date: Fri, 23 Jul 2021 23:01:42 -0700
Subject: [PATCH] Add System.out/err catcher
diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8e813ca89b033f061e695288b3383bdcf128531
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
@@ -0,0 +1,94 @@
+package io.papermc.paper.logging;
+
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+
+public final class SysoutCatcher {
+ private static final boolean SUPPRESS_NAGS = Boolean.getBoolean("io.papermc.paper.suppress.sout.nags");
+ // Nanoseconds between nag at most; if interval is caught first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_TIMEOUT = TimeUnit.MILLISECONDS.toNanos(
+ Long.getLong("io.papermc.paper.sout.nags.timeout", TimeUnit.MINUTES.toMillis(5L)));
+ // Count since last nag; if timeout is first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_INTERVAL = Long.getLong("io.papermc.paper.sout.nags.interval", 200L);
+
+ // We don't particularly care about how correct this is at any given moment; let's do it on a best attempt basis.
+ // The records are also pretty small, so let's just go for a size of 64 to start...
+ //
+ // Content: Plugin name => nag object
+ // Why plugin name?: This doesn't store a reference to the plugin; keeps the reload ability.
+ // Why not clean on reload?: Effort.
+ private final ConcurrentMap<String, PluginNag> nagRecords = new ConcurrentHashMap<>(64);
+
+ public SysoutCatcher() {
+ System.setOut(new WrappedOutStream(System.out, Level.INFO, "[STDOUT] "));
+ System.setErr(new WrappedOutStream(System.err, Level.SEVERE, "[STDERR] "));
+ }
+
+ private final class WrappedOutStream extends PrintStream {
+ private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ private final Level level;
+ private final String prefix;
+
+ public WrappedOutStream(@NotNull final OutputStream out, final Level level, final String prefix) {
+ super(out);
+ this.level = level;
+ this.prefix = prefix;
+ }
+
+ @Override
+ public void println(@Nullable final String line) {
+ final Class<?> clazz = STACK_WALKER.getCallerClass();
+ try {
+ final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(clazz);
+
+ // Instead of just printing the message, send it to the plugin's logger
+ plugin.getLogger().log(this.level, this.prefix + line);
+
+ if (SysoutCatcher.SUPPRESS_NAGS) {
+ return;
+ }
+ if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {
+ final PluginNag nagRecord = SysoutCatcher.this.nagRecords.computeIfAbsent(plugin.getName(), k -> new PluginNag());
+ final boolean hasTimePassed = SysoutCatcher.NAG_TIMEOUT > 0
+ && (nagRecord.lastNagTimestamp == Long.MIN_VALUE
+ || nagRecord.lastNagTimestamp + SysoutCatcher.NAG_TIMEOUT <= System.nanoTime());
+ final boolean hasMessagesPassed = SysoutCatcher.NAG_INTERVAL > 0
+ && (nagRecord.messagesSinceNag == Long.MIN_VALUE
+ || ++nagRecord.messagesSinceNag >= SysoutCatcher.NAG_INTERVAL);
+ if (!hasMessagesPassed && !hasTimePassed) {
+ return;
+ }
+ nagRecord.lastNagTimestamp = System.nanoTime();
+ nagRecord.messagesSinceNag = 0;
+ }
+ Bukkit.getLogger().warning(
+ String.format("Nag author(s): '%s' of '%s' about their usage of System.out/err.print. "
+ + "Please use your plugin's logger instead (JavaPlugin#getLogger).",
+ plugin.getPluginMeta().getAuthors(),
+ plugin.getPluginMeta().getDisplayName())
+ );
+ } catch (final IllegalArgumentException | IllegalStateException e) {
+ // If anything happens, the calling class doesn't exist, there is no JavaPlugin that "owns" the calling class, etc
+ // Just print out normally, with some added information
+ Bukkit.getLogger().log(this.level, String.format("%s[%s] %s", this.prefix, clazz.getName(), line));
+ }
+ }
+ }
+
+ private static class PluginNag {
+ private long lastNagTimestamp = Long.MIN_VALUE;
+ private long messagesSinceNag = Long.MIN_VALUE;
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index d921b15100b83cb7073d79f2a1b2bfbdc7b745ca..35e5a3dc58f93b85f93ec5301cc9b5c7505503bc 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -310,6 +310,7 @@ public final class CraftServer implements Server {
public Set<String> activeCompatibilities = Collections.emptySet();
private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
public static Exception excessiveVelEx; // Paper - Velocity warnings
+ private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Noah van der Aa <ndvdaa@gmail.com>
Date: Sat, 24 Jul 2021 16:54:11 +0200
Subject: [PATCH] Prevent AFK kick while watching end credits
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index e9e5b35cd09fe50ce4f2116ca5c38137408105bf..74b21852d9346708a62033c78fac04050b98c80b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -394,7 +394,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.tabSpamThrottler.tick(); // Paper - configurable tab spam limits
this.recipeSpamPackets.tick(); // Paper - auto recipe limit
this.dropSpamThrottler.tick();
- if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) {
+ if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}

View file

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Fri, 23 Jul 2021 02:32:04 +0200
Subject: [PATCH] Allow skipping writing of comments to server.properties
Makes less git noise, as it won't update the date every single time
Use -DPaper.skipServerPropertiesComments=true flag to disable writing it
diff --git a/src/main/java/net/minecraft/server/dedicated/Settings.java b/src/main/java/net/minecraft/server/dedicated/Settings.java
index 0ec3b546db0cf3858dd9cd9ea067d1d6713a8491..d7bd235ef2815890e038091dd625177049d253a5 100644
--- a/src/main/java/net/minecraft/server/dedicated/Settings.java
+++ b/src/main/java/net/minecraft/server/dedicated/Settings.java
@@ -29,6 +29,7 @@ public abstract class Settings<T extends Settings<T>> {
private static final Logger LOGGER = LogUtils.getLogger();
public final Properties properties;
+ private static final boolean skipComments = Boolean.getBoolean("Paper.skipServerPropertiesComments"); // Paper - allow skipping server.properties comments
// CraftBukkit start
private OptionSet options = null;
@@ -123,7 +124,46 @@ public abstract class Settings<T extends Settings<T>> {
return;
}
// CraftBukkit end
- BufferedWriter bufferedwriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
+ // Paper start - allow skipping server.properties comments
+ java.io.OutputStream outputstream = Files.newOutputStream(path);
+ java.io.BufferedOutputStream bufferedOutputStream = !skipComments ? new java.io.BufferedOutputStream(outputstream) : new java.io.BufferedOutputStream(outputstream) {
+ private boolean isRightAfterNewline = true; // If last written char was newline
+ private boolean isComment = false; // Are we writing comment currently?
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] b) throws IOException {
+ this.write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] bbuf, int off, int len) throws IOException {
+ int latest_offset = off; // The latest offset, updated when comment ends
+ for (int index = off; index < off + len; ++index ) {
+ byte c = bbuf[index];
+ boolean isNewline = (c == '\n' || c == '\r');
+ if (isNewline && this.isComment) {
+ // Comment has ended
+ this.isComment = false;
+ latest_offset = index+1;
+ }
+ if (c == '#' && this.isRightAfterNewline) {
+ this.isComment = true;
+ if (index != latest_offset) {
+ // We got some non-comment data earlier
+ super.write(bbuf, latest_offset, index-latest_offset);
+ }
+ }
+ this.isRightAfterNewline = isNewline; // Store for next iteration
+
+ }
+ if (latest_offset < off+len && !this.isComment) {
+ // We have some unwritten data, that isn't part of a comment
+ super.write(bbuf, latest_offset, (off + len) - latest_offset);
+ }
+ }
+ };
+ BufferedWriter bufferedwriter = new BufferedWriter(new java.io.OutputStreamWriter(bufferedOutputStream, java.nio.charset.StandardCharsets.UTF_8.newEncoder()));
+ // Paper end - allow skipping server.properties comments
try {
this.properties.store(bufferedwriter, "Minecraft server properties");

View file

@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 19 May 2021 18:59:10 -0700
Subject: [PATCH] Add PlayerSetSpawnEvent
diff --git a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
index a2d0699e8427b2262a2396495111125eccafbb66..15db9368227dbc29d07d74e85bd126b345b526b6 100644
--- a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
+++ b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
@@ -38,24 +38,34 @@ public class SetSpawnCommand {
ResourceKey<Level> resourcekey = source.getLevel().dimension();
Iterator iterator = targets.iterator();
+ final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper - Add PlayerSetSpawnEvent
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
- entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.COMMAND); // CraftBukkit
+ // Paper start - Add PlayerSetSpawnEvent
+ if (entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
+ actualTargets.add(entityplayer);
+ }
+ // Paper end - Add PlayerSetSpawnEvent
}
+ // Paper start - Add PlayerSetSpawnEvent
+ if (actualTargets.isEmpty()) {
+ return 0;
+ }
+ // Paper end - Add PlayerSetSpawnEvent
String s = resourcekey.location().toString();
- if (targets.size() == 1) {
+ if (actualTargets.size() == 1) { // Paper - Add PlayerSetSpawnEvent
source.sendSuccess(() -> {
- return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) targets.iterator().next()).getDisplayName());
+ return Component.translatable("commands.spawnpoint.success.single", pos.getX(), pos.getY(), pos.getZ(), angle, s, ((ServerPlayer) actualTargets.iterator().next()).getDisplayName()); // Paper - Add PlayerSetSpawnEvent
}, true);
} else {
source.sendSuccess(() -> {
- return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, targets.size());
+ return Component.translatable("commands.spawnpoint.success.multiple", pos.getX(), pos.getY(), pos.getZ(), angle, s, actualTargets.size()); // Paper - Add PlayerSetSpawnEvent
}, true);
}
- return targets.size();
+ return actualTargets.size(); // Paper - Add PlayerSetSpawnEvent
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 94cc69ed1ccbcfcc8f431762fef641c313b2f634..c680b311760601bb539d685bceddba6712d141d4 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1690,7 +1690,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
} else if (this.bedBlocked(blockposition, enumdirection)) {
return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.OBSTRUCTED);
} else {
- this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, PlayerSpawnChangeEvent.Cause.BED); // CraftBukkit
+ this.setRespawnPosition(this.level().dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - Add PlayerSetSpawnEvent
if (this.level().isDay()) {
return Either.left(net.minecraft.world.entity.player.Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
} else {
@@ -2640,44 +2640,50 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
this.setRespawnPosition(player.getRespawnDimension(), player.getRespawnPosition(), player.getRespawnAngle(), player.isRespawnForced(), false);
}
+ @Deprecated // Paper - Add PlayerSetSpawnEvent
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
- // CraftBukkit start
- this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, PlayerSpawnChangeEvent.Cause.UNKNOWN);
- }
-
- public void setRespawnPosition(ResourceKey<Level> resourcekey, @Nullable BlockPos blockposition, float f, boolean flag, boolean flag1, PlayerSpawnChangeEvent.Cause cause) {
- ServerLevel newWorld = this.server.getLevel(resourcekey);
- Location newSpawn = (blockposition != null) ? CraftLocation.toBukkit(blockposition, newWorld.getWorld(), f, 0) : null;
-
- PlayerSpawnChangeEvent event = new PlayerSpawnChangeEvent(this.getBukkitEntity(), newSpawn, flag, cause);
- Bukkit.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
- newSpawn = event.getNewSpawn();
- flag = event.isForced();
-
- if (newSpawn != null) {
- resourcekey = ((CraftWorld) newSpawn.getWorld()).getHandle().dimension();
- blockposition = BlockPos.containing(newSpawn.getX(), newSpawn.getY(), newSpawn.getZ());
- f = newSpawn.getYaw();
- } else {
- resourcekey = Level.OVERWORLD;
- blockposition = null;
- f = 0.0F;
+ // Paper start - Add PlayerSetSpawnEvent
+ this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN);
+ }
+ @Deprecated
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, PlayerSpawnChangeEvent.Cause cause) {
+ return this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, cause == PlayerSpawnChangeEvent.Cause.RESET ?
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN : com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.valueOf(cause.name()));
+ }
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) {
+ Location spawnLoc = null;
+ boolean willNotify = false;
+ if (pos != null) {
+ boolean flag2 = pos.equals(this.respawnPosition) && dimension.equals(this.respawnDimension);
+ spawnLoc = io.papermc.paper.util.MCUtil.toLocation(this.getServer().getLevel(dimension), pos);
+ spawnLoc.setYaw(angle);
+ willNotify = sendMessage && !flag2;
+ }
+
+ PlayerSpawnChangeEvent dumbEvent = new PlayerSpawnChangeEvent(this.getBukkitEntity(), spawnLoc, forced,
+ cause == com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN ? PlayerSpawnChangeEvent.Cause.RESET : PlayerSpawnChangeEvent.Cause.valueOf(cause.name()));
+ dumbEvent.callEvent();
+
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent event = new com.destroystokyo.paper.event.player.PlayerSetSpawnEvent(this.getBukkitEntity(), cause, dumbEvent.getNewSpawn(), dumbEvent.isForced(), willNotify, willNotify ? net.kyori.adventure.text.Component.translatable("block.minecraft.set_spawn") : null);
+ event.setCancelled(dumbEvent.isCancelled());
+ if (!event.callEvent()) {
+ return false;
}
- // CraftBukkit end
- if (blockposition != null) {
- boolean flag2 = blockposition.equals(this.respawnPosition) && resourcekey.equals(this.respawnDimension);
+ if (event.getLocation() != null) {
+ dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension;
+ pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation());
+ angle = event.getLocation().getYaw();
+ forced = event.isForced();
+ // Paper end - Add PlayerSetSpawnEvent
- if (flag1 && !flag2) {
- this.sendSystemMessage(Component.translatable("block.minecraft.set_spawn"));
+ if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper - Add PlayerSetSpawnEvent
+ this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper - Add PlayerSetSpawnEvent
}
- this.respawnPosition = blockposition;
- this.respawnDimension = resourcekey;
- this.respawnAngle = f;
- this.respawnForced = flag;
+ this.respawnPosition = pos;
+ this.respawnDimension = dimension;
+ this.respawnAngle = angle;
+ this.respawnForced = forced;
} else {
this.respawnPosition = null;
this.respawnDimension = Level.OVERWORLD;
@@ -2685,6 +2691,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
this.respawnForced = false;
}
+ return true; // Paper - Add PlayerSetSpawnEvent
}
public SectionPos getLastSectionPos() {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 55e1e8ab83e8ca44735a0b1a7365526d0a3b24e7..1b6540ae28d73501c59581b1864f0e01ab53e365 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -803,7 +803,7 @@ public abstract class PlayerList {
// CraftBukkit end
if (teleporttransition.missingRespawnBlock()) {
entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
- entityplayer1.setRespawnPosition(null, null, 0f, false, false, PlayerSpawnChangeEvent.Cause.RESET); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed
+ entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent
}
int i = flag ? 1 : 0;
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index db26b5a0464bd6087eeacaf6dd61eba37365df92..9117c035d5a6ff114b028fad3380ceb1fc2b9691 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -88,9 +88,14 @@ public class RespawnAnchorBlock extends Block {
ServerPlayer entityplayer = (ServerPlayer) player;
if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) {
- entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR); // CraftBukkit
+ if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - Add PlayerSetSpawnEvent
world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
return InteractionResult.SUCCESS_SERVER;
+ // Paper start - Add PlayerSetSpawnEvent
+ } else {
+ return InteractionResult.FAIL;
+ }
+ // Paper end - Add PlayerSetSpawnEvent
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 5347ad30130d598644902cdc8902e0b77ac4dfb1..b3efe7391b7e43327bcca419efe72811574c0664 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1426,9 +1426,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setRespawnLocation(Location location, boolean override) {
if (location == null) {
- this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - Add PlayerSetSpawnEvent
} else {
- this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - Add PlayerSetSpawnEvent
}
}

View file

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:30:17 -0700
Subject: [PATCH] Make hoppers respect inventory max stack size
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 8913f434967457a16dd708252834ba001ada1a03..b35b44f0776aeb95ef0eda666ba0b652c5e90274 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -495,15 +495,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (itemstack1.isEmpty()) {
// Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
+ ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
if (!stack.isEmpty() && stack.getCount() > to.getMaxStackSize()) {
+ leftover = stack; // Paper - Make hoppers respect inventory max stack size
stack = stack.split(to.getMaxStackSize());
}
// Spigot end
to.setItem(slot, stack);
- stack = ItemStack.EMPTY;
+ stack = leftover; // Paper - Make hoppers respect inventory max stack size
flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
- int j = stack.getMaxStackSize() - itemstack1.getCount();
+ int j = Math.min(stack.getMaxStackSize(), to.getMaxStackSize()) - itemstack1.getCount(); // Paper - Make hoppers respect inventory max stack size
int k = Math.min(stack.getCount(), j);
stack.shrink(k);

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Sun, 8 Aug 2021 00:52:54 -0400
Subject: [PATCH] Optimize entity tracker passenger checks
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 52fcf6df392aaa795335ee9bb7ae406009e2fda1..cfb58901476b1f9bbffd205e82c92d39d587afab 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -75,7 +75,7 @@ public class ServerEntity {
private Vec3 lastSentMovement;
private int tickCount;
private int teleportDelay;
- private List<Entity> lastPassengers = Collections.emptyList();
+ private List<Entity> lastPassengers = com.google.common.collect.ImmutableList.of(); // Paper - optimize passenger checks
private boolean wasRiding;
private boolean wasOnGround;
@Nullable

View file

@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 2 Dec 2020 03:07:58 -0800
Subject: [PATCH] Config option for Piglins guarding chests
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index 55868c82bf8bd61ce3494aa9f363c20c88ec6aa6..4f3048615a34fc2c067e09aec76af94cde6a74e0 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -478,6 +478,7 @@ public class PiglinAi {
}
public static void angerNearbyPiglins(ServerLevel world, Player player, boolean blockOpen) {
+ if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests
List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {

View file

@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 22 Dec 2020 13:52:48 -0800
Subject: [PATCH] Add EntityDamageItemEvent
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index f00b756fe5dad616323e3b11e35e27353f347042..8c9ae9ac38def29ae4cd8944395e566e434d46d0 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -692,11 +692,11 @@ public final class ItemStack implements DataComponentHolder {
return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1;
}
- public void hurtAndBreak(int amount, ServerLevel world, @Nullable ServerPlayer player, Consumer<Item> breakCallback) {
+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer<Item> breakCallback) { // Paper - Add EntityDamageItemEvent
int j = this.processDurabilityChange(amount, world, player);
// CraftBukkit start
- if (player != null) {
- PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j);
+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j); // Paper - Add EntityDamageItemEvent
event.getPlayer().getServer().getPluginManager().callEvent(event);
if (j != event.getDamage() || event.isCancelled()) {
@@ -707,6 +707,14 @@ public final class ItemStack implements DataComponentHolder {
}
j = event.getDamage();
+ // Paper start - Add EntityDamageItemEvent
+ } else if (player != null) {
+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount);
+ if (!event.callEvent()) {
+ return;
+ }
+ j = event.getDamage();
+ // Paper end - Add EntityDamageItemEvent
}
// CraftBukkit end
@@ -716,21 +724,21 @@ public final class ItemStack implements DataComponentHolder {
}
- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable ServerPlayer player) {
- return !this.isDamageableItem() ? 0 : (player != null && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage));
+ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent
+ return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent
}
- private void applyDamage(int damage, @Nullable ServerPlayer player, Consumer<Item> breakCallback) {
- if (player != null) {
- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, damage);
+ private void applyDamage(int damage, @Nullable LivingEntity player, Consumer<Item> breakCallback) { // Paper - Add EntityDamageItemEvent
+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, damage); // Paper - Add EntityDamageItemEvent
}
this.setDamageValue(damage);
if (this.isBroken()) {
Item item = this.getItem();
// CraftBukkit start - Check for item breaking
- if (this.count == 1 && player != null) {
- org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(player, this);
+ if (this.count == 1 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent
}
// CraftBukkit end
@@ -768,7 +776,7 @@ public final class ItemStack implements DataComponentHolder {
entityplayer = null;
}
- this.hurtAndBreak(amount, worldserver, entityplayer, (item) -> {
+ this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent
entity.onEquippedItemBroken(item, slot);
});
}
diff --git a/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java b/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java
index 0019c8548aa4901b248ced32cc1475ad14b725bf..7e21c8b10debd70c35a138c14b9b177ef6fff37a 100644
--- a/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java
+++ b/src/main/java/net/minecraft/world/item/enchantment/effects/ChangeItemDamage.java
@@ -21,9 +21,9 @@ public record ChangeItemDamage(LevelBasedValue amount) implements EnchantmentEnt
public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity user, Vec3 pos) {
ItemStack itemStack = context.itemStack();
if (itemStack.has(DataComponents.MAX_DAMAGE) && itemStack.has(DataComponents.DAMAGE)) {
- ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null;
+ // ServerPlayer serverPlayer2 = context.owner() instanceof ServerPlayer serverPlayer ? serverPlayer : null; // Paper - EntityDamageItemEvent - always pass in entity
int i = (int)this.amount.calculate(level);
- itemStack.hurtAndBreak(i, world, serverPlayer2, context.onBreak());
+ itemStack.hurtAndBreak(i, world, context.owner(), context.onBreak()); // Paper - EntityDamageItemEvent - always pass in entity
}
}

View file

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 9 Aug 2021 00:38:37 -0400
Subject: [PATCH] Optimize indirect passenger iteration
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 42004784a5421bd27d0a4a2bf1c17d14341fc5a4..ea1492559653063bb14b934f4d40d910b81d8801 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -4087,20 +4087,34 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
private Stream<Entity> getIndirectPassengersStream() {
+ if (this.passengers.isEmpty()) { return Stream.of(); } // Paper - Optimize indirect passenger iteration
return this.passengers.stream().flatMap(Entity::getSelfAndPassengers);
}
@Override
public Stream<Entity> getSelfAndPassengers() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper - Optimize indirect passenger iteration
return Stream.concat(Stream.of(this), this.getIndirectPassengersStream());
}
@Override
public Stream<Entity> getPassengersAndSelf() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper - Optimize indirect passenger iteration
return Stream.concat(this.passengers.stream().flatMap(Entity::getPassengersAndSelf), Stream.of(this));
}
public Iterable<Entity> getIndirectPassengers() {
+ // Paper start - Optimize indirect passenger iteration
+ if (this.passengers.isEmpty()) { return ImmutableList.of(); }
+ ImmutableList.Builder<Entity> indirectPassengers = ImmutableList.builder();
+ for (Entity passenger : this.passengers) {
+ indirectPassengers.add(passenger);
+ indirectPassengers.addAll(passenger.getIndirectPassengers());
+ }
+ return indirectPassengers.build();
+ }
+ private Iterable<Entity> getIndirectPassengers_old() {
+ // Paper end - Optimize indirect passenger iteration
return () -> {
return this.getIndirectPassengersStream().iterator();
};
@@ -4113,6 +4127,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public boolean hasExactlyOnePlayerPassenger() {
+ if (this.passengers.isEmpty()) { return false; } // Paper - Optimize indirect passenger iteration
return this.countPlayerPassengers() == 1;
}

View file

@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
Date: Fri, 13 Aug 2021 01:14:38 +0200
Subject: [PATCH] Configurable item frame map cursor update interval
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index cfb58901476b1f9bbffd205e82c92d39d587afab..bc0f1aa61e68d2a8638d89c10bc5c71922d057f9 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -120,7 +120,7 @@ public class ServerEntity {
if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block
ItemStack itemstack = entityitemframe.getItem();
- if (this.tickCount % 10 == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks
+ if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable
MapId mapid = (MapId) itemstack.get(DataComponents.MAP_ID);
MapItemSavedData worldmap = MapItem.getSavedData(mapid, this.level);

View file

@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 21 Aug 2021 12:13:53 -0700
Subject: [PATCH] Change EnderEye target without changing other things
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
index 573b96c9e0c89860c3da031c5aa239f6a7ad0c6e..fd1f5de7dc151dfd187d23e022b2c5435ed8accc 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -76,6 +76,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
}
public void signalTo(BlockPos pos) {
+ // Paper start - Change EnderEye target without changing other things
+ this.signalTo(pos, true);
+ }
+ public void signalTo(BlockPos pos, boolean update) {
+ // Paper end - Change EnderEye target without changing other things
double d0 = (double) pos.getX();
int i = pos.getY();
double d1 = (double) pos.getZ();
@@ -93,8 +98,10 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
this.tz = d1;
}
+ if (update) { // Paper - Change EnderEye target without changing other things
this.life = 0;
this.surviveAfterDeath = this.random.nextInt(5) > 0;
+ } // Paper - Change EnderEye target without changing other things
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
index d4dfc7a0266086b9bf2c3966c6e149453d0583ba..27f56fa4b7ef92a9a4dfa6b782350424b88210f2 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
@@ -32,8 +32,15 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
@Override
public void setTargetLocation(Location location) {
+ // Paper start - Change EnderEye target without changing other things
+ this.setTargetLocation(location, true);
+ }
+
+ @Override
+ public void setTargetLocation(Location location, boolean update) {
+ // Paper end - Change EnderEye target without changing other things
Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
- this.getHandle().signalTo(CraftLocation.toBlockPosition(location));
+ this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things
}
@Override