From 3d79a61a2598df779fccce92e229e105e6114475 Mon Sep 17 00:00:00 2001 From: Ben Kerllenevich Date: Tue, 15 Jun 2021 20:47:29 -0400 Subject: [PATCH] pain is all i know --- patches/server-unmapped/0017-Anvil-API.patch | 147 ----------- ...18-Configurable-villager-brain-ticks.patch | 53 ---- .../0019-Alternative-Keepalive-Handling.patch | 85 ------- .../0020-Silk-touch-spawners.patch | 235 ------------------ ...772-Fix-Add-turtle-egg-block-options.patch | 71 ------ patches/server/0016-Anvil-API.patch | 146 +++++++++++ ...17-Configurable-villager-brain-ticks.patch | 53 ++++ .../0018-Alternative-Keepalive-Handling.patch | 73 ++++++ patches/server/0019-Silk-touch-spawners.patch | 218 ++++++++++++++++ ...772-Fix-Add-turtle-egg-block-options.patch | 71 ++++++ ...-vanilla-command-permission-handler.patch} | 12 +- ...settings-suppressing-pointless-logs.patch} | 22 +- .../0023-Disable-outdated-build-check.patch} | 12 +- 13 files changed, 584 insertions(+), 614 deletions(-) delete mode 100644 patches/server-unmapped/0017-Anvil-API.patch delete mode 100644 patches/server-unmapped/0018-Configurable-villager-brain-ticks.patch delete mode 100644 patches/server-unmapped/0019-Alternative-Keepalive-Handling.patch delete mode 100644 patches/server-unmapped/0020-Silk-touch-spawners.patch delete mode 100644 patches/server-unmapped/0021-MC-168772-Fix-Add-turtle-egg-block-options.patch create mode 100644 patches/server/0016-Anvil-API.patch create mode 100644 patches/server/0017-Configurable-villager-brain-ticks.patch create mode 100644 patches/server/0018-Alternative-Keepalive-Handling.patch create mode 100644 patches/server/0019-Silk-touch-spawners.patch create mode 100644 patches/server/0020-MC-168772-Fix-Add-turtle-egg-block-options.patch rename patches/{server-unmapped/0022-Fix-vanilla-command-permission-handler.patch => server/0021-Fix-vanilla-command-permission-handler.patch} (77%) rename patches/{server-unmapped/0023-Logger-settings-suppressing-pointless-logs.patch => server/0022-Logger-settings-suppressing-pointless-logs.patch} (68%) rename patches/{server-unmapped/0024-Disable-outdated-build-check.patch => server/0023-Disable-outdated-build-check.patch} (55%) diff --git a/patches/server-unmapped/0017-Anvil-API.patch b/patches/server-unmapped/0017-Anvil-API.patch deleted file mode 100644 index 8465320bc..000000000 --- a/patches/server-unmapped/0017-Anvil-API.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sun, 19 Apr 2020 00:17:56 -0500 -Subject: [PATCH] Anvil API - - -diff --git a/src/main/java/net/minecraft/world/inventory/ContainerAnvil.java b/src/main/java/net/minecraft/world/inventory/ContainerAnvil.java -index ae5674ae9c539720a657838a640050cd3b4dc5b5..1b2d633f3d5d735039f18f27fb1387bd5a74f0d8 100644 ---- a/src/main/java/net/minecraft/world/inventory/ContainerAnvil.java -+++ b/src/main/java/net/minecraft/world/inventory/ContainerAnvil.java -@@ -2,8 +2,13 @@ package net.minecraft.world.inventory; - - import java.util.Iterator; - import java.util.Map; -+ -+import net.minecraft.nbt.NBTTagInt; - import net.minecraft.network.chat.ChatComponentText; - import net.minecraft.network.chat.IChatBaseComponent; -+import net.minecraft.network.protocol.game.PacketPlayOutSetSlot; -+import net.minecraft.network.protocol.game.PacketPlayOutWindowData; -+import net.minecraft.server.level.EntityPlayer; - import net.minecraft.tags.Tag; - import net.minecraft.tags.TagsBlock; - import net.minecraft.world.entity.player.EntityHuman; -@@ -33,6 +38,8 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - public int maximumRepairCost = 40; - private CraftInventoryView bukkitEntity; - // CraftBukkit end -+ public boolean bypassCost = false; // Purpur -+ public boolean canDoUnsafeEnchants = false; // Purpur - - public ContainerAnvil(int i, PlayerInventory playerinventory) { - this(i, playerinventory, ContainerAccess.a); -@@ -51,12 +58,14 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - - @Override - protected boolean b(EntityHuman entityhuman, boolean flag) { -- return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= this.levelCost.get()) && this.levelCost.get() > 0; -+ return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= this.levelCost.get()) && (bypassCost || this.levelCost.get() > 0); // Purpur - } - - @Override - protected ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { -+ if (net.pl3x.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilTakeResultEvent(entityhuman.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)).callEvent(); // Purpur - if (!entityhuman.abilities.canInstantlyBuild) { -+ if (bypassCost) ((EntityPlayer) entityhuman).lastSentExp = -1; else // Purpur - entityhuman.levelDown(-this.levelCost.get()); - } - -@@ -107,6 +116,12 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - - @Override - public void e() { -+ // Purpur start -+ bypassCost = false; -+ canDoUnsafeEnchants = false; -+ if (net.pl3x.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); -+ // Purpur end -+ - ItemStack itemstack = this.repairInventory.getItem(0); - - this.levelCost.set(1); -@@ -183,7 +198,7 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - int i2 = (Integer) map1.get(enchantment); - - i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); -- boolean flag3 = enchantment.canEnchant(itemstack); -+ boolean flag3 = canDoUnsafeEnchants || enchantment.canEnchant(itemstack); // Purpur - - if (this.player.abilities.canInstantlyBuild || itemstack.getItem() == Items.ENCHANTED_BOOK) { - flag3 = true; -@@ -195,7 +210,7 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - Enchantment enchantment1 = (Enchantment) iterator1.next(); - - if (enchantment1 != enchantment && !enchantment.isCompatible(enchantment1)) { -- flag3 = false; -+ flag3 = canDoUnsafeEnchants; // Purpur - ++i; - } - } -@@ -266,6 +281,13 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - this.levelCost.set(maximumRepairCost - 1); // CraftBukkit - } - -+ // Purpur start -+ if (bypassCost && levelCost.get() >= maximumRepairCost) { -+ itemstack.getOrCreateTagAndSet("Purpur.realCost", NBTTagInt.a(levelCost.get())); -+ levelCost.set(maximumRepairCost - 1); -+ } -+ // Purpur end -+ - if (this.levelCost.get() >= maximumRepairCost && !this.player.abilities.canInstantlyBuild) { // CraftBukkit - itemstack1 = ItemStack.b; - } -@@ -287,6 +309,12 @@ public class ContainerAnvil extends ContainerAnvilAbstract { - - org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1); // CraftBukkit - this.c(); -+ // Purpur start -+ if (canDoUnsafeEnchants && itemstack1 != ItemStack.NULL_ITEM) { -+ ((EntityPlayer) player).playerConnection.sendPacket(new PacketPlayOutSetSlot(windowId, 2, itemstack1)); -+ ((EntityPlayer) player).playerConnection.sendPacket(new PacketPlayOutWindowData(windowId, 0, levelCost.get())); -+ } -+ // Purpur end - } - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java -index fd59f77d78a97898657919a77405b39ca24cddc9..151c478c6cb19d88000da46b6fbb952e97e58c95 100644 ---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java -+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java -@@ -9,7 +9,7 @@ import org.bukkit.inventory.AnvilInventory; - public class CraftInventoryAnvil extends CraftResultInventory implements AnvilInventory { - - private final Location location; -- private final ContainerAnvil container; -+ public final ContainerAnvil container; // Purpur - private -> public - - public CraftInventoryAnvil(Location location, IInventory inventory, IInventory resultInventory, ContainerAnvil container) { - super(inventory, resultInventory); -@@ -47,4 +47,26 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn - Preconditions.checkArgument(levels >= 0, "Maximum repair cost must be positive (or 0)"); - container.maximumRepairCost = levels; - } -+ -+ // Purpur start -+ @Override -+ public boolean canBypassCost() { -+ return container.bypassCost; -+ } -+ -+ @Override -+ public void setBypassCost(boolean bypassCost) { -+ container.bypassCost = bypassCost; -+ } -+ -+ @Override -+ public boolean canDoUnsafeEnchants() { -+ return container.canDoUnsafeEnchants; -+ } -+ -+ @Override -+ public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { -+ container.canDoUnsafeEnchants = canDoUnsafeEnchants; -+ } -+ // Purpur end - } diff --git a/patches/server-unmapped/0018-Configurable-villager-brain-ticks.patch b/patches/server-unmapped/0018-Configurable-villager-brain-ticks.patch deleted file mode 100644 index 60d849457..000000000 --- a/patches/server-unmapped/0018-Configurable-villager-brain-ticks.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Tue, 23 Jul 2019 08:28:21 -0500 -Subject: [PATCH] Configurable villager brain ticks - - -diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -index 85374ac8f5460790de03b47d7c3ce19ed5596afe..c45e6ae3f912ac582c6ba693517e05cd8fbf33e2 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java -@@ -127,6 +127,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - }, MemoryModuleType.MEETING_POINT, (entityvillager, villageplacetype) -> { - return villageplacetype == VillagePlaceType.s; - }); -+ private final int brainTickOffset; // Purpur - - public EntityVillager(EntityTypes entitytypes, World world) { - this(entitytypes, world, VillagerType.PLAINS); -@@ -139,6 +140,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - this.getNavigation().d(true); - this.setCanPickupLoot(true); - this.setVillagerData(this.getVillagerData().withType(villagertype).withProfession(VillagerProfession.NONE)); -+ this.brainTickOffset = getRandom().nextInt(100); // Purpur - } - - @Override -@@ -235,6 +237,10 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation - protected void mobTick() { mobTick(false); } - protected void mobTick(boolean inactive) { - this.world.getMethodProfiler().enter("villagerBrain"); -+ // Purpur start -+ boolean tick = (world.getTime() + brainTickOffset) % world.purpurConfig.villagerBrainTicks == 0; -+ if (((WorldServer) world).getMinecraftServer().lagging ? tick : world.purpurConfig.villagerUseBrainTicksOnlyWhenLagging || tick) -+ // Purpur end - if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper - this.world.getMethodProfiler().exit(); - if (this.bF) { -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c441fcea9b2b5a77b801c8a69541cf42050927dc..c7fb5a737cab0083c39732247acb8f4e87562894 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -74,4 +74,11 @@ public class PurpurWorldConfig { - playerSpawnInvulnerableTicks = getInt("gameplay-mechanics.player.spawn-invulnerable-ticks", playerSpawnInvulnerableTicks); - playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); - } -+ -+ public int villagerBrainTicks = 1; -+ public boolean villagerUseBrainTicksOnlyWhenLagging = true; -+ private void villagerSettings() { -+ villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); -+ villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); -+ } - } diff --git a/patches/server-unmapped/0019-Alternative-Keepalive-Handling.patch b/patches/server-unmapped/0019-Alternative-Keepalive-Handling.patch deleted file mode 100644 index 54630ced3..000000000 --- a/patches/server-unmapped/0019-Alternative-Keepalive-Handling.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Fri, 11 Oct 2019 00:17:39 -0500 -Subject: [PATCH] Alternative Keepalive Handling - - -diff --git a/src/main/java/net/minecraft/network/protocol/game/PacketPlayInKeepAlive.java b/src/main/java/net/minecraft/network/protocol/game/PacketPlayInKeepAlive.java -index b4c37287362907b8507d156b978ba5b9d961bb7b..9e6e6636539702507abb78515e002819661027af 100644 ---- a/src/main/java/net/minecraft/network/protocol/game/PacketPlayInKeepAlive.java -+++ b/src/main/java/net/minecraft/network/protocol/game/PacketPlayInKeepAlive.java -@@ -24,6 +24,7 @@ public class PacketPlayInKeepAlive implements Packet { - packetdataserializer.writeLong(this.a); - } - -+ public long getId() { return b(); } // Purpur - OBFHELPER - public long b() { - return this.a; - } -diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java -index ab807588a4b7dc0fd8bb6f829f9d1a785490d733..293b2c187b813c2cf7204f12eec768fd2e92a233 100644 ---- a/src/main/java/net/minecraft/server/network/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java -@@ -233,6 +233,7 @@ public class PlayerConnection implements PacketListenerPlayIn { - private long lastKeepAlive = SystemUtils.getMonotonicMillis(); private void setLastPing(long lastPing) { this.lastKeepAlive = lastPing;}; private long getLastPing() { return this.lastKeepAlive;}; // Paper - OBFHELPER - private boolean awaitingKeepAlive; private void setPendingPing(boolean isPending) { this.awaitingKeepAlive = isPending;}; private boolean isPendingPing() { return this.awaitingKeepAlive;}; // Paper - OBFHELPER - private long h; private void setKeepAliveID(long keepAliveID) { this.h = keepAliveID;}; private long getKeepAliveID() {return this.h; }; // Paper - OBFHELPER -+ private java.util.List keepAlives = new java.util.ArrayList<>(); // Purpur - // CraftBukkit start - multithreaded fields - private volatile int chatThrottle; - private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle"); -@@ -367,6 +368,21 @@ public class PlayerConnection implements PacketListenerPlayIn { - long currentTime = SystemUtils.getMonotonicMillis(); - long elapsedTime = currentTime - this.getLastPing(); - -+ // Purpur start -+ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) { -+ if (elapsedTime >= 1000L) { // 1 second -+ if (!processedDisconnect && keepAlives.size() > KEEPALIVE_LIMIT) { -+ PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", player.getName()); -+ disconnect(new ChatMessage("disconnect.timeout")); -+ } else { -+ setLastPing(currentTime); // hijack this field for 1 second intervals -+ keepAlives.add(currentTime); // currentTime is ID -+ sendPacket(new PacketPlayOutKeepAlive(currentTime)); -+ } -+ } -+ } else -+ // Purpur end -+ - if (this.isPendingPing()) { - if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected - PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getName()); // more info -@@ -3011,6 +3027,16 @@ public class PlayerConnection implements PacketListenerPlayIn { - - @Override - public void a(PacketPlayInKeepAlive packetplayinkeepalive) { -+ // Purpur start -+ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) { -+ long id = packetplayinkeepalive.getId(); -+ if (keepAlives.size() > 0 && keepAlives.contains(id)) { -+ int ping = (int) (SystemUtils.getMonotonicMillis() - id); -+ player.ping = (player.ping * 3 + ping) / 4; -+ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest -+ } -+ } else -+ // Purpur end - //PlayerConnectionUtils.ensureMainThread(packetplayinkeepalive, this, this.player.getWorldServer()); // CraftBukkit // Paper - This shouldn't be on the main thread - if (this.awaitingKeepAlive && packetplayinkeepalive.b() == this.h) { - int i = (int) (SystemUtils.getMonotonicMillis() - this.lastKeepAlive); -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index 089ae62c2189fe774796ecc6caf9961d3edb5ea3..afd0c577069f2a856caf41bd2dd5187db4866fa3 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -155,6 +155,11 @@ public class PurpurConfig { - laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); - } - -+ public static boolean useAlternateKeepAlive = false; -+ private static void useAlternateKeepAlive() { -+ useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); -+ } -+ - public static boolean barrelSixRows = false; - public static boolean enderChestSixRows = false; - public static boolean enderChestPermissionRows = false; diff --git a/patches/server-unmapped/0020-Silk-touch-spawners.patch b/patches/server-unmapped/0020-Silk-touch-spawners.patch deleted file mode 100644 index 65b904c44..000000000 --- a/patches/server-unmapped/0020-Silk-touch-spawners.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 9 May 2019 14:27:37 -0500 -Subject: [PATCH] Silk touch spawners - - -diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -index 7b14b3c2486f03778d4673cf9684aa576dc2724a..822ffa8e4b554fd6aa7ce1b2bb68c198c863d86c 100644 ---- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -+++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java -@@ -81,6 +81,7 @@ public final class PaperAdventure { - }) - .build(); - public static final LegacyComponentSerializer LEGACY_SECTION_UXRC = LegacyComponentSerializer.builder().flattener(FLATTENER).hexColors().useUnusualXRepeatedCharacterHexFormat().build(); -+ public static final LegacyComponentSerializer LEGACY_AMPERSAND = LegacyComponentSerializer.builder().character(LegacyComponentSerializer.AMPERSAND_CHAR).hexColors().build(); // Purpur - public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build(); - public static final GsonComponentSerializer GSON = GsonComponentSerializer.builder() - .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE) -diff --git a/src/main/java/net/minecraft/server/ItemSpawner.java b/src/main/java/net/minecraft/server/ItemSpawner.java -new file mode 100644 -index 0000000000000000000000000000000000000000..599672ed4d0fc412ad3c0fa2e9d9df7035694fa2 ---- /dev/null -+++ b/src/main/java/net/minecraft/server/ItemSpawner.java -@@ -0,0 +1,35 @@ -+package net.minecraft.server; -+ -+import net.minecraft.core.BlockPosition; -+import net.minecraft.nbt.NBTTagCompound; -+import net.minecraft.world.entity.EntityTypes; -+import net.minecraft.world.entity.player.EntityHuman; -+import net.minecraft.world.item.ItemBlock; -+import net.minecraft.world.item.ItemStack; -+import net.minecraft.world.level.World; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.entity.TileEntity; -+import net.minecraft.world.level.block.entity.TileEntityMobSpawner; -+import net.minecraft.world.level.block.state.IBlockData; -+ -+public class ItemSpawner extends ItemBlock { -+ public ItemSpawner(Block block, Info info) { -+ super(block, info); -+ } -+ -+ @Override -+ protected boolean a(BlockPosition blockposition, World world, EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { -+ boolean handled = super.a(blockposition, world, entityhuman, itemstack, iblockdata); -+ if (world.purpurConfig.silkTouchEnabled && entityhuman.getBukkitEntity().hasPermission("purpur.place.spawners")) { -+ TileEntity spawner = world.getTileEntity(blockposition); -+ if (spawner instanceof TileEntityMobSpawner && itemstack.hasTag()) { -+ NBTTagCompound tag = itemstack.getTag(); -+ if (tag.hasKey("Purpur.mob_type")) { -+ EntityTypes.getByName(tag.getString("Purpur.mob_type")).ifPresent(type -> -+ ((TileEntityMobSpawner) spawner).getSpawner().setMobName(type)); -+ } -+ } -+ } -+ return handled; -+ } -+} -diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java -index fc5cc610e7ea584ce72600b9d9f47543265725bb..8e9a25495d76251a86268d3059e2960a86dc46b3 100644 ---- a/src/main/java/net/minecraft/world/item/Items.java -+++ b/src/main/java/net/minecraft/world/item/Items.java -@@ -2,6 +2,7 @@ package net.minecraft.world.item; - - import net.minecraft.core.IRegistry; - import net.minecraft.resources.MinecraftKey; -+import net.minecraft.server.ItemSpawner; - import net.minecraft.sounds.SoundEffects; - import net.minecraft.world.entity.EntityTypes; - import net.minecraft.world.entity.EnumItemSlot; -@@ -193,7 +194,7 @@ public class Items { - public static final Item ct = a(Blocks.PURPUR_BLOCK, CreativeModeTab.b); - public static final Item cu = a(Blocks.PURPUR_PILLAR, CreativeModeTab.b); - public static final Item cv = a(Blocks.PURPUR_STAIRS, CreativeModeTab.b); -- public static final Item cw = a(Blocks.SPAWNER); -+ public static final Item cw = a(Blocks.SPAWNER, new ItemSpawner(Blocks.SPAWNER, new Item.Info().a(EnumItemRarity.EPIC))); // Purpur - public static final Item cx = a(Blocks.OAK_STAIRS, CreativeModeTab.b); - public static final Item cy = a(Blocks.CHEST, CreativeModeTab.c); - public static final Item cz = a(Blocks.DIAMOND_ORE, CreativeModeTab.b); -diff --git a/src/main/java/net/minecraft/world/level/block/BlockMobSpawner.java b/src/main/java/net/minecraft/world/level/block/BlockMobSpawner.java -index 287dd5f1b2b913df4029966860cd1a426947b187..af3c1a6307fb9e244226794508382d2ffa2aeb4b 100644 ---- a/src/main/java/net/minecraft/world/level/block/BlockMobSpawner.java -+++ b/src/main/java/net/minecraft/world/level/block/BlockMobSpawner.java -@@ -1,14 +1,35 @@ - package net.minecraft.world.level.block; - - import net.minecraft.core.BlockPosition; -+import net.minecraft.nbt.NBTTagCompound; -+import net.minecraft.nbt.NBTTagList; -+import net.minecraft.nbt.NBTTagString; -+import net.minecraft.resources.MinecraftKey; - import net.minecraft.server.level.WorldServer; -+import net.minecraft.world.entity.EntityTypes; -+import net.minecraft.world.entity.player.EntityHuman; - import net.minecraft.world.item.ItemStack; -+import net.minecraft.world.item.enchantment.EnchantmentManager; -+import net.minecraft.world.item.enchantment.Enchantments; - import net.minecraft.world.level.IBlockAccess; -+import net.minecraft.world.level.World; - import net.minecraft.world.level.block.entity.TileEntity; - import net.minecraft.world.level.block.entity.TileEntityMobSpawner; - import net.minecraft.world.level.block.state.BlockBase; - import net.minecraft.world.level.block.state.IBlockData; - -+// Purpur start -+import io.papermc.paper.adventure.PaperAdventure; -+import net.kyori.adventure.text.Component; -+import net.kyori.adventure.text.TextReplacementConfig; -+import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -+ -+import java.util.List; -+ -+import static net.kyori.adventure.text.format.TextDecoration.ITALIC; -+// Purpur end -+ - public class BlockMobSpawner extends BlockTileEntity { - - protected BlockMobSpawner(BlockBase.Info blockbase_info) { -@@ -20,6 +41,59 @@ public class BlockMobSpawner extends BlockTileEntity { - return new TileEntityMobSpawner(); - } - -+ // Purpur start -+ @Override -+ public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity, ItemStack itemstack) { -+ if (world.purpurConfig.silkTouchEnabled && entityhuman.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(world, itemstack)) { -+ MinecraftKey type = ((TileEntityMobSpawner) tileentity).getSpawner().getMobName(); -+ if (type != null) { -+ final Component mobName = PaperAdventure.asAdventure(EntityTypes.getFromKey(type).getNameComponent()); -+ final TextReplacementConfig config = TextReplacementConfig.builder() -+ .matchLiteral("{mob}") -+ .replacement(mobName) -+ .build(); -+ -+ NBTTagCompound display = new NBTTagCompound(); -+ boolean customDisplay = false; -+ -+ String name = world.purpurConfig.silkTouchSpawnerName; -+ if (name != null && !name.isEmpty() && !name.equals("Spawner")) { -+ final Component displayName = PaperAdventure.LEGACY_AMPERSAND.deserialize(name).replaceText(config).decoration(ITALIC, false); -+ display.set("Name", NBTTagString.create(GsonComponentSerializer.gson().serialize(displayName))); -+ customDisplay = true; -+ } -+ -+ List lore = world.purpurConfig.silkTouchSpawnerLore; -+ if (lore != null && !lore.isEmpty()) { -+ NBTTagList list = new NBTTagList(); -+ for (String line : lore) { -+ final Component lineComponent = PaperAdventure.LEGACY_AMPERSAND.deserialize(line).replaceText(config).decoration(ITALIC, false); -+ list.add(NBTTagString.create(GsonComponentSerializer.gson().serialize(lineComponent))); -+ } -+ display.set("Lore", list); -+ customDisplay = true; -+ } -+ -+ NBTTagCompound tag = new NBTTagCompound(); -+ if (customDisplay) { -+ tag.set("display", display); -+ } -+ tag.setString("Purpur.mob_type", type.toString()); -+ -+ ItemStack item = new ItemStack(Blocks.SPAWNER.getItem()); -+ item.setTag(tag); -+ -+ dropItem(world, blockposition, item); -+ } -+ } -+ super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); -+ } -+ -+ private boolean isSilkTouch(World world, ItemStack itemstack) { -+ return itemstack != null && world.purpurConfig.silkTouchTools.contains(itemstack.getItem()) && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) > 0; -+ } -+ // Purpur end -+ - @Override - public void dropNaturally(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, ItemStack itemstack) { - super.dropNaturally(iblockdata, worldserver, blockposition, itemstack); -@@ -32,6 +106,7 @@ public class BlockMobSpawner extends BlockTileEntity { - - @Override - public int getExpDrop(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, ItemStack itemstack) { -+ if (isSilkTouch(worldserver, itemstack)) return 0; // Purpur - int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15); - - return i; -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index c7fb5a737cab0083c39732247acb8f4e87562894..10a6fcd70869719ed2b2d1442a83ab912e00c898 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -1,6 +1,12 @@ - package net.pl3x.purpur; - -+import net.minecraft.core.IRegistry; -+import net.minecraft.world.item.Item; -+import net.minecraft.world.item.Items; -+import net.minecraft.resources.MinecraftKey; - import org.bukkit.configuration.ConfigurationSection; -+ -+import java.util.ArrayList; - import java.util.List; - import static net.pl3x.purpur.PurpurConfig.log; - -@@ -75,6 +81,29 @@ public class PurpurWorldConfig { - playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); - } - -+ public boolean silkTouchEnabled = false; -+ public String silkTouchSpawnerName = "Spawner"; -+ public List silkTouchSpawnerLore = new ArrayList<>(); -+ public List silkTouchTools = new ArrayList<>(); -+ private void silkTouchSettings() { -+ silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled); -+ silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); -+ silkTouchSpawnerLore.clear(); -+ getList("gameplay-mechanics.silk-touch.spawner-lore", new ArrayList(){{ -+ add("Spawns a {mob}"); -+ }}).forEach(line -> silkTouchSpawnerLore.add(line.toString())); -+ silkTouchTools.clear(); -+ getList("gameplay-mechanics.silk-touch.tools", new ArrayList(){{ -+ add("minecraft:iron_pickaxe"); -+ add("minecraft:golden_pickaxe"); -+ add("minecraft:diamond_pickaxe"); -+ add("minecraft:netherite_pickaxe"); -+ }}).forEach(key -> { -+ Item item = IRegistry.ITEM.get(new MinecraftKey(key.toString())); -+ if (item != Items.AIR) silkTouchTools.add(item); -+ }); -+ } -+ - public int villagerBrainTicks = 1; - public boolean villagerUseBrainTicksOnlyWhenLagging = true; - private void villagerSettings() { diff --git a/patches/server-unmapped/0021-MC-168772-Fix-Add-turtle-egg-block-options.patch b/patches/server-unmapped/0021-MC-168772-Fix-Add-turtle-egg-block-options.patch deleted file mode 100644 index ae221310a..000000000 --- a/patches/server-unmapped/0021-MC-168772-Fix-Add-turtle-egg-block-options.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Thu, 6 Jun 2019 22:15:46 -0500 -Subject: [PATCH] MC-168772 Fix - Add turtle egg block options - - -diff --git a/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java b/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java -index 6093d4c7431a286477c9be97163ea8d64168c3b0..04504901b1933ed760b34b8abb994de8ec340a4e 100644 ---- a/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java -+++ b/src/main/java/net/minecraft/world/level/block/BlockTurtleEgg.java -@@ -9,12 +9,15 @@ import net.minecraft.sounds.SoundEffects; - import net.minecraft.tags.Tag; - import net.minecraft.tags.TagsBlock; - import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityExperienceOrb; - import net.minecraft.world.entity.EntityLiving; - import net.minecraft.world.entity.EntityTypes; - import net.minecraft.world.entity.ambient.EntityBat; - import net.minecraft.world.entity.animal.EntityTurtle; -+import net.minecraft.world.entity.item.EntityItem; - import net.minecraft.world.entity.monster.EntityZombie; - import net.minecraft.world.entity.player.EntityHuman; -+import net.minecraft.world.entity.vehicle.EntityMinecartAbstract; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.context.BlockActionContext; - import net.minecraft.world.level.GameRules; -@@ -189,6 +192,23 @@ public class BlockTurtleEgg extends Block { - } - - private boolean a(World world, Entity entity) { -- return !(entity instanceof EntityTurtle) && !(entity instanceof EntityBat) ? (!(entity instanceof EntityLiving) ? false : entity instanceof EntityHuman || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) : false; -+ // Purpur start - fix MC-168772 -+ if (entity instanceof EntityTurtle) { -+ return false; -+ } -+ if (!world.purpurConfig.turtleEggsBreakFromExpOrbs && entity instanceof EntityExperienceOrb) { -+ return false; -+ } -+ if (!world.purpurConfig.turtleEggsBreakFromItems && entity instanceof EntityItem) { -+ return false; -+ } -+ if (!world.purpurConfig.turtleEggsBreakFromMinecarts && entity instanceof EntityMinecartAbstract) { -+ return false; -+ } -+ if (entity instanceof EntityLiving && !(entity instanceof EntityHuman)) { -+ return world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); -+ } -+ return true; -+ // Purpur end - } - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -index 10a6fcd70869719ed2b2d1442a83ab912e00c898..2f18ca7ae23e913155f25fd07627f376e401ab0f 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java -@@ -104,6 +104,15 @@ public class PurpurWorldConfig { - }); - } - -+ public boolean turtleEggsBreakFromExpOrbs = true; -+ public boolean turtleEggsBreakFromItems = true; -+ public boolean turtleEggsBreakFromMinecarts = true; -+ private void turtleEggSettings() { -+ turtleEggsBreakFromExpOrbs = getBoolean("blocks.turtle_egg.break-from-exp-orbs", turtleEggsBreakFromExpOrbs); -+ turtleEggsBreakFromItems = getBoolean("blocks.turtle_egg.break-from-items", turtleEggsBreakFromItems); -+ turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); -+ } -+ - public int villagerBrainTicks = 1; - public boolean villagerUseBrainTicksOnlyWhenLagging = true; - private void villagerSettings() { diff --git a/patches/server/0016-Anvil-API.patch b/patches/server/0016-Anvil-API.patch new file mode 100644 index 000000000..223da7f3d --- /dev/null +++ b/patches/server/0016-Anvil-API.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 19 Apr 2020 00:17:56 -0500 +Subject: [PATCH] Anvil API + + +diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +index 56d3ed1cdafd7904c35be5db568b9975a97418a7..2db80c986e1dbd4aa9be288cc802f650169dc11a 100644 +--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java ++++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +@@ -2,8 +2,12 @@ package net.minecraft.world.inventory; + + import java.util.Iterator; + import java.util.Map; ++import net.minecraft.nbt.IntTag; + import net.minecraft.network.chat.Component; + import net.minecraft.network.chat.TextComponent; ++import net.minecraft.network.protocol.game.ClientboundContainerSetDataPacket; ++import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.tags.BlockTags; + import net.minecraft.tags.Tag; + import net.minecraft.world.entity.player.Inventory; +@@ -42,6 +46,8 @@ public class AnvilMenu extends ItemCombinerMenu { + public int maximumRepairCost = 40; + private CraftInventoryView bukkitEntity; + // CraftBukkit end ++ public boolean bypassCost = false; // Purpur ++ public boolean canDoUnsafeEnchants = false; // Purpur + + public AnvilMenu(int syncId, Inventory inventory) { + this(syncId, inventory, ContainerLevelAccess.NULL); +@@ -60,12 +66,14 @@ public class AnvilMenu extends ItemCombinerMenu { + + @Override + protected boolean mayPickup(Player player, boolean present) { +- return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && this.cost.get() > 0; ++ return (player.getAbilities().instabuild || player.experienceLevel >= this.cost.get()) && (bypassCost || this.cost.get() > 0); // Purpur + } + + @Override + protected void onTake(Player player, ItemStack stack) { ++ if (net.pl3x.purpur.event.inventory.AnvilTakeResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)).callEvent(); // Purpur + if (!player.getAbilities().instabuild) { ++ if (bypassCost) ((ServerPlayer) player).lastSentExp = -1; else // Purpur + player.giveExperienceLevels(-this.cost.get()); + } + +@@ -117,6 +125,12 @@ public class AnvilMenu extends ItemCombinerMenu { + + @Override + public void createResult() { ++ // Purpur start ++ bypassCost = false; ++ canDoUnsafeEnchants = false; ++ if (net.pl3x.purpur.event.inventory.AnvilUpdateResultEvent.getHandlerList().getRegisteredListeners().length > 0) new net.pl3x.purpur.event.inventory.AnvilUpdateResultEvent(getBukkitView()).callEvent(); ++ // Purpur end ++ + ItemStack itemstack = this.inputSlots.getItem(0); + + this.cost.set(1); +@@ -193,7 +207,7 @@ public class AnvilMenu extends ItemCombinerMenu { + int i2 = (Integer) map1.get(enchantment); + + i2 = l1 == i2 ? i2 + 1 : Math.max(i2, l1); +- boolean flag3 = enchantment.canEnchant(itemstack); ++ boolean flag3 = canDoUnsafeEnchants || enchantment.canEnchant(itemstack); // Purpur + + if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { + flag3 = true; +@@ -205,7 +219,7 @@ public class AnvilMenu extends ItemCombinerMenu { + Enchantment enchantment1 = (Enchantment) iterator1.next(); + + if (enchantment1 != enchantment && !enchantment.isCompatibleWith(enchantment1)) { +- flag3 = false; ++ flag3 = canDoUnsafeEnchants; // Purpur + ++i; + } + } +@@ -276,6 +290,13 @@ public class AnvilMenu extends ItemCombinerMenu { + this.cost.set(this.maximumRepairCost - 1); // CraftBukkit + } + ++ // Purpur start ++ if (bypassCost && cost.get() >= maximumRepairCost) { ++ itemstack.getOrCreateTagAndSet("Purpur.realCost", IntTag.valueOf(cost.get())); ++ cost.set(maximumRepairCost - 1); ++ } ++ // Purpur end ++ + if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit + itemstack1 = ItemStack.EMPTY; + } +@@ -297,6 +318,12 @@ public class AnvilMenu extends ItemCombinerMenu { + + org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(this.getBukkitView(), itemstack1); // CraftBukkit + this.broadcastChanges(); ++ // Purpur start ++ if (canDoUnsafeEnchants && itemstack1 != ItemStack.EMPTY) { ++ ((ServerPlayer) player).connection.send(new ClientboundContainerSetSlotPacket(containerId, 2, itemstack1)); ++ ((ServerPlayer) player).connection.send(new ClientboundContainerSetDataPacket(containerId, 0, cost.get())); ++ } ++ // Purpur end + } + } + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +index 3ff03e3e8c723d0f2a7c115d4dba01f1b3c2c46e..4dc71c761371400fb92e6943ba44bf40968dae97 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +@@ -9,7 +9,7 @@ import org.bukkit.inventory.AnvilInventory; + public class CraftInventoryAnvil extends CraftResultInventory implements AnvilInventory { + + private final Location location; +- private final AnvilMenu container; ++ public final AnvilMenu container; // Purpur - private -> public + + public CraftInventoryAnvil(Location location, Container inventory, Container resultInventory, AnvilMenu container) { + super(inventory, resultInventory); +@@ -47,4 +47,26 @@ public class CraftInventoryAnvil extends CraftResultInventory implements AnvilIn + Preconditions.checkArgument(levels >= 0, "Maximum repair cost must be positive (or 0)"); + container.maximumRepairCost = levels; + } ++ ++ // Purpur start ++ @Override ++ public boolean canBypassCost() { ++ return container.bypassCost; ++ } ++ ++ @Override ++ public void setBypassCost(boolean bypassCost) { ++ container.bypassCost = bypassCost; ++ } ++ ++ @Override ++ public boolean canDoUnsafeEnchants() { ++ return container.canDoUnsafeEnchants; ++ } ++ ++ @Override ++ public void setDoUnsafeEnchants(boolean canDoUnsafeEnchants) { ++ container.canDoUnsafeEnchants = canDoUnsafeEnchants; ++ } ++ // Purpur end + } diff --git a/patches/server/0017-Configurable-villager-brain-ticks.patch b/patches/server/0017-Configurable-villager-brain-ticks.patch new file mode 100644 index 000000000..226503ba4 --- /dev/null +++ b/patches/server/0017-Configurable-villager-brain-ticks.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Tue, 23 Jul 2019 08:28:21 -0500 +Subject: [PATCH] Configurable villager brain ticks + + +diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java +index 27530389690ec329bd92a722e4faf87e367bce91..d9d12330e84f204f96761051e1d92984d8a96330 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -141,6 +141,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + }, MemoryModuleType.MEETING_POINT, (entityvillager, villageplacetype) -> { + return villageplacetype == PoiType.MEETING; + }); ++ private final int brainTickOffset; // Purpur + + public Villager(EntityType entityType, Level world) { + this(entityType, world, VillagerType.PLAINS); +@@ -153,6 +154,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + this.getNavigation().setCanFloat(true); + this.setCanPickUpLoot(true); + this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); ++ this.brainTickOffset = getRandom().nextInt(100); // Purpur + } + + @Override +@@ -249,6 +251,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + protected void customServerAiStep() { mobTick(false); } + protected void mobTick(boolean inactive) { + this.level.getProfiler().push("villagerBrain"); ++ // Purpur start ++ boolean tick = (level.getGameTime() + brainTickOffset) % level.purpurConfig.villagerBrainTicks == 0; ++ if (((ServerLevel) level).getServer().lagging ? tick : level.purpurConfig.villagerUseBrainTicksOnlyWhenLagging || tick) ++ // Purpur end + if (!inactive) this.getBrain().tick((ServerLevel) this.level, this); // CraftBukkit - decompile error // Paper + this.level.getProfiler().pop(); + if (this.assignProfessionWhenSpawned) { +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index c441fcea9b2b5a77b801c8a69541cf42050927dc..c7fb5a737cab0083c39732247acb8f4e87562894 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -74,4 +74,11 @@ public class PurpurWorldConfig { + playerSpawnInvulnerableTicks = getInt("gameplay-mechanics.player.spawn-invulnerable-ticks", playerSpawnInvulnerableTicks); + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); + } ++ ++ public int villagerBrainTicks = 1; ++ public boolean villagerUseBrainTicksOnlyWhenLagging = true; ++ private void villagerSettings() { ++ villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); ++ villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); ++ } + } diff --git a/patches/server/0018-Alternative-Keepalive-Handling.patch b/patches/server/0018-Alternative-Keepalive-Handling.patch new file mode 100644 index 000000000..fedc8476f --- /dev/null +++ b/patches/server/0018-Alternative-Keepalive-Handling.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Fri, 11 Oct 2019 00:17:39 -0500 +Subject: [PATCH] Alternative Keepalive Handling + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 7700bad94ad07bfac4a5efd90689f26bec1eed45..85e43bb2da113c2d45d6a67496a1fa89a53b1e39 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -229,6 +229,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + private long keepAliveTime = Util.getMillis(); + private boolean keepAlivePending; + private long keepAliveChallenge; ++ private java.util.List keepAlives = new java.util.ArrayList<>(); // Purpur + // CraftBukkit start - multithreaded fields + private AtomicInteger chatSpamTickCount = new AtomicInteger(); + private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits +@@ -359,6 +360,21 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + long currentTime = Util.getMillis(); + long elapsedTime = currentTime - this.keepAliveTime; + ++ // Purpur start ++ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) { ++ if (elapsedTime >= 1000L) { // 1 second ++ if (!processedDisconnect && keepAlives.size() > KEEPALIVE_LIMIT) { ++ LOGGER.warn("{} was kicked due to keepalive timeout!", player.getName()); ++ disconnect(new TranslatableComponent("disconnect.timeout")); ++ } else { ++ keepAliveTime = currentTime; // hijack this field for 1 second intervals ++ keepAlives.add(currentTime); // currentTime is ID ++ send(new ClientboundKeepAlivePacket(currentTime)); ++ } ++ } ++ } else ++ // Purpur end ++ + if (this.keepAlivePending) { + if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info +@@ -3009,6 +3025,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + + @Override + public void handleKeepAlive(ServerboundKeepAlivePacket packet) { ++ // Purpur start ++ if (net.pl3x.purpur.PurpurConfig.useAlternateKeepAlive) { ++ long id = packet.getId(); ++ if (keepAlives.size() > 0 && keepAlives.contains(id)) { ++ int ping = (int) (Util.getMillis() - id); ++ player.latency = (player.latency * 3 + ping) / 4; ++ keepAlives.clear(); // we got a valid response, lets roll with it and forget the rest ++ } ++ } else ++ // Purpur end + //PlayerConnectionUtils.ensureMainThread(packetplayinkeepalive, this, this.player.getWorldServer()); // CraftBukkit // Paper - This shouldn't be on the main thread + if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { + int i = (int) (Util.getMillis() - this.keepAliveTime); +diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java +index d940b295dc8657387e6e62fb9e0009a7b2c37121..675d29694c3acf5806c237459407ac45a2825409 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java +@@ -153,6 +153,11 @@ public class PurpurConfig { + laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold); + } + ++ public static boolean useAlternateKeepAlive = false; ++ private static void useAlternateKeepAlive() { ++ useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive); ++ } ++ + public static boolean barrelSixRows = false; + public static boolean enderChestSixRows = false; + public static boolean enderChestPermissionRows = false; diff --git a/patches/server/0019-Silk-touch-spawners.patch b/patches/server/0019-Silk-touch-spawners.patch new file mode 100644 index 000000000..127d95b11 --- /dev/null +++ b/patches/server/0019-Silk-touch-spawners.patch @@ -0,0 +1,218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 9 May 2019 14:27:37 -0500 +Subject: [PATCH] Silk touch spawners + + +diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +index f72511a71c01718be48ee6b714e902d0f41e14ae..b24c26a94ac3ff88252c20d294227cfd1646e64e 100644 +--- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java ++++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +@@ -79,6 +79,7 @@ public final class PaperAdventure { + }) + .build(); + public static final LegacyComponentSerializer LEGACY_SECTION_UXRC = LegacyComponentSerializer.builder().flattener(FLATTENER).hexColors().useUnusualXRepeatedCharacterHexFormat().build(); ++ public static final LegacyComponentSerializer LEGACY_AMPERSAND = LegacyComponentSerializer.builder().character(LegacyComponentSerializer.AMPERSAND_CHAR).hexColors().build(); // Purpur + public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build(); + public static final GsonComponentSerializer GSON = GsonComponentSerializer.builder() + .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE) +diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java +index bd52d7d19060b0922c5165a071a5d12123028f79..39f2b1f30a475a1e571789c24b63028bdeff6cbb 100644 +--- a/src/main/java/net/minecraft/world/item/Items.java ++++ b/src/main/java/net/minecraft/world/item/Items.java +@@ -258,7 +258,7 @@ public class Items { + public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK, CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR, CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS, CreativeModeTab.TAB_BUILDING_BLOCKS); +- public static final Item SPAWNER = registerBlock(new BlockItem(Blocks.SPAWNER, (new Item.Properties()).rarity(Rarity.EPIC))); ++ public static final Item SPAWNER = registerBlock(Blocks.SPAWNER, new SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur + public static final Item OAK_STAIRS = registerBlock(Blocks.OAK_STAIRS, CreativeModeTab.TAB_BUILDING_BLOCKS); + public static final Item CHEST = registerBlock(Blocks.CHEST, CreativeModeTab.TAB_DECORATIONS); + public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE, CreativeModeTab.TAB_DECORATIONS); +diff --git a/src/main/java/net/minecraft/world/item/SpawnerItem.java b/src/main/java/net/minecraft/world/item/SpawnerItem.java +new file mode 100644 +index 0000000000000000000000000000000000000000..db721669c86ca0d3e393005182a8592fd0dba8cd +--- /dev/null ++++ b/src/main/java/net/minecraft/world/item/SpawnerItem.java +@@ -0,0 +1,34 @@ ++package net.minecraft.world.item; ++ ++import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.player.Player; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.Block; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.entity.SpawnerBlockEntity; ++import net.minecraft.world.level.block.state.BlockState; ++ ++public class SpawnerItem extends BlockItem { ++ ++ public SpawnerItem(Block block, Properties settings) { ++ super(block, settings); ++ } ++ ++ @Override ++ protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, Player player, ItemStack stack, BlockState state) { ++ boolean handled = super.updateCustomBlockEntityTag(pos, level, player, stack, state); ++ if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.place.spawners")) { ++ BlockEntity spawner = level.getBlockEntity(pos); ++ if (spawner instanceof SpawnerBlockEntity && stack.hasTag()) { ++ CompoundTag tag = stack.getTag(); ++ if (tag.contains("Purpur.mob_type")) { ++ EntityType.getByName(tag.getString("Purpur.mob_type")).ifPresent(type -> ++ ((SpawnerBlockEntity) spawner).getSpawner().setEntityId(type)); ++ } ++ } ++ } ++ return handled; ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +index b1e04d41de80971a7a1616beb0860226ecc25045..9ce53046b7f67309c2d4636b95e6fb05c103a13f 100644 +--- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +@@ -2,8 +2,16 @@ package net.minecraft.world.level.block; + + import javax.annotation.Nullable; + import net.minecraft.core.BlockPos; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.StringTag; ++import net.minecraft.resources.ResourceLocation; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.item.enchantment.EnchantmentHelper; ++import net.minecraft.world.item.enchantment.Enchantments; + import net.minecraft.world.level.BlockGetter; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.entity.BlockEntity; +@@ -13,6 +21,18 @@ import net.minecraft.world.level.block.entity.SpawnerBlockEntity; + import net.minecraft.world.level.block.state.BlockBehaviour; + import net.minecraft.world.level.block.state.BlockState; + ++// Purpur start ++import io.papermc.paper.adventure.PaperAdventure; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.TextReplacementConfig; ++import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; ++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; ++ ++import java.util.List; ++ ++import static net.kyori.adventure.text.format.TextDecoration.ITALIC; ++// Purpur end ++ + public class SpawnerBlock extends BaseEntityBlock { + + protected SpawnerBlock(BlockBehaviour.Properties settings) { +@@ -30,6 +50,59 @@ public class SpawnerBlock extends BaseEntityBlock { + return createTickerHelper(type, BlockEntityType.MOB_SPAWNER, world.isClientSide ? SpawnerBlockEntity::clientTick : SpawnerBlockEntity::serverTick); + } + ++ // Purpur start ++ @Override ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack) { ++ if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) { ++ ResourceLocation type = ((SpawnerBlockEntity) blockEntity).getSpawner().getEntityId(level, pos); ++ if (type != null) { ++ final Component mobName = PaperAdventure.asAdventure(EntityType.getFromKey(type).getDescription()); ++ final TextReplacementConfig config = TextReplacementConfig.builder() ++ .matchLiteral("{mob}") ++ .replacement(mobName) ++ .build(); ++ ++ CompoundTag display = new CompoundTag(); ++ boolean customDisplay = false; ++ ++ String name = level.purpurConfig.silkTouchSpawnerName; ++ if (name != null && !name.isEmpty() && !name.equals("Spawner")) { ++ final Component displayName = PaperAdventure.LEGACY_AMPERSAND.deserialize(name).replaceText(config).decoration(ITALIC, false); ++ display.put("Name", StringTag.create(GsonComponentSerializer.gson().serialize(displayName))); ++ customDisplay = true; ++ } ++ ++ List lore = level.purpurConfig.silkTouchSpawnerLore; ++ if (lore != null && !lore.isEmpty()) { ++ ListTag list = new ListTag(); ++ for (String line : lore) { ++ final Component lineComponent = PaperAdventure.LEGACY_AMPERSAND.deserialize(line).replaceText(config).decoration(ITALIC, false); ++ list.add(StringTag.create(GsonComponentSerializer.gson().serialize(lineComponent))); ++ } ++ display.put("Lore", list); ++ customDisplay = true; ++ } ++ ++ CompoundTag tag = new CompoundTag(); ++ if (customDisplay) { ++ tag.put("display", display); ++ } ++ tag.putString("Purpur.mob_type", type.toString()); ++ ++ ItemStack item = new ItemStack(Blocks.SPAWNER.asItem()); ++ item.setTag(tag); ++ ++ popResource(level, pos, item); ++ } ++ } ++ super.playerDestroy(level, player, pos, state, blockEntity, stack); ++ } ++ ++ private boolean isSilkTouch(Level level, ItemStack stack) { ++ return stack != null && level.purpurConfig.silkTouchTools.contains(stack.getItem()) && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0; ++ } ++ // Purpur end ++ + @Override + public void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack stack) { + super.spawnAfterBreak(state, world, pos, stack); +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index c7fb5a737cab0083c39732247acb8f4e87562894..f06be7e567f39b7c3c3d4b75bb5892b3d938533b 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -1,6 +1,12 @@ + package net.pl3x.purpur; + ++import net.minecraft.core.Registry; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.item.Items; + import org.bukkit.configuration.ConfigurationSection; ++ ++import java.util.ArrayList; + import java.util.List; + import static net.pl3x.purpur.PurpurConfig.log; + +@@ -75,6 +81,29 @@ public class PurpurWorldConfig { + playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); + } + ++ public boolean silkTouchEnabled = false; ++ public String silkTouchSpawnerName = "Spawner"; ++ public List silkTouchSpawnerLore = new ArrayList<>(); ++ public List silkTouchTools = new ArrayList<>(); ++ private void silkTouchSettings() { ++ silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled); ++ silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); ++ silkTouchSpawnerLore.clear(); ++ getList("gameplay-mechanics.silk-touch.spawner-lore", new ArrayList(){{ ++ add("Spawns a {mob}"); ++ }}).forEach(line -> silkTouchSpawnerLore.add(line.toString())); ++ silkTouchTools.clear(); ++ getList("gameplay-mechanics.silk-touch.tools", new ArrayList(){{ ++ add("minecraft:iron_pickaxe"); ++ add("minecraft:golden_pickaxe"); ++ add("minecraft:diamond_pickaxe"); ++ add("minecraft:netherite_pickaxe"); ++ }}).forEach(key -> { ++ Item item = Registry.ITEM.get(new ResourceLocation(key.toString())); ++ if (item != Items.AIR) silkTouchTools.add(item); ++ }); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { diff --git a/patches/server/0020-MC-168772-Fix-Add-turtle-egg-block-options.patch b/patches/server/0020-MC-168772-Fix-Add-turtle-egg-block-options.patch new file mode 100644 index 000000000..83fe2a993 --- /dev/null +++ b/patches/server/0020-MC-168772-Fix-Add-turtle-egg-block-options.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Thu, 6 Jun 2019 22:15:46 -0500 +Subject: [PATCH] MC-168772 Fix - Add turtle egg block options + + +diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +index fdb3ab919a78221605257ae82bfd026346ce2ffb..e98fc3c235f9160f1928a8afb0d7991a6d3430cb 100644 +--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +@@ -10,11 +10,15 @@ import net.minecraft.tags.BlockTags; + import net.minecraft.tags.Tag; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.ExperienceOrb; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.ambient.Bat; + import net.minecraft.world.entity.animal.Turtle; ++import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.monster.Zombie; + import net.minecraft.world.entity.player.Player; ++import net.minecraft.world.entity.vehicle.AbstractMinecart; ++import net.minecraft.world.item.Item; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.item.context.BlockPlaceContext; + import net.minecraft.world.level.BlockGetter; +@@ -187,6 +191,23 @@ public class TurtleEggBlock extends Block { + } + + private boolean canDestroyEgg(Level world, Entity entity) { +- return !(entity instanceof Turtle) && !(entity instanceof Bat) ? (!(entity instanceof LivingEntity) ? false : entity instanceof Player || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) : false; ++ // Purpur start - fix MC-168772 ++ if (entity instanceof Turtle) { ++ return false; ++ } ++ if (!world.purpurConfig.turtleEggsBreakFromExpOrbs && entity instanceof ExperienceOrb) { ++ return false; ++ } ++ if (!world.purpurConfig.turtleEggsBreakFromItems && entity instanceof ItemEntity) { ++ return false; ++ } ++ if (!world.purpurConfig.turtleEggsBreakFromMinecarts && entity instanceof AbstractMinecart) { ++ return false; ++ } ++ if (entity instanceof LivingEntity && !(entity instanceof Player)) { ++ return world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ } ++ return true; ++ // Purpur end + } + } +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index f06be7e567f39b7c3c3d4b75bb5892b3d938533b..e778601b9a075311715d24beffaa421abb25c153 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -104,6 +104,15 @@ public class PurpurWorldConfig { + }); + } + ++ public boolean turtleEggsBreakFromExpOrbs = true; ++ public boolean turtleEggsBreakFromItems = true; ++ public boolean turtleEggsBreakFromMinecarts = true; ++ private void turtleEggSettings() { ++ turtleEggsBreakFromExpOrbs = getBoolean("blocks.turtle_egg.break-from-exp-orbs", turtleEggsBreakFromExpOrbs); ++ turtleEggsBreakFromItems = getBoolean("blocks.turtle_egg.break-from-items", turtleEggsBreakFromItems); ++ turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); ++ } ++ + public int villagerBrainTicks = 1; + public boolean villagerUseBrainTicksOnlyWhenLagging = true; + private void villagerSettings() { diff --git a/patches/server-unmapped/0022-Fix-vanilla-command-permission-handler.patch b/patches/server/0021-Fix-vanilla-command-permission-handler.patch similarity index 77% rename from patches/server-unmapped/0022-Fix-vanilla-command-permission-handler.patch rename to patches/server/0021-Fix-vanilla-command-permission-handler.patch index 06216b6dc..6d30ce222 100644 --- a/patches/server-unmapped/0022-Fix-vanilla-command-permission-handler.patch +++ b/patches/server/0021-Fix-vanilla-command-permission-handler.patch @@ -1,29 +1,29 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath +From: William Blake Galbreath Date: Sat, 28 Mar 2020 01:51:32 -0500 Subject: [PATCH] Fix vanilla command permission handler diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java -index c0fac7369b111e65b896a15848ae22457e5e8914..5278997e522b495b83e53cac5968388d6eca45e4 100644 +index 39708be1b445791b053023dec16ad7d4efcc9048..797c0c86c4a99e1608106881be849a3326de1bab 100644 --- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java +++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java -@@ -35,6 +35,7 @@ public abstract class CommandNode implements Comparable> { +@@ -34,6 +34,7 @@ public abstract class CommandNode implements Comparable> { private final RedirectModifier modifier; private final boolean forks; private Command command; + private String permission = null; public String getPermission() { return permission; } public void setPermission(String permission) { this.permission = permission; } // Purpur // CraftBukkit start public void removeCommand(String name) { - children.remove(name); + this.children.remove(name); diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java -index 56a0665127c7c55049b8438c91e72b6881ed11e0..575bc7d8a433cd6d4755757d82fe3a18da184d5a 100644 +index 2311819fc944c3ddb76efe59fd2920d4aca6b490..25c3fbc310f8f0292b26766601226531ad1200f4 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -87,6 +87,7 @@ public final class VanillaCommandWrapper extends BukkitCommand { } - public static String getPermission(CommandNode vanillaCommand) { + public static String getPermission(CommandNode vanillaCommand) { + if (vanillaCommand.getPermission() != null) return vanillaCommand.getPermission(); // Purpur return "minecraft.command." + ((vanillaCommand.getRedirect() == null) ? vanillaCommand.getName() : vanillaCommand.getRedirect().getName()); } diff --git a/patches/server-unmapped/0023-Logger-settings-suppressing-pointless-logs.patch b/patches/server/0022-Logger-settings-suppressing-pointless-logs.patch similarity index 68% rename from patches/server-unmapped/0023-Logger-settings-suppressing-pointless-logs.patch rename to patches/server/0022-Logger-settings-suppressing-pointless-logs.patch index 2819f1b7a..f86aba059 100644 --- a/patches/server-unmapped/0023-Logger-settings-suppressing-pointless-logs.patch +++ b/patches/server/0022-Logger-settings-suppressing-pointless-logs.patch @@ -4,24 +4,24 @@ Date: Sat, 19 Oct 2019 00:52:12 -0500 Subject: [PATCH] Logger settings (suppressing pointless logs) -diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -index dfdbc028f68ced197ad179248ed3b1e9d70ba057..a1ee1066108985a95abddb03ff447b5a14f4f85f 100644 ---- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -+++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java -@@ -190,6 +190,7 @@ public class AdvancementDataPlayer { +diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java +index d1f85b092eba829b003e39c913a4afeffc140568..e159bf06a225aa63b4d397a7c76fa9ef8691d052 100644 +--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java ++++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java +@@ -186,6 +186,7 @@ public class PlayerAdvancements { if (advancement == null) { // CraftBukkit start if (entry.getKey().getNamespace().equals("minecraft")) { + if (!net.pl3x.purpur.PurpurConfig.loggerSuppressIgnoredAdvancementWarnings) // Purpur - AdvancementDataPlayer.LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.f); + PlayerAdvancements.LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.file); } // CraftBukkit end diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index afd0c577069f2a856caf41bd2dd5187db4866fa3..c7755cea5e8337af7acc96c6a34afa547b391035 100644 +index 675d29694c3acf5806c237459407ac45a2825409..4e8f346cfe09b5806f53ae85729b3597b2e7c9eb 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -178,4 +178,11 @@ public class PurpurConfig { - InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); +@@ -176,4 +176,11 @@ public class PurpurConfig { + org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); } + @@ -33,10 +33,10 @@ index afd0c577069f2a856caf41bd2dd5187db4866fa3..c7755cea5e8337af7acc96c6a34afa54 + } } diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -index b86604cbf3543b978df000d8f74c6185aa2ae7ec..5df82b0409278bd298e837aa43941247de3f94fe 100644 +index b2a15c986c7500a0ce227a54cb61ec3f5378f6f3..6d5f030b678dbc86dceddcbb050b4aaed4102c50 100644 --- a/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java +++ b/src/main/java/org/bukkit/craftbukkit/legacy/CraftLegacy.java -@@ -254,6 +254,7 @@ public final class CraftLegacy { +@@ -255,6 +255,7 @@ public final class CraftLegacy { } static { diff --git a/patches/server-unmapped/0024-Disable-outdated-build-check.patch b/patches/server/0023-Disable-outdated-build-check.patch similarity index 55% rename from patches/server-unmapped/0024-Disable-outdated-build-check.patch rename to patches/server/0023-Disable-outdated-build-check.patch index 0f6f2f074..8ba1d4f08 100644 --- a/patches/server-unmapped/0024-Disable-outdated-build-check.patch +++ b/patches/server/0023-Disable-outdated-build-check.patch @@ -1,19 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath +From: William Blake Galbreath Date: Sun, 15 Dec 2019 12:53:59 -0600 Subject: [PATCH] Disable outdated build check diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index e34f27c6782b049d96de20e4acec1325bd97a26a..7cc2a04f921729b470be71eaddb8e79cdf605a9e 100644 +index b913ea98eb000edbab20d448da71a904570b48d6..47e436b079ad2f3c17348f730a29228d5feb3ce3 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -265,7 +265,7 @@ public class Main { +@@ -269,7 +269,7 @@ public class Main { System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper } -- if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { -+ if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { // Purpur - break on change - Date buildDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper +- if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { ++ if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { // Purpur + Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance();