diff --git a/patches/server/0096-Add-adjustable-breeding-cooldown-to-config.patch b/patches/server/0096-Add-adjustable-breeding-cooldown-to-config.patch deleted file mode 100644 index 0afa0827b..000000000 --- a/patches/server/0096-Add-adjustable-breeding-cooldown-to-config.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: montlikadani -Date: Fri, 13 Nov 2020 17:52:40 +0100 -Subject: [PATCH] Add adjustable breeding cooldown to config - - -diff --git a/net/minecraft/world/entity/animal/Animal.java b/net/minecraft/world/entity/animal/Animal.java -index 5677dc97ed83652f261100cf391883cfac7d16fe..4637d062b6a4c4d6de2ef54ec3cfdeb4344ff38e 100644 ---- a/net/minecraft/world/entity/animal/Animal.java -+++ b/net/minecraft/world/entity/animal/Animal.java -@@ -157,7 +157,7 @@ public abstract class Animal extends AgeableMob { - if (this.isFood(itemstack)) { - int i = this.getAge(); - -- if (!this.level().isClientSide && i == 0 && this.canFallInLove()) { -+ if (!this.level().isClientSide && i == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - final ItemStack breedCopy = itemstack.copy(); // Paper - Fix EntityBreedEvent copying - this.usePlayerItem(player, hand, itemstack); - this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying -@@ -261,12 +261,20 @@ public abstract class Animal extends AgeableMob { - AgeableMob entityageable = this.getBreedOffspring(world, other); - - if (entityageable != null) { -- entityageable.setBaby(true); -- entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -- // CraftBukkit start - call EntityBreedEvent -+ // Purpur start - ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> { - return Optional.ofNullable(other.getLoveCause()); - }).orElse(null); -+ if (breeder != null && world.purpurConfig.animalBreedingCooldownSeconds > 0) { -+ if (world.hasBreedingCooldown(breeder.getUUID(), this.getClass())) { -+ return; -+ } -+ world.addBreedingCooldown(breeder.getUUID(), this.getClass()); -+ } -+ entityageable.setBaby(true); -+ entityageable.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); -+ // CraftBukkit start - call EntityBreedEvent -+ // Purpur end - int experience = this.getRandom().nextInt(7) + 1; - EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, other, breeder, this.breedItem, experience); - if (entityBreedEvent.isCancelled()) { -diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 13c99a770e8c466cdba5f397cf8156aed42b55ba..1aa251cfdf941027f529ce02f0c16c815ade296f 100644 ---- a/net/minecraft/world/level/Level.java -+++ b/net/minecraft/world/level/Level.java -@@ -183,6 +183,49 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions - public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here - -+ // Purpur start -+ private com.google.common.cache.Cache playerBreedingCooldowns; -+ -+ private com.google.common.cache.Cache getNewBreedingCooldownCache() { -+ return com.google.common.cache.CacheBuilder.newBuilder().expireAfterWrite(this.purpurConfig.animalBreedingCooldownSeconds, java.util.concurrent.TimeUnit.SECONDS).build(); -+ } -+ -+ public void resetBreedingCooldowns() { -+ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); -+ } -+ -+ public boolean hasBreedingCooldown(java.util.UUID player, Class animalType) { // Purpur -+ return this.playerBreedingCooldowns.getIfPresent(new BreedingCooldownPair(player, animalType)) != null; -+ } -+ -+ public void addBreedingCooldown(java.util.UUID player, Class animalType) { -+ this.playerBreedingCooldowns.put(new BreedingCooldownPair(player, animalType), new Object()); -+ } -+ -+ private static final class BreedingCooldownPair { -+ private final java.util.UUID playerUUID; -+ private final Class animalType; -+ -+ public BreedingCooldownPair(java.util.UUID playerUUID, Class animalType) { -+ this.playerUUID = playerUUID; -+ this.animalType = animalType; -+ } -+ -+ @Override -+ public boolean equals(Object o) { -+ if (this == o) return true; -+ if (o == null || getClass() != o.getClass()) return false; -+ BreedingCooldownPair that = (BreedingCooldownPair) o; -+ return playerUUID.equals(that.playerUUID) && animalType.equals(that.animalType); -+ } -+ -+ @Override -+ public int hashCode() { -+ return java.util.Objects.hash(playerUUID, animalType); -+ } -+ } -+ // Purpur end -+ - public CraftWorld getWorld() { - return this.world; - } -@@ -845,6 +888,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot - this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config - this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName(), env); // Purpur - Purpur config files -+ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur - this.generator = gen; - this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); - -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index acc45259de6b0178408146b71ebaf4de9d1891bd..6805a2f2803bb4e859afba5369308dd4d2ac5165 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -114,6 +114,7 @@ public class PurpurWorldConfig { - public double tridentLoyaltyVoidReturnHeight = 0.0D; - public boolean entitiesCanUsePortals = true; - public int raidCooldownSeconds = 0; -+ public int animalBreedingCooldownSeconds = 0; - private void miscGameplayMechanicsSettings() { - useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); - boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); -@@ -122,6 +123,7 @@ public class PurpurWorldConfig { - tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); - entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals); - raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds); -+ animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds); - } - - public int daytimeTicks = 12000; -diff --git a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java -index afdf04f8b22ad0b7c0b41675e44687b49c2f86d6..2621e54879e9ab0029a875f1d09eee67878b90d5 100644 ---- a/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java -+++ b/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java -@@ -49,6 +49,7 @@ public class PurpurCommand extends Command { - PurpurConfig.init((File) console.options.valueOf("purpur-settings")); - for (ServerLevel level : console.getAllLevels()) { - level.purpurConfig.init(); -+ level.resetBreedingCooldowns(); - } - console.server.reloadCount++; - diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch new file mode 100644 index 000000000..56a99c436 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/entity/animal/Animal.java.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/world/entity/animal/Animal.java ++++ b/net/minecraft/world/entity/animal/Animal.java +@@ -142,7 +_,7 @@ + ItemStack itemInHand = player.getItemInHand(hand); + if (this.isFood(itemInHand)) { + int age = this.getAge(); +- if (!this.level().isClientSide && age == 0 && this.canFallInLove()) { ++ if (!this.level().isClientSide && age == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - Add adjustable breeding cooldown to config + final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying + this.usePlayerItem(player, hand, itemInHand); + this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying +@@ -239,10 +_,20 @@ + public void spawnChildFromBreeding(ServerLevel level, Animal mate) { + AgeableMob breedOffspring = this.getBreedOffspring(level, mate); + if (breedOffspring != null) { +- breedOffspring.setBaby(true); +- breedOffspring.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); ++ //breedOffspring.setBaby(true); // Purpur - Add adjustable breeding cooldown to config - moved down ++ //breedOffspring.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); // Purpur - Add adjustable breeding cooldown to config - moved down + // CraftBukkit start - call EntityBreedEvent + ServerPlayer breeder = Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(mate.getLoveCause())).orElse(null); ++ // Purpur start - Add adjustable breeding cooldown to config ++ if (breeder != null && level.purpurConfig.animalBreedingCooldownSeconds > 0) { ++ if (level.hasBreedingCooldown(breeder.getUUID(), this.getClass())) { ++ return; ++ } ++ level.addBreedingCooldown(breeder.getUUID(), this.getClass()); ++ } ++ breedOffspring.setBaby(true); ++ breedOffspring.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); ++ // Purpur end - Add adjustable breeding cooldown to config + int experience = this.getRandom().nextInt(7) + 1; + org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, this, mate, breeder, this.breedItem, experience); + if (entityBreedEvent.isCancelled()) { diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/Level.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/Level.java.patch index 0cc7dabde..cfd4c384e 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/world/level/Level.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/world/level/Level.java.patch @@ -8,11 +8,62 @@ public static BlockPos lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; -@@ -853,6 +_,7 @@ +@@ -177,6 +_,49 @@ + public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions + public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here + ++ // Purpur start - Add adjustable breeding cooldown to config ++ private com.google.common.cache.Cache playerBreedingCooldowns; ++ ++ private com.google.common.cache.Cache getNewBreedingCooldownCache() { ++ return com.google.common.cache.CacheBuilder.newBuilder().expireAfterWrite(this.purpurConfig.animalBreedingCooldownSeconds, java.util.concurrent.TimeUnit.SECONDS).build(); ++ } ++ ++ public void resetBreedingCooldowns() { ++ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); ++ } ++ ++ public boolean hasBreedingCooldown(java.util.UUID player, Class animalType) { // Purpur ++ return this.playerBreedingCooldowns.getIfPresent(new BreedingCooldownPair(player, animalType)) != null; ++ } ++ ++ public void addBreedingCooldown(java.util.UUID player, Class animalType) { ++ this.playerBreedingCooldowns.put(new BreedingCooldownPair(player, animalType), new Object()); ++ } ++ ++ private static final class BreedingCooldownPair { ++ private final java.util.UUID playerUUID; ++ private final Class animalType; ++ ++ public BreedingCooldownPair(java.util.UUID playerUUID, Class animalType) { ++ this.playerUUID = playerUUID; ++ this.animalType = animalType; ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) return true; ++ if (o == null || getClass() != o.getClass()) return false; ++ BreedingCooldownPair that = (BreedingCooldownPair) o; ++ return playerUUID.equals(that.playerUUID) && animalType.equals(that.animalType); ++ } ++ ++ @Override ++ public int hashCode() { ++ return java.util.Objects.hash(playerUUID, animalType); ++ } ++ } ++ // Purpur end - Add adjustable breeding cooldown to config ++ + public CraftWorld getWorld() { + return this.world; + } +@@ -853,6 +_,8 @@ // Paper end - getblock optimisations - cache world height/sections this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config + this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // Purpur - Purpur config files ++ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur - Add adjustable breeding cooldown to config this.generator = gen; this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index 9f77340da..f1c09c202 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -105,6 +105,7 @@ public class PurpurWorldConfig { public double tridentLoyaltyVoidReturnHeight = 0.0D; public boolean entitiesCanUsePortals = true; public int raidCooldownSeconds = 0; + public int animalBreedingCooldownSeconds = 0; private void miscGameplayMechanicsSettings() { useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending); boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); @@ -113,6 +114,7 @@ public class PurpurWorldConfig { tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); entitiesCanUsePortals = getBoolean("gameplay-mechanics.entities-can-use-portals", entitiesCanUsePortals); raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds); + animalBreedingCooldownSeconds = getInt("gameplay-mechanics.animal-breeding-cooldown-seconds", animalBreedingCooldownSeconds); } public int daytimeTicks = 12000; diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java b/purpur-server/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java index afdf04f8b..7163c8247 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/command/PurpurCommand.java @@ -49,6 +49,7 @@ public class PurpurCommand extends Command { PurpurConfig.init((File) console.options.valueOf("purpur-settings")); for (ServerLevel level : console.getAllLevels()) { level.purpurConfig.init(); + level.resetBreedingCooldowns(); // Purpur - Add adjustable breeding cooldown to config } console.server.reloadCount++;