diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/arguments/selector/EntitySelector.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/commands/arguments/selector/EntitySelector.java.patch deleted file mode 100644 index b97128433..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/arguments/selector/EntitySelector.java.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/commands/arguments/selector/EntitySelector.java b/net/minecraft/commands/arguments/selector/EntitySelector.java -index af71e0e1eb1c93745f3e4954ecc8fbd2ad4808a3..fbab3e2f4e3a9cdc1c148fc794036c5655368666 100644 ---- a/net/minecraft/commands/arguments/selector/EntitySelector.java -+++ b/net/minecraft/commands/arguments/selector/EntitySelector.java -@@ -190,26 +190,27 @@ public class EntitySelector { - this.checkPermissions(source); - if (this.playerName != null) { - ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(this.playerName); -- return playerByName == null ? List.of() : List.of(playerByName); -+ return playerByName == null || !canSee(source, playerByName) ? List.of() : List.of(playerByName); // Purpur - Hide hidden players from entity selector - } else if (this.entityUUID != null) { - ServerPlayer playerByName = source.getServer().getPlayerList().getPlayer(this.entityUUID); -- return playerByName == null ? List.of() : List.of(playerByName); -+ return playerByName == null || !canSee(source, playerByName) ? List.of() : List.of(playerByName); // Purpur - Hide hidden players from entity selector - } else { - Vec3 vec3 = this.position.apply(source.getPosition()); - AABB absoluteAabb = this.getAbsoluteAabb(vec3); - Predicate predicate = this.getPredicate(vec3, absoluteAabb, null); - if (this.currentEntity) { -- return source.getEntity() instanceof ServerPlayer serverPlayer && predicate.test(serverPlayer) ? List.of(serverPlayer) : List.of(); -+ return source.getEntity() instanceof ServerPlayer serverPlayer && predicate.test(serverPlayer) && canSee(source, serverPlayer) ? List.of(serverPlayer) : List.of(); // Purpur - Hide hidden players from entity selector - } else { - int resultLimit = this.getResultLimit(); - List players; - if (this.isWorldLimited()) { - players = source.getLevel().getPlayers(predicate, resultLimit); -+ players.removeIf(entityplayer3 -> !canSee(source, entityplayer3)); // Purpur - Hide hidden players from entity selector - } else { - players = new ObjectArrayList<>(); - - for (ServerPlayer serverPlayer1 : source.getServer().getPlayerList().getPlayers()) { -- if (predicate.test(serverPlayer1)) { -+ if (predicate.test(serverPlayer1) && canSee(source, serverPlayer1)) { // Purpur - Hide hidden players from entity selector - players.add(serverPlayer1); - if (players.size() >= resultLimit) { - return players; -@@ -267,4 +268,10 @@ public class EntitySelector { - public static Component joinNames(List names) { - return ComponentUtils.formatList(names, Entity::getDisplayName); - } -+ -+ // Purpur start - Hide hidden players from entity selector -+ private boolean canSee(CommandSourceStack sender, ServerPlayer target) { -+ return !org.purpurmc.purpur.PurpurConfig.hideHiddenPlayersFromEntitySelector || !(sender.getEntity() instanceof ServerPlayer player) || player.getBukkitEntity().canSee(target.getBukkitEntity()); -+ } -+ // Purpur end - Hide hidden players from entity selector - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/core/BlockPos.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/core/BlockPos.java.patch deleted file mode 100644 index 752f0f76f..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/core/BlockPos.java.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/core/BlockPos.java b/net/minecraft/core/BlockPos.java -index e87473fcb36e18d960ef3e4082995785d64b9c0f..e4dee5426e186d44d4d929967c65710848ace11d 100644 ---- a/net/minecraft/core/BlockPos.java -+++ b/net/minecraft/core/BlockPos.java -@@ -61,6 +61,12 @@ public class BlockPos extends Vec3i { - public static final int MAX_HORIZONTAL_COORDINATE = 33554431; - // Paper end - Optimize Bit Operations by inlining - -+ // Purpur start - Ridables -+ public BlockPos(net.minecraft.world.entity.Entity entity) { -+ super(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()); -+ } -+ // Purpur end - Ridables -+ - public BlockPos(int x, int y, int z) { - super(x, y, z); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch deleted file mode 100644 index 58ff0d2c2..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -index e2d169b45f1dba6559ca337b07a110f79d3db504..727d04a442053f6d0c4df3e744554e2866fa38cd 100644 ---- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -+++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java -@@ -32,7 +32,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { - return false; - } else { - LivingEntity livingEntity = entitiesOfClass.getFirst(); -- EquipmentSlot equipmentSlotForItem = livingEntity.getEquipmentSlotForItem(item); -+ EquipmentSlot equipmentSlotForItem = blockSource.level().purpurConfig.dispenserApplyCursedArmor ? livingEntity.getEquipmentSlotForItem(item) : livingEntity.getEquipmentSlotForDispenserItem(item); if (equipmentSlotForItem == null) return false; // Purpur - Dispenser curse of binding protection - ItemStack itemStack = item.copyWithCount(1); // Paper - shrink below and single item in event - // CraftBukkit start - net.minecraft.world.level.Level world = blockSource.level(); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/gametest/framework/TestCommand.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/gametest/framework/TestCommand.java.patch deleted file mode 100644 index f942dce8c..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/gametest/framework/TestCommand.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/gametest/framework/TestCommand.java b/net/minecraft/gametest/framework/TestCommand.java -index 4a06b20b60f67a2d383dbd09b3bad713155dc81e..63e0294f5624643b6d37983f523bf2434cbe47e2 100644 ---- a/net/minecraft/gametest/framework/TestCommand.java -+++ b/net/minecraft/gametest/framework/TestCommand.java -@@ -443,7 +443,7 @@ public class TestCommand { - ) - ) - ); -- if (SharedConstants.IS_RUNNING_IN_IDE) { -+ if (org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands || SharedConstants.IS_RUNNING_IN_IDE) { // Purpur - register minecraft debug commands - literalArgumentBuilder = literalArgumentBuilder.then( - Commands.literal("export") - .then( diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/EnchantCommand.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/EnchantCommand.java.patch deleted file mode 100644 index e371f4b2a..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/EnchantCommand.java.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/commands/EnchantCommand.java b/net/minecraft/server/commands/EnchantCommand.java -index 21548995eb278236946b6e495d27f6261e24f7a2..1735a87a974028779cc64cbeb39ff2eeb16034b1 100644 ---- a/net/minecraft/server/commands/EnchantCommand.java -+++ b/net/minecraft/server/commands/EnchantCommand.java -@@ -70,7 +70,7 @@ public class EnchantCommand { - - private static int enchant(CommandSourceStack source, Collection targets, Holder enchantment, int level) throws CommandSyntaxException { - Enchantment enchantment1 = enchantment.value(); -- if (level > enchantment1.getMaxLevel()) { -+ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment1.getMaxLevel()) { // Purpur - Config to allow unsafe enchants - throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment1.getMaxLevel()); - } else { - int i = 0; -@@ -80,7 +80,7 @@ public class EnchantCommand { - ItemStack mainHandItem = livingEntity.getMainHandItem(); - if (!mainHandItem.isEmpty()) { - if (enchantment1.canEnchant(mainHandItem) -- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(mainHandItem).keySet(), enchantment)) { -+ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(mainHandItem).keySet(), enchantment) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !mainHandItem.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants - mainHandItem.enchant(enchantment, level); - i++; - } else if (targets.size() == 1) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GiveCommand.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GiveCommand.java.patch deleted file mode 100644 index 0fcac4169..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GiveCommand.java.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java -index 0fc63717af24ca37497db8ea5a2395548d9d8491..2f8fd2240d603346e751a5f7afb91121065423d6 100644 ---- a/net/minecraft/server/commands/GiveCommand.java -+++ b/net/minecraft/server/commands/GiveCommand.java -@@ -68,6 +68,7 @@ public class GiveCommand { - i1 -= min; - ItemStack itemStack1 = item.createItemStack(min, false); - boolean flag = serverPlayer.getInventory().add(itemStack1); -+ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping - if (flag && itemStack1.isEmpty()) { - ItemEntity itemEntity = serverPlayer.drop(itemStack, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command - if (itemEntity != null) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/gui/MinecraftServerGui.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/server/gui/MinecraftServerGui.java.patch deleted file mode 100644 index 46c208f18..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/gui/MinecraftServerGui.java.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/gui/MinecraftServerGui.java b/net/minecraft/server/gui/MinecraftServerGui.java -index f262a7c5ae4e7d56f16f5c0f4f145a2e428abbe4..614c7d9f673c926562acc8fa3b3788623900db41 100644 ---- a/net/minecraft/server/gui/MinecraftServerGui.java -+++ b/net/minecraft/server/gui/MinecraftServerGui.java -@@ -39,6 +39,11 @@ public class MinecraftServerGui extends JComponent { - private Thread logAppenderThread; - private final Collection finalizers = Lists.newArrayList(); - final AtomicBoolean isClosing = new AtomicBoolean(); -+ // Purpur start - GUI Improvements -+ private final CommandHistory history = new CommandHistory(); -+ private String currentCommand = ""; -+ private int historyIndex = 0; -+ // Purpur end - GUI Improvements - - public static MinecraftServerGui showFrameFor(final DedicatedServer server) { - try { -@@ -46,7 +51,7 @@ public class MinecraftServerGui extends JComponent { - } catch (Exception var3) { - } - -- final JFrame jFrame = new JFrame("Minecraft server"); -+ final JFrame jFrame = new JFrame("Purpur Minecraft server"); // Purpur - Improve GUI - final MinecraftServerGui minecraftServerGui = new MinecraftServerGui(server); - jFrame.setDefaultCloseOperation(2); - jFrame.add(minecraftServerGui); -@@ -54,7 +59,7 @@ public class MinecraftServerGui extends JComponent { - jFrame.setLocationRelativeTo(null); - jFrame.setVisible(true); - // Paper start - Improve ServerGUI -- jFrame.setName("Minecraft server"); -+ jFrame.setName("Purpur Minecraft server"); // Purpur - Improve GUI - try { - jFrame.setIconImage(javax.imageio.ImageIO.read(java.util.Objects.requireNonNull(MinecraftServerGui.class.getClassLoader().getResourceAsStream("logo.png")))); - } catch (java.io.IOException ignore) { -@@ -64,7 +69,7 @@ public class MinecraftServerGui extends JComponent { - @Override - public void windowClosing(WindowEvent event) { - if (!minecraftServerGui.isClosing.getAndSet(true)) { -- jFrame.setTitle("Minecraft server - shutting down!"); -+ jFrame.setTitle("Purpur Minecraft server - shutting down!"); // Purpur - Improve GUI - server.halt(true); - minecraftServerGui.runFinalizers(); - } -@@ -112,7 +117,7 @@ public class MinecraftServerGui extends JComponent { - - private JComponent buildChatPanel() { - JPanel jPanel = new JPanel(new BorderLayout()); -- JTextArea jTextArea = new JTextArea(); -+ org.purpurmc.purpur.gui.JColorTextPane jTextArea = new org.purpurmc.purpur.gui.JColorTextPane(); // Purpur - GUI Improvements - JScrollPane jScrollPane = new JScrollPane(jTextArea, 22, 30); - jTextArea.setEditable(false); - jTextArea.setFont(MONOSPACED); -@@ -121,10 +126,43 @@ public class MinecraftServerGui extends JComponent { - String trimmed = jTextField.getText().trim(); - if (!trimmed.isEmpty()) { - this.server.handleConsoleInput(trimmed, this.server.createCommandSourceStack()); -+ // Purpur start - GUI Improvements -+ history.add(trimmed); -+ historyIndex = -1; -+ // Purpur end - GUI Improvements - } - - jTextField.setText(""); - }); -+ // Purpur start - GUI Improvements -+ jTextField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("UP"), "up"); -+ jTextField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("DOWN"), "down"); -+ jTextField.getActionMap().put("up", new javax.swing.AbstractAction() { -+ @Override -+ public void actionPerformed(java.awt.event.ActionEvent actionEvent) { -+ if (historyIndex < 0) { -+ currentCommand = jTextField.getText(); -+ } -+ if (historyIndex < history.size() - 1) { -+ jTextField.setText(history.get(++historyIndex)); -+ } -+ } -+ }); -+ jTextField.getActionMap().put("down", new javax.swing.AbstractAction() { -+ @Override -+ public void actionPerformed(java.awt.event.ActionEvent actionEvent) { -+ if (historyIndex >= 0) { -+ if (historyIndex == 0) { -+ --historyIndex; -+ jTextField.setText(currentCommand); -+ } else { -+ --historyIndex; -+ jTextField.setText(history.get(historyIndex)); -+ } -+ } -+ } -+ }); -+ // Purpur end - GUI Improvements - jTextArea.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent event) { -@@ -159,7 +197,7 @@ public class MinecraftServerGui extends JComponent { - } - - private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper -- public void print(JTextArea textArea, JScrollPane scrollPane, String line) { -+ public void print(org.purpurmc.purpur.gui.JColorTextPane textArea, JScrollPane scrollPane, String line) { // Purpur - GUI Improvements - if (!SwingUtilities.isEventDispatchThread()) { - SwingUtilities.invokeLater(() -> this.print(textArea, scrollPane, line)); - } else { -@@ -170,10 +208,11 @@ public class MinecraftServerGui extends JComponent { - flag = verticalScrollBar.getValue() + verticalScrollBar.getSize().getHeight() + MONOSPACED.getSize() * 4 > verticalScrollBar.getMaximum(); - } - -- try { -+ /*try { // Purpur - GUI Improvements - document.insertString(document.getLength(), MinecraftServerGui.ANSI.matcher(line).replaceAll(""), null); // CraftBukkit - } catch (BadLocationException var8) { -- } -+ }*/ // Purpur - GUI Improvements -+ textArea.append(line); // Purpur - GUI Improvements - - if (flag) { - verticalScrollBar.setValue(Integer.MAX_VALUE); -@@ -181,6 +220,18 @@ public class MinecraftServerGui extends JComponent { - } - } - -+ // Purpur start - GUI Improvements -+ public static class CommandHistory extends java.util.LinkedList { -+ @Override -+ public boolean add(String command) { -+ if (size() > 1000) { -+ remove(); -+ } -+ return super.offerFirst(command); -+ } -+ } -+ // Purpur end - GUI Improvements -+ - // Paper start - Add onboarding message for initial server start - private JComponent buildOnboardingPanel() { - String onboardingLink = "https://docs.papermc.io/paper/next-steps"; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/players/SleepStatus.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/server/players/SleepStatus.java.patch deleted file mode 100644 index c9dabaaf5..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/players/SleepStatus.java.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/players/SleepStatus.java b/net/minecraft/server/players/SleepStatus.java -index 2a7ae521654ad5c9f392baa5562e64bb71b13097..3a3e6992563236141db687084aeec9684437a7db 100644 ---- a/net/minecraft/server/players/SleepStatus.java -+++ b/net/minecraft/server/players/SleepStatus.java -@@ -15,7 +15,7 @@ public class SleepStatus { - - public boolean areEnoughDeepSleeping(int requiredSleepPercentage, List sleepingPlayers) { - // CraftBukkit start -- int i = (int) sleepingPlayers.stream().filter(player -> player.isSleepingLongEnough() || player.fauxSleeping).count(); -+ int i = (int) sleepingPlayers.stream().filter(player -> player.isSleepingLongEnough() || player.fauxSleeping || (player.level().purpurConfig.idleTimeoutCountAsSleeping && player.isAfk())).count(); // Purpur - AFK API - boolean anyDeepSleep = sleepingPlayers.stream().anyMatch(Player::isSleepingLongEnough); - return anyDeepSleep && i >= this.sleepersNeeded(requiredSleepPercentage); - // CraftBukkit end -@@ -43,7 +43,7 @@ public class SleepStatus { - for (ServerPlayer serverPlayer : players) { - if (!serverPlayer.isSpectator()) { - this.activePlayers++; -- if (serverPlayer.isSleeping() || serverPlayer.fauxSleeping) { // CraftBukkit -+ if (serverPlayer.isSleeping() || serverPlayer.fauxSleeping || (serverPlayer.level().purpurConfig.idleTimeoutCountAsSleeping && serverPlayer.isAfk())) { // CraftBukkit // Purpur - AFK API - this.sleepingPlayers++; - } - // CraftBukkit start diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/stats/ServerRecipeBook.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/stats/ServerRecipeBook.java.patch deleted file mode 100644 index 301a39b44..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/stats/ServerRecipeBook.java.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/stats/ServerRecipeBook.java b/net/minecraft/stats/ServerRecipeBook.java -index 736a52c23da313bec6b25a9d1abf08816462403c..2f4f90bf428deb682fe9ec8c1218ae31ebaeea7c 100644 ---- a/net/minecraft/stats/ServerRecipeBook.java -+++ b/net/minecraft/stats/ServerRecipeBook.java -@@ -106,6 +106,7 @@ public class ServerRecipeBook extends RecipeBook { - private void loadRecipes(List>> recipes, Consumer>> output, Predicate>> isRecognized) { - for (ResourceKey> resourceKey : recipes) { - if (!isRecognized.test(resourceKey)) { -+ if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressUnrecognizedRecipeErrors) // Purpur - Logger settings (suppressing pointless logs) - LOGGER.error("Tried to load unrecognized recipe: {} removed now.", resourceKey); - } else { - output.accept(resourceKey); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatRules.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatRules.java.patch deleted file mode 100644 index c32e46645..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatRules.java.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/damagesource/CombatRules.java b/net/minecraft/world/damagesource/CombatRules.java -index 5f8637dfe4703cb78f486fe49d2e81518cf48715..d27215349f63e73198d23e107a6b634ddef8f7ca 100644 ---- a/net/minecraft/world/damagesource/CombatRules.java -+++ b/net/minecraft/world/damagesource/CombatRules.java -@@ -15,7 +15,7 @@ public class CombatRules { - - public static float getDamageAfterAbsorb(LivingEntity entity, float damageAmount, DamageSource damageSource, float armorValue, float armorToughness) { - float f = 2.0F + armorToughness / 4.0F; -- float f1 = Mth.clamp(armorValue - damageAmount / f, armorValue * 0.2F, 20.0F); -+ float f1 = Mth.clamp(armorValue - damageAmount / f, armorValue * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur - Add attribute clamping and armor limit config - float f2 = f1 / 25.0F; - ItemStack weaponItem = damageSource.getWeaponItem(); - float f3; -@@ -30,7 +30,7 @@ public class CombatRules { - } - - public static float getDamageAfterMagicAbsorb(float damageAmount, float enchantModifiers) { -- float f = Mth.clamp(enchantModifiers, 0.0F, 20.0F); -+ float f = Mth.clamp(enchantModifiers, 0.0F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur - Add attribute clamping and armor limit config - return damageAmount * (1.0F - f / 25.0F); - } - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatTracker.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatTracker.java.patch deleted file mode 100644 index 96790ad11..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/CombatTracker.java.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/damagesource/CombatTracker.java b/net/minecraft/world/damagesource/CombatTracker.java -index ffdfb4c4e3d6496ebdba6e4bad7146a9cbdcf5ec..30d0807d7adf46a6cd23b81b979e06f943a2bca1 100644 ---- a/net/minecraft/world/damagesource/CombatTracker.java -+++ b/net/minecraft/world/damagesource/CombatTracker.java -@@ -64,7 +64,7 @@ public class CombatTracker { - - private Component getMessageForAssistedFall(Entity entity, Component entityDisplayName, String hasWeaponTranslationKey, String noWeaponTranslationKey) { - ItemStack itemStack = entity instanceof LivingEntity livingEntity ? livingEntity.getMainHandItem() : ItemStack.EMPTY; -- return !itemStack.isEmpty() && itemStack.has(DataComponents.CUSTOM_NAME) -+ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.has(DataComponents.CUSTOM_NAME)) // Purpur - always show item in player death messages - ? Component.translatable(hasWeaponTranslationKey, this.mob.getDisplayName(), entityDisplayName, itemStack.getDisplayName()) - : Component.translatable(noWeaponTranslationKey, this.mob.getDisplayName(), entityDisplayName); - } -@@ -107,6 +107,15 @@ public class CombatTracker { - Component component = ComponentUtils.wrapInSquareBrackets(Component.translatable(string + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE); - return Component.translatable(string + ".message", this.mob.getDisplayName(), component); - } else { -+ // Purpur start - Dont run with scissors! -+ if (damageSource.isScissors()) { -+ return damageSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgRunWithScissors, this.mob); -+ // Purpur start - Stonecutter damage -+ } else if (damageSource.isStonecutter()) { -+ return damageSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgStonecutter, this.mob); -+ // Purpur end - Stonecutter damage -+ } -+ // Purpur end - Dont run with scissors! - return damageSource.getLocalizedDeathMessage(this.mob); - } - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/HungerMobEffect.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/HungerMobEffect.java.patch deleted file mode 100644 index 23947965e..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/HungerMobEffect.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/effect/HungerMobEffect.java b/net/minecraft/world/effect/HungerMobEffect.java -index 0890694ae96b6cd60079c34066e7a6e288f038e8..6c0e6bd2a171edc57dec71af178764454de73313 100644 ---- a/net/minecraft/world/effect/HungerMobEffect.java -+++ b/net/minecraft/world/effect/HungerMobEffect.java -@@ -12,7 +12,7 @@ class HungerMobEffect extends MobEffect { - @Override - public boolean applyEffectTick(ServerLevel level, LivingEntity entity, int amplifier) { - if (entity instanceof Player player) { -- player.causeFoodExhaustion(0.005F * (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent -+ player.causeFoodExhaustion(entity.level().purpurConfig.humanHungerExhaustionAmount * (amplifier + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur - Config MobEffect by world - } - - return true; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/PoisonMobEffect.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/PoisonMobEffect.java.patch deleted file mode 100644 index 089dd145b..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/PoisonMobEffect.java.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/effect/PoisonMobEffect.java b/net/minecraft/world/effect/PoisonMobEffect.java -index 75327fd96858fd508ea63a6983e5cbc655a8800f..73cfc61ac3f8e33e6b9f4fd08a292266c0adb535 100644 ---- a/net/minecraft/world/effect/PoisonMobEffect.java -+++ b/net/minecraft/world/effect/PoisonMobEffect.java -@@ -12,8 +12,8 @@ public class PoisonMobEffect extends MobEffect { - - @Override - public boolean applyEffectTick(ServerLevel level, LivingEntity entity, int amplifier) { -- if (entity.getHealth() > 1.0F) { -- entity.hurtServer(level, entity.damageSources().magic().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.POISON), 1.0F); // CraftBukkit -+ if (entity.getHealth() > entity.level().purpurConfig.entityMinimalHealthPoison) { // Purpur -+ entity.hurtServer(level, entity.damageSources().magic().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.POISON), entity.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit // Purpur - Config MobEffect by world - } - - return true; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/RegenerationMobEffect.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/RegenerationMobEffect.java.patch deleted file mode 100644 index 07ea9eb81..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/RegenerationMobEffect.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/effect/RegenerationMobEffect.java b/net/minecraft/world/effect/RegenerationMobEffect.java -index 76cffa4d4d18d6c04749d941dbdf5eb60aed4095..81481267a1577721dcc405f39a4c350bd59ac9a2 100644 ---- a/net/minecraft/world/effect/RegenerationMobEffect.java -+++ b/net/minecraft/world/effect/RegenerationMobEffect.java -@@ -11,7 +11,7 @@ class RegenerationMobEffect extends MobEffect { - @Override - public boolean applyEffectTick(ServerLevel level, LivingEntity entity, int amplifier) { - if (entity.getHealth() < entity.getMaxHealth()) { -- entity.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit -+ entity.heal(entity.level().purpurConfig.entityHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur - Config MobEffect by world - } - - return true; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/WitherMobEffect.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/WitherMobEffect.java.patch deleted file mode 100644 index 433070231..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/effect/WitherMobEffect.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/effect/WitherMobEffect.java b/net/minecraft/world/effect/WitherMobEffect.java -index 1fc9e1ad541c46124183a401b2a7d99aea69cecf..881271f0bc77a8a8a7d31daad9a8188bebaca67b 100644 ---- a/net/minecraft/world/effect/WitherMobEffect.java -+++ b/net/minecraft/world/effect/WitherMobEffect.java -@@ -12,7 +12,7 @@ public class WitherMobEffect extends MobEffect { - - @Override - public boolean applyEffectTick(ServerLevel level, LivingEntity entity, int amplifier) { -- entity.hurtServer(level, entity.damageSources().wither(), 1.0F); -+ entity.hurtServer(level, entity.damageSources().wither(), entity.level().purpurConfig.entityWitherDegenerationAmount); // Purpur - Config MobEffect by world - return true; - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Entity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Entity.java.patch deleted file mode 100644 index ede4567ed..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Entity.java.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 118ba985eff209ff97dd2c8b2749a75113f5ce43..5efb94bf1029fdbbd48937c1f3925421d6daacfd 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -153,6 +153,7 @@ import org.jspecify.annotations.Nullable; - import org.slf4j.Logger; - - public abstract class Entity implements SyncedDataHolder, DebugValueSource, Nameable, ItemOwner, SlotProvider, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker -+ public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur - Configurable entity base attributes - // CraftBukkit start - private static final int CURRENT_LEVEL = 2; - static boolean isLevelAtLeast(ValueInput input, int level) { -@@ -282,8 +283,9 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - public double xOld; - public double yOld; - public double zOld; -+ public float maxUpStep; // Purpur - Add option to set armorstand step height - public boolean noPhysics; -- public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random -+ public final RandomSource random; // Paper - Share random for entities to make them more random // Add toggle for RNG manipulation - public int tickCount; - private int remainingFireTicks; - public boolean wasTouchingWater; -@@ -316,8 +318,8 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - public @Nullable PortalProcessor portalProcess; - public int portalCooldown; - private boolean invulnerable; -- protected UUID uuid = Mth.createInsecureUUID(this.random); -- protected String stringUUID = this.uuid.toString(); -+ protected UUID uuid; // Purpur - Add toggle for RNG manipulation -+ protected String stringUUID; // Purpur - Add toggle for RNG manipulation - private boolean hasGlowingTag; - private final Set tags = new io.papermc.paper.util.SizeLimitedSet<>(new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(), MAX_ENTITY_TAG_COUNT); // Paper - fully limit tag size - replace set impl - private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; -@@ -373,6 +375,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - public long activatedTick = Integer.MIN_VALUE; - public boolean isTemporarilyActive; - public long activatedImmunityTick = Integer.MIN_VALUE; -+ public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API - - public void inactiveTick() { - } -@@ -535,10 +538,22 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - } - // Paper end - optimise entity tracker - -+ // Purpur start - Add canSaveToDisk to Entity -+ public boolean canSaveToDisk() { -+ return true; -+ } -+ // Purpur end - Add canSaveToDisk to Entity -+ - public Entity(EntityType type, Level level) { - this.type = type; - this.level = level; - this.dimensions = type.getDimensions(); -+ this.maxAirTicks = level == null ? Entity.TOTAL_AIR_SUPPLY : this.level.purpurConfig.drowningAirTicks; // Purpur - Drowning Settings -+ // Purpur start - Add toggle for RNG manipulation -+ this.random = level == null || level.purpurConfig.entitySharedRandom ? SHARED_RANDOM : RandomSource.create(); -+ this.uuid = Mth.createInsecureUUID(this.random); -+ this.stringUUID = this.uuid.toString(); -+ // Purpur end - Add toggle for RNG manipulation - this.position = Vec3.ZERO; - this.blockPosition = BlockPos.ZERO; - this.chunkPosition = ChunkPos.ZERO; -@@ -931,6 +946,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v) - && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { - // Paper end - Configurable nether ceiling damage -+ if (this.level.purpurConfig.teleportOnNetherCeilingDamage && this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this instanceof ServerPlayer player) player.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.level.levelData.getRespawnData().pos(), this.level)); else // Purpur - Add option to teleport to spawn on nether ceiling damage - this.onBelowWorld(); - } - } -@@ -1960,7 +1976,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - } - - public boolean fireImmune() { -- return this.getType().fireImmune(); -+ return this.immuneToFire != null ? immuneToFire : this.getType().fireImmune(); // Purpur - add fire immune API - } - - public boolean causeFallDamage(double fallDistance, float damageMultiplier, DamageSource damageSource) { -@@ -2572,7 +2588,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - output.putBoolean("Bukkit.invisible", this.persistentInvisibility); - } - // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() -- if (this.maxAirTicks != this.getDefaultMaxAirSupply()) { -+ if (this.maxAirTicks != this.getDefaultMaxAirSupply() && this.getDefaultMaxAirSupply() != this.level().purpurConfig.drowningAirTicks) { // Purpur - Drowning Settings - output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); - } - output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper -@@ -2659,6 +2675,11 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - output.putBoolean("Paper.FreezeLock", true); - } - // Paper end -+ // Purpur start - Fire immune API -+ if (immuneToFire != null) { -+ output.putBoolean("Purpur.FireImmune", immuneToFire); -+ } -+ // Purpur end - Fire immune API - } catch (Throwable var7) { - CrashReport crashReport = CrashReport.forThrowable(var7, "Saving entity NBT"); - CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being saved"); -@@ -2779,6 +2800,9 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - } - freezeLocked = input.getBooleanOr("Paper.FreezeLock", false); - // Paper end -+ -+ immuneToFire = input.read("Purpur.FireImmune", com.mojang.serialization.Codec.BOOL).orElse(null); // Purpur - Fire immune API -+ - } catch (Throwable var7) { - CrashReport crashReport = CrashReport.forThrowable(var7, "Loading entity NBT"); - CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded"); -@@ -3042,6 +3066,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - if (this.isAlive() && this instanceof Leashable leashable2) { - if (leashable2.getLeashHolder() == player) { - if (!this.level().isClientSide()) { -+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.villager.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers - // Paper start - EntityUnleashEvent - if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( - leashable2, player, hand, !player.hasInfiniteMaterials(), true -@@ -3472,15 +3497,18 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - return Vec3.directionFromRotation(this.getRotationVector()); - } - -+ public BlockPos portalPos = BlockPos.ZERO; // Purpur - Fix stuck in portals - public void setAsInsidePortal(Portal portal, BlockPos pos) { - if (this.isOnPortalCooldown()) { -+ if (!(level().purpurConfig.playerFixStuckPortal && this instanceof Player && !pos.equals(this.portalPos))) // Purpur - Fix stuck in portals - this.setPortalCooldown(); -- } else { -+ } else if (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur - Entities can use portals - if (this.portalProcess == null || !this.portalProcess.isSamePortal(portal)) { - this.portalProcess = new PortalProcessor(portal, pos.immutable()); - } else if (!this.portalProcess.isInsidePortalThisTick()) { - this.portalProcess.updateEntryPosition(pos.immutable()); - this.portalProcess.setAsInsidePortalThisTick(true); -+ this.portalPos = BlockPos.ZERO; // Purpur - Fix stuck in portals - } - } - } -@@ -4220,7 +4248,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - } - - public boolean canUsePortal(boolean allowPassengers) { -- return (allowPassengers || !this.isPassenger()) && this.isAlive(); -+ return (allowPassengers || !this.isPassenger()) && this.isAlive() && (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Purpur - Entities can use portals - } - - public boolean canTeleport(Level fromLevel, Level toLevel) { -@@ -4739,6 +4767,12 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - return Mth.lerp(partialTick, this.yRotO, this.yRot); - } - -+ // Purpur start - Stop squids floating on top of water -+ public AABB getAxisForFluidCheck() { -+ return this.getBoundingBox().deflate(0.001D); -+ } -+ // Purpur end - Stop squids floating on top of water -+ - // Paper start - optimise collisions - public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { - if (this.touchingUnloadedChunk()) { -@@ -5159,7 +5193,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name - } - - public float maxUpStep() { -- return 0.0F; -+ return maxUpStep; // Purpur - Add option to set armorstand step height - } - - public void onExplosionHit(@Nullable Entity entity) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/EntityType.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/EntityType.java.patch deleted file mode 100644 index cc899c605..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/EntityType.java.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java -index a3cba4a65687c61fefbfcf3c35625ceed2e50bfb..f0731609fbfb06ea23baba2a8b3694003a470b7d 100644 ---- a/net/minecraft/world/entity/EntityType.java -+++ b/net/minecraft/world/entity/EntityType.java -@@ -1240,6 +1240,16 @@ public class EntityType implements FeatureElement, EntityTypeT - return register(vanillaEntityId(key), builder); - } - -+ // Purpur start - PlayerSetSpawnerTypeWithEggEvent -+ public static EntityType getFromBukkitType(org.bukkit.entity.EntityType bukkitType) { -+ return getFromKey(Identifier.parse(bukkitType.getKey().toString())); -+ } -+ -+ public static EntityType getFromKey(Identifier location) { -+ return BuiltInRegistries.ENTITY_TYPE.getValue(location); -+ } -+ // Purpur end - PlayerSetSpawnerTypeWithEggEvent -+ - public static Identifier getKey(EntityType entityType) { - return BuiltInRegistries.ENTITY_TYPE.getKey(entityType); - } -@@ -1467,6 +1477,16 @@ public class EntityType implements FeatureElement, EntityTypeT - return this.category; - } - -+ // Purpur start - PlayerSetSpawnerTypeWithEggEvent -+ public String getName() { -+ return BuiltInRegistries.ENTITY_TYPE.getKey(this).getPath(); -+ } -+ -+ public String getTranslatedName() { -+ return getDescription().getString(); -+ } -+ // Purpur end - PlayerSetSpawnerTypeWithEggEvent -+ - public String getDescriptionId() { - return this.descriptionId; - } -@@ -1528,6 +1548,7 @@ public class EntityType implements FeatureElement, EntityTypeT - // Paper start - Add logging for debugging entity tags with invalid ids - () -> { - LOGGER.warn("Skipping Entity with id {}", input.getStringOr("id", "[invalid]")); -+ LOGGER.warn("Location: {} {}", level.getWorld().getName(), input.read("Pos", net.minecraft.world.phys.Vec3.CODEC).orElse(net.minecraft.world.phys.Vec3.ZERO)); // Purpur - log skipped entity's position - if ((DEBUG_ENTITIES_WITH_INVALID_IDS || level.getCraftServer().getServer().isDebugging()) && input instanceof TagValueInput tagInput) { - LOGGER.warn("Skipped entity tag: {}", tagInput.input); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ExperienceOrb.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ExperienceOrb.java.patch deleted file mode 100644 index 3b9777340..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/ExperienceOrb.java.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java -index f2ec0bd8cca3c08d558790537e17a8a2f95f1953..c655689cdd2d4e655dfc872edd231dcdfb7c0995 100644 ---- a/net/minecraft/world/entity/ExperienceOrb.java -+++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -355,7 +355,7 @@ public class ExperienceOrb extends Entity { - public void playerTouch(Player entity) { - if (entity instanceof ServerPlayer serverPlayer) { - if (entity.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent -- entity.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(entity, 2, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entity.takeXpDelay = 2; -+ entity.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(entity, this.level().purpurConfig.playerExpPickupDelay, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entity.takeXpDelay = 2; // Purpur - Configurable player pickup exp delay - entity.take(this, 1); - int i = this.repairPlayerItems(serverPlayer, this.getValue()); - if (i > 0) { -@@ -371,7 +371,7 @@ public class ExperienceOrb extends Entity { - } - - private int repairPlayerItems(ServerPlayer player, int value) { -- Optional randomItemWith = EnchantmentHelper.getRandomItemWith( -+ Optional randomItemWith = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith( // Purpur - Add option to mend the most damaged equipment first - EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged - ); - if (randomItemWith.isPresent()) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/LivingEntity.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/LivingEntity.java.patch deleted file mode 100644 index 232784cb7..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/LivingEntity.java.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 54f31965213309a2cd228b7211e96ae1b9c219d4..527db90fa6faa6f39a80e64db16e28f1d616ce4d 100644 ---- a/net/minecraft/world/entity/LivingEntity.java -+++ b/net/minecraft/world/entity/LivingEntity.java -@@ -447,6 +447,12 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - if (d < 0.0) { - double damagePerBlock = serverLevel1.getWorldBorder().getDamagePerBlock(); - if (damagePerBlock > 0.0) { -+ // Purpur start - Add option to teleport to spawn if outside world border -+ if (this.level().purpurConfig.teleportIfOutsideBorder && this instanceof ServerPlayer serverPlayer) { -+ serverPlayer.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.level().levelData.getRespawnData().pos(), this.level())); -+ return; -+ } -+ // Purpur end - Add option to teleport to spawn if outside world border - this.hurtServer(serverLevel1, this.damageSources().outOfBorder(), Math.max(1, Mth.floor(-d * damagePerBlock))); - } - } -@@ -462,7 +468,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - if (this.shouldTakeDrowningDamage()) { - this.setAirSupply(0); - serverLevel1.broadcastEntityEvent(this, EntityEvent.DROWN_PARTICLES); -- this.hurtServer(serverLevel1, this.damageSources().drown(), 2.0F); -+ this.hurtServer(serverLevel1, this.damageSources().drown(), (float) this.level().purpurConfig.damageFromDrowning); // Purpur - Drowning Settings - } - } else if (this.getAirSupply() < this.getMaxAirSupply() && MobEffectUtil.shouldEffectsRefillAirsupply(this)) { - this.setAirSupply(this.increaseAirSupply(this.getAirSupply())); -@@ -522,7 +528,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - } - - protected boolean shouldTakeDrowningDamage() { -- return this.getAirSupply() <= -20; -+ return this.getAirSupply() <= -this.level().purpurConfig.drowningDamageInterval; // Purpur - Drowning Settings - } - - @Override -@@ -1050,15 +1056,33 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - if (lookingEntity != null) { - ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD); - EntityType type = lookingEntity.getType(); -- if (type == EntityType.SKELETON && itemBySlot.is(Items.SKELETON_SKULL) -- || type == EntityType.ZOMBIE && itemBySlot.is(Items.ZOMBIE_HEAD) -- || type == EntityType.PIGLIN && itemBySlot.is(Items.PIGLIN_HEAD) -- || type == EntityType.PIGLIN_BRUTE && itemBySlot.is(Items.PIGLIN_HEAD) -- || type == EntityType.CREEPER && itemBySlot.is(Items.CREEPER_HEAD)) { -- d *= 0.5; -+ // Purpur start - Mob head visibility percent -+ if (type == EntityType.SKELETON && itemBySlot.is(Items.SKELETON_SKULL)) { -+ d *= lookingEntity.level().purpurConfig.skeletonHeadVisibilityPercent; -+ } -+ else if (type == EntityType.ZOMBIE && itemBySlot.is(Items.ZOMBIE_HEAD)) { -+ d *= lookingEntity.level().purpurConfig.zombieHeadVisibilityPercent; -+ } -+ else if ((type == EntityType.PIGLIN || type == EntityType.PIGLIN_BRUTE) && itemBySlot.is(Items.PIGLIN_HEAD)) { -+ d *= lookingEntity.level().purpurConfig.piglinHeadVisibilityPercent; - } -+ else if (type == EntityType.CREEPER && itemBySlot.is(Items.CREEPER_HEAD)) { -+ d *= lookingEntity.level().purpurConfig.creeperHeadVisibilityPercent; -+ } -+ // Purpur end - Mob head visibility percent - } - -+ // Purpur start - Configurable mob blindness -+ if (lookingEntity instanceof LivingEntity entityliving) { -+ if (entityliving.hasEffect(MobEffects.BLINDNESS)) { -+ int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier(); -+ for (int i = 0; i < amplifier; i++) { -+ d *= this.level().purpurConfig.mobsBlindnessMultiplier; -+ } -+ } -+ } -+ // Purpur end - Configurable mob blindness -+ - return d; - } - -@@ -1104,6 +1128,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - Iterator iterator = this.activeEffects.values().iterator(); - while (iterator.hasNext()) { - MobEffectInstance effect = iterator.next(); -+ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur - Milk Keeps Beneficial Effects - EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); - if (event.isCancelled()) { - continue; -@@ -1436,6 +1461,24 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - this.stopSleeping(); - } - -+ // Purpur start - One Punch Man! -+ if (damageSource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damageSource.getEntity().level().purpurConfig.creativeOnePunch && !damageSource.is(DamageTypeTags.IS_PROJECTILE)) { -+ if (player.isCreative()) { -+ org.apache.commons.lang3.mutable.MutableDouble attackDamage = new org.apache.commons.lang3.mutable.MutableDouble(); -+ player.getMainHandItem().forEachModifier(EquipmentSlot.MAINHAND, (attributeHolder, attributeModifier) -> { -+ if (attributeModifier.operation() == AttributeModifier.Operation.ADD_VALUE) { -+ attackDamage.addAndGet(attributeModifier.amount()); -+ } -+ }); -+ -+ if (attackDamage.doubleValue() == 0.0D) { -+ // One punch! -+ amount = 9999F; -+ } -+ } -+ } -+ // Purpur end - One Punch Man! -+ - this.noActionTime = 0; - if (amount < 0.0F) { - amount = 0.0F; -@@ -1697,10 +1740,10 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - protected @Nullable Player resolvePlayerResponsibleForDamage(DamageSource damageSource) { - Entity entity = damageSource.getEntity(); - if (entity instanceof Player player) { -- this.setLastHurtByPlayer(player, 100); -+ this.setLastHurtByPlayer(player, this.level().purpurConfig.mobLastHurtByPlayerTime); // Purpur - Config for mob last hurt by player time - } else if (entity instanceof Wolf wolf && wolf.isTame()) { - if (wolf.getOwnerReference() != null) { -- this.setLastHurtByPlayer(wolf.getOwnerReference().getUUID(), 100); -+ this.setLastHurtByPlayer(wolf.getOwnerReference().getUUID(), this.level().purpurConfig.mobLastHurtByPlayerTime); // Purpur - Config for mob last hurt by player time - } else { - this.lastHurtByPlayer = null; - this.lastHurtByPlayerMemoryTime = 0; -@@ -1751,6 +1794,30 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - } - } - -+ // Purpur start - Totems work in inventory -+ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { -+ for (ItemStack item : player.getInventory().getNonEquipmentItems()) { -+ if (item.getItem() == Items.TOTEM_OF_UNDYING) { -+ itemInHand = item; -+ itemStack = item.copy(); -+ break; -+ } -+ } -+ } -+ // Purpur end - Totems work in inventory -+ -+ // Purpur start - Totems work in inventory -+ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { -+ for (ItemStack item : player.getInventory().getNonEquipmentItems()) { -+ if (item.getItem() == Items.TOTEM_OF_UNDYING) { -+ itemInHand = item; -+ itemStack = item.copy(); -+ break; -+ } -+ } -+ } -+ // Purpur end - Totems work in inventory -+ - final org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; - final EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot); - event.setCancelled(itemStack == null); -@@ -1932,6 +1999,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - boolean flag = this.lastHurtByPlayerMemoryTime > 0; - this.dropEquipment(level); // CraftBukkit - from below - if (this.shouldDropLoot(level)) { -+ if (!(damageSource.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level().purpurConfig.disableDropsOnCrammingDeath)) { // Purpur - Disable loot drops on death by cramming - this.dropFromLootTable(level, damageSource, flag); - // Paper start - final boolean prev = this.clearEquipmentSlots; -@@ -1940,6 +2008,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - // Paper end - this.dropCustomDeathLoot(level, damageSource, flag); - this.clearEquipmentSlots = prev; // Paper -+ } // Purpur - Disable loot drops on death by cramming - } - - // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment -@@ -3214,6 +3283,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - float f = (float)(d * 10.0 - 3.0); - if (f > 0.0F) { - this.playSound(this.getFallDamageSound((int)f), 1.0F, 1.0F); -+ if (level().purpurConfig.elytraKineticDamage) // Purpur - Toggle for kinetic damage - this.hurt(this.damageSources().flyIntoWall(), f); - } - } -@@ -4680,6 +4750,12 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin - : slot == equippable.slot() && this.canUseSlot(equippable.slot()) && equippable.canBeEquippedBy(this.getType()); - } - -+ // Purpur start - Dispenser curse of binding protection -+ public @Nullable EquipmentSlot getEquipmentSlotForDispenserItem(ItemStack itemstack) { -+ return EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BINDING_CURSE, itemstack) > 0 ? null : this.getEquipmentSlotForItem(itemstack); -+ } -+ // Purpur end - Dispenser curse of binding protection -+ - private static SlotAccess createEquipmentSlotAccess(LivingEntity entity, EquipmentSlot slot) { - return slot != EquipmentSlot.HEAD && slot != EquipmentSlot.MAINHAND && slot != EquipmentSlot.OFFHAND - ? SlotAccess.forEquipmentSlot(entity, slot, itemStack -> itemStack.isEmpty() || entity.getEquipmentSlotForItem(itemStack) == slot) diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/CatSpawner.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/CatSpawner.java.patch deleted file mode 100644 index 1756d7534..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/CatSpawner.java.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/npc/CatSpawner.java b/net/minecraft/world/entity/npc/CatSpawner.java -index 5401976c4fa86e2db6622743c8e8ea7381f72878..278a4000d06690a41e58a059d54e0044944a51fe 100644 ---- a/net/minecraft/world/entity/npc/CatSpawner.java -+++ b/net/minecraft/world/entity/npc/CatSpawner.java -@@ -23,7 +23,7 @@ public class CatSpawner implements CustomSpawner { - public void tick(ServerLevel level, boolean spawnEnemies) { - this.nextTick--; - if (this.nextTick <= 0) { -- this.nextTick = 1200; -+ this.nextTick = level.purpurConfig.catSpawnDelay; // Purpur - Cat spawning options - Player randomPlayer = level.getRandomPlayer(); - if (randomPlayer != null) { - RandomSource randomSource = level.random; -@@ -45,9 +45,12 @@ public class CatSpawner implements CustomSpawner { - } - - private void spawnInVillage(ServerLevel level, BlockPos pos) { -- int i = 48; -- if (level.getPoiManager().getCountInRange(holder -> holder.is(PoiTypes.HOME), pos, 48, PoiManager.Occupancy.IS_OCCUPIED) > 4L) { -- List entitiesOfClass = level.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(48.0, 8.0, 48.0)); -+ // Purpur start - Cat spawning options -+ int range = level.purpurConfig.catSpawnVillageScanRange; -+ if (range <= 0) return; -+ if (level.getPoiManager().getCountInRange(holder -> holder.is(PoiTypes.HOME), pos, range, PoiManager.Occupancy.IS_OCCUPIED) > 4L) { -+ List entitiesOfClass = level.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(range, 8.0, range)); -+ // Purpur end - Cat spawning options - if (entitiesOfClass.size() < 5) { - this.spawnCat(pos, level, false); - } -@@ -55,8 +58,11 @@ public class CatSpawner implements CustomSpawner { - } - - private void spawnInHut(ServerLevel level, BlockPos pos) { -- int i = 16; -- List entitiesOfClass = level.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(16.0, 8.0, 16.0)); -+ // Purpur start - Cat spawning options -+ int range = level.purpurConfig.catSpawnSwampHutScanRange; -+ if (range <= 0) return; -+ List entitiesOfClass = level.getEntitiesOfClass(Cat.class, new AABB(pos).inflate(range, 8.0, range)); -+ // Purpur end - Cat spawning options - if (entitiesOfClass.isEmpty()) { - this.spawnCat(pos, level, true); - } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch deleted file mode 100644 index 6d12df279..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java -index 3eb6ee2ffecbdeb6057d81b7936b80e205db7cdc..aceeb9919473f5ff1b84efe950d10aa4dbc10121 100644 ---- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java -+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java -@@ -61,6 +61,13 @@ public class WanderingTrader extends AbstractVillager implements Consumable.Over - super(type, level); - } - -+ // Purpur start - Allow leashing villagers -+ @Override -+ public boolean canBeLeashed() { -+ return level().purpurConfig.wanderingTraderCanBeLeashed; -+ } -+ // Purpur end - Allow leashing villagers -+ - @Override - protected void registerGoals() { - this.goalSelector.addGoal(0, new FloatGoal(this)); -@@ -81,7 +88,7 @@ public class WanderingTrader extends AbstractVillager implements Consumable.Over - this, - new ItemStack(Items.MILK_BUCKET), - SoundEvents.WANDERING_TRADER_REAPPEARED, -- wanderingTrader -> this.canDrinkMilk && this.level().isBrightOutside() && wanderingTrader.isInvisible() // Paper - Add more WanderingTrader API -+ wanderingTrader -> level().purpurConfig.milkClearsBeneficialEffects && this.canDrinkMilk && this.level().isBrightOutside() && wanderingTrader.isInvisible() // Paper - Add more WanderingTrader API // // Purpur - Milk Keeps Beneficial Effects - ) - ); - this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this)); -@@ -124,8 +131,10 @@ public class WanderingTrader extends AbstractVillager implements Consumable.Over - return InteractionResult.CONSUME; - } - -+ if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur - Add config for villager trading - this.setTradingPlayer(player); - this.openTradingScreen(player, this.getDisplayName(), 1); -+ } // Purpur - Add config for villager trading - } - - return InteractionResult.SUCCESS; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/player/Player.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/player/Player.java.patch deleted file mode 100644 index 132700bb1..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/player/Player.java.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index e5540b85cfa159d102a5710b4ccea5c3b61b7f1d..616c1aafcda05ae1d2a833f2f725b9eefb52cbc6 100644 ---- a/net/minecraft/world/entity/player/Player.java -+++ b/net/minecraft/world/entity/player/Player.java -@@ -179,11 +179,20 @@ public abstract class Player extends Avatar implements ContainerUser { - private int currentImpulseContextResetGraceTime = 0; - public boolean affectsSpawning = true; // Paper - Affects Spawning API - public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage -+ public int burpDelay = 0; // Purpur - Burp delay -+ public boolean canPortalInstant = false; // Purpur - Add portal permission bypass - - // CraftBukkit start - public boolean fauxSleeping; - public int oldLevel = -1; - -+ // Purpur start - AFK API -+ public abstract void setAfk(boolean afk); -+ -+ public boolean isAfk() { -+ return false; -+ } -+ // Purpur end - AFK API - @Override - public org.bukkit.craftbukkit.entity.CraftHumanEntity getBukkitEntity() { - return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity(); -@@ -245,6 +254,12 @@ public abstract class Player extends Avatar implements ContainerUser { - - @Override - public void tick() { -+ // Purpur start - Burp delay -+ if (this.burpDelay > 0 && --this.burpDelay == 0) { -+ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().random.nextFloat() * 0.1F + 0.9F); -+ } -+ // Purpur end - Burp delay -+ - this.noPhysics = this.isSpectator(); - if (this.isSpectator() || this.isPassenger()) { - this.setOnGround(false); -@@ -302,6 +317,17 @@ public abstract class Player extends Avatar implements ContainerUser { - this.turtleHelmetTick(); - } - -+ // Purpur start - Full netherite armor grants fire resistance -+ if (this.level().purpurConfig.playerNetheriteFireResistanceDuration > 0 && this.level().getGameTime() % 20 == 0) { -+ if (this.getItemBySlot(EquipmentSlot.HEAD).is(Items.NETHERITE_HELMET) -+ && this.getItemBySlot(EquipmentSlot.CHEST).is(Items.NETHERITE_CHESTPLATE) -+ && this.getItemBySlot(EquipmentSlot.LEGS).is(Items.NETHERITE_LEGGINGS) -+ && this.getItemBySlot(EquipmentSlot.FEET).is(Items.NETHERITE_BOOTS)) { -+ this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, this.level().purpurConfig.playerNetheriteFireResistanceDuration, this.level().purpurConfig.playerNetheriteFireResistanceAmplifier, this.level().purpurConfig.playerNetheriteFireResistanceAmbient, this.level().purpurConfig.playerNetheriteFireResistanceShowParticles, this.level().purpurConfig.playerNetheriteFireResistanceShowIcon), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.NETHERITE_ARMOR); -+ } -+ } -+ // Purpur end - Full netherite armor grants fire resistance -+ - this.cooldowns.tick(); - this.updatePlayerPose(); - if (this.currentImpulseContextResetGraceTime > 0) { -@@ -510,7 +536,7 @@ public abstract class Player extends Avatar implements ContainerUser { - List list = Lists.newArrayList(); - - for (Entity entity : entities) { -- if (entity.getType() == EntityType.EXPERIENCE_ORB) { -+ if (entity.getType() == EntityType.EXPERIENCE_ORB && entity.level().purpurConfig.playerExpPickupDelay >= 0) { // Purpur - Configurable player pickup exp delay - list.add(entity); - } else if (!entity.isRemoved()) { - this.touch(entity); -@@ -1052,7 +1078,7 @@ public abstract class Player extends Avatar implements ContainerUser { - flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits - if (flag2) { - damageSource = damageSource.critical(); // Paper - critical damage API -- f *= 1.5F; -+ f *= (float) this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur - Add config change multiplier critical damage value - } - - float f2 = f + f1; -@@ -1764,7 +1790,23 @@ public abstract class Player extends Avatar implements ContainerUser { - - @Override - protected int getBaseExperienceReward(ServerLevel level) { -- return !level.getGameRules().get(GameRules.KEEP_INVENTORY) && !this.isSpectator() ? Math.min(this.experienceLevel * 7, 100) : 0; -+ // Purpur start - Add player death exp control options -+ if (!level.getGameRules().get(GameRules.KEEP_INVENTORY) && !this.isSpectator()) { -+ int toDrop; -+ try { -+ toDrop = Math.round(((Number) scriptEngine.eval("let expLevel = " + experienceLevel + "; " + -+ "let expTotal = " + totalExperience + "; " + -+ "let exp = " + experienceProgress + "; " + -+ level().purpurConfig.playerDeathExpDropEquation)).floatValue()); -+ } catch (javax.script.ScriptException e) { -+ e.printStackTrace(); -+ toDrop = experienceLevel * 7; -+ } -+ return Math.min(toDrop, level().purpurConfig.playerDeathExpDropMax); -+ } else { -+ return 0; -+ } -+ // Purpur end - Add player death exp control options - } - - @Override -@@ -1808,6 +1850,13 @@ public abstract class Player extends Avatar implements ContainerUser { - return this.inventory.add(stack); - } - -+ // Purpur start - Player ridable in water option -+ @Override -+ public boolean dismountsUnderwater() { -+ return !level().purpurConfig.playerRidableInWater; -+ } -+ // Purpur end - Player ridable in water option -+ - public abstract @Nullable GameType gameMode(); - - @Override diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch deleted file mode 100644 index c117174d1..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java b/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java -index 483b8247d3be5839f9d764912ae5b879a9f729aa..fc29a8c27ce02ce81e3799fc999aba70b9800c10 100644 ---- a/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java -+++ b/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java -@@ -72,7 +72,7 @@ public class ThrownTrident extends AbstractArrow { - - Entity owner = this.getOwner(); - int i = this.entityData.get(ID_LOYALTY); -- if (i > 0 && (this.dealtDamage || this.isNoPhysics()) && owner != null) { -+ if (i > 0 && (this.dealtDamage || this.isNoPhysics() || (level().purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && getY() < level().purpurConfig.tridentLoyaltyVoidReturnHeight)) && owner != null) { // Purpur - Add option to allow loyalty on tridents to work in the void - if (!this.isAcceptibleReturnOwner()) { - if (this.level() instanceof ServerLevel serverLevel && this.pickup == AbstractArrow.Pickup.ALLOWED) { - this.spawnAtLocation(serverLevel, this.getPickupItem(), 0.1F); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch deleted file mode 100644 index 732923ba0..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java -index 66df6c69a95c5ca6b07294fdb3b13eee6651d22d..6ad07d8f82c0f745d3c3c742f25d05b9b38193c2 100644 ---- a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java -+++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java -@@ -112,9 +112,10 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { - return; - } - // CraftBukkit end -- if (this.random.nextFloat() < 0.05F && serverLevel.isSpawningMonsters()) { -+ if (this.random.nextFloat() < serverLevel.purpurConfig.enderPearlEndermiteChance && serverLevel.isSpawningMonsters()) { // Purpur - Configurable Ender Pearl RNG - Endermite endermite = EntityType.ENDERMITE.create(serverLevel, EntitySpawnReason.TRIGGERED); - if (endermite != null) { -+ endermite.setPlayerSpawned(true); // Purpur - Add back player spawned endermite API - endermite.snapTo(preTeleportX, preTeleportY, preTeleportZ, preTeleportYRot, preTeleportXRot); // Paper - spawn endermite at pre teleport position as teleport has been moved up - serverLevel.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); // Paper - add reason - } -@@ -134,7 +135,7 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { - if (serverPlayer1 != null) { - serverPlayer1.resetFallDistance(); - serverPlayer1.resetCurrentImpulseContext(); -- serverPlayer1.hurtServer(serverPlayer.level(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API -+ serverPlayer1.hurtServer(serverPlayer.level(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage - } - - this.playSound(serverLevel, vec3); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch deleted file mode 100644 index 4e9342059..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java -index 6b337848d91cc4f24655d053bc69b0cd22447dda..d17269c9274bd29c761403138bfc56355c800d9c 100644 ---- a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java -+++ b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java -@@ -431,6 +431,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable { - float groundFriction = this.getGroundFriction(); - if (groundFriction > 0.0F) { - this.landFriction = groundFriction; -+ if (level().purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur - Add option for boats to eject players on land - return AbstractBoat.Status.ON_LAND; - } else { - return AbstractBoat.Status.IN_AIR; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch deleted file mode 100644 index 34658d173..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java b/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java -index 7cc494d53c9a6d2fa0d34a60da50a9d199d65340..84b11654411eaa561a9b58ffa1210ca3d3b5a7cd 100644 ---- a/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java -+++ b/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java -@@ -391,7 +391,7 @@ public class NewMinecartBehavior extends MinecartBehavior { - private Vec3 calculateBoostTrackSpeed(Vec3 speed, BlockPos pos, BlockState state) { - if (state.is(Blocks.POWERED_RAIL) && state.getValue(PoweredRailBlock.POWERED)) { - if (speed.length() > 0.01) { -- return speed.normalize().scale(speed.length() + 0.06); -+ return speed.normalize().scale(speed.length() + this.level().purpurConfig.poweredRailBoostModifier); // Purpur - Configurable powered rail boost modifier - } else { - Vec3 redstoneDirection = this.minecart.getRedstoneDirection(pos); - return redstoneDirection.lengthSqr() <= 0.0 ? speed : redstoneDirection.scale(speed.length() + 0.2); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch deleted file mode 100644 index ed1dfb486..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java b/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java -index 780b53eab14a087436e5f27c8d646042f4b357c9..7ab2542ddd7494585f240657906ccee80cd7944e 100644 ---- a/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java -+++ b/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java -@@ -243,8 +243,8 @@ public class OldMinecartBehavior extends MinecartBehavior { - Vec3 deltaMovement1 = this.getDeltaMovement(); - double d13 = deltaMovement1.horizontalDistance(); - if (d13 > 0.01) { -- double d14 = 0.06; -- this.setDeltaMovement(deltaMovement1.add(deltaMovement1.x / d13 * 0.06, 0.0, deltaMovement1.z / d13 * 0.06)); -+ double d14 = level.purpurConfig.poweredRailBoostModifier; // Purpur - Configurable powered rail boost modifier -+ this.setDeltaMovement(deltaMovement1.add(deltaMovement1.x / d13 * level.purpurConfig.poweredRailBoostModifier, 0.0, deltaMovement1.z / d13 * level.purpurConfig.poweredRailBoostModifier)); // Purpur - Configurable powered rail boost modifier - } else { - Vec3 deltaMovement2 = this.getDeltaMovement(); - double d15 = deltaMovement2.x; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch b/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch deleted file mode 100644 index 77bf2b244..000000000 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/level/block/piston/PistonStructureResolver.java b/net/minecraft/world/level/block/piston/PistonStructureResolver.java -index ad143a92569f5b420ccaa2089758b2fb3b4ab7c5..5a3660e02bc805e9a35a81b8a61f07b3f20b5ba9 100644 ---- a/net/minecraft/world/level/block/piston/PistonStructureResolver.java -+++ b/net/minecraft/world/level/block/piston/PistonStructureResolver.java -@@ -81,7 +81,7 @@ public class PistonStructureResolver { - return true; - } else { - int i = 1; -- if (i + this.toPush.size() > 12) { -+ if (i + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit - return false; - } else { - while (isSticky(blockState)) { -@@ -95,7 +95,7 @@ public class PistonStructureResolver { - break; - } - -- if (++i + this.toPush.size() > 12) { -+ if (++i + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit - return false; - } - } -@@ -140,7 +140,7 @@ public class PistonStructureResolver { - return true; - } - -- if (this.toPush.size() >= 12) { -+ if (this.toPush.size() >= this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit - return false; - } - diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/CommandSourceStack.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/commands/CommandSourceStack.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/commands/CommandSourceStack.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/commands/CommandSourceStack.java.patch index aba60d83c..28f2bdf95 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/CommandSourceStack.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/commands/CommandSourceStack.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java -index 566304106fd4f1c677a56e7c66282d1570e7b974..21d135189a4d67605e0dfb991283d48268ce5d5c 100644 --- a/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java -@@ -430,6 +430,19 @@ public class CommandSourceStack implements ExecutionCommandSource io.papermc.paper.adventure.PaperAdventure.asVanilla(message), broadcastToOps); + } + // Purpur end - Purpur config files -+ - public void sendSuccess(Supplier messageSupplier, boolean allowLogging) { - boolean flag = this.source.acceptsSuccess() && !this.silent; - boolean flag1 = allowLogging && this.source.shouldInformAdmins() && !this.silent; + + public void sendSuccess(final Supplier messageSupplier, final boolean broadcast) { + boolean shouldSendSystemMessage = this.source.acceptsSuccess() && !this.silent; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/Commands.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch similarity index 78% rename from purpur-server/minecraft-patches/rejected/net/minecraft/commands/Commands.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch index 00a6f9cb4..ae21764c0 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/commands/Commands.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/commands/Commands.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java -index 668eb52d71d77f75c24d4840be9a6c49d96dfc34..83148f756ecc77ae45abffbd1d7cbfacf6c99e7f 100644 --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -265,11 +265,11 @@ public class Commands { +@@ -268,11 +_,11 @@ JfrCommand.register(this.dispatcher); } @@ -22,7 +14,7 @@ index 668eb52d71d77f75c24d4840be9a6c49d96dfc34..83148f756ecc77ae45abffbd1d7cbfac RaidCommand.register(this.dispatcher, context); DebugPathCommand.register(this.dispatcher); DebugMobSpawningCommand.register(this.dispatcher); -@@ -297,6 +297,14 @@ public class Commands { +@@ -300,6 +_,14 @@ StopCommand.register(this.dispatcher); TransferCommand.register(this.dispatcher); WhitelistCommand.register(this.dispatcher); @@ -36,21 +28,21 @@ index 668eb52d71d77f75c24d4840be9a6c49d96dfc34..83148f756ecc77ae45abffbd1d7cbfac + org.purpurmc.purpur.command.RamCommand.register(this.dispatcher); // Purpur - Add ram command } - if (selection.includeIntegrated) { -@@ -522,6 +530,7 @@ public class Commands { - private void runSync(ServerPlayer player, java.util.Collection bukkit, RootCommandNode rootCommandNode) { + if (commandSelection.includeIntegrated) { +@@ -522,6 +_,7 @@ + private void runSync(ServerPlayer player, java.util.Collection bukkit, RootCommandNode root) { // Paper end - Perf: Async command map building - new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, true).callEvent(); // Paper - Brigadier API + new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) root, true).callEvent(); // Paper - Brigadier API + if (org.bukkit.event.player.PlayerCommandSendEvent.getHandlerList().getRegisteredListeners().length > 0) { // Purpur - Skip events if there's no listeners org.bukkit.event.player.PlayerCommandSendEvent event = new org.bukkit.event.player.PlayerCommandSendEvent(player.getBukkitEntity(), new java.util.LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -532,6 +541,8 @@ public class Commands { +@@ -532,6 +_,8 @@ } } // CraftBukkit end + } // Purpur - Skip events if there's no listeners + - player.connection.send(new ClientboundCommandsPacket(rootCommandNode, COMMAND_NODE_INSPECTOR)); + player.connection.send(new ClientboundCommandsPacket(root, COMMAND_NODE_INSPECTOR)); } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch new file mode 100644 index 000000000..7e2801498 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/commands/arguments/selector/EntitySelector.java ++++ b/net/minecraft/commands/arguments/selector/EntitySelector.java +@@ -206,26 +_,27 @@ + this.checkPermissions(sender); + if (this.playerName != null) { + ServerPlayer result = sender.getServer().getPlayerList().getPlayerByName(this.playerName); +- return result == null ? List.of() : List.of(result); ++ return result == null || !canSee(sender, result) ? List.of() : List.of(result); // Purpur - Hide hidden players from entity selector + } else if (this.entityUUID != null) { + ServerPlayer result = sender.getServer().getPlayerList().getPlayer(this.entityUUID); +- return result == null ? List.of() : List.of(result); ++ return result == null || !canSee(sender, result) ? List.of() : List.of(result); // Purpur - Hide hidden players from entity selector + } else { + Vec3 pos = this.position.apply(sender.getPosition()); + AABB absoluteAabb = this.getAbsoluteAabb(pos); + Predicate predicate = this.getPredicate(pos, absoluteAabb, null); + if (this.currentEntity) { +- return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) ? List.of(player) : List.of(); ++ return sender.getEntity() instanceof ServerPlayer player && predicate.test(player) && canSee(sender, player) ? List.of(player) : List.of(); // Purpur - Hide hidden players from entity selector + } else { + int limit = this.getResultLimit(); + List result; + if (this.isWorldLimited()) { + result = sender.getLevel().getPlayers(predicate, limit); ++ result.removeIf(entityplayer3 -> !canSee(sender, entityplayer3)); // Purpur - Hide hidden players from entity selector + } else { + result = new ObjectArrayList<>(); + + for (ServerPlayer player : sender.getServer().getPlayerList().getPlayers()) { +- if (predicate.test(player)) { ++ if (predicate.test(player) && canSee(sender, player)) { // Purpur - Hide hidden players from entity selector + result.add(player); + if (result.size() >= limit) { + return result; +@@ -283,4 +_,10 @@ + public static Component joinNames(final List entities) { + return ComponentUtils.formatList(entities, Entity::getDisplayName); + } ++ ++ // Purpur start - Hide hidden players from entity selector ++ private boolean canSee(CommandSourceStack sender, ServerPlayer target) { ++ return !org.purpurmc.purpur.PurpurConfig.hideHiddenPlayersFromEntitySelector || !(sender.getEntity() instanceof ServerPlayer player) || player.getBukkitEntity().canSee(target.getBukkitEntity()); ++ } ++ // Purpur end - Hide hidden players from entity selector + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch new file mode 100644 index 000000000..d2d012b44 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/core/BlockPos.java ++++ b/net/minecraft/core/BlockPos.java +@@ -58,6 +_,12 @@ + private static final int X_OFFSET = PACKED_Y_LENGTH + PACKED_HORIZONTAL_LENGTH; + public static final int MAX_HORIZONTAL_COORDINATE = (1 << PACKED_HORIZONTAL_LENGTH) / 2 - 1; + ++ // Purpur start - Ridables ++ public BlockPos(net.minecraft.world.entity.Entity entity) { ++ super(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()); ++ } ++ // Purpur end - Ridables ++ + public BlockPos(final int x, final int y, final int z) { + super(x, y, z); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch new file mode 100644 index 000000000..bfc31c584 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java ++++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +@@ -31,7 +_,7 @@ + return false; + } else { + LivingEntity target = entities.getFirst(); +- EquipmentSlot slot = target.getEquipmentSlotForItem(dispensed); ++ EquipmentSlot slot = source.level().purpurConfig.dispenserApplyCursedArmor ? target.getEquipmentSlotForItem(dispensed) : target.getEquipmentSlotForDispenserItem(dispensed); if (slot == null) return false; // Purpur - Dispenser curse of binding protection + ItemStack equip = dispensed.copyWithCount(1); // Paper - shrink below and single item in event + // CraftBukkit start + net.minecraft.world.level.Level world = source.level(); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/gametest/framework/TestCommand.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/gametest/framework/TestCommand.java.patch new file mode 100644 index 000000000..dca3acc9a --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/gametest/framework/TestCommand.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/gametest/framework/TestCommand.java ++++ b/net/minecraft/gametest/framework/TestCommand.java +@@ -424,7 +_,7 @@ + ) + ) + ); +- if (SharedConstants.IS_RUNNING_IN_IDE) { ++ if (org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands || SharedConstants.IS_RUNNING_IN_IDE) { // Purpur - register minecraft debug commands + testCommand = testCommand.then( + Commands.literal("export") + .then( diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/Main.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/Main.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/Main.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/Main.java.patch index 3f5a1647e..a5ed8bd61 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/Main.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/Main.java.patch @@ -1,24 +1,16 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 9216e85e74bb0121c72665f155b07cf9a37f430a..31ce71305260f082729780d4e8fb4dba557f9883 100644 --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -105,6 +105,13 @@ public class Main { +@@ -104,6 +_,13 @@ JvmProfiler.INSTANCE.start(Environment.SERVER); } + // Purpur start - Add toggle for enchant level clamping - load config files early -+ org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("purpur-settings")); ++ org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) options.valueOf("purpur-settings")); + org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true); + org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands + org.purpurmc.purpur.PurpurConfig.registerMinecraftDisabledCommands = purpurConfiguration.getBoolean("settings.register-minecraft-disabled-commands"); // Purpur - register disabled minecraft commands + // Purpur end - Add toggle for enchant level clamping - load config files early + - io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper + io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper Bootstrap.bootStrap(); Bootstrap.validate(); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/PlayerAdvancements.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/PlayerAdvancements.java.patch similarity index 50% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/PlayerAdvancements.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index d44bf91fb..1e1afb420 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/PlayerAdvancements.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -1,23 +1,15 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java -index 98004b77b7f40d315f41be82105df6d4b9000e33..9612e9dd36010ffcc0e038301233d90b3ed7aeed 100644 --- a/net/minecraft/server/PlayerAdvancements.java +++ b/net/minecraft/server/PlayerAdvancements.java -@@ -146,6 +146,7 @@ public class PlayerAdvancements { - AdvancementHolder advancementHolder = advancementManager.get(path); - if (advancementHolder == null) { - if (!path.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) return; // CraftBukkit +@@ -148,6 +_,7 @@ + AdvancementHolder advancement = manager.get(id); + if (advancement == null) { + if (!id.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) return; // CraftBukkit + if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressIgnoredAdvancementWarnings) // Purpur - Logger settings (suppressing pointless logs) - LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath); + LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", id, this.playerSavePath); } else { - this.startProgress(advancementHolder, progress); -@@ -193,6 +194,7 @@ public class PlayerAdvancements { - advancement.value().display().ifPresent(displayInfo -> { + this.startProgress(advancement, progress); +@@ -195,6 +_,7 @@ + holder.value().display().ifPresent(display -> { // Paper start - Add Adventure message to PlayerAdvancementDoneEvent if (event.message() != null && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) { + if (org.purpurmc.purpur.PurpurConfig.advancementOnlyBroadcastToAffectedPlayer) this.player.sendMessage(message); else // Purpur - Configurable broadcast settings diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch new file mode 100644 index 000000000..c77c16529 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/EnchantCommand.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/commands/EnchantCommand.java ++++ b/net/minecraft/server/commands/EnchantCommand.java +@@ -67,7 +_,7 @@ + final CommandSourceStack source, final Collection targets, final Holder enchantmentHolder, final int level + ) throws CommandSyntaxException { + Enchantment enchantment = enchantmentHolder.value(); +- if (level > enchantment.getMaxLevel()) { ++ if (!org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && level > enchantment.getMaxLevel()) { // Purpur - Config to allow unsafe enchants + throw ERROR_LEVEL_TOO_HIGH.create(level, enchantment.getMaxLevel()); + } else { + int success = 0; +@@ -77,7 +_,7 @@ + ItemStack item = target.getMainHandItem(); + if (!item.isEmpty()) { + if (enchantment.canEnchant(item) +- && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder)) { ++ && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(item).keySet(), enchantmentHolder) || (org.purpurmc.purpur.PurpurConfig.allowUnsafeEnchantCommand && !mainHandItem.hasEnchantment(enchantment))) { // Purpur - Config to allow unsafe enchants + item.enchant(enchantmentHolder, level); + success++; + } else if (targets.size() == 1) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GameModeCommand.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch similarity index 53% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GameModeCommand.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch index eb392822f..3a0a7cc8d 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/commands/GameModeCommand.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch @@ -1,20 +1,12 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/commands/GameModeCommand.java b/net/minecraft/server/commands/GameModeCommand.java -index 503447fbb54bed493f1d867c75ef3f344fe7b81b..a601df223c685f435241cd193a912898e60bab03 100644 --- a/net/minecraft/server/commands/GameModeCommand.java +++ b/net/minecraft/server/commands/GameModeCommand.java -@@ -53,6 +53,18 @@ public class GameModeCommand { +@@ -47,6 +_,18 @@ } - private static int setMode(CommandContext context, Collection players, GameType gameType) { + private static int setMode(final CommandContext context, final Collection players, final GameType type) { + // Purpur start - Gamemode extra permissions + if (org.purpurmc.purpur.PurpurConfig.commandGamemodeRequiresPermission) { -+ String gamemode = gameType.getName(); ++ String gamemode = type.getName(); + CommandSourceStack sender = context.getSource(); + if (!sender.testPermission(Permissions.COMMANDS_GAMEMASTER, "minecraft.command.gamemode." + gamemode)) { + return 0; @@ -24,6 +16,6 @@ index 503447fbb54bed493f1d867c75ef3f344fe7b81b..a601df223c685f435241cd193a912898 + } + } + // Purpur end - Gamemode extra permissions - int i = 0; + int count = 0; - for (ServerPlayer serverPlayer : players) { + for (ServerPlayer player : players) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GiveCommand.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GiveCommand.java.patch new file mode 100644 index 000000000..7b54e64f5 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/commands/GiveCommand.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/commands/GiveCommand.java ++++ b/net/minecraft/server/commands/GiveCommand.java +@@ -61,6 +_,7 @@ + remaining -= size; + ItemStack copyToDrop = prototypeItemStack.copyWithCount(size); + boolean added = player.getInventory().add(copyToDrop); ++ if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping + if (added && copyToDrop.isEmpty()) { + ItemEntity drop = player.drop(prototypeItemStack.copy(), false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command + if (drop != null) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/gui/MinecraftServerGui.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/gui/MinecraftServerGui.java.patch new file mode 100644 index 000000000..8b532b8ac --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/gui/MinecraftServerGui.java.patch @@ -0,0 +1,135 @@ +--- a/net/minecraft/server/gui/MinecraftServerGui.java ++++ b/net/minecraft/server/gui/MinecraftServerGui.java +@@ -40,6 +_,11 @@ + private Thread logAppenderThread; + private final Collection finalizers = Lists.newArrayList(); + private final AtomicBoolean isClosing = new AtomicBoolean(); ++ // Purpur start - GUI Improvements ++ private final CommandHistory history = new CommandHistory(); ++ private String currentCommand = ""; ++ private int historyIndex = 0; ++ // Purpur end - GUI Improvements + + public static MinecraftServerGui showFrameFor(final DedicatedServer server) { + try { +@@ -47,7 +_,7 @@ + } catch (Exception var3) { + } + +- final JFrame frame = new JFrame("Minecraft server"); ++ final JFrame frame = new JFrame("Purpur Minecraft server"); // Purpur - Improve GUI + final MinecraftServerGui gui = new MinecraftServerGui(server); + frame.setDefaultCloseOperation(2); + frame.add(gui); +@@ -55,7 +_,7 @@ + frame.setLocationRelativeTo(null); + frame.setVisible(true); + // Paper start - Improve ServerGUI +- frame.setName("Minecraft server"); ++ frame.setName("Purpur Minecraft server"); // Purpur - Improve GUI + try { + frame.setIconImage(javax.imageio.ImageIO.read(java.util.Objects.requireNonNull(MinecraftServerGui.class.getClassLoader().getResourceAsStream("logo.png")))); + } catch (java.io.IOException ignore) { +@@ -65,7 +_,7 @@ + @Override + public void windowClosing(final WindowEvent event) { + if (!gui.isClosing.getAndSet(true)) { +- frame.setTitle("Minecraft server - shutting down!"); ++ frame.setTitle("Purpur Minecraft server - shutting down!"); // Purpur - Improve GUI + server.halt(true); + gui.runFinalizers(); + } +@@ -113,7 +_,7 @@ + + private JComponent buildChatPanel() { + JPanel panel = new JPanel(new BorderLayout()); +- JTextArea chatArea = new JTextArea(); ++ org.purpurmc.purpur.gui.JColorTextPane chatArea = new org.purpurmc.purpur.gui.JColorTextPane(); // Purpur - GUI Improvements + JScrollPane scrollPane = new JScrollPane(chatArea, 22, 30); + chatArea.setEditable(false); + chatArea.setFont(MONOSPACED); +@@ -122,10 +_,43 @@ + String text = chatField.getText().trim(); + if (!text.isEmpty()) { + this.server.handleConsoleInput(text, this.server.createCommandSourceStack()); ++ // Purpur start - GUI Improvements ++ history.add(text); ++ historyIndex = -1; ++ // Purpur end - GUI Improvements + } + + chatField.setText(""); + }); ++ // Purpur start - GUI Improvements ++ chatField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("UP"), "up"); ++ chatField.getInputMap().put(javax.swing.KeyStroke.getKeyStroke("DOWN"), "down"); ++ chatField.getActionMap().put("up", new javax.swing.AbstractAction() { ++ @Override ++ public void actionPerformed(java.awt.event.ActionEvent actionEvent) { ++ if (historyIndex < 0) { ++ currentCommand = chatField.getText(); ++ } ++ if (historyIndex < history.size() - 1) { ++ chatField.setText(history.get(++historyIndex)); ++ } ++ } ++ }); ++ chatField.getActionMap().put("down", new javax.swing.AbstractAction() { ++ @Override ++ public void actionPerformed(java.awt.event.ActionEvent actionEvent) { ++ if (historyIndex >= 0) { ++ if (historyIndex == 0) { ++ --historyIndex; ++ chatField.setText(currentCommand); ++ } else { ++ --historyIndex; ++ chatField.setText(history.get(historyIndex)); ++ } ++ } ++ } ++ }); ++ // Purpur end - GUI Improvements + chatArea.addFocusListener(new FocusAdapter() { + { + Objects.requireNonNull(MinecraftServerGui.this); +@@ -164,7 +_,7 @@ + } + + private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper +- public void print(final JTextArea console, final JScrollPane scrollPane, final String line) { ++ public void print(final org.purpurmc.purpur.gui.JColorTextPane console, final JScrollPane scrollPane, final String line) { + if (!SwingUtilities.isEventDispatchThread()) { + SwingUtilities.invokeLater(() -> this.print(console, scrollPane, line)); + } else { +@@ -175,16 +_,29 @@ + shouldScroll = scrollBar.getValue() + scrollBar.getSize().getHeight() + MONOSPACED.getSize() * 4 > scrollBar.getMaximum(); + } + +- try { ++ /*try { // Purpur - GUI Improvements + document.insertString(document.getLength(), MinecraftServerGui.ANSI.matcher(line).replaceAll(""), null); // CraftBukkit + } catch (BadLocationException var8) { +- } ++ }*/ // Purpur - GUI Improvements ++ console.append(line); // Purpur - GUI Improvements + + if (shouldScroll) { + scrollBar.setValue(Integer.MAX_VALUE); + } + } + } ++ ++ // Purpur start - GUI Improvements ++ public static class CommandHistory extends java.util.LinkedList { ++ @Override ++ public boolean add(String command) { ++ if (size() > 1000) { ++ remove(); ++ } ++ return super.offerFirst(command); ++ } ++ } ++ // Purpur end - GUI Improvements + + // Paper start - Add onboarding message for initial server start + private JComponent buildOnboardingPanel() { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayer.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch similarity index 72% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayer.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 8daf28a74..0796377e5 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayer.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c550d39e75 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -433,6 +433,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -447,6 +_,9 @@ public boolean isRealPlayer; // Paper public com.destroystokyo.paper.event.entity.@Nullable PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public org.bukkit.event.player.PlayerQuitEvent.@Nullable 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 @@ -16,9 +8,9 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 + private boolean compassBar = false; // Purpur - Add compass command + private boolean ramBar = false; // Purpur - Implement rambar commands - // Paper start - rewrite chunk system - private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; -@@ -506,6 +509,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + public ServerPlayer(final MinecraftServer server, final ServerLevel level, final GameProfile gameProfile, final ClientInformation clientInformation) { + super(level, gameProfile); +@@ -490,6 +_,9 @@ this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null); this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false); this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null); @@ -28,7 +20,7 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 // Paper start - Expand PlayerGameModeChangeEvent this.loadGameTypes(input); } -@@ -547,6 +553,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -531,6 +_,9 @@ output.store("ShoulderEntityRight", CompoundTag.CODEC, this.getShoulderEntityRight()); } this.getBukkitEntity().setExtraData(output); // CraftBukkit @@ -37,8 +29,8 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 + output.putBoolean("Purpur.RamBar", this.ramBar); // Purpur - Add rambar command } - private void saveParentVehicle(ValueOutput output) { -@@ -1183,6 +1192,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + private void saveParentVehicle(final ValueOutput playerOutput) { +@@ -1166,6 +_,7 @@ // Paper - moved up to sendClientboundPlayerCombatKillPacket() sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent Team team = this.getTeam(); @@ -46,67 +38,67 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) { this.server.getPlayerList().broadcastSystemMessage(deathMessage, false); } else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { -@@ -1290,6 +1300,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc - if (this.isInvulnerableTo(level, damageSource)) { +@@ -1274,6 +_,13 @@ + if (this.isInvulnerableTo(level, source)) { return false; } else { + // Purpur start - Add boat fall damage config -+ if (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) { ++ if (source.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) { + if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.boat.Boat && !level().purpurConfig.boatsDoFallDamage) { + return false; + } + } + // Purpur end - Add boat fall damage config - Entity entity = damageSource.getEntity(); + Entity entity = source.getEntity(); if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false. - !(entity instanceof Player player && !this.canHarmPlayer(player)) -@@ -1544,6 +1561,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + !(entity instanceof Player playerx && !this.canHarmPlayer(playerx)) +@@ -1531,6 +_,7 @@ - profilerFiller.pop(); - profilerFiller.push("placing"); + profiler.pop(); + profiler.push("placing"); + this.portalPos = org.bukkit.craftbukkit.util.CraftLocation.toBlockPosition(exit); // Purpur - Fix stuck in portals - this.setServerLevel(level); - this.connection.internalTeleport(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); // CraftBukkit - use internal teleport without event + this.setServerLevel(newLevel); + this.connection.internalTeleport(PositionMoveRotation.of(transition), transition.relatives()); // CraftBukkit - use internal teleport without event this.connection.resetPosition(); -@@ -1652,7 +1670,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc - new AABB(vec3.x() - 8.0, vec3.y() - 5.0, vec3.z() - 8.0, vec3.x() + 8.0, vec3.y() + 5.0, vec3.z() + 8.0), +@@ -1647,7 +_,7 @@ + ), monster -> monster.isPreventingPlayerRest(this.level(), this) ); -- if (!entitiesOfClass.isEmpty()) { -+ if (!this.level().purpurConfig.playerSleepNearMonsters && !entitiesOfClass.isEmpty()) { // Purpur - Config to ignore nearby mobs when sleeping +- if (!monsters.isEmpty()) { ++ if (!this.level().purpurConfig.playerSleepNearMonsters && !monsters.isEmpty()) { // Purpur - Config to ignore nearby mobs when sleeping return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } -@@ -1692,8 +1710,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1687,8 +_,19 @@ CriteriaTriggers.SLEPT_IN_BED.trigger(this); }); if (!this.level().canSleepThroughNights()) { -- this.displayClientMessage(Component.translatable("sleep.not_possible"), true); +- this.sendOverlayMessage(Component.translatable("sleep.not_possible")); + // Purpur start - Customizable sleeping actionbar messages -+ Component clientMessage; -+ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) { -+ clientMessage = null; -+ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) { -+ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible)); -+ } else { ++ Component clientMessage; ++ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) { ++ clientMessage = null; ++ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) { ++ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible)); ++ } else { + clientMessage = Component.translatable("sleep.not_possible"); } + if (clientMessage != null) { -+ this.displayClientMessage(clientMessage, true); ++ this.sendOverlayMessage(clientMessage); + }// Purpur end - Customizable sleeping actionbar messages + } this.level().updateSleepingPlayerList(); - return either; -@@ -1784,6 +1813,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + return result; +@@ -1782,6 +_,7 @@ @Override - public void openTextEdit(SignBlockEntity signEntity, boolean isFrontText) { -+ if (level().purpurConfig.signAllowColors) this.connection.send(signEntity.getTranslatedUpdatePacket(textFilteringEnabled, isFrontText)); // Purpur - Signs allow color codes - this.connection.send(new ClientboundBlockUpdatePacket(this.level(), signEntity.getBlockPos())); - this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText)); + public void openTextEdit(final SignBlockEntity sign, final boolean isFrontText) { ++ if (level().purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled, isFrontText)); // Purpur - Signs allow color codes + this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos())); + this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), isFrontText)); } -@@ -2121,6 +2151,26 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -2125,6 +_,26 @@ this.lastSentExp = -1; // CraftBukkit - Added to reset } @@ -125,15 +117,15 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 + + public void sendActionBarMessage(@Nullable Component message) { + if (message != null) { -+ displayClientMessage(message, true); ++ sendOverlayMessage(message); + } + } + // Purpur end - Component related conveniences + @Override - public void displayClientMessage(Component message, boolean overlay) { - this.sendSystemMessage(message, overlay); -@@ -2355,6 +2405,20 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + public void completeUsingItem() { + if (!this.useItem.isEmpty() && this.isUsingItem()) { +@@ -2364,6 +_,20 @@ ); } @@ -151,16 +143,17 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 + } + // Purpur end - Component related conveniences + - public void sendSystemMessage(Component message) { + @Override + public void sendSystemMessage(final Component message) { this.sendSystemMessage(message, false); - } -@@ -2492,8 +2556,68 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -2511,7 +_,67 @@ public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); +- } + this.setAfk(false); // Purpur - AFK API - } - ++ } ++ + // Purpur start - AFK API + private boolean isAfk = false; + @@ -219,11 +212,10 @@ index 79c804245c7f41a5a7f062e1c5e01760adde7d84..a16813766ad244c002a752b0c03779c5 + return !this.isAfk() && super.canBeCollidedWith(entity); + } + // Purpur end - AFK API -+ + public ServerStatsCounter getStats() { return this.stats; - } -@@ -3126,4 +3250,65 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -3136,4 +_,65 @@ return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch similarity index 50% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayerGameMode.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 9c3cbeaa0..ecc241585 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java -index 84d19d79e77cec6a5d64f59fbcce703e467b2407..9b9cdb23a55b82efbeea3ba68b8144c15791dff0 100644 --- a/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -365,6 +365,7 @@ public class ServerPlayerGameMode { +@@ -364,6 +_,7 @@ } return false; } @@ -16,26 +8,26 @@ index 84d19d79e77cec6a5d64f59fbcce703e467b2407..9b9cdb23a55b82efbeea3ba68b8144c1 } // CraftBukkit end -@@ -490,6 +491,7 @@ public class ServerPlayerGameMode { - public InteractionHand interactHand; - public ItemStack interactItemStack; - public InteractionResult useItemOn(ServerPlayer player, Level level, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) { -+ if (shiftClickMended(stack)) return InteractionResult.SUCCESS; // Purpur - Shift right click to use exp for mending - BlockPos blockPos = hitResult.getBlockPos(); - BlockState blockState = level.getBlockState(blockPos); +@@ -494,6 +_,7 @@ + public InteractionResult useItemOn( + final ServerPlayer player, final Level level, final ItemStack itemStack, final InteractionHand hand, final BlockHitResult hitResult + ) { ++ if (shiftClickMended(itemStack)) return InteractionResult.SUCCESS; // Purpur - Shift right click to use exp for mending + BlockPos pos = hitResult.getBlockPos(); + BlockState state = level.getBlockState(pos); boolean cancelledBlock = false; -@@ -538,7 +540,7 @@ public class ServerPlayerGameMode { - boolean flag = !player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty(); - boolean flag1 = player.isSecondaryUseActive() && flag; - ItemStack itemStack = stack.copy(); -- if (!flag1) { -+ if (!flag1 || (player.level().purpurConfig.composterBulkProcess && blockState.is(net.minecraft.world.level.block.Blocks.COMPOSTER))) { // Purpur - Sneak to bulk process composter - InteractionResult interactionResult = blockState.useItemOn(player.getItemInHand(hand), level, player, hand, hitResult); - if (interactionResult.consumesAction()) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(player, blockPos, itemStack); -@@ -584,4 +586,18 @@ public class ServerPlayerGameMode { - public void setLevel(ServerLevel level) { - this.level = level; +@@ -542,7 +_,7 @@ + boolean haveSomethingInOurHands = !player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty(); + boolean suppressUsingBlock = player.isSecondaryUseActive() && haveSomethingInOurHands; + ItemStack usedItemStack = itemStack.copy(); +- if (!suppressUsingBlock) { ++ if (!suppressUsingBlock || (player.level().purpurConfig.composterBulkProcess && state.is(net.minecraft.world.level.block.Blocks.COMPOSTER))) { // Purpur - Sneak to bulk process composter + InteractionResult itemUse = state.useItemOn(player.getItemInHand(hand), level, player, hand, hitResult); + if (itemUse.consumesAction()) { + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(player, pos, usedItemStack); +@@ -588,4 +_,18 @@ + public void setLevel(final ServerLevel newLevel) { + this.level = newLevel; } + + // Purpur start - Shift right click to use exp for mending diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index a72318178..6856e43a1 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13d9d93dc5 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -346,6 +346,20 @@ public class ServerGamePacketListenerImpl +@@ -354,6 +_,20 @@ } // Paper end - configuration phase API @@ -25,11 +17,11 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 + } + ); + // Purpur end - AFK API -+ ++ @Override public void tick() { if (this.isDisconnected()) return; // Paper -@@ -364,6 +378,12 @@ public class ServerGamePacketListenerImpl +@@ -372,6 +_,12 @@ && this.server.playerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > TimeUnit.MINUTES.toMillis(this.server.playerIdleTimeout()) && !this.player.wonGame) { @@ -42,7 +34,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } } -@@ -683,6 +703,8 @@ public class ServerGamePacketListenerImpl +@@ -682,6 +_,8 @@ this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -51,7 +43,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -@@ -762,6 +784,7 @@ public class ServerGamePacketListenerImpl +@@ -738,6 +_,7 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { @@ -59,7 +51,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause return; } -@@ -1302,6 +1325,10 @@ public class ServerGamePacketListenerImpl +@@ -1306,6 +_,10 @@ final int maxBookPageSize = pageMax.intValue(); final double multiplier = Math.clamp(io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier, 0.3D, 1D); long byteAllowed = maxBookPageSize; @@ -70,7 +62,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 for (final String page : pageList) { final int byteLength = page.getBytes(java.nio.charset.StandardCharsets.UTF_8).length; byteTotal += byteLength; -@@ -1326,7 +1353,8 @@ public class ServerGamePacketListenerImpl +@@ -1330,7 +_,8 @@ } if (byteTotal > byteAllowed) { @@ -80,58 +72,58 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 this.disconnectAsync(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - add proper async disconnect return; } -@@ -1345,31 +1373,45 @@ public class ServerGamePacketListenerImpl - Optional optional = packet.title(); - optional.ifPresent(list::add); - list.addAll(packet.pages()); +@@ -1349,31 +_,45 @@ + Optional title = packet.title(); + title.ifPresent(contents::add); + contents.addAll(packet.pages()); + // Purpur start - Allow color codes in books + boolean hasEditPerm = getCraftPlayer().hasPermission("purpur.book.color.edit"); + boolean hasSignPerm = hasEditPerm || getCraftPlayer().hasPermission("purpur.book.color.sign"); + // Purpur end - Allow color codes in books - Consumer> consumer = optional.isPresent() -- ? texts -> this.signBook(texts.get(0), texts.subList(1, texts.size()), slot) -- : list1 -> this.updateBookContents(list1, slot); -+ ? texts -> this.signBook(texts.get(0), texts.subList(1, texts.size()), slot, hasSignPerm) // Purpur - Allow color codes in books -+ : list1 -> this.updateBookContents(list1, slot, hasEditPerm); // Purpur - Allow color codes in books - this.filterTextPacket(list).thenAcceptAsync(consumer, this.server); + Consumer> handler = title.isPresent() +- ? filteredContents -> this.signBook(filteredContents.get(0), filteredContents.subList(1, filteredContents.size()), slot) +- : filteredContents -> this.updateBookContents(filteredContents, slot); ++ ? filteredContents -> this.signBook(filteredContents.get(0), filteredContents.subList(1, filteredContents.size()), slot, hasSignPerm) // Purpur - Allow color codes in books ++ : filteredContents -> this.updateBookContents(filteredContents, slot, hasEditPerm); // Purpur - Allow color codes in books + this.filterTextPacket(contents).thenAcceptAsync(handler, this.server); } } - private void updateBookContents(List pages, int index) { + private void updateBookContents(final List contents, final int slot) { + // Purpur start - Allow color codes in books -+ updateBookContents(pages, index, false); ++ updateBookContents(contents, slot, false); + } -+ private void updateBookContents(List pages, int index, boolean hasPerm) { ++ private void updateBookContents(List contents, int slot, boolean hasPerm) { + // Purpur end - Allow color codes in books // CraftBukkit start - ItemStack handItem = this.player.getInventory().getItem(index); - ItemStack item = handItem.copy(); + ItemStack handItem = this.player.getInventory().getItem(slot); + ItemStack carried = handItem.copy(); // CraftBukkit end - if (item.has(DataComponents.WRITABLE_BOOK_CONTENT)) { -- List> list = pages.stream().map(this::filterableFromOutgoing).toList(); -+ List> list = pages.stream().map(filteredText -> filterableFromOutgoing(filteredText).map(s -> color(s, hasPerm))).toList(); // Purpur - Allow color codes in books - item.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list)); - this.player.getInventory().setItem(index, CraftEventFactory.handleEditBookEvent(this.player, index, handItem, item)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) + if (carried.has(DataComponents.WRITABLE_BOOK_CONTENT)) { +- List> pages = contents.stream().map(this::filterableFromOutgoing).toList(); ++ List> pages = contents.stream().map(filteredText -> filterableFromOutgoing(filteredText).map(s -> color(s, hasPerm))).toList(); // Purpur - Allow color codes in books + carried.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(pages)); + this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(this.player, slot, handItem, carried)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) } } - private void signBook(FilteredText title, List pages, int index) { + private void signBook(final FilteredText title, final List contents, final int slot) { + // Purpur start - Allow color codes in books -+ signBook(title, pages, index, false); ++ signBook(title, contents, slot, false); + } -+ private void signBook(FilteredText title, List pages, int index, boolean hasPerm) { ++ private void signBook(final FilteredText title, final List contents, final int slot, boolean hasPerm) { + // Purpur end - Allow color codes in books - ItemStack item = this.player.getInventory().getItem(index); - if (item.has(DataComponents.WRITABLE_BOOK_CONTENT)) { - ItemStack itemStack = item.transmuteCopy(Items.WRITTEN_BOOK); - itemStack.remove(DataComponents.WRITABLE_BOOK_CONTENT); -- List> list = pages.stream().map(filteredText -> this.filterableFromOutgoing(filteredText).map(Component::literal)).toList(); -+ List> list = pages.stream().map((filteredText) -> this.filterableFromOutgoing(filteredText).map(s -> hexColor(s, hasPerm))).toList(); // Purpur - Allow color codes in books - itemStack.set( - DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getPlainTextName(), 0, list, true) + ItemStack carried = this.player.getInventory().getItem(slot); + if (carried.has(DataComponents.WRITABLE_BOOK_CONTENT)) { + ItemStack writtenBook = carried.transmuteCopy(Items.WRITTEN_BOOK); + writtenBook.remove(DataComponents.WRITABLE_BOOK_CONTENT); +- List> pages = contents.stream().map(page -> this.filterableFromOutgoing(page).map(Component::literal)).toList(); ++ List> pages = contents.stream().map(page -> this.filterableFromOutgoing(page).map(s -> hexColor(s, hasPerm))).toList(); // Purpur - Allow color codes in books + writtenBook.set( + DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getPlainTextName(), 0, pages, true) ); -@@ -1382,6 +1424,16 @@ public class ServerGamePacketListenerImpl - return this.player.isTextFilteringEnabled() ? Filterable.passThrough(filteredText.filteredOrEmpty()) : Filterable.from(filteredText); +@@ -1386,6 +_,16 @@ + return this.player.isTextFilteringEnabled() ? Filterable.passThrough(text.filteredOrEmpty()) : Filterable.from(text); } + // Purpur start - Allow color codes in books @@ -145,11 +137,11 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 + // Purpur end - Allow color codes in books + @Override - public void handleEntityTagQuery(ServerboundEntityTagQueryPacket packet) { + public void handleEntityTagQuery(final ServerboundEntityTagQueryPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); -@@ -1421,7 +1473,15 @@ public class ServerGamePacketListenerImpl +@@ -1425,7 +_,15 @@ @Override - public void handleMovePlayer(ServerboundMovePlayerPacket packet) { + public void handleMovePlayer(final ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); - if (containsInvalidValues(packet.getX(0.0), packet.getY(0.0), packet.getZ(0.0), packet.getYRot(0.0F), packet.getXRot(0.0F))) { + // Purpur start - Add more logger output for invalid movement kicks @@ -163,8 +155,8 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 + // Purpur end - Add more logger output for invalid movement kicks this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause } else { - ServerLevel serverLevel = this.player.level(); -@@ -1604,7 +1664,7 @@ public class ServerGamePacketListenerImpl + ServerLevel level = this.player.level(); +@@ -1609,7 +_,7 @@ movedWrongly = true; if (event.getLogWarning()) // Paper end @@ -173,7 +165,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 } // Paper } -@@ -1669,6 +1729,8 @@ public class ServerGamePacketListenerImpl +@@ -1664,6 +_,8 @@ this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); @@ -182,7 +174,7 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 Location oldTo = to.clone(); PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); this.cserver.getPluginManager().callEvent(event); -@@ -1724,6 +1786,13 @@ public class ServerGamePacketListenerImpl +@@ -1719,6 +_,13 @@ this.player.tryResetCurrentImpulseContext(); } @@ -193,10 +185,10 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 + } + // Purpur end - Dont run with scissors! + - this.player.checkMovementStatistics(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z); + this.player.checkMovementStatistics(this.player.getX() - startX, this.player.getY() - startY, this.player.getZ() - startZ); this.lastGoodX = this.player.getX(); this.lastGoodY = this.player.getY(); -@@ -1741,6 +1810,17 @@ public class ServerGamePacketListenerImpl +@@ -1739,6 +_,17 @@ } } @@ -211,28 +203,28 @@ index e158d614abed8d16e80192c0c9abd8537c92b9dc..74f8f1c8a3d688fadcbc266bac126e13 + } + // Purpur end - Dont run with scissors! + - private boolean shouldCheckPlayerMovement(boolean isElytraMovement) { + private boolean shouldCheckPlayerMovement(final boolean isFallFlying) { if (this.isSingleplayerOwner()) { return false; -@@ -2169,6 +2249,7 @@ public class ServerGamePacketListenerImpl +@@ -2155,6 +_,7 @@ boolean cancelled; if (hitResult == null || hitResult.getType() != HitResult.Type.BLOCK) { -+ if (this.player.gameMode.shiftClickMended(itemInHand)) return; // Purpur - Shift right click to use exp for mending - org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemInHand, hand); ++ if (this.player.gameMode.shiftClickMended(itemStack)) return; // Purpur - Shift right click to use exp for mending + org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemStack, hand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { -@@ -2821,6 +2902,7 @@ public class ServerGamePacketListenerImpl - - AABB boundingBox = target.getBoundingBox(); - if (packet.isWithinRange(this.player, boundingBox, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0))) { // Paper - configurable lenience value for interact range +@@ -2800,6 +_,7 @@ + if (target != null && level.getWorldBorder().isWithinBounds(target.blockPosition())) { + AABB targetBounds = target.getBoundingBox(); + if (this.player.isWithinAttackRange(this.player.getMainHandItem(), targetBounds, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0))) { // Paper - configurable lenience value for interact range + if (target instanceof net.minecraft.world.entity.Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur - Entity lifespan - packet.dispatch( - new ServerboundInteractPacket.Handler() { - private void performInteraction(InteractionHand hand, ServerGamePacketListenerImpl.EntityInteraction entityInteraction, PlayerInteractEntityEvent event) { // CraftBukkit -@@ -3581,7 +3663,7 @@ public class ServerGamePacketListenerImpl + if (!(target instanceof ItemEntity) + && !(target instanceof ExperienceOrb) + && (target != this.player || this.player.isSpectator()) // CraftBukkit +@@ -3590,7 +_,7 @@ @Override - public void handleChangeGameMode(ServerboundChangeGameModePacket packet) { + public void handleChangeGameMode(final ServerboundChangeGameModePacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); - if (!GameModeCommand.PERMISSION_CHECK.check(this.player.permissions())) { + if (!GameModeCommand.PERMISSION_CHECK.check(this.player.permissions()) && !player.getBukkitEntity().hasPermission("purpur.debug.f3n")) { // Purpur - Add permission for F3+N debug diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch similarity index 64% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch index 5967b9f17..2f269cfb6 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch @@ -1,19 +1,11 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 51a29ab542136e67741be10bbc5c6377715a207c..e16bb386ae500bc290970f8cba33c5999cf0a58d 100644 --- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -278,7 +278,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, +@@ -284,7 +_,7 @@ ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!"); - ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(string1)); // Spigot + ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(name)); // Spigot } else { - ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.unverified_username")); + ServerLoginPacketListenerImpl.this.disconnect(org.purpurmc.purpur.PurpurConfig.unverifiedUsername.equals("default") ? Component.translatable("multiplayer.disconnect.unverified_username") : io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.unverifiedUsername))); // Purpur - Config for unverified username message - ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", string1); + ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", name); } } catch (AuthenticationUnavailableException var4) { diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/server/players/PlayerList.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch similarity index 69% rename from purpur-server/minecraft-patches/rejected/net/minecraft/server/players/PlayerList.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch index 283b55aa3..59fe96f58 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/server/players/PlayerList.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 989ac565c47a70c7947cb7315d0f5c2cfecd0363..646e16b3d69b5516e8f7c401828fec731378979c 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -311,6 +311,7 @@ public abstract class PlayerList { +@@ -313,6 +_,7 @@ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); } // Paper end - Configurable player collision @@ -16,15 +8,15 @@ index 989ac565c47a70c7947cb7315d0f5c2cfecd0363..646e16b3d69b5516e8f7c401828fec73 // CraftBukkit start - moved down LOGGER.info( "{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", // CraftBukkit - add world name -@@ -431,6 +432,7 @@ public abstract class PlayerList { +@@ -436,6 +_,7 @@ } - public net.kyori.adventure.text.@Nullable Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) { + public net.kyori.adventure.text.@Nullable Component remove(final ServerPlayer player, final net.kyori.adventure.text.Component leaveMessage) { // Paper end - Fix kick event leave message not being sent + org.purpurmc.purpur.task.BossBarTask.removeFromAll(player.getBukkitEntity()); // Purpur - Implement TPSBar - ServerLevel serverLevel = player.level(); + ServerLevel level = player.level(); player.awardStat(Stats.LEAVE_GAME); // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it -@@ -770,6 +772,20 @@ public abstract class PlayerList { +@@ -771,6 +_,20 @@ } } @@ -42,18 +34,18 @@ index 989ac565c47a70c7947cb7315d0f5c2cfecd0363..646e16b3d69b5516e8f7c401828fec73 + } + // Purpur end - Component related conveniences + - public void broadcastAll(Packet packet, ResourceKey dimension) { - for (ServerPlayer serverPlayer : this.players) { - if (serverPlayer.level().dimension() == dimension) { -@@ -863,6 +879,7 @@ public abstract class PlayerList { + public void broadcastAll(final Packet packet, final ResourceKey dimension) { + for (ServerPlayer player : this.players) { + if (player.level().dimension() == dimension) { +@@ -864,6 +_,7 @@ case ADMINS -> EntityEvent.PERMISSION_LEVEL_ADMINS; case OWNERS -> EntityEvent.PERMISSION_LEVEL_OWNERS; }; -+ if (b < EntityEvent.PERMISSION_LEVEL_OWNERS && player.getBukkitEntity().hasPermission("purpur.debug.f3n")) b = EntityEvent.PERMISSION_LEVEL_OWNERS; // Purpur - Add permission for F3+N debug - player.connection.send(new ClientboundEntityEventPacket(player, b)); ++ if (eventId < EntityEvent.PERMISSION_LEVEL_OWNERS && player.getBukkitEntity().hasPermission("purpur.debug.f3n")) eventId = EntityEvent.PERMISSION_LEVEL_OWNERS; // Purpur - Add permission for F3+N debug + player.connection.send(new ClientboundEntityEventPacket(player, eventId)); } -@@ -874,7 +891,7 @@ public abstract class PlayerList { +@@ -875,7 +_,7 @@ // Paper start - whitelist verify event / login event public LoginResult canBypassFullServerLogin(final NameAndId nameAndId, final LoginResult currentResult) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/players/SleepStatus.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/players/SleepStatus.java.patch new file mode 100644 index 000000000..b96fd1931 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/players/SleepStatus.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/players/SleepStatus.java ++++ b/net/minecraft/server/players/SleepStatus.java +@@ -15,7 +_,7 @@ + + public boolean areEnoughDeepSleeping(final int sleepPercentageNeeded, final List players) { + // CraftBukkit start +- int deepSleepers = (int)players.stream().filter(player -> player.isSleepingLongEnough() || player.fauxSleeping).count(); ++ int deepSleepers = (int)players.stream().filter(player -> player.isSleepingLongEnough() || player.fauxSleeping || (player.level().purpurConfig.idleTimeoutCountAsSleeping && player.isAfk())).count(); // Purpur - AFK API + boolean anyDeepSleep = players.stream().anyMatch(Player::isSleepingLongEnough); + return anyDeepSleep && deepSleepers >= this.sleepersNeeded(sleepPercentageNeeded); + // CraftBukkit end +@@ -43,7 +_,7 @@ + for (ServerPlayer player : players) { + if (!player.isSpectator()) { + this.activePlayers++; +- if (player.isSleeping() || player.fauxSleeping) { // CraftBukkit ++ if (player.isSleeping() || player.fauxSleeping || (player.level().purpurConfig.idleTimeoutCountAsSleeping && player.isAfk())) { // CraftBukkit // Purpur - AFK API + this.sleepingPlayers++; + } + // CraftBukkit start diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch new file mode 100644 index 000000000..0dcd99cba --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/stats/ServerRecipeBook.java ++++ b/net/minecraft/stats/ServerRecipeBook.java +@@ -110,6 +_,7 @@ + ) { + for (ResourceKey> recipe : recipes) { + if (!validator.test(recipe)) { ++ if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressUnrecognizedRecipeErrors) // Purpur - Logger settings (suppressing pointless logs) + LOGGER.error("Tried to load unrecognized recipe: {} removed now.", recipe); + } else { + recipeAddingMethod.accept(recipe); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatRules.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatRules.java.patch new file mode 100644 index 000000000..39f6a751a --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatRules.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/damagesource/CombatRules.java ++++ b/net/minecraft/world/damagesource/CombatRules.java +@@ -17,7 +_,7 @@ + final LivingEntity victim, final float damage, final DamageSource source, final float totalArmor, final float armorToughness + ) { + float toughness = 2.0F + armorToughness / 4.0F; +- float realArmor = Mth.clamp(totalArmor - damage / toughness, totalArmor * 0.2F, 20.0F); ++ float realArmor = Mth.clamp(totalArmor - damage / toughness, totalArmor * 0.2F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur - Add attribute clamping and armor limit config + float armorFraction = realArmor / 25.0F; + ItemStack weaponItem = source.getWeaponItem(); + float modifiedArmorFraction; +@@ -32,7 +_,7 @@ + } + + public static float getDamageAfterMagicAbsorb(final float damage, final float totalMagicArmor) { +- float realArmor = Mth.clamp(totalMagicArmor, 0.0F, 20.0F); ++ float realArmor = Mth.clamp(totalMagicArmor, 0.0F, org.purpurmc.purpur.PurpurConfig.limitArmor ? 20F : Float.MAX_VALUE); // Purpur - Add attribute clamping and armor limit config + return damage * (1.0F - realArmor / 25.0F); + } + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch new file mode 100644 index 000000000..049de4313 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/world/damagesource/CombatTracker.java ++++ b/net/minecraft/world/damagesource/CombatTracker.java +@@ -66,7 +_,7 @@ + final Entity attackerEntity, final Component attackerName, final String messageWithItem, final String messageWithoutItem + ) { + ItemStack attackerItem = attackerEntity instanceof LivingEntity livingEntity ? livingEntity.getMainHandItem() : ItemStack.EMPTY; +- return !attackerItem.isEmpty() && attackerItem.has(DataComponents.CUSTOM_NAME) ++ return !attackerItem.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || attackerItem.has(DataComponents.CUSTOM_NAME)) // Purpur - always show item in player death messages + ? Component.translatable(messageWithItem, this.mob.getDisplayName(), attackerName, attackerItem.getDisplayName()) + : Component.translatable(messageWithoutItem, this.mob.getDisplayName(), attackerName); + } +@@ -109,6 +_,15 @@ + Component link = ComponentUtils.wrapInSquareBrackets(Component.translatable(deathMsg + ".link")).withStyle(INTENTIONAL_GAME_DESIGN_STYLE); + return Component.translatable(deathMsg + ".message", this.mob.getDisplayName(), link); + } else { ++ // Purpur start - Dont run with scissors! ++ if (killingSource.isScissors()) { ++ return killingSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgRunWithScissors, this.mob); ++ // Purpur start - Stonecutter damage ++ } else if (killingSource.isStonecutter()) { ++ return killingSource.getLocalizedDeathMessage(org.purpurmc.purpur.PurpurConfig.deathMsgStonecutter, this.mob); ++ // Purpur end - Stonecutter damage ++ } ++ // Purpur end - Dont run with scissors! + return killingSource.getLocalizedDeathMessage(this.mob); + } + } diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/DamageSource.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch similarity index 68% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/DamageSource.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch index f2d0ce705..490260603 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/damagesource/DamageSource.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/damagesource/DamageSource.java b/net/minecraft/world/damagesource/DamageSource.java -index 4df37fcd42b8edf789ee8e99d61ee1fa6471288b..67318e32fa58a89ba9321a36627af07697aacea4 100644 --- a/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java -@@ -24,6 +24,8 @@ public class DamageSource { +@@ -24,6 +_,8 @@ private org.bukkit.block.@Nullable Block eventBlockDamager; // Relevant block set. damageSourcePosition is only used for bad respawn point explosion or custom damage private org.bukkit.block.@Nullable BlockState fromBlockSnapshot; // Captured block snapshot when the eventBlockDamager is not relevant (e.g. for bad respawn point explosions the block is already removed) private boolean critical; // Supports arrows and sweeping damage @@ -17,7 +9,7 @@ index 4df37fcd42b8edf789ee8e99d61ee1fa6471288b..67318e32fa58a89ba9321a36627af076 public DamageSource knownCause(final org.bukkit.event.entity.EntityDamageEvent.DamageCause cause) { final DamageSource damageSource = this.copy(); -@@ -35,6 +37,30 @@ public class DamageSource { +@@ -35,6 +_,30 @@ return this.knownCause; } @@ -48,7 +40,7 @@ index 4df37fcd42b8edf789ee8e99d61ee1fa6471288b..67318e32fa58a89ba9321a36627af076 @Nullable public Entity eventEntityDamager() { return this.eventEntityDamager; -@@ -94,6 +120,8 @@ public class DamageSource { +@@ -94,6 +_,8 @@ damageSource.eventBlockDamager = this.eventBlockDamager; damageSource.fromBlockSnapshot = this.fromBlockSnapshot; damageSource.critical = this.critical; @@ -57,17 +49,17 @@ index 4df37fcd42b8edf789ee8e99d61ee1fa6471288b..67318e32fa58a89ba9321a36627af076 return damageSource; } // CraftBukkit end -@@ -157,12 +185,21 @@ public class DamageSource { +@@ -159,11 +_,20 @@ } else { - Component component = this.causingEntity == null ? this.directEntity.getDisplayName() : this.causingEntity.getDisplayName(); - ItemStack itemStack = this.causingEntity instanceof LivingEntity livingEntity1 ? livingEntity1.getMainHandItem() : ItemStack.EMPTY; -- return !itemStack.isEmpty() && itemStack.has(DataComponents.CUSTOM_NAME) -+ return !itemStack.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || itemStack.has(DataComponents.CUSTOM_NAME)) // Purpur - always show item in player death messages - ? Component.translatable(string + ".item", livingEntity.getDisplayName(), component, itemStack.getDisplayName()) - : Component.translatable(string, livingEntity.getDisplayName(), component); + Component name = this.causingEntity == null ? this.directEntity.getDisplayName() : this.causingEntity.getDisplayName(); + ItemStack held = this.causingEntity instanceof LivingEntity livingEntity ? livingEntity.getMainHandItem() : ItemStack.EMPTY; +- return !held.isEmpty() && held.has(DataComponents.CUSTOM_NAME) ++ return !held.isEmpty() && (org.purpurmc.purpur.PurpurConfig.playerDeathsAlwaysShowItem || held.has(DataComponents.CUSTOM_NAME)) // Purpur - always show item in player death messages + ? Component.translatable(deathMsg + ".item", victim.getDisplayName(), name, held.getDisplayName()) + : Component.translatable(deathMsg, victim.getDisplayName(), name); } } - ++ + // Purpur start - Component related conveniences + public Component getLocalizedDeathMessage(String str, LivingEntity entity) { + net.kyori.adventure.text.Component name = io.papermc.paper.adventure.PaperAdventure.asAdventure(entity.getDisplayName()); @@ -76,7 +68,6 @@ index 4df37fcd42b8edf789ee8e99d61ee1fa6471288b..67318e32fa58a89ba9321a36627af076 + return io.papermc.paper.adventure.PaperAdventure.asVanilla(component); + } + // Purpur end - Component related conveniences -+ + public String getMsgId() { return this.type().msgId(); - } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/HungerMobEffect.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/HungerMobEffect.java.patch new file mode 100644 index 000000000..a7a98612b --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/HungerMobEffect.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/effect/HungerMobEffect.java ++++ b/net/minecraft/world/effect/HungerMobEffect.java +@@ -12,7 +_,7 @@ + @Override + public boolean applyEffectTick(final ServerLevel serverLevel, final LivingEntity mob, final int amplification) { + if (mob instanceof Player player) { +- player.causeFoodExhaustion(0.005F * (amplification + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent ++ player.causeFoodExhaustion(mob.level().purpurConfig.humanHungerExhaustionAmount * (amplification + 1), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.HUNGER_EFFECT); // CraftBukkit - EntityExhaustionEvent // Purpur - Config MobEffect by world + } + + return true; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch new file mode 100644 index 000000000..e612b600a --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/effect/PoisonMobEffect.java ++++ b/net/minecraft/world/effect/PoisonMobEffect.java +@@ -12,8 +_,8 @@ + + @Override + public boolean applyEffectTick(final ServerLevel level, final LivingEntity mob, final int amplification) { +- if (mob.getHealth() > 1.0F) { +- mob.hurtServer(level, mob.damageSources().magic().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.POISON), 1.0F); // CraftBukkit ++ if (mob.getHealth() > mob.level().purpurConfig.entityMinimalHealthPoison) { // Purpur ++ mob.hurtServer(level, mob.damageSources().magic().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.POISON), mob.level().purpurConfig.entityPoisonDegenerationAmount); // CraftBukkit // Purpur - Config MobEffect by world + } + + return true; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/RegenerationMobEffect.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/RegenerationMobEffect.java.patch new file mode 100644 index 000000000..a90b00f26 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/RegenerationMobEffect.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/effect/RegenerationMobEffect.java ++++ b/net/minecraft/world/effect/RegenerationMobEffect.java +@@ -11,7 +_,7 @@ + @Override + public boolean applyEffectTick(final ServerLevel level, final LivingEntity mob, final int amplification) { + if (mob.getHealth() < mob.getMaxHealth()) { +- mob.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit ++ mob.heal(mob.level().purpurConfig.entityHealthRegenAmount, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC_REGEN); // CraftBukkit // Purpur - Config MobEffect by world + } + + return true; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/WitherMobEffect.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/WitherMobEffect.java.patch new file mode 100644 index 000000000..25d63c3de --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/effect/WitherMobEffect.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/effect/WitherMobEffect.java ++++ b/net/minecraft/world/effect/WitherMobEffect.java +@@ -12,7 +_,7 @@ + + @Override + public boolean applyEffectTick(final ServerLevel level, final LivingEntity mob, final int amplification) { +- mob.hurtServer(level, mob.damageSources().wither(), 1.0F); ++ mob.hurtServer(level, mob.damageSources().wither(), mob.level().purpurConfig.entityWitherDegenerationAmount); // Purpur - Config MobEffect by world + return true; + } + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch index 9c77f8af6..bb829bbb2 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -1,6 +1,33 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -380,7 +_,7 @@ +@@ -168,6 +_,7 @@ + SlotProvider, + DebugValueSource, + TypedInstance> { ++ public static javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); // Purpur - Configurable entity base attributes + // CraftBukkit start + private static final int CURRENT_LEVEL = 2; + static boolean isLevelAtLeast(ValueInput input, int level) { +@@ -341,8 +_,9 @@ + public double xOld; + public double yOld; + public double zOld; ++ public float maxUpStep; // Purpur - Add option to set armorstand step height + public boolean noPhysics; +- public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random ++ public final RandomSource random; // Paper - Share random for entities to make them more random // Add toggle for RNG manipulation + public int tickCount; + private int remainingFireTicks; + private final EntityFluidInteraction fluidInteraction = new EntityFluidInteraction(Set.of(FluidTags.WATER, FluidTags.LAVA)); +@@ -374,13 +_,13 @@ + public @Nullable PortalProcessor portalProcess; + public int portalCooldown; + private boolean invulnerable; +- protected UUID uuid = Mth.createInsecureUUID(this.random); +- protected String stringUUID = this.uuid.toString(); ++ protected UUID uuid; // Purpur - Add toggle for RNG manipulation ++ protected String stringUUID; // Purpur - Add toggle for RNG manipulation + private boolean hasGlowingTag; private final Set tags = new io.papermc.paper.util.SizeLimitedSet<>(new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(), MAX_ENTITY_TAG_COUNT); // Paper - fully limit tag size - replace set impl private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; private long pistonDeltasGameTime; @@ -9,3 +36,141 @@ private float eyeHeight; public boolean isInPowderSnow; public boolean wasInPowderSnow; +@@ -426,6 +_,7 @@ + private final int despawnTime; // Paper - entity despawn time limit + public int totalEntityAge; // Paper - age-like counter for all entities + public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges ++ public @Nullable Boolean immuneToFire = null; // Purpur - Fire immune API + // CraftBukkit end + + // Paper start +@@ -434,10 +_,22 @@ + } + // Paper end + ++ // Purpur start - Add canSaveToDisk to Entity ++ public boolean canSaveToDisk() { ++ return true; ++ } ++ // Purpur end - Add canSaveToDisk to Entity ++ + public Entity(final EntityType type, final Level level) { + this.type = type; + this.level = level; + this.dimensions = type.getDimensions(); ++ this.maxAirTicks = level == null ? Entity.TOTAL_AIR_SUPPLY : this.level.purpurConfig.drowningAirTicks; // Purpur - Drowning Settings ++ // Purpur start - Add toggle for RNG manipulation ++ this.random = level == null || level.purpurConfig.entitySharedRandom ? SHARED_RANDOM : RandomSource.create(); ++ this.uuid = Mth.createInsecureUUID(this.random); ++ this.stringUUID = this.uuid.toString(); ++ // Purpur end - Add toggle for RNG manipulation + this.position = Vec3.ZERO; + this.blockPosition = BlockPos.ZERO; + this.chunkPosition = ChunkPos.ZERO; +@@ -828,6 +_,7 @@ + && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v) + && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) { + // Paper end - Configurable nether ceiling damage ++ if (this.level.purpurConfig.teleportOnNetherCeilingDamage && this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this instanceof ServerPlayer player) player.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.level.levelData.getRespawnData().pos(), this.level)); else // Purpur - Add option to teleport to spawn on nether ceiling damage + this.onBelowWorld(); + } + } +@@ -1826,7 +_,7 @@ + } + + public boolean fireImmune() { +- return this.getType().fireImmune(); ++ return this.immuneToFire != null ? immuneToFire : this.getType().fireImmune(); // Purpur - add fire immune API + } + + public boolean causeFallDamage(final double fallDistance, final float damageModifier, final DamageSource damageSource) { +@@ -2412,7 +_,7 @@ + output.putBoolean("Bukkit.invisible", this.persistentInvisibility); + } + // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() +- if (this.maxAirTicks != this.getDefaultMaxAirSupply()) { ++ if (this.maxAirTicks != this.getDefaultMaxAirSupply() && this.getDefaultMaxAirSupply() != this.level().purpurConfig.drowningAirTicks) { // Purpur - Drowning Settings + output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); + } + output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper +@@ -2499,6 +_,11 @@ + output.putBoolean("Paper.FreezeLock", true); + } + // Paper end ++ // Purpur start - Fire immune API ++ if (immuneToFire != null) { ++ output.putBoolean("Purpur.FireImmune", immuneToFire); ++ } ++ // Purpur end - Fire immune API + } catch (Throwable var7) { + CrashReport report = CrashReport.forThrowable(var7, "Saving entity NBT"); + CrashReportCategory category = report.addCategory("Entity being saved"); +@@ -2621,6 +_,9 @@ + } + freezeLocked = input.getBooleanOr("Paper.FreezeLock", false); + // Paper end ++ ++ immuneToFire = input.read("Purpur.FireImmune", com.mojang.serialization.Codec.BOOL).orElse(null); // Purpur - Fire immune API ++ + } catch (Throwable var7) { + CrashReport report = CrashReport.forThrowable(var7, "Loading entity NBT"); + CrashReportCategory category = report.addCategory("Entity being loaded"); +@@ -2800,6 +_,7 @@ + if (this.isAlive() && this instanceof Leashable leashablex) { + if (leashablex.getLeashHolder() == player) { + if (!this.level().isClientSide()) { ++ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.villager.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers + // Paper start - EntityUnleashEvent + if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( + leashablex, player, hand, !player.hasInfiniteMaterials(), true +@@ -3230,15 +_,18 @@ + return Vec3.directionFromRotation(this.getRotationVector()); + } + ++ public BlockPos portalPos = BlockPos.ZERO; // Purpur - Fix stuck in portals + public void setAsInsidePortal(final Portal portal, final BlockPos pos) { + if (this.isOnPortalCooldown()) { ++ if (!(level().purpurConfig.playerFixStuckPortal && this instanceof Player && !pos.equals(this.portalPos))) // Purpur - Fix stuck in portals + this.setPortalCooldown(); +- } else { ++ } else if (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer) { // Purpur - Entities can use portals + if (this.portalProcess == null || !this.portalProcess.isSamePortal(portal)) { + this.portalProcess = new PortalProcessor(portal, pos.immutable()); + } else if (!this.portalProcess.isInsidePortalThisTick()) { + this.portalProcess.updateEntryPosition(pos.immutable()); + this.portalProcess.setAsInsidePortalThisTick(true); ++ this.portalPos = BlockPos.ZERO; // Purpur - Fix stuck in portals + } + } + } +@@ -3967,7 +_,7 @@ + } + + public boolean canUsePortal(final boolean ignorePassenger) { +- return (ignorePassenger || !this.isPassenger()) && this.isAlive(); ++ return (ignorePassenger || !this.isPassenger()) && this.isAlive() && (this.level.purpurConfig.entitiesCanUsePortals || this instanceof ServerPlayer); // Purpur - Entities can use portals + } + + public boolean canTeleport(final Level from, final Level to) { +@@ -4515,6 +_,12 @@ + return Mth.lerp(partial, this.yRotO, this.yRot); + } + ++ // Purpur start - Stop squids floating on top of water ++ public AABB getAxisForFluidCheck() { ++ return this.getBoundingBox().deflate(0.001D); ++ } ++ // Purpur end - Stop squids floating on top of water ++ + public boolean touchingUnloadedChunk() { + AABB box = this.getBoundingBox().inflate(1.0); + int x0 = Mth.floor(box.minX); +@@ -4809,7 +_,7 @@ + } + + public float maxUpStep() { +- return 0.0F; ++ return maxUpStep; // Purpur - Add option to set armorstand step height + } + + public void onExplosionHit(final @Nullable Entity explosionCausedBy) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/EntityType.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/EntityType.java.patch index c2a2888d4..71faa3a72 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/EntityType.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/EntityType.java.patch @@ -9,3 +9,45 @@ private final float spawnDimensionsScale; private final FeatureFlagSet requiredFeatures; private final boolean allowedInPeaceful; +@@ -1238,6 +_,16 @@ + return register(vanillaEntityId(vanillaId), builder); + } + ++ // Purpur start - PlayerSetSpawnerTypeWithEggEvent ++ public static EntityType getFromBukkitType(org.bukkit.entity.EntityType bukkitType) { ++ return getFromKey(Identifier.parse(bukkitType.getKey().toString())); ++ } ++ ++ public static EntityType getFromKey(Identifier location) { ++ return BuiltInRegistries.ENTITY_TYPE.getValue(location); ++ } ++ // Purpur end - PlayerSetSpawnerTypeWithEggEvent ++ + public static Identifier getKey(final EntityType type) { + return BuiltInRegistries.ENTITY_TYPE.getKey(type); + } +@@ -1495,6 +_,16 @@ + return this.category; + } + ++ // Purpur start - PlayerSetSpawnerTypeWithEggEvent ++ public String getName() { ++ return BuiltInRegistries.ENTITY_TYPE.getKey(this).getPath(); ++ } ++ ++ public String getTranslatedName() { ++ return getDescription().getString(); ++ } ++ // Purpur end - PlayerSetSpawnerTypeWithEggEvent ++ + public String getDescriptionId() { + return this.descriptionId; + } +@@ -1556,6 +_,7 @@ + // Paper start - Add logging for debugging entity tags with invalid ids + () -> { + LOGGER.warn("Skipping Entity with id {}", input.getStringOr("id", "[invalid]")); ++ LOGGER.warn("Location: {} {}", level.getWorld().getName(), input.read("Pos", net.minecraft.world.phys.Vec3.CODEC).orElse(net.minecraft.world.phys.Vec3.ZERO)); // Purpur - log skipped entity's position + if ((DEBUG_ENTITIES_WITH_INVALID_IDS || level.getCraftServer().getServer().isDebugging()) && input instanceof TagValueInput tagInput) { + LOGGER.warn("Skipped entity tag: {}", tagInput.input); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch new file mode 100644 index 000000000..48508398d --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/entity/ExperienceOrb.java ++++ b/net/minecraft/world/entity/ExperienceOrb.java +@@ -352,7 +_,7 @@ + public void playerTouch(final Player player) { + if (player instanceof ServerPlayer serverPlayer) { + if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent +- player.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(player, 2, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entity.takeXpDelay = 2; ++ player.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(player, this.level().purpurConfig.playerExpPickupDelay, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entity.takeXpDelay = 2; // Purpur - Configurable player pickup exp delay + player.take(this, 1); + int remaining = this.repairPlayerItems(serverPlayer, this.getValue()); + if (remaining > 0) { +@@ -368,7 +_,8 @@ + } + + private int repairPlayerItems(final ServerPlayer player, final int amount) { +- Optional selected = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); ++ Optional selected = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) :EnchantmentHelper.getRandomItemWith(// Purpur - Add option to mend the most damaged equipment first ++ EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); + if (selected.isPresent()) { + ItemStack itemStack = selected.get().itemStack(); + int toRepairFromXpAmount = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.level(), itemStack, amount); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index c7632f6ce..51a8077f9 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -1,5 +1,180 @@ --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java +@@ -440,6 +_,12 @@ + if (dist < 0.0) { + double damagePerBlock = level.getWorldBorder().getDamagePerBlock(); + if (damagePerBlock > 0.0) { ++ // Purpur start - Add option to teleport to spawn if outside world border ++ if (this.level().purpurConfig.teleportIfOutsideBorder && this instanceof ServerPlayer serverPlayer) { ++ serverPlayer.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.level().levelData.getRespawnData().pos(), this.level())); ++ return; ++ } ++ // Purpur end - Add option to teleport to spawn if outside world border + this.hurtServer(level, this.damageSources().outOfBorder(), Math.max(1, Mth.floor(-dist * damagePerBlock))); + } + } +@@ -455,7 +_,7 @@ + if (this.shouldTakeDrowningDamage()) { + this.setAirSupply(0); + level.broadcastEntityEvent(this, EntityEvent.DROWN_PARTICLES); +- this.hurtServer(level, this.damageSources().drown(), 2.0F); ++ this.hurtServer(level, this.damageSources().drown(), (float) this.level().purpurConfig.damageFromDrowning); // Purpur - Drowning Settings + } + } else if (this.getAirSupply() < this.getMaxAirSupply() && MobEffectUtil.shouldEffectsRefillAirsupply(this)) { + this.setAirSupply(this.increaseAirSupply(this.getAirSupply())); +@@ -515,7 +_,7 @@ + } + + protected boolean shouldTakeDrowningDamage() { +- return this.getAirSupply() <= -20; ++ return this.getAirSupply() <= -this.level().purpurConfig.drowningDamageInterval; // Purpur - Drowning Settings + } + + @Override +@@ -1045,15 +_,33 @@ + } + + if (targetingEntity != null) { +- ItemStack itemStack = this.getItemBySlot(EquipmentSlot.HEAD); +- if (targetingEntity.is(EntityType.SKELETON) && itemStack.is(Items.SKELETON_SKULL) +- || targetingEntity.is(EntityType.ZOMBIE) && itemStack.is(Items.ZOMBIE_HEAD) +- || targetingEntity.is(EntityType.PIGLIN) && itemStack.is(Items.PIGLIN_HEAD) +- || targetingEntity.is(EntityType.PIGLIN_BRUTE) && itemStack.is(Items.PIGLIN_HEAD) +- || targetingEntity.is(EntityType.CREEPER) && itemStack.is(Items.CREEPER_HEAD)) { +- visibilityPercent *= 0.5; +- } +- } ++ ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.HEAD); ++ // Purpur start - Mob head visibility percent ++ if (targetingEntity.is(EntityType.SKELETON) && itemBySlot.is(Items.SKELETON_SKULL)) { ++ visibilityPercent *= targetingEntity.level().purpurConfig.skeletonHeadVisibilityPercent; ++ } ++ else if (targetingEntity.is(EntityType.ZOMBIE) && itemBySlot.is(Items.ZOMBIE_HEAD)) { ++ visibilityPercent *= targetingEntity.level().purpurConfig.zombieHeadVisibilityPercent; ++ } ++ else if ((targetingEntity.is(EntityType.PIGLIN) || targetingEntity.is(EntityType.PIGLIN_BRUTE)) && itemBySlot.is(Items.PIGLIN_HEAD)) { ++ visibilityPercent *= targetingEntity.level().purpurConfig.piglinHeadVisibilityPercent; ++ } ++ else if (targetingEntity.is(EntityType.CREEPER) && itemBySlot.is(Items.CREEPER_HEAD)) { ++ visibilityPercent *= targetingEntity.level().purpurConfig.creeperHeadVisibilityPercent; ++ } ++ // Purpur end - Mob head visibility percent ++ } ++ ++ // Purpur start - Configurable mob blindness ++ if (targetingEntity instanceof LivingEntity entityliving) { ++ if (entityliving.hasEffect(MobEffects.BLINDNESS)) { ++ int amplifier = entityliving.getEffect(MobEffects.BLINDNESS).getAmplifier(); ++ for (int i = 0; i < amplifier; i++) { ++ d *= this.level().purpurConfig.mobsBlindnessMultiplier; ++ } ++ } ++ } ++ // Purpur end - Configurable mob blindness + + return visibilityPercent; + } +@@ -1100,6 +_,7 @@ + Iterator iterator = this.activeEffects.values().iterator(); + while (iterator.hasNext()) { + MobEffectInstance effect = iterator.next(); ++ if (cause == EntityPotionEffectEvent.Cause.MILK && !this.level().purpurConfig.milkClearsBeneficialEffects && effect.getEffect().value().isBeneficial()) continue; // Purpur - Milk Keeps Beneficial Effects + EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, effect, null, cause, EntityPotionEffectEvent.Action.CLEARED); + if (event.isCancelled()) { + continue; +@@ -1431,6 +_,24 @@ + this.stopSleeping(); + } + ++ // Purpur start - One Punch Man! ++ if (damageSource.getEntity() instanceof net.minecraft.world.entity.player.Player player && damageSource.getEntity().level().purpurConfig.creativeOnePunch && !damageSource.is(DamageTypeTags.IS_PROJECTILE)) { ++ if (player.isCreative()) { ++ org.apache.commons.lang3.mutable.MutableDouble attackDamage = new org.apache.commons.lang3.mutable.MutableDouble(); ++ player.getMainHandItem().forEachModifier(EquipmentSlot.MAINHAND, (attributeHolder, attributeModifier) -> { ++ if (attributeModifier.operation() == AttributeModifier.Operation.ADD_VALUE) { ++ attackDamage.addAndGet(attributeModifier.amount()); ++ } ++ }); ++ ++ if (attackDamage.doubleValue() == 0.0D) { ++ // One punch! ++ amount = 9999F; ++ } ++ } ++ } ++ // Purpur end - One Punch Man! ++ + this.noActionTime = 0; + if (damage < 0.0F) { + damage = 0.0F; +@@ -1692,10 +_,10 @@ + protected @Nullable Player resolvePlayerResponsibleForDamage(final DamageSource source) { + Entity sourceEntity = source.getEntity(); + if (sourceEntity instanceof Player playerSource) { +- this.setLastHurtByPlayer(playerSource, 100); ++ this.setLastHurtByPlayer(playerSource, this.level().purpurConfig.mobLastHurtByPlayerTime); // Purpur - Config for mob last hurt by player time + } else if (sourceEntity instanceof Wolf wolf && wolf.isTame()) { + if (wolf.getOwnerReference() != null) { +- this.setLastHurtByPlayer(wolf.getOwnerReference().getUUID(), 100); ++ this.setLastHurtByPlayer(wolf.getOwnerReference().getUUID(), this.level().purpurConfig.mobLastHurtByPlayerTime); // Purpur - Config for mob last hurt by player time + } else { + this.lastHurtByPlayer = null; + this.lastHurtByPlayerMemoryTime = 0; +@@ -1746,6 +_,30 @@ + } + } + ++ // Purpur start - Totems work in inventory ++ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { ++ for (ItemStack item : player.getInventory().getNonEquipmentItems()) { ++ if (item.getItem() == Items.TOTEM_OF_UNDYING) { ++ itemInHand = item; ++ itemStack = item.copy(); ++ break; ++ } ++ } ++ } ++ // Purpur end - Totems work in inventory ++ ++ // Purpur start - Totems work in inventory ++ if (level().purpurConfig.totemOfUndyingWorksInInventory && this instanceof ServerPlayer player && (itemStack == null || itemStack.getItem() != Items.TOTEM_OF_UNDYING) && player.getBukkitEntity().hasPermission("purpur.inventory_totem")) { ++ for (ItemStack item : player.getInventory().getNonEquipmentItems()) { ++ if (item.getItem() == Items.TOTEM_OF_UNDYING) { ++ itemInHand = item; ++ itemStack = item.copy(); ++ break; ++ } ++ } ++ } ++ // Purpur end - Totems work in inventory ++ + final org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; + final EntityResurrectEvent event = new EntityResurrectEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), handSlot); + event.setCancelled(protectionItem == null); +@@ -1920,6 +_,7 @@ + boolean playerKilled = this.lastHurtByPlayerMemoryTime > 0; + this.dropEquipment(level); // CraftBukkit - from below + if (this.shouldDropLoot(level)) { ++ if (!(source.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level().purpurConfig.disableDropsOnCrammingDeath)) { // Purpur - Disable loot drops on death by cramming + this.dropFromLootTable(level, source, playerKilled); + // Paper start + final boolean prev = this.clearEquipmentSlots; +@@ -1928,6 +_,7 @@ + // Paper end + this.dropCustomDeathLoot(level, source, playerKilled); + this.clearEquipmentSlots = prev; // Paper ++ } // Purpur - Disable loot drops on death by cramming + } + + // CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment +@@ -3269,6 +_,7 @@ + float dmg = (float)(diff * 10.0 - 3.0); + if (dmg > 0.0F) { + this.playSound(this.getFallDamageSound((int)dmg), 1.0F, 1.0F); ++ if (level().purpurConfig.elytraKineticDamage) // Purpur - Toggle for kinetic damage + this.hurt(this.damageSources().flyIntoWall(), dmg); + } + } @@ -3852,7 +_,7 @@ } } @@ -9,3 +184,16 @@ if (!this.onGround() && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) { for (EquipmentSlot slot : EquipmentSlot.VALUES) { if (canGlideUsing(this.getItemBySlot(slot), slot)) { +@@ -4740,6 +_,12 @@ + ? slot == EquipmentSlot.MAINHAND && this.canUseSlot(EquipmentSlot.MAINHAND) + : slot == equippable.slot() && this.canUseSlot(equippable.slot()) && equippable.canBeEquippedBy(this.typeHolder()); + } ++ ++ // Purpur start - Dispenser curse of binding protection ++ public @Nullable EquipmentSlot getEquipmentSlotForDispenserItem(ItemStack itemstack) { ++ return EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BINDING_CURSE, itemstack) > 0 ? null : this.getEquipmentSlotForItem(itemstack); ++ } ++ // Purpur end - Dispenser curse of binding protection + + private static SlotAccess createEquipmentSlotAccess(final LivingEntity entity, final EquipmentSlot equipmentSlot) { + return equipmentSlot != EquipmentSlot.HEAD && equipmentSlot != EquipmentSlot.MAINHAND && equipmentSlot != EquipmentSlot.OFFHAND diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Mob.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Mob.java.patch similarity index 66% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Mob.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Mob.java.patch index 22074d323..54668db2d 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/Mob.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -1,36 +1,29 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 92175cc019750e829fcad7691a937024c2649882..cf2cbc3bf5e0000737ebeac3867f12d7e07bda01 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -150,6 +150,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -150,6 +_,7 @@ private int homeRadius = -1; public boolean aware = true; // CraftBukkit public net.kyori.adventure.util.TriState despawnInPeacefulOverride = net.kyori.adventure.util.TriState.NOT_SET; // Paper - allow changing despawnInPeaceful + public int ticksSinceLastInteraction; // Purpur - Entity lifespan - protected Mob(EntityType type, Level level) { + protected Mob(final EntityType type, final Level level) { super(type, level); -@@ -292,6 +293,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -285,6 +_,7 @@ target = null; } } + if (target instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur - Entity lifespan - this.target = target; + this.target = this.asValidTarget(target); return true; // CraftBukkit end -@@ -335,8 +337,28 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -328,7 +_,27 @@ } - profilerFiller.pop(); + profiler.pop(); +- } + incrementTicksSinceLastInteraction(); // Purpur - Entity lifespan - } - ++ } ++ + // Purpur start - Entity lifespan + private void incrementTicksSinceLastInteraction() { + ++this.ticksSinceLastInteraction; @@ -49,11 +42,10 @@ index 92175cc019750e829fcad7691a937024c2649882..cf2cbc3bf5e0000737ebeac3867f12d7 + } + } + // Purpur end - Entity lifespan -+ + @Override - protected void playHurtSound(DamageSource damageSource) { - this.resetAmbientSoundTime(); -@@ -439,6 +461,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + protected void playHurtSound(final DamageSource source) { +@@ -432,6 +_,7 @@ output.putString("Paper.DespawnInPeacefulOverride", this.despawnInPeacefulOverride.name()); } // Paper end - allow changing despawnInPeaceful @@ -61,7 +53,7 @@ index 92175cc019750e829fcad7691a937024c2649882..cf2cbc3bf5e0000737ebeac3867f12d7 } @Override -@@ -466,6 +489,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -459,6 +_,7 @@ this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L); this.setNoAi(input.getBooleanOr("NoAI", false)); this.aware = input.getBooleanOr("Bukkit.Aware", true); // CraftBukkit @@ -69,20 +61,20 @@ index 92175cc019750e829fcad7691a937024c2649882..cf2cbc3bf5e0000737ebeac3867f12d7 // Paper start - allow changing despawnInPeaceful this.despawnInPeacefulOverride = readDespawnInPeacefulOverride(input); } -@@ -1246,7 +1270,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1237,7 +_,7 @@ ); } - this.setLeftHanded(random.nextFloat() < 0.05F); + this.setLeftHanded(random.nextFloat() < level.getLevel().purpurConfig.entityLeftHandedChance); // Purpur - Changeable Mob Left Handed Chance - return spawnGroupData; + return groupData; } -@@ -1597,6 +1621,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1598,6 +_,7 @@ } - this.lungeForwardMaybe(); + this.postPiercingAttack(); + if (target instanceof net.minecraft.server.level.ServerPlayer) this.ticksSinceLastInteraction = 0; // Purpur - Entity lifespan - return flag; + return wasHurt; } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch new file mode 100644 index 000000000..71884aeff --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/CatSpawner.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/entity/npc/CatSpawner.java ++++ b/net/minecraft/world/entity/npc/CatSpawner.java +@@ -23,7 +_,7 @@ + public void tick(final ServerLevel level, final boolean spawnEnemies) { + this.nextTick--; + if (this.nextTick <= 0) { +- this.nextTick = 1200; ++ this.nextTick = level.purpurConfig.catSpawnDelay; // Purpur - Cat spawning options + Player player = level.getRandomPlayer(); + if (player != null) { + RandomSource random = level.getRandom(); +@@ -45,9 +_,12 @@ + } + + private void spawnInVillage(final ServerLevel serverLevel, final BlockPos spawnPos) { +- int radius = 48; +- if (serverLevel.getPoiManager().getCountInRange(p -> p.is(PoiTypes.HOME), spawnPos, 48, PoiManager.Occupancy.IS_OCCUPIED) > 4L) { +- List cats = serverLevel.getEntitiesOfClass(Cat.class, new AABB(spawnPos).inflate(48.0, 8.0, 48.0)); ++ // Purpur start - Cat spawning options ++ int radius = serverLevel.purpurConfig.catSpawnVillageScanRange; ++ if (radius <= 0) return; ++ if (serverLevel.getPoiManager().getCountInRange(holder -> holder.is(PoiTypes.HOME), spawnPos, radius, PoiManager.Occupancy.IS_OCCUPIED) > 4L) { ++ List cats = serverLevel.getEntitiesOfClass(Cat.class, new AABB(spawnPos).inflate(radius, 8.0, radius)); ++ // Purpur end - Cat spawning options + if (cats.size() < 5) { + this.spawnCat(spawnPos, serverLevel, false); + } +@@ -55,8 +_,11 @@ + } + + private void spawnInHut(final ServerLevel level, final BlockPos spawnPos) { +- int radius = 16; +- List cats = level.getEntitiesOfClass(Cat.class, new AABB(spawnPos).inflate(16.0, 8.0, 16.0)); ++ // Purpur start - Cat spawning options ++ int radius = level.purpurConfig.catSpawnSwampHutScanRange; ++ if (radius <= 0) return; ++ List cats = level.getEntitiesOfClass(Cat.class, new AABB(spawnPos).inflate(radius, 8.0, radius)); ++ // Purpur end - Cat spawning options + if (cats.isEmpty()) { + this.spawnCat(spawnPos, level, true); + } diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch new file mode 100644 index 000000000..ef4a56413 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java.patch @@ -0,0 +1,36 @@ +--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java ++++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java +@@ -61,6 +_,13 @@ + super(type, level); + } + ++ // Purpur start - Allow leashing villagers ++ @Override ++ public boolean canBeLeashed() { ++ return level().purpurConfig.wanderingTraderCanBeLeashed; ++ } ++ // Purpur end - Allow leashing villagers ++ + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); +@@ -78,7 +_,7 @@ + .addGoal( + 0, + new UseItemGoal<>( +- this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, e -> this.canDrinkMilk && this.level().isBrightOutside() && e.isInvisible() // Paper - Add more WanderingTrader API ++ this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, e -> level().purpurConfig.milkClearsBeneficialEffects && this.canDrinkMilk && this.level().isBrightOutside() && e.isInvisible() // Paper - Add more WanderingTrader API // Purpur - Milk Keeps Beneficial Effects + ) + ); + this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this)); +@@ -121,8 +_,10 @@ + return InteractionResult.CONSUME; + } + ++ if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur - Add config for villager trading + this.setTradingPlayer(player); + this.openTradingScreen(player, this.getDisplayName(), 1); ++ } // Purpur - Add config for villager trading + } + + return InteractionResult.SUCCESS; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch index 459d3bea3..f84f9a5d1 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -1,5 +1,75 @@ --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java +@@ -174,11 +_,20 @@ + public float hurtDir; + public boolean affectsSpawning = true; // Paper - Affects Spawning API + public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage ++ public int burpDelay = 0; // Purpur - Burp delay ++ public boolean canPortalInstant = false; // Purpur - Add portal permission bypass + + // CraftBukkit start + public boolean fauxSleeping; + public int oldLevel = -1; + ++ // Purpur start - AFK API ++ public abstract void setAfk(boolean afk); ++ ++ public boolean isAfk() { ++ return false; ++ } ++ // Purpur end - AFK API + @Override + public org.bukkit.craftbukkit.entity.CraftHumanEntity getBukkitEntity() { + return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity(); +@@ -240,6 +_,12 @@ + + @Override + public void tick() { ++ // Purpur start - Burp delay ++ if (this.burpDelay > 0 && --this.burpDelay == 0) { ++ this.level().playSound(null, getX(), getY(), getZ(), SoundEvents.PLAYER_BURP, SoundSource.PLAYERS, 1.0F, this.level().random.nextFloat() * 0.1F + 0.9F); ++ } ++ // Purpur end - Burp delay ++ + this.noPhysics = this.isSpectator(); + if (this.isSpectator() || this.isPassenger()) { + this.setOnGround(false); +@@ -297,6 +_,17 @@ + this.turtleHelmetTick(); + } + ++ // Purpur start - Full netherite armor grants fire resistance ++ if (this.level().purpurConfig.playerNetheriteFireResistanceDuration > 0 && this.level().getGameTime() % 20 == 0) { ++ if (this.getItemBySlot(EquipmentSlot.HEAD).is(Items.NETHERITE_HELMET) ++ && this.getItemBySlot(EquipmentSlot.CHEST).is(Items.NETHERITE_CHESTPLATE) ++ && this.getItemBySlot(EquipmentSlot.LEGS).is(Items.NETHERITE_LEGGINGS) ++ && this.getItemBySlot(EquipmentSlot.FEET).is(Items.NETHERITE_BOOTS)) { ++ this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, this.level().purpurConfig.playerNetheriteFireResistanceDuration, this.level().purpurConfig.playerNetheriteFireResistanceAmplifier, this.level().purpurConfig.playerNetheriteFireResistanceAmbient, this.level().purpurConfig.playerNetheriteFireResistanceShowParticles, this.level().purpurConfig.playerNetheriteFireResistanceShowIcon), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.NETHERITE_ARMOR); ++ } ++ } ++ // Purpur end - Full netherite armor grants fire resistance ++ + this.cooldowns.tick(); + this.updatePlayerPose(); + } +@@ -502,7 +_,7 @@ + List orbs = Lists.newArrayList(); + + for (Entity entity : entities) { +- if (entity.is(EntityType.EXPERIENCE_ORB)) { ++ if (entity.is(EntityType.EXPERIENCE_ORB) && entity.level().purpurConfig.playerExpPickupDelay >= 0) { // Purpur - Configurable player pickup exp delay + orbs.add(entity); + } else if (!entity.isRemoved()) { + this.touch(entity); +@@ -1045,7 +_,7 @@ + criticalAttack = criticalAttack && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits + if (criticalAttack) { + damageSource = damageSource.critical(); // Paper - critical damage API +- baseDamage *= 1.5F; ++ baseDamage *= (float) this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur - Add config change multiplier critical damage value + } + + float totalDamage = baseDamage + magicBoost; @@ -1519,7 +_,7 @@ } @@ -9,3 +79,42 @@ return !this.abilities.flying && super.canGlide(); } +@@ -1747,7 +_,23 @@ + + @Override + protected int getBaseExperienceReward(final ServerLevel level) { +- return !level.getGameRules().get(GameRules.KEEP_INVENTORY) && !this.isSpectator() ? Math.min(this.experienceLevel * 7, 100) : 0; ++ // Purpur start - Add player death exp control options ++ if (!level.getGameRules().get(GameRules.KEEP_INVENTORY) && !this.isSpectator()) { ++ int toDrop; ++ try { ++ toDrop = Math.round(((Number) scriptEngine.eval("let expLevel = " + experienceLevel + "; " + ++ "let expTotal = " + totalExperience + "; " + ++ "let exp = " + experienceProgress + "; " + ++ level().purpurConfig.playerDeathExpDropEquation)).floatValue()); ++ } catch (javax.script.ScriptException e) { ++ e.printStackTrace(); ++ toDrop = experienceLevel * 7; ++ } ++ return Math.min(toDrop, level().purpurConfig.playerDeathExpDropMax); ++ } else { ++ return 0; ++ } ++ // Purpur end - Add player death exp control options + } + + @Override +@@ -1790,6 +_,13 @@ + public boolean addItem(final ItemStack itemStack) { + return this.inventory.add(itemStack); + } ++ ++ // Purpur start - Player ridable in water option ++ @Override ++ public boolean dismountsUnderwater() { ++ return !level().purpurConfig.playerRidableInWater; ++ } ++ // Purpur end - Player ridable in water option + + public abstract @Nullable GameType gameMode(); + diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch new file mode 100644 index 000000000..5f3c42406 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java ++++ b/net/minecraft/world/entity/projectile/arrow/ThrownTrident.java +@@ -72,7 +_,7 @@ + + Entity currentOwner = this.getOwner(); + int loyalty = this.entityData.get(ID_LOYALTY); +- if (loyalty > 0 && (this.dealtDamage || this.isNoPhysics()) && currentOwner != null) { ++ if (loyalty > 0 && (this.dealtDamage || this.isNoPhysics() || (level().purpurConfig.tridentLoyaltyVoidReturnHeight < 0.0D && getY() < level().purpurConfig.tridentLoyaltyVoidReturnHeight)) && currentOwner != null) { // Purpur - Add option to allow loyalty on tridents to work in the void + if (!this.isAcceptibleReturnOwner()) { + if (this.level() instanceof ServerLevel level && this.pickup == AbstractArrow.Pickup.ALLOWED) { + this.spawnAtLocation(level, this.getPickupItem(), 0.1F); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch similarity index 72% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch index f6a60729b..fc07f8cde 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java.patch @@ -1,22 +1,14 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java b/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java -index 89a061cd0a2b39fc05ea96ac0f5d5a8c26582f97..3dfe7eef12d40d986d2eb3f750b09b47ee04aecc 100644 --- a/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java +++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/Snowball.java -@@ -53,10 +53,40 @@ public class Snowball extends ThrowableItemProjectile { - protected void onHitEntity(EntityHitResult result) { - super.onHitEntity(result); - Entity entity = result.getEntity(); -- int i = entity instanceof Blaze ? 3 : 0; -+ int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur - Add configurable snowball damage - entity.hurt(this.damageSources().thrown(this, this.getOwner()), i); +@@ -56,9 +_,39 @@ + protected void onHitEntity(final EntityHitResult hitResult) { + super.onHitEntity(hitResult); + Entity entity = hitResult.getEntity(); +- int damage = entity instanceof Blaze ? 3 : 0; ++ int damage = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur - Add configurable snowball damage + entity.hurt(this.damageSources().thrown(this, this.getOwner()), damage); } - ++ + // Purpur start - options to extinguish fire blocks with snowballs - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire + @Override + protected void onHitBlock(net.minecraft.world.phys.BlockHitResult blockHitResult) { @@ -46,7 +38,6 @@ index 89a061cd0a2b39fc05ea96ac0f5d5a8c26582f97..3dfe7eef12d40d986d2eb3f750b09b47 + } + } + // Purpur end - options to extinguish fire blocks with snowballs -+ + @Override - protected void onHit(HitResult result) { - super.onHit(result); + protected void onHit(final HitResult hitResult) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch new file mode 100644 index 000000000..2fc857d67 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java ++++ b/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java +@@ -113,9 +_,10 @@ + return; + } + // CraftBukkit end +- if (this.random.nextFloat() < 0.05F && level.isSpawningMonsters()) { ++ if (this.random.nextFloat() < level.purpurConfig.enderPearlEndermiteChance && level.isSpawningMonsters()) { // Purpur - Configurable Ender Pearl RNG + Endermite endermite = EntityType.ENDERMITE.create(level, EntitySpawnReason.TRIGGERED); + if (endermite != null) { ++ endermite.setPlayerSpawned(true); // Purpur - Add back player spawned endermite API + endermite.snapTo(preTeleportX, preTeleportY, preTeleportZ, preTeleportYRot, preTeleportXRot); // Paper - spawn endermite at pre teleport position as teleport has been moved up + level.addFreshEntity(endermite, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.ENDER_PEARL); // Paper - add reason + } +@@ -135,7 +_,7 @@ + if (newOwner != null) { + newOwner.resetFallDistance(); + newOwner.resetCurrentImpulseContext(); +- newOwner.hurtServer(player.level(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API ++ newOwner.hurtServer(player.level(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage + } + + this.playSound(level, teleportPos); diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/raid/Raids.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raids.java.patch similarity index 55% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/raid/Raids.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raids.java.patch index 4727e0287..346c5d665 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/entity/raid/Raids.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/raid/Raids.java.patch @@ -1,24 +1,16 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/entity/raid/Raids.java b/net/minecraft/world/entity/raid/Raids.java -index 9ded4e75da1efd2fb351fa1544dca33da8455d98..f96d8c241bc0aa44750da7231edbbc5abd802619 100644 --- a/net/minecraft/world/entity/raid/Raids.java +++ b/net/minecraft/world/entity/raid/Raids.java -@@ -31,6 +31,7 @@ import org.jspecify.annotations.Nullable; +@@ -29,6 +_,7 @@ public class Raids extends SavedData { - private static final String RAID_FILE_ID = "raids"; + private static final Identifier RAID_FILE_ID = Identifier.withDefaultNamespace("raids"); + public final java.util.Map playerCooldowns = com.google.common.collect.Maps.newHashMap(); // Purpur - Raid cooldown setting public static final Codec CODEC = RecordCodecBuilder.create( - instance -> instance.group( + i -> i.group( Raids.RaidWithId.CODEC -@@ -82,6 +83,17 @@ public class Raids extends SavedData { +@@ -75,6 +_,17 @@ - public void tick(ServerLevel level) { + public void tick(final ServerLevel level) { this.tick++; + // Purpur start - Raid cooldown setting + if (level.purpurConfig.raidCooldownSeconds != 0 && this.tick % 20 == 0) { @@ -31,20 +23,20 @@ index 9ded4e75da1efd2fb351fa1544dca33da8455d98..f96d8c241bc0aa44750da7231edbbc5a + }); + } + // Purpur end - Raid cooldown setting - Iterator iterator = this.raidMap.values().iterator(); + Iterator raidIterator = this.raidMap.values().iterator(); - while (iterator.hasNext()) { -@@ -144,11 +156,11 @@ public class Raids extends SavedData { + while (raidIterator.hasNext()) { +@@ -137,11 +_,11 @@ // } if (!raid.isStarted() || (raid.isInProgress() && raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel())) { // CraftBukkit - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished - // CraftBukkit start -+ if (serverLevel.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur - Raid cooldown setting// CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(serverLevel, raid, player)) { ++ if (level.purpurConfig.raidCooldownSeconds != 0 && playerCooldowns.containsKey(player.getUUID())) return null; // Purpur - Raid cooldown setting// CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(level, raid, player)) { player.removeEffect(net.minecraft.world.effect.MobEffects.RAID_OMEN); return null; - } -+ }if (serverLevel.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), serverLevel.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting ++ }if (level.purpurConfig.raidCooldownSeconds != 0) playerCooldowns.put(player.getUUID(), serverLevel.purpurConfig.raidCooldownSeconds); // Purpur - Raid cooldown setting if (!raid.isStarted() && !this.raidMap.containsValue(raid)) { this.raidMap.put(this.getUniqueId(), raid); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch new file mode 100644 index 000000000..c13eb8906 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java ++++ b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java +@@ -431,6 +_,7 @@ + float friction = this.getGroundFriction(); + if (friction > 0.0F) { + this.landFriction = friction; ++ if (level().purpurConfig.boatEjectPlayersOnLand) ejectPassengers(); // Purpur - Add option for boats to eject players on land + return AbstractBoat.Status.ON_LAND; + } else { + return AbstractBoat.Status.IN_AIR; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch new file mode 100644 index 000000000..348f58ff5 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/minecart/NewMinecartBehavior.java +@@ -394,7 +_,7 @@ + private Vec3 calculateBoostTrackSpeed(final Vec3 deltaMovement, final BlockPos pos, final BlockState state) { + if (state.is(Blocks.POWERED_RAIL) && state.getValue(PoweredRailBlock.POWERED)) { + if (deltaMovement.length() > 0.01) { +- return deltaMovement.normalize().scale(deltaMovement.length() + 0.06); ++ return deltaMovement.normalize().scale(deltaMovement.length() + this.level().purpurConfig.poweredRailBoostModifier); // Purpur - Configurable powered rail boost modifier + } else { + Vec3 powerDirection = this.minecart.getRedstoneDirection(pos); + return powerDirection.lengthSqr() <= 0.0 ? deltaMovement : powerDirection.scale(deltaMovement.length() + 0.2); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch new file mode 100644 index 000000000..3f8579e30 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java +@@ -242,8 +_,8 @@ + Vec3 vec3 = this.getDeltaMovement(); + double speedLength = vec3.horizontalDistance(); + if (speedLength > 0.01) { +- double speed = 0.06; +- this.setDeltaMovement(vec3.add(vec3.x / speedLength * 0.06, 0.0, vec3.z / speedLength * 0.06)); ++ double speed = level.purpurConfig.poweredRailBoostModifier; // Purpur - Configurable powered rail boost modifier ++ this.setDeltaMovement(vec3.add(vec3.x / speedLength * level.purpurConfig.poweredRailBoostModifier, 0.0, vec3.z / speedLength * level.purpurConfig.poweredRailBoostModifier)); // Purpur - Configurable powered rail boost modifier + } else { + Vec3 deltaMovement = this.getDeltaMovement(); + double dx = deltaMovement.x; diff --git a/purpur-server/minecraft-patches/rejected/net/minecraft/world/food/FoodData.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/food/FoodData.java.patch similarity index 60% rename from purpur-server/minecraft-patches/rejected/net/minecraft/world/food/FoodData.java.patch rename to purpur-server/minecraft-patches/sources/net/minecraft/world/food/FoodData.java.patch index 177fdb835..1d663773e 100644 --- a/purpur-server/minecraft-patches/rejected/net/minecraft/world/food/FoodData.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/food/FoodData.java.patch @@ -1,14 +1,6 @@ -From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001 -From: File -Date: Sun, 20 Apr 1997 05:37:42 -0800 -Subject: [PATCH] purpur File Patches - - -diff --git a/net/minecraft/world/food/FoodData.java b/net/minecraft/world/food/FoodData.java -index f4925847ee2dac8740148ffa82d8c23c4d0c7af0..5fa21ff6624df90925a6850f9f9f092396ed8b83 100644 --- a/net/minecraft/world/food/FoodData.java +++ b/net/minecraft/world/food/FoodData.java -@@ -39,6 +39,7 @@ public class FoodData { +@@ -39,6 +_,7 @@ int oldFoodLevel = this.foodLevel; org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(serverPlayer, foodProperties.nutrition() + oldFoodLevel, stack); if (!event.isCancelled()) { @@ -16,12 +8,12 @@ index f4925847ee2dac8740148ffa82d8c23c4d0c7af0..5fa21ff6624df90925a6850f9f9f0923 this.add(event.getFoodLevel() - oldFoodLevel, foodProperties.saturation()); } serverPlayer.getBukkitEntity().sendHealthUpdate(); -@@ -87,7 +88,7 @@ public class FoodData { +@@ -87,7 +_,7 @@ this.tickTimer++; if (this.tickTimer >= this.starvationRate) { // CraftBukkit - add regen rate manipulation if (player.getHealth() > 10.0F || difficulty == Difficulty.HARD || player.getHealth() > 1.0F && difficulty == Difficulty.NORMAL) { -- player.hurtServer(serverLevel, player.damageSources().starve(), 1.0F); -+ player.hurtServer(serverLevel, player.damageSources().starve(), player.level().purpurConfig.hungerStarvationDamage); // Purpur - Configurable hunger starvation damage +- player.hurtServer(level, player.damageSources().starve(), 1.0F); ++ player.hurtServer(level, player.damageSources().starve(), player.level().purpurConfig.hungerStarvationDamage); // Purpur - Configurable hunger starvation damage } this.tickTimer = 0; diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch new file mode 100644 index 000000000..d021a25df --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/block/piston/PistonStructureResolver.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/level/block/piston/PistonStructureResolver.java ++++ b/net/minecraft/world/level/block/piston/PistonStructureResolver.java +@@ -81,7 +_,7 @@ + return true; + } else { + int blockCount = 1; +- if (blockCount + this.toPush.size() > 12) { ++ if (blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit + return false; + } else { + while (isSticky(nextState)) { +@@ -95,7 +_,7 @@ + break; + } + +- if (++blockCount + this.toPush.size() > 12) { ++ if (++blockCount + this.toPush.size() > this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit + return false; + } + } +@@ -139,7 +_,7 @@ + return true; + } + +- if (this.toPush.size() >= 12) { ++ if (this.toPush.size() >= this.level.purpurConfig.pistonBlockPushLimit) { // Purpur - Configurable piston push limit + return false; + } +