13
0
geforkt von Mirrors/Paper

Add restrict-player-reloot-time config (#7652)

Dieser Commit ist enthalten in:
Jake Potrebic 2023-08-12 14:26:47 -07:00
Ursprung 4e4417723a
Commit 3d0d1cb6ae
3 geänderte Dateien mit 94 neuen und 7 gelöschten Zeilen

Datei anzeigen

@ -106,6 +106,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ /**
+ * 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

Datei anzeigen

@ -196,6 +196,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @Override
+ default boolean canPlayerLoot(final UUID player) {
+ return getLootableData().canPlayerLoot(player, this.getNMSWorld().paperConfig());
+ }
+
+ @Override
+ default Long getLastLooted(UUID player) {
+ return getLootableData().getLastLooted(player);
+ }
@ -242,6 +247,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+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;
@ -318,9 +326,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ 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) {
@ -402,14 +408,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ 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);
+ }

Datei anzeigen

@ -978,6 +978,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+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;
@ -1166,6 +1167,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ .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))
@ -1496,6 +1498,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+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;
@ -1775,6 +1778,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ 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");
@ -4021,7 +4025,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return (int) num;
+ }
+
+ private static final class Serializer extends ScalarSerializer<Duration> {
+ static final class Serializer extends ScalarSerializer<Duration> {
+ private Serializer() {
+ super(Duration.class);
+ }
@ -4037,6 +4041,66 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+}
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..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/type/DurationOrDisabled.java
@@ -0,0 +0,0 @@
+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..0000000000000000000000000000000000000000