diff --git a/patches/server/0045-AddLinearSupport.patch b/patches/server/0045-AddLinearSupport.patch index 897ebb26..54586b67 100644 --- a/patches/server/0045-AddLinearSupport.patch +++ b/patches/server/0045-AddLinearSupport.patch @@ -5,7 +5,7 @@ Subject: [PATCH] AddLinearSupport diff --git a/build.gradle.kts b/build.gradle.kts -index a6ac60d7d57e4b0662b0c30f7bc43ba84179d697..a4ed90ae8b704bac060409c0218543fcc9a3e15c 100644 +index 0baaa2bcd05ea65c5fbb9ae646b3a9eeb12bac14..2f374fd4cb05d2c597d0dbd1a554cd6624f84863 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,6 +22,8 @@ dependencies { @@ -121,10 +121,10 @@ index c13df3a375f416273c6a26f5f77624c1f34a918c..e2c780e7d914e2cfd322fe07951aa54a long expectedChunks = (long)regionFiles.length * (32L * 32L); // Gale start - instantly continue on world upgrade finish diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index fb3bbe36c7bf67be65f0978ead2d4c778c32ba82..76022824dc9de7e64009383378f8ba75f70b09f3 100644 +index 1b4e0c7f23186afd88c7a71e296a5ca958f1c1d8..d6bdcb21ec79a81c31eaab24a73b55d08351e19b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -870,7 +870,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop +Date: Wed, 17 Jan 2024 13:46:16 +0800 +Subject: [PATCH] Leaves Disable Moved Wrongly Threshold + + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 5736cb60316da784590ef03d5808376254aae20b..06c716715b29fa4d2481bb8716ac25e8ba3c4209 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -247,7 +247,9 @@ import org.bukkit.inventory.EquipmentSlot; + import org.bukkit.inventory.InventoryView; + import org.bukkit.inventory.SmithingInventory; + // CraftBukkit end +- ++// Leaf start ++import org.dreeam.leaf.LeafConfig; ++// Leaf end + public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { + + static final Logger LOGGER = LogUtils.getLogger(); +@@ -583,7 +585,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + } + // Paper end + +- if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { ++ if (!LeafConfig.disableMovedWronglyThreshold && d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Leaves - disable can + // CraftBukkit end + ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); + this.send(new ClientboundMoveVehiclePacket(entity)); +@@ -619,7 +621,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + d10 = d6 * d6 + d7 * d7 + d8 * d8; + boolean flag2 = false; + +- if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot ++ if (!LeafConfig.disableMovedWronglyThreshold && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // Leaves - disable can + flag2 = true; // Paper - diff on change, this should be moved wrongly + ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", new Object[]{entity.getName().getString(), this.player.getName().getString(), Math.sqrt(d10)}); + } +@@ -1487,7 +1489,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, + toX, toY, toZ, toYaw, toPitch, true); + if (!event.isAllowed()) { +- if (event.getLogWarning()) ++ if (!LeafConfig.disableMovedWronglyThreshold && event.getLogWarning()) // Leaves - disable can + ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); + this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); + return; +@@ -1557,7 +1559,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + d10 = d6 * d6 + d7 * d7 + d8 * d8; + boolean flag2 = false; + +- if (!this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot ++ if (!LeafConfig.disableMovedWronglyThreshold && !this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot // Leaves - disable can + // Paper start - Add fail move event + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY, + toX, toY, toZ, toYaw, toPitch, true); +diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java +index c51b54bcb96d06197d6265055e2e9e44858cd224..156765eeee6ab46f18e34cf62dde1a7d878932cc 100644 +--- a/src/main/java/org/dreeam/leaf/LeafConfig.java ++++ b/src/main/java/org/dreeam/leaf/LeafConfig.java +@@ -313,4 +313,8 @@ public class LeafConfig { + extraHorizontal = getDouble("playerKnockback.extraHorizontal", extraHorizontal); + extraVertical = getDouble("playerKnockback.extraVertical", extraVertical); + } ++ public static boolean disableMovedWronglyThreshold = false; ++ private static void getDisableMovedWronglyThreshold() { ++ disableMovedWronglyThreshold = getBoolean("disableMovedWronglyThreshold",disableMovedWronglyThreshold,:"Disable Moved Wrongly Threshold") ++ } + } diff --git a/patches/server/0049-Leaves-be-vanilla-end-gateway.patch b/patches/server/0049-Leaves-be-vanilla-end-gateway.patch new file mode 100644 index 00000000..ddd87db6 --- /dev/null +++ b/patches/server/0049-Leaves-be-vanilla-end-gateway.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 14:29:37 +0800 +Subject: [PATCH] Leaves be vanilla end gateway + + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +index 5d9f25da1bd502b0047abc64ef7602968ee3cb20..2ca123ecd7cac2c7fdaafcc2c58c8c126adcf94a 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +@@ -38,6 +38,9 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; + import org.bukkit.craftbukkit.util.CraftLocation; + import org.bukkit.event.player.PlayerTeleportEvent; + // CraftBukkit end ++// Leaf start ++import org.dreeam.leaf.LeafConfig; ++// Leaf end + + public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { + +@@ -107,7 +110,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { + if (!list.isEmpty()) { + // Paper start + for (Entity entity : list) { +- if (entity.canChangeDimensions()) { ++ if (LeafConfig.vanillaEndTeleport || entity.canChangeDimensions()) { // Leaf - be vanilla + TheEndGatewayBlockEntity.teleportEntity(world, pos, state, entity, blockEntity); + break; + } +diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java +index 156765eeee6ab46f18e34cf62dde1a7d878932cc..728082120af5a7afe20078b3fa6d80605f5ff6c7 100644 +--- a/src/main/java/org/dreeam/leaf/LeafConfig.java ++++ b/src/main/java/org/dreeam/leaf/LeafConfig.java +@@ -315,6 +315,10 @@ public class LeafConfig { + } + public static boolean disableMovedWronglyThreshold = false; + private static void getDisableMovedWronglyThreshold() { +- disableMovedWronglyThreshold = getBoolean("disableMovedWronglyThreshold",disableMovedWronglyThreshold,:"Disable Moved Wrongly Threshold") ++ disableMovedWronglyThreshold = getBoolean("disableMovedWronglyThreshold",disableMovedWronglyThreshold,"Disable Moved Wrongly Threshold"); ++ } ++ public static boolean vanillaEndTeleport = false; ++ private static void getVanillaTeleport() { ++ vanillaEndTeleport = getBoolean("vanillaEndTeleport",vanillaEndTeleport,"Vanilla End Gateway Teleport"); + } + } diff --git a/patches/server/0050-Add-Purpur-and-Pufferfish-missing-config.patch b/patches/server/0050-Add-Purpur-and-Pufferfish-missing-config.patch new file mode 100644 index 00000000..60eb4998 --- /dev/null +++ b/patches/server/0050-Add-Purpur-and-Pufferfish-missing-config.patch @@ -0,0 +1,329 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 18:02:03 +0800 +Subject: [PATCH] Add Purpur and Pufferfish missing config + + +diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +index eb60d2d99155aae4a761051175fbbddf9ed5dad9..5444213b336bc08eb371673890ded04c1178fd90 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java ++++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java +@@ -150,6 +150,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.allayTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.allayAlwaysDropExp; ++ } ++ ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.allayMaxHealth); ++ } ++ // Plazma end + // Purpur end + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +index 11181c0429b720381e7752f8a0d5e89615bcce4b..30564115cea127cfff255cf203a187c6790040a8 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java ++++ b/src/main/java/net/minecraft/world/entity/animal/camel/Camel.java +@@ -95,6 +95,18 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl + public int getPurpurBreedTime() { + return this.level().purpurConfig.camelBreedingTicks; + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.camelTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.camelAlwaysDropExp; ++ } ++ // Plazma end + // Purpur end + + @Override +@@ -155,10 +167,11 @@ public class Camel extends AbstractHorse implements PlayerRideableJumping, Saddl + protected float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) { + return dimensions.height - 0.1F * this.getScale(); + } +- ++ private int behaviorTick = 0; // Leaf + @Override + protected void customServerAiStep() { + Brain brain = (Brain) this.getBrain(); // Paper - decompile fix ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Add missing pufferfish configurations + brain.tick((ServerLevel)this.level(), this); + CamelAi.updateActivity(this); + super.customServerAiStep(); +diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +index 80a7197835531fa8cd276d9d31860f2b5ad3089f..8fd223ef7a72fcd0c62bcfbb17b83f63ceb8b70f 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java ++++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +@@ -138,6 +138,23 @@ public class Frog extends Animal implements VariantHolder { + public float getJumpPower() { + return (getRider() != null && isControllable()) ? level().purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower(); + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.frogTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.frogAlwaysDropExp; ++ } ++ ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.frogMaxHealth); ++ } ++ // Plazma end + // Purpur end + + public int getPurpurBreedTime() { +diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +index 1fbd034002fd5761011976510b9f9263ca0f5cac..a9d75fe602d0f946519582d2eaf2eb55db69e4b8 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java ++++ b/src/main/java/net/minecraft/world/entity/animal/frog/Tadpole.java +@@ -87,6 +87,23 @@ public class Tadpole extends AbstractFish { + protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.tadpoleTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.tadpoleAlwaysDropExp; ++ } ++ ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.tadpoleMaxHealth); ++ } ++ // Plazma end + // Purpur end + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +index b8a055f938ade211c07ca5a74bade19707568eb1..af5b46d198ff950c501c9f65ba5a0ca76d94f4a8 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java ++++ b/src/main/java/net/minecraft/world/entity/animal/sniffer/Sniffer.java +@@ -106,6 +106,18 @@ public class Sniffer extends Animal { + public boolean isControllable() { + return level().purpurConfig.snifferControllable; + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.snifferTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.snifferAlwaysDropExp; ++ } ++ // Plazma end + // Purpur end + + @Override +@@ -514,9 +526,10 @@ public class Sniffer extends Animal { + protected Brain.Provider brainProvider() { + return Brain.provider(SnifferAi.MEMORY_TYPES, SnifferAi.SENSOR_TYPES); + } +- ++ private int behaviorTick; + @Override + protected void customServerAiStep() { ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Leaf - Add missing pufferfish configurations + this.getBrain().tick((ServerLevel) this.level(), this); + SnifferAi.updateActivity(this); + super.customServerAiStep(); +diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +index c23d192baf78890093b0e88d03735eef4569e75f..5cd66f51463d519fdfb33eb80864a7593a419193 100644 +--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java ++++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +@@ -147,6 +147,23 @@ public class Warden extends Monster implements VibrationSystem { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur + } ++ ++ // Plazma start ++ @Override ++ public boolean isSensitiveToWater() { ++ return level().purpurConfig.wardenTakeDamageFromWater; ++ } ++ ++ @Override ++ public boolean isAlwaysExperienceDropper() { ++ return level().purpurConfig.wardenAlwaysDropExp; ++ } ++ ++ @Override ++ public void initAttributes() { ++ this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(level().purpurConfig.wardenMaxHealth); ++ } ++ // Plazma end + // Purpur end + + @Override +@@ -302,7 +319,7 @@ public class Warden extends Monster implements VibrationSystem { + protected void customServerAiStep() { + ServerLevel worldserver = (ServerLevel) this.level(); + +- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish ++ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Leaf + this.getBrain().tick(worldserver, this); + super.customServerAiStep(); + if ((this.tickCount + this.getId()) % 120 == 0) { +diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java +index bc3fe45d12ffc2069a03d1587b7623d31130565a..b621ec04e8bcca75ad8e8daf22e74197530b1c51 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java +@@ -41,7 +41,7 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain + + public ChestBoat(EntityType type, Level world) { + super(type, world); +- this.itemStacks = NonNullList.withSize(27, ItemStack.EMPTY); ++ this.itemStacks = NonNullList.withSize(org.purpurmc.purpur.PurpurConfig.chestBoatRows * 9, ItemStack.EMPTY); // Leaf + } + + public ChestBoat(Level world, double d0, double d1, double d2) { +diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +index c3f095236093c436d37c4730f5537d4fbc0ea6c0..d13bc7e913ebe816598f6104f928c90b320fee18 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +@@ -336,6 +336,7 @@ public class PurpurConfig { + } + + public static int barrelRows = 3; ++ public static int chestBoatRows = 3; // Plazma + public static boolean enderChestSixRows = false; + public static boolean enderChestPermissionRows = false; + public static boolean cryingObsidianValidForPortalFrame = false; +@@ -376,6 +377,7 @@ public class PurpurConfig { + case 1 -> 9; + default -> 27; + }); ++ chestBoatRows = getInt("settings.blocks.chest_boat.rows", chestBoatRows); // Plazma + enderChestSixRows = getBoolean("settings.blocks.ender_chest.six-rows", enderChestSixRows); + org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27); + enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows); +diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +index 2b4408d398962fa4feab9eb248540c6d11037a94..3ede56b60a06b6ef808a73a38719968656f66f08 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +@@ -1195,7 +1195,15 @@ public class PurpurWorldConfig { + public boolean allayRidableInWater = true; + public boolean allayControllable = true; + public List allayRespectNBT = new ArrayList<>(); ++ // Plazma start - Add missing purpur config options ++ public double allayMaxHealth = 20.0D; ++ public boolean allayTakeDamageFromWater = false; ++ public boolean allayAlwaysDropExp = false; + private void allaySettings() { ++ allayMaxHealth = getDouble("mobs.allay.max-health", allayMaxHealth); ++ allayTakeDamageFromWater = getBoolean("mobs.allay.take-damage-from-water", allayTakeDamageFromWater); ++ allayAlwaysDropExp = getBoolean("mobs.allay.always-drop-exp", allayAlwaysDropExp); ++ // Plazma end + allayRidable = getBoolean("mobs.allay.ridable", allayRidable); + allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); + allayControllable = getBoolean("mobs.allay.controllable", allayControllable); +@@ -1314,7 +1322,15 @@ public class PurpurWorldConfig { + public double camelMovementSpeedMin = 0.09D; + public double camelMovementSpeedMax = 0.09D; + public int camelBreedingTicks = 6000; ++ // Plazma start - Add missing purpur config options ++ //public boolean camelRidableInWater = false; ++ public boolean camelTakeDamageFromWater = false; ++ public boolean camelAlwaysDropExp = false; + private void camelSettings() { ++ //camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); ++ camelTakeDamageFromWater = getBoolean("mobs.camel.takes-damage-from-water", camelTakeDamageFromWater); ++ camelAlwaysDropExp = getBoolean("mobs.camel.always-drop-exp", camelAlwaysDropExp); ++ // Plazma end + camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); + camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin); + camelMaxHealthMax = getDouble("mobs.camel.attributes.max_health.max", camelMaxHealthMax); +@@ -1744,7 +1760,15 @@ public class PurpurWorldConfig { + public boolean frogControllable = true; + public float frogRidableJumpHeight = 0.65F; + public int frogBreedingTicks = 6000; ++ // Plazma start - Add missing purpur config options ++ public double frogMaxHealth = 10.0D; ++ public boolean frogTakeDamageFromWater = false; ++ public boolean frogAlwaysDropExp = false; + private void frogSettings() { ++ frogMaxHealth = getDouble("mobs.frog.attributes.max_health", frogMaxHealth); ++ frogTakeDamageFromWater = getBoolean("mobs.frog.takes-damage-from-water", frogTakeDamageFromWater); ++ frogAlwaysDropExp = getBoolean("mobs.frog.always-drop-exp", frogAlwaysDropExp); ++ // Plazma end + frogRidable = getBoolean("mobs.frog.ridable", frogRidable); + frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); + frogControllable = getBoolean("mobs.frog.controllable", frogControllable); +@@ -2690,7 +2714,13 @@ public class PurpurWorldConfig { + public boolean snifferControllable = true; + public double snifferMaxHealth = 14.0D; + public int snifferBreedingTicks = 6000; ++ // Plazma start - Add missing purpur config options ++ public boolean snifferTakeDamageFromWater = false; ++ public boolean snifferAlwaysDropExp = false; + private void snifferSettings() { ++ snifferTakeDamageFromWater = getBoolean("mobs.sniffer.takes-damage-from-water", snifferTakeDamageFromWater); ++ snifferAlwaysDropExp = getBoolean("mobs.sniffer.always-drop-exp", snifferAlwaysDropExp); ++ // Plazma end + snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); + snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); + snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); +@@ -2789,7 +2819,15 @@ public class PurpurWorldConfig { + public boolean tadpoleRidable = false; + public boolean tadpoleRidableInWater = true; + public boolean tadpoleControllable = true; ++ // Plazma start - Add missing purpur config options ++ public double tadpoleMaxHealth = 10.0D; ++ public boolean tadpoleTakeDamageFromWater = false; ++ public boolean tadpoleAlwaysDropExp = false; + private void tadpoleSettings() { ++ tadpoleMaxHealth = getDouble("mobs.tadpole.attributes.max_health", tadpoleMaxHealth); ++ tadpoleTakeDamageFromWater = getBoolean("mobs.tadpole.takes-damage-from-water", tadpoleTakeDamageFromWater); ++ tadpoleAlwaysDropExp = getBoolean("mobs.tadpole.always-drop-exp", tadpoleAlwaysDropExp); ++ // Plazma end + tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); + tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); + tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); +@@ -2999,7 +3037,15 @@ public class PurpurWorldConfig { + public boolean wardenRidable = false; + public boolean wardenRidableInWater = true; + public boolean wardenControllable = true; ++ // Plazma start - Add missing purpur config options ++ public double wardenMaxHealth = 500.0D; ++ public boolean wardenTakeDamageFromWater = false; ++ public boolean wardenAlwaysDropExp = false; + private void wardenSettings() { ++ wardenMaxHealth = getDouble("mobs.warden.attributes.max_health", wardenMaxHealth); ++ wardenTakeDamageFromWater = getBoolean("mobs.warden.takes-damage-from-water", wardenTakeDamageFromWater); ++ wardenAlwaysDropExp = getBoolean("mobs.warden.always-drop-exp", wardenAlwaysDropExp); ++ // Plazma end + wardenRidable = getBoolean("mobs.warden.ridable", wardenRidable); + wardenRidableInWater = getBoolean("mobs.warden.ridable-in-water", wardenRidableInWater); + wardenControllable = getBoolean("mobs.warden.controllable", wardenControllable); diff --git a/patches/server/0051-Skip-event-if-no-listeners.patch b/patches/server/0051-Skip-event-if-no-listeners.patch new file mode 100644 index 00000000..42a9b06a --- /dev/null +++ b/patches/server/0051-Skip-event-if-no-listeners.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 18:16:38 +0800 +Subject: [PATCH] Skip event if no listeners + + +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..90b40040b2dc0e8a481515a9b139cf1277578545 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +@@ -35,6 +35,10 @@ class PaperEventManager { + + // SimplePluginManager + public void callEvent(@NotNull Event event) { ++ // Leaf start - Skip event if no listeners ++ RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); ++ if (listeners.length == 0) return; ++ // Leaf end + // KTP start - Optimise spigot event bus + if (event.asynchronous() != net.kyori.adventure.util.TriState.NOT_SET) { + final boolean onPrimaryThread = this.server.isPrimaryThread(); +@@ -47,9 +51,6 @@ class PaperEventManager { + // KTP stop - Optimise spigot event bus + } + +- HandlerList handlers = event.getHandlers(); +- RegisteredListener[] listeners = handlers.getRegisteredListeners(); +- + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled()) { + continue; diff --git a/patches/server/0052-Optimize-canSee-checks.patch b/patches/server/0052-Optimize-canSee-checks.patch new file mode 100644 index 00000000..5cf4dacc --- /dev/null +++ b/patches/server/0052-Optimize-canSee-checks.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 18:58:47 +0800 +Subject: [PATCH] Optimize canSee checks + + +diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java +index 38ddd6684535f9a4e6e9fb432282e0b6be0ede4c..673f0b1f8ad35559d050cb73f6593dc466d6ac0c 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +@@ -1409,7 +1409,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider + // Paper end - check Y + + // CraftBukkit start - respect vanish API +- if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits ++ if (flag && !player.getBukkitEntity().canSeeChunkMapUpdatePlayer(this.entity.getBukkitEntity())) { // Paper - only consider hits // Polpot - Optimize canSee checks + flag = false; + } + // CraftBukkit end +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index 468ac1525c97043b53b16440fec6bb784e1e9c25..86a4a62dfb9c81078e630885f43d7bd24826e58a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -188,7 +188,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + private boolean hasPlayedBefore = false; + private final ConversationTracker conversationTracker = new ConversationTracker(); + private final Set channels = new HashSet(); +- private final Map>> invertedVisibilityEntities = new HashMap<>(); ++ private final Map>> invertedVisibilityEntities = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // Polpot - optimize canSee checks + private final Set unlistedEntities = new HashSet<>(); // Paper + private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); + private int hash = 0; +@@ -2166,7 +2166,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + // Leaf - TODO + @Override + public boolean canSee(org.bukkit.entity.Entity entity) { +- return this.equals(entity) || entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()); // SPIGOT-7312: Can always see self ++ return this.equals(entity) || entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // Polpot - optimize canSee checks + } + + public boolean canSee(UUID uuid) { +@@ -2178,7 +2178,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + return (entity != null) ? this.canSee(entity) : false; // If we can't find it, we can't see it + } + ++ // Polpot - optimize canSee checks ++ // The check in ChunkMap#updatePlayer already rejects if it is the same entity, so we don't need to check it twice, especially because CraftPlayer's equals check is a bit expensive ++ public boolean canSeeChunkMapUpdatePlayer(org.bukkit.entity.Entity entity) { ++ return entity.isVisibleByDefault() ^ (!invertedVisibilityEntities.isEmpty() && this.invertedVisibilityEntities.containsKey(entity.getUniqueId())); // SPIGOT-7312: Can always see self // SparklyPaper - optimize canSee checks ++ } ++ // Polpot end + // Paper start ++ + @Override + public boolean isListed(Player other) { + return !this.unlistedEntities.contains(other.getUniqueId()); diff --git a/patches/server/0053-SparklyPaper-Rewrite-framed-map-tracker-ticking.patch b/patches/server/0053-SparklyPaper-Rewrite-framed-map-tracker-ticking.patch new file mode 100644 index 00000000..b91da0b4 --- /dev/null +++ b/patches/server/0053-SparklyPaper-Rewrite-framed-map-tracker-ticking.patch @@ -0,0 +1,286 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 19:40:17 +0800 +Subject: [PATCH] SparklyPaper Rewrite-framed-map-tracker-ticking + + +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index 068dd1194016b65227ec44747b065860a48e7f1d..26a68dd4e7373291c645053990e63eb27ac41dbf 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -115,23 +115,35 @@ public class ServerEntity { + ItemFrame entityitemframe = (ItemFrame) entity; + + if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block +- ItemStack itemstack = entityitemframe.getItem(); ++ //ItemStack itemstack = entityitemframe.getItem(); // SparklyPaper + +- if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable ++ if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 /*&&itemstack.getItem() instanceof MapItem*/) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // SparklyPaper - Make item frame map cursor update interval configurable + Integer integer = entityitemframe.cachedMapId; // Paper + MapItemSavedData worldmap = MapItem.getSavedData(integer, this.level); + + if (worldmap != null) { +- Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit ++ // SparklyPaper start - re-use the same update packet when possible ++ if (!worldmap.hasContextualRenderer) { ++ // Pass in a "random" player when a non-contextual plugin renderer is added to make sure its called ++ final Packet updatePacket = worldmap.framedUpdatePacket(integer, worldmap.hasPluginRenderer ? com.google.common.collect.Iterables.getFirst(this.trackedPlayers, null).getPlayer() : null); ++ if (updatePacket != null) { ++ for (ServerPlayerConnection connection : this.trackedPlayers) { ++ connection.send(updatePacket); ++ } ++ } ++ } else { ++ // SparklyPaper end ++ Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit + +- while (iterator.hasNext()) { +- ServerPlayer entityplayer = iterator.next().getPlayer(); // CraftBukkit ++ while (iterator.hasNext()) { ++ ServerPlayer entityplayer = iterator.next().getPlayer(); // CraftBukkit + +- worldmap.tickCarriedBy(entityplayer, itemstack); +- Packet packet = worldmap.getUpdatePacket(integer, entityplayer); ++ //worldmap.tickCarriedBy(entityplayer, itemstack); // SparklyPaper ++ Packet packet = worldmap.framedUpdatePacket(integer, entityplayer); // SparklyPaper + +- if (packet != null) { +- entityplayer.connection.send(packet); ++ if (packet != null) { ++ entityplayer.connection.send(packet); ++ } + } + } + } +@@ -367,7 +379,19 @@ public class ServerEntity { + sender.accept(new ClientboundSetEntityLinkPacket(entityinsentient, entityinsentient.getLeashHolder())); + } + } ++ // SparklyPaper start ++ if (this.entity instanceof ItemFrame frame && frame.cachedMapId != null) { ++ MapItemSavedData mapData = MapItem.getSavedData(frame.cachedMapId, this.level); ++ ++ if (mapData != null) { ++ mapData.addFrameDecoration(frame); + ++ final Packet mapPacket = mapData.fullUpdatePacket(frame.cachedMapId, mapData.hasPluginRenderer ? player : null); ++ if (mapPacket != null) ++ sender.accept((Packet) mapPacket); ++ } ++ } ++ // SparklyPaper end + } + + private void sendDirtyEntityData() { +diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +index d728dc8a9b5fa2de0a824aaf132ee15db090b02e..37d83ae140ee07dc448a18d0061fc091785da063 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +@@ -489,6 +489,16 @@ public class ItemFrame extends HangingEntity { + } + this.setItem(ItemStack.fromBukkitCopy(event.getItemStack())); + // Paper end ++ // SparklyPaper start - add decoration and mark everything dirty for other players who are already tracking this frame ++ final ItemStack item = this.getItem(); ++ if (item.is(Items.FILLED_MAP)) { ++ final MapItemSavedData data = MapItem.getSavedData(item, this.level()); ++ if (data != null) { ++ data.addFrameDecoration(this); ++ data.markAllDirty(); ++ } ++ } ++ // SparklyPaper end + this.gameEvent(GameEvent.BLOCK_CHANGE, player); + if (!player.getAbilities().instabuild) { + itemstack.shrink(1); +diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +index 804c342783baccdc12e8ca49a362770e31596f6a..a0b760388407469adbd9569edfccadcb1b3d37a1 100644 +--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java ++++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java +@@ -67,6 +67,16 @@ public class MapItemSavedData extends SavedData { + private final Map frameMarkers = Maps.newHashMap(); + private int trackedDecorationCount; + private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper ++ // SparklyPaper start - shared between all players tracking this map inside an item frame ++ public boolean dirtyColorData; ++ public int minDirtyX; ++ public int minDirtyY; ++ public int maxDirtyX; ++ public int maxDirtyY; ++ public boolean dirtyFrameDecorations; ++ public boolean hasPluginRenderer; ++ public boolean hasContextualRenderer; ++ // SparklyPaper end + public boolean isExplorerMap; // Purpur + + // CraftBukkit start +@@ -333,6 +343,7 @@ public class MapItemSavedData extends SavedData { + } + + this.setDecorationsDirty(); ++ if (mapicon != null && mapicon.renderOnFrame()) this.dirtyFrameDecorations = true; // SparklyPaper + } + + public static void addTargetDecoration(ItemStack stack, BlockPos pos, String id, MapDecoration.Type type) { +@@ -428,6 +439,7 @@ public class MapItemSavedData extends SavedData { + } + + this.setDecorationsDirty(); ++ if (type.isRenderedOnFrame() || (mapicon1 != null && mapicon.type().isRenderedOnFrame())) this.dirtyFrameDecorations = true; // SparklyPaper + } + + } +@@ -441,6 +453,20 @@ public class MapItemSavedData extends SavedData { + + public void setColorsDirty(int x, int z) { + this.setDirty(); ++ // SparklyPaper start ++ if (this.dirtyColorData) { ++ this.minDirtyX = Math.min(this.minDirtyX, x); ++ this.minDirtyY = Math.min(this.minDirtyY, z); ++ this.maxDirtyX = Math.max(this.maxDirtyX, x); ++ this.maxDirtyY = Math.max(this.maxDirtyY, z); ++ } else { ++ this.dirtyColorData = true; ++ this.minDirtyX = x; ++ this.minDirtyY = z; ++ this.maxDirtyX = x; ++ this.maxDirtyY = z; ++ } ++ // SparklyPaper end + Iterator iterator = this.carriedBy.iterator(); + + while (iterator.hasNext()) { +@@ -523,6 +549,7 @@ public class MapItemSavedData extends SavedData { + public void removedFromFrame(BlockPos pos, int id) { + this.removeDecoration("frame-" + id); + this.frameMarkers.remove(MapFrame.frameId(pos)); ++ this.dirtyFrameDecorations = true; // SparklyPaper + } + + public boolean updateColor(int x, int z, byte color) { +@@ -579,7 +606,90 @@ public class MapItemSavedData extends SavedData { + public boolean isTrackedCountOverLimit(int iconCount) { + return this.trackedDecorationCount >= iconCount; + } ++ // SparklyPaper start ++ public final @Nullable Packet framedUpdatePacket(int id, @Nullable Player player) { ++ return createUpdatePacket(id, player, false); ++ } ++ ++ public final @Nullable Packet fullUpdatePacket(int id, @Nullable Player player) { ++ return createUpdatePacket(id, player, true); ++ } ++ ++ public final @Nullable Packet createUpdatePacket(int id, @Nullable Player player, boolean full) { ++ if (!dirtyColorData && !dirtyFrameDecorations && (player == null || server.getCurrentTick() % 5 != 0) && !full) { ++ return null; ++ } ++ ++ final org.bukkit.craftbukkit.map.RenderData render = player != null ? this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) player.getBukkitEntity()) : this.vanillaRender; ++ ++ final MapPatch patch; ++ if (full) { ++ patch = createPatch(render.buffer, 0, 0, 127, 127); ++ } else if (dirtyColorData) { ++ dirtyColorData = false; ++ patch = createPatch(render.buffer, this.minDirtyX, this.minDirtyY, this.maxDirtyX, this.maxDirtyY); ++ } else { ++ patch = null; ++ } ++ ++ Collection decorations = null; ++ if (dirtyFrameDecorations || full || hasPluginRenderer) { ++ dirtyFrameDecorations = false; ++ decorations = new java.util.ArrayList<>(); ++ ++ if (player == null) { ++ for (MapDecoration decoration : this.decorations.values()) { ++ if (decoration.renderOnFrame()) { ++ decorations.add(decoration); ++ } ++ } ++ } + ++ for (final org.bukkit.map.MapCursor cursor : render.cursors) { ++ if (cursor.isVisible()) { ++ decorations.add(new MapDecoration(MapDecoration.Type.byIcon(cursor.getRawType()), cursor.getX(), cursor.getY(), cursor.getDirection(), PaperAdventure.asVanilla(cursor.caption()))); // Paper - Adventure ++ } ++ } ++ } ++ ++ return new ClientboundMapItemDataPacket(id, this.scale, this.locked, decorations, patch); ++ } ++ ++ private MapPatch createPatch(byte[] buffer, int minDirtyX, int minDirtyY, int maxDirtyX, int maxDirtyY) { ++ int i = minDirtyX; ++ int j = minDirtyY; ++ int k = maxDirtyX + 1 - minDirtyX; ++ int l = maxDirtyY + 1 - minDirtyY; ++ byte[] abyte = new byte[k * l]; ++ ++ for (int i1 = 0; i1 < k; ++i1) { ++ for (int j1 = 0; j1 < l; ++j1) { ++ abyte[i1 + j1 * k] = buffer[i + i1 + (j + j1) * 128]; ++ } ++ } ++ ++ return new MapItemSavedData.MapPatch(i, j, k, l, abyte); ++ } ++ ++ public void addFrameDecoration(net.minecraft.world.entity.decoration.ItemFrame frame) { ++ if (this.trackedDecorationCount >= frame.level().paperConfig().maps.itemFrameCursorLimit || this.frameMarkers.containsKey(MapFrame.frameId(frame.getPos()))) { ++ return; ++ } ++ ++ MapFrame mapFrame = new MapFrame(frame.getPos(), frame.getDirection().get2DDataValue() * 90, frame.getId()); ++ this.addDecoration(MapDecoration.Type.FRAME, frame.level(), "frame-" + frame.getId(), frame.getPos().getX(), frame.getPos().getZ(), mapFrame.getRotation(), (Component) null); ++ this.frameMarkers.put(mapFrame.getId(), mapFrame); ++ } ++ ++ public void markAllDirty() { ++ this.dirtyColorData = true; ++ this.minDirtyX = 0; ++ this.minDirtyY = 0; ++ this.maxDirtyX = 127; ++ this.maxDirtyY = 127; ++ this.dirtyFrameDecorations = true; ++ } ++ // SparklyPaper end + public class HoldingPlayer { + + // Paper start +diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java +index c3266c43a073cb7d7eff10d1a1b15f0a2265b859..ff3b0f8ebea13f52a1d86085e32489db86969dd1 100644 +--- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java ++++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java +@@ -108,6 +108,10 @@ public final class CraftMapView implements MapView { + this.renderers.add(renderer); + this.canvases.put(renderer, new HashMap()); + renderer.initialize(this); ++ // SparklyPaper start ++ this.worldMap.hasPluginRenderer |= !(renderer instanceof CraftMapRenderer); ++ this.worldMap.hasContextualRenderer |= renderer.isContextual(); ++ // SparklyPaper end + } + } + +@@ -123,6 +127,17 @@ public final class CraftMapView implements MapView { + } + } + this.canvases.remove(renderer); ++ // SparklyPaper start ++ this.worldMap.hasPluginRenderer = !(this.renderers.size() == 1 && this.renderers.get(0) instanceof CraftMapRenderer); ++ if (renderer.isContextual()) { ++ // Re-check all renderers ++ boolean contextualFound = false; ++ for (final MapRenderer mapRenderer : this.renderers) { ++ contextualFound |= mapRenderer.isContextual(); ++ } ++ this.worldMap.hasContextualRenderer = contextualFound; ++ } ++ // SparklyPaper end + return true; + } else { + return false; diff --git a/patches/server/0054-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch b/patches/server/0054-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch new file mode 100644 index 00000000..43be7ef5 --- /dev/null +++ b/patches/server/0054-SparklyPaper-Skip-MapItem-update-if-the-map-does-not.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Wed, 17 Jan 2024 19:57:53 +0800 +Subject: [PATCH] + SparklyPaper-Skip-MapItem-update-if-the-map-does-not-have-the-Cra + + +diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java +index 6cfd169c2c32b644d70907358c2d4a2087c00a68..62aa1717eee90032c2ddf848424e903cc952a913 100644 +--- a/src/main/java/net/minecraft/world/item/MapItem.java ++++ b/src/main/java/net/minecraft/world/item/MapItem.java +@@ -32,6 +32,9 @@ import net.minecraft.world.level.levelgen.Heightmap; + import net.minecraft.world.level.material.FluidState; + import net.minecraft.world.level.material.MapColor; + import net.minecraft.world.level.saveddata.maps.MapItemSavedData; ++// Leaf Start ++import org.dreeam.leaf.LeafConfig; ++// Leaf end + + public class MapItem extends ComplexItem { + +@@ -314,6 +317,7 @@ public class MapItem extends ComplexItem { + } + + @Override ++ + public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) { + if (!world.isClientSide) { + MapItemSavedData worldmap = MapItem.getSavedData(stack, world); +@@ -325,7 +329,7 @@ public class MapItem extends ComplexItem { + worldmap.tickCarriedBy(entityhuman, stack); + } + +- if (!worldmap.locked && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { ++ if (!worldmap.locked && (!LeafConfig.skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer || worldmap.mapView.getRenderers().stream().anyMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list + this.update(world, entity, worldmap); + } + +diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java +index 728082120af5a7afe20078b3fa6d80605f5ff6c7..db12eb7e81307cc3fd4fe0602697e32e71289f7e 100644 +--- a/src/main/java/org/dreeam/leaf/LeafConfig.java ++++ b/src/main/java/org/dreeam/leaf/LeafConfig.java +@@ -321,4 +321,8 @@ public class LeafConfig { + private static void getVanillaTeleport() { + vanillaEndTeleport = getBoolean("vanillaEndTeleport",vanillaEndTeleport,"Vanilla End Gateway Teleport"); + } ++ public static boolean skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer=true; ++ private static void getSkipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer() { ++ skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer = getBoolean("skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer",skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer); ++ } + } diff --git a/patches/server/0055-Polpot-Cache-coordinate-key-used-for-nearby-players.patch b/patches/server/0055-Polpot-Cache-coordinate-key-used-for-nearby-players.patch new file mode 100644 index 00000000..88dec429 --- /dev/null +++ b/patches/server/0055-Polpot-Cache-coordinate-key-used-for-nearby-players.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Thu, 18 Jan 2024 13:14:57 +0800 +Subject: [PATCH] Polpot Cache-coordinate-key-used-for-nearby-players + + +diff --git a/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java +index 17ba07cbd4792f63d88ce29d00da280f30c4abff..98ae712c78d500e8c463aa671909a931a001407e 100644 +--- a/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java ++++ b/src/main/java/io/papermc/paper/util/player/NearbyPlayers.java +@@ -106,6 +106,13 @@ public final class NearbyPlayers { + return chunk == null ? null : chunk.players[type.ordinal()]; + } + ++ // Polpot start - cache coordinate key used for nearby players ++ public ReferenceList getPlayers(final long nearbyPlayersCoordinateKey, final NearbyMapType type) { ++ final TrackedChunk chunk = this.byChunk.get(nearbyPlayersCoordinateKey); ++ return chunk == null ? null : chunk.players[type.ordinal()]; ++ } ++ // Polpot end ++ + public ReferenceList getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) { + final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ)); + +diff --git a/src/main/java/net/minecraft/server/Eula.java b/src/main/java/net/minecraft/server/Eula.java +index b9403a3eafc1b30b33ac654f253d0849cacadd03..a6190f14cb9463ee75e8890f191a7ec88e59b37f 100644 +--- a/src/main/java/net/minecraft/server/Eula.java ++++ b/src/main/java/net/minecraft/server/Eula.java +@@ -47,7 +47,7 @@ public class Eula { + return var3; + } catch (Exception var6) { + if (file == this.file) { // Gale - YAPFA - global EULA file +- LOGGER.warn("Failed to load {}", (Object)this.file); ++ LOGGER.warn("Failed to load {}", this.file); // Leaf - remove convert + this.saveDefaults(); + } // Gale - YAPFA - global EULA file + return false; +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index 02b517288ef0794ccfd46802bf76fa56af21c524..e7fe8e2a7f5cb0c36679142f3743467efbed9c31 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -602,7 +602,7 @@ public class ServerChunkCache extends ChunkSource { + + // Paper start - optimise chunk tick iteration + com.destroystokyo.paper.util.maplist.ReferenceList playersNearby +- = nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE); ++ = nearbyPlayers.getPlayers(chunk1.nearbyPlayersCoordinateKey, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE); // nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE); // Polpot - cache coordinate key used for nearby players + if (playersNearby == null) { + continue; + } +diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +index f7e5e016a7028a9196e689e950805b0d5b31fe38..29d5848dec547245a1bafc5674b62b54ff7cd287 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java ++++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +@@ -62,7 +62,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom + protected final ShortList[] postProcessing; + protected volatile boolean unsaved; + private volatile boolean isLightCorrect; +- protected final ChunkPos chunkPos; public final long coordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key ++ protected final ChunkPos chunkPos; public final long coordinateKey; public final long nearbyPlayersCoordinateKey; public final int locX; public final int locZ; // Paper - cache coordinate key // Polpot - cache coordinate key used for nearby players + private long inhabitedTime; + /** @deprecated */ + @Nullable +@@ -136,7 +136,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom + } + // Paper end - rewrite light engine + this.locX = pos.x; this.locZ = pos.z; // Paper - reduce need for field lookups +- this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); // Paper - cache long key ++ this.chunkPos = pos; this.coordinateKey = ChunkPos.asLong(locX, locZ); this.nearbyPlayersCoordinateKey = io.papermc.paper.util.CoordinateUtils.getChunkKey(locX, locZ); // Paper - cache long key // Polpot - cache coordinate key used for nearby players + this.upgradeData = upgradeData; + this.levelHeightAccessor = heightLimitView; + this.sections = new LevelChunkSection[heightLimitView.getSectionsCount()]; diff --git a/patches/server/0056-Polpot-make-make-egg-and-snowball-can-knockback-play.patch b/patches/server/0056-Polpot-make-make-egg-and-snowball-can-knockback-play.patch new file mode 100644 index 00000000..2d5d5d44 --- /dev/null +++ b/patches/server/0056-Polpot-make-make-egg-and-snowball-can-knockback-play.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lilingfengdev <145678359+lilingfengdev@users.noreply.github.com> +Date: Thu, 18 Jan 2024 13:30:02 +0800 +Subject: [PATCH] Polpot make make egg and snowball can knockback player + + +diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +index 440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6..26f1f1c588095d791b24b678c054cccfbbbf0706 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +@@ -3,6 +3,7 @@ package net.minecraft.world.entity.projectile; + import net.minecraft.core.particles.ItemParticleOption; + import net.minecraft.core.particles.ParticleOptions; + import net.minecraft.core.particles.ParticleTypes; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; + import net.minecraft.world.entity.LivingEntity; +@@ -13,6 +14,9 @@ import net.minecraft.world.item.Items; + import net.minecraft.world.level.Level; + import net.minecraft.world.phys.EntityHitResult; + import net.minecraft.world.phys.HitResult; ++// Leaf start ++import org.dreeam.leaf.LeafConfig; ++// Leaf end + + public class Snowball extends ThrowableItemProjectile { + public Snowball(EntityType type, Level world) { +@@ -55,6 +59,12 @@ public class Snowball extends ThrowableItemProjectile { + Entity entity = entityHitResult.getEntity(); + int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur + entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float)i); ++ // Leaf - Polpot start - make snowball can knockback player ++ if (LeafConfig.snowballAndEggCanKnockback && entity instanceof ServerPlayer) { ++ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); ++ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this); ++ } ++ // Leaf - Polpot end + } + + // Purpur start - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire +diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +index b64ecadae45c2126b92963ac8d118dde76126ddd..8daa0d7ee597f94901948a732df5d5e9e1f670ad 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +@@ -15,6 +15,9 @@ import org.bukkit.entity.EntityType; + import org.bukkit.entity.Player; + import org.bukkit.event.player.PlayerEggThrowEvent; + // CraftBukkit end ++// Leaf start ++import org.dreeam.leaf.LeafConfig; ++// Leaf end + + public class ThrownEgg extends ThrowableItemProjectile { + +@@ -45,7 +48,14 @@ public class ThrownEgg extends ThrowableItemProjectile { + @Override + protected void onHitEntity(EntityHitResult entityHitResult) { + super.onHitEntity(entityHitResult); ++ Entity entity = entityHitResult.getEntity(); // Polpot - make egg can knockback player + entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F); ++ // Leaf - Polpot start - make egg can knockback player ++ if (LeafConfig.snowballAndEggCanKnockback && entity instanceof ServerPlayer) { ++ entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); ++ ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ(), this); ++ } ++ // Leaf - Polpot end - make egg can knockback player + } + + @Override +diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java +index db12eb7e81307cc3fd4fe0602697e32e71289f7e..0439423d1c8b3a9f063595f6df542ce54aa646ab 100644 +--- a/src/main/java/org/dreeam/leaf/LeafConfig.java ++++ b/src/main/java/org/dreeam/leaf/LeafConfig.java +@@ -325,4 +325,8 @@ public class LeafConfig { + private static void getSkipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer() { + skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer = getBoolean("skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer",skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer); + } ++ public static boolean snowballAndEggCanKnockback = false; ++ private static void SnowballAndEggCanKnockback() { ++ snowballAndEggCanKnockback = getBoolean("settings.snowball-egg-knockback-players", snowballAndEggCanKnockback,"Make snowball and egg can knock back player"); ++ } + }