Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add restrict-player-reloot-time config #7652

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions patches/api/0040-LootTable-API.patch
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ index 0000000000000000000000000000000000000000..b387894fe8001edb41ad2ad2b70ebabe
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
new file mode 100644
index 0000000000000000000000000000000000000000..97815eeb231cf0706b34fa47a4f7d1bb786305b4
index 0000000000000000000000000000000000000000..2b01a50b6e18856f4c9e28340a7a111cae646a0a
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
@@ -0,0 +1,116 @@
@@ -0,0 +1,125 @@
+package com.destroystokyo.paper.loottable;
+
+import org.bukkit.entity.Player;
Expand Down Expand Up @@ -106,6 +106,15 @@ index 0000000000000000000000000000000000000000..97815eeb231cf0706b34fa47a4f7d1bb
+ }
+
+ /**
+ * Checks if this player can loot this block. Takes into account the "restrict player reloot" settings
+ *
+ * @param player the player to check
+ *
+ * @return Whether this player can loot this block
+ */
+ boolean canPlayerLoot(@NotNull UUID player);
+
+ /**
+ * Has this player ever looted this block
+ * @param player The player to check
+ * @return Whether or not this player has looted this block
Expand Down
78 changes: 71 additions & 7 deletions patches/server/0005-Paper-config-files.patch
Original file line number Diff line number Diff line change
Expand Up @@ -948,10 +948,10 @@ index 0000000000000000000000000000000000000000..69add4a7f1147015806bc9b63a8340d1
+}
diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad2177cdbc61a6f41c7e2ed81af262d4ffe7d861
index 0000000000000000000000000000000000000000..e471960e0443392f6f54732b052a4debf2a8fd97
--- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java
@@ -0,0 +1,440 @@
@@ -0,0 +1,442 @@
+package io.papermc.paper.configuration;
+
+import com.google.common.base.Suppliers;
Expand All @@ -978,6 +978,7 @@ index 0000000000000000000000000000000000000000..ad2177cdbc61a6f41c7e2ed81af262d4
+import io.papermc.paper.configuration.type.BooleanOrDefault;
+import io.papermc.paper.configuration.type.DoubleOrDefault;
+import io.papermc.paper.configuration.type.Duration;
+import io.papermc.paper.configuration.type.DurationOrDisabled;
+import io.papermc.paper.configuration.type.EngineMode;
+import io.papermc.paper.configuration.type.IntOr;
+import io.papermc.paper.configuration.type.fallback.FallbackValueSerializer;
Expand Down Expand Up @@ -1166,6 +1167,7 @@ index 0000000000000000000000000000000000000000..ad2177cdbc61a6f41c7e2ed81af262d4
+ .register(DoubleOrDefault.SERIALIZER)
+ .register(BooleanOrDefault.SERIALIZER)
+ .register(Duration.SERIALIZER)
+ .register(DurationOrDisabled.SERIALIZER)
+ .register(EngineMode.SERIALIZER)
+ .register(NbtPathSerializer.SERIALIZER)
+ .register(FallbackValueSerializer.create(contextMap.require(SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer))
Expand Down Expand Up @@ -1477,10 +1479,10 @@ index 0000000000000000000000000000000000000000..f0d4ec73bc8872a85e34f5c6b4d342e7
+}
diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..a33de97340f14219291c4175e9194914cdf441db
index 0000000000000000000000000000000000000000..d47c57afafc01e25b965f1844938b2516a7bd031
--- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java
@@ -0,0 +1,482 @@
@@ -0,0 +1,484 @@
+package io.papermc.paper.configuration;
+
+import com.google.common.collect.HashBasedTable;
Expand All @@ -1496,6 +1498,7 @@ index 0000000000000000000000000000000000000000..a33de97340f14219291c4175e9194914
+import io.papermc.paper.configuration.type.BooleanOrDefault;
+import io.papermc.paper.configuration.type.DoubleOrDefault;
+import io.papermc.paper.configuration.type.Duration;
+import io.papermc.paper.configuration.type.DurationOrDisabled;
+import io.papermc.paper.configuration.type.EngineMode;
+import io.papermc.paper.configuration.type.IntOr;
+import io.papermc.paper.configuration.type.fallback.ArrowDespawnRate;
Expand Down Expand Up @@ -1775,6 +1778,7 @@ index 0000000000000000000000000000000000000000..a33de97340f14219291c4175e9194914
+ public class Lootables extends ConfigurationPart {
+ public boolean autoReplenish = false;
+ public boolean restrictPlayerReloot = true;
+ public DurationOrDisabled restrictPlayerRelootTime = DurationOrDisabled.USE_DISABLED;
+ public boolean resetSeedOnFill = true;
+ public int maxRefills = -1;
+ public Duration refreshMin = Duration.of("12h");
Expand Down Expand Up @@ -3936,7 +3940,7 @@ index 0000000000000000000000000000000000000000..193709f1d08e489fc51cbe11d4325297
+}
diff --git a/src/main/java/io/papermc/paper/configuration/type/Duration.java b/src/main/java/io/papermc/paper/configuration/type/Duration.java
new file mode 100644
index 0000000000000000000000000000000000000000..fdc906b106a5c6fff2675d5399650f5b793deb70
index 0000000000000000000000000000000000000000..422ccb0b332b3e94be228b9b94f379467d6461a5
--- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/type/Duration.java
@@ -0,0 +1,97 @@
Expand Down Expand Up @@ -4021,7 +4025,7 @@ index 0000000000000000000000000000000000000000..fdc906b106a5c6fff2675d5399650f5b
+ return (int) num;
+ }
+
+ private static final class Serializer extends ScalarSerializer<Duration> {
+ static final class Serializer extends ScalarSerializer<Duration> {
+ private Serializer() {
+ super(Duration.class);
+ }
Expand All @@ -4037,6 +4041,66 @@ index 0000000000000000000000000000000000000000..fdc906b106a5c6fff2675d5399650f5b
+ }
+ }
+}
diff --git a/src/main/java/io/papermc/paper/configuration/type/DurationOrDisabled.java b/src/main/java/io/papermc/paper/configuration/type/DurationOrDisabled.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f17e75e08e1cb4359b96a78c5b8d5284c484e43
--- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/type/DurationOrDisabled.java
@@ -0,0 +1,54 @@
+package io.papermc.paper.configuration.type;
+
+import java.lang.reflect.Type;
+import java.util.Optional;
+import java.util.function.Predicate;
+import org.spongepowered.configurate.serialize.ScalarSerializer;
+import org.spongepowered.configurate.serialize.SerializationException;
+
+@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+public final class DurationOrDisabled {
+ private static final String DISABLE_VALUE = "disabled";
+ public static final DurationOrDisabled USE_DISABLED = new DurationOrDisabled(Optional.empty());
+ public static final ScalarSerializer<DurationOrDisabled> SERIALIZER = new Serializer();
+
+ private Optional<Duration> value;
+
+ public DurationOrDisabled(final Optional<Duration> value) {
+ this.value = value;
+ }
+
+ public Optional<Duration> value() {
+ return this.value;
+ }
+
+ public void value(final Optional<Duration> value) {
+ this.value = value;
+ }
+
+ public Duration or(final Duration fallback) {
+ return this.value.orElse(fallback);
+ }
+
+ private static final class Serializer extends ScalarSerializer<DurationOrDisabled> {
+ Serializer() {
+ super(DurationOrDisabled.class);
+ }
+
+ @Override
+ public DurationOrDisabled deserialize(final Type type, final Object obj) throws SerializationException {
+ if (obj instanceof final String string) {
+ if (DISABLE_VALUE.equalsIgnoreCase(string)) {
+ return USE_DISABLED;
+ }
+ return new DurationOrDisabled(Optional.of(Duration.SERIALIZER.deserialize(string)));
+ }
+ throw new SerializationException(obj + "(" + type + ") is not a duration or '" + DISABLE_VALUE + "'");
+ }
+
+ @Override
+ protected Object serialize(final DurationOrDisabled item, final Predicate<Class<?>> typeSupported) {
+ return item.value.map(Duration::value).orElse(DISABLE_VALUE);
+ }
+ }
+}
diff --git a/src/main/java/io/papermc/paper/configuration/type/EngineMode.java b/src/main/java/io/papermc/paper/configuration/type/EngineMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f8b685762f59049fde88e8d1bc10e1504916010
Expand Down Expand Up @@ -4474,7 +4538,7 @@ index e7240acad17dc9c0d93f2792cc0d90c1855ac436..35e7f8e7b19c217fa5f3f55abb0f8b9c
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 49eaa50c5e83e47022a1d126c62f6984f2d16f46..8eb949b43e8b403f3d98e36066cabd7cb9ab0e63 100644
index c7d90803c302fc3cb06f44abf12d86c7e02944cd..a6e12acf65068a2eaea75a7df877f6145a229195 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -295,6 +295,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ index 0000000000000000000000000000000000000000..2fba5bc0f982e143ad5f5bda55d768ed
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce135d990c785b02df468391ea622aa236290f07
index 0000000000000000000000000000000000000000..8e6dac2cef7af26ad74928eff631c1826c2980bb
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java
@@ -0,0 +1,70 @@
@@ -0,0 +1,75 @@
+package com.destroystokyo.paper.loottable;
+
+import org.bukkit.loot.Lootable;
Expand Down Expand Up @@ -196,6 +196,11 @@ index 0000000000000000000000000000000000000000..ce135d990c785b02df468391ea622aa2
+ }
+
+ @Override
+ default boolean canPlayerLoot(final UUID player) {
+ return getLootableData().canPlayerLoot(player, this.getNMSWorld().paperConfig());
+ }
+
+ @Override
+ default Long getLastLooted(UUID player) {
+ return getLootableData().getLastLooted(player);
+ }
Expand Down Expand Up @@ -235,13 +240,16 @@ index 0000000000000000000000000000000000000000..ce135d990c785b02df468391ea622aa2
+}
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5ea9f27a1936ed9e329e74317c91c5df89b9fbd
index 0000000000000000000000000000000000000000..87c5f8a43b8643486ba898e1cea33873398f3b1c
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java
@@ -0,0 +1,179 @@
@@ -0,0 +1,188 @@
+package com.destroystokyo.paper.loottable;
+
+import io.papermc.paper.configuration.WorldConfiguration;
+import io.papermc.paper.configuration.type.DurationOrDisabled;
+import java.time.temporal.ChronoUnit;
+import java.util.concurrent.TimeUnit;
+import org.bukkit.entity.Player;
+import org.bukkit.loot.LootTable;
+import javax.annotation.Nullable;
Expand Down Expand Up @@ -318,9 +326,7 @@ index 0000000000000000000000000000000000000000..e5ea9f27a1936ed9e329e74317c91c5d
+
+ final Player bukkitPlayer = (Player) player.getBukkitEntity();
+ LootableInventoryReplenishEvent event = new LootableInventoryReplenishEvent(bukkitPlayer, lootable.getAPILootableInventory());
+ if (paperConfig.lootables.restrictPlayerReloot && hasPlayerLooted(player.getUUID())) {
+ event.setCancelled(true);
+ }
+ event.setCancelled(!canPlayerLoot(player.getUUID(), paperConfig));
+ return event.callEvent();
+ }
+ public void processRefill(@Nullable net.minecraft.world.entity.player.Player player) {
Expand Down Expand Up @@ -402,14 +408,22 @@ index 0000000000000000000000000000000000000000..e5ea9f27a1936ed9e329e74317c91c5d
+ this.lootedPlayers = new HashMap<>();
+ }
+ if (looted) {
+ if (!this.lootedPlayers.containsKey(player)) {
+ this.lootedPlayers.put(player, System.currentTimeMillis());
+ }
+ this.lootedPlayers.put(player, System.currentTimeMillis());
+ } else if (this.lootedPlayers != null) {
+ this.lootedPlayers.remove(player);
+ }
+ }
+
+ boolean canPlayerLoot(final UUID player, final WorldConfiguration worldConfiguration) {
+ final Long lastLooted = getLastLooted(player);
+ if (!worldConfiguration.lootables.restrictPlayerReloot || lastLooted == null) return true;
+
+ final DurationOrDisabled restrictPlayerRelootTime = worldConfiguration.lootables.restrictPlayerRelootTime;
+ if (restrictPlayerRelootTime.value().isEmpty()) return true;
+
+ return TimeUnit.SECONDS.toMillis(restrictPlayerRelootTime.value().get().seconds()) + lastLooted < System.currentTimeMillis();
+ }
+
+ boolean hasPlayerLooted(UUID player) {
+ return this.lootedPlayers != null && this.lootedPlayers.containsKey(player);
+ }
Expand Down Expand Up @@ -490,7 +504,7 @@ index 0000000000000000000000000000000000000000..9cfa5d36a6991067a3866e0d437749fa
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 9fadfb41a41b575aa1ca1c28e34118708eded498..fbd28a3f571766e6ed4ba73f337b2e835ef50453 100644
index 2f15c9df59ebfbe7619e190b8d6ef1fe122809f8..069fe5df02806103c9bbef396c2e39ca3be90101 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -235,6 +235,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
Expand Down