diff --git a/core/src/main/java/dev/pgm/community/requests/RequestConfig.java b/core/src/main/java/dev/pgm/community/requests/RequestConfig.java index 0bc9038..1ce96a9 100644 --- a/core/src/main/java/dev/pgm/community/requests/RequestConfig.java +++ b/core/src/main/java/dev/pgm/community/requests/RequestConfig.java @@ -23,6 +23,7 @@ public class RequestConfig extends FeatureConfigImpl { private static final String MAX_TOKENS = SPONSORS + ".max-tokens"; private static final String REFUND = SPONSORS + ".refund"; private static final String MAP_COOLDOWN_MULTIPLY = SPONSORS + ".map-cooldown"; + private static final String USE_PGM_COOLDOWNS = SPONSORS + ".use-pgm-cooldowns"; private static final String SCALE_FACTOR = SPONSORS + ".scale-factor"; private static final String LOWER_LIMIT_OFFSET = SPONSORS + ".lower-limit-offset"; private static final String UPPER_LIMIT_OFFSET = SPONSORS + ".upper-limit-offset"; @@ -47,6 +48,8 @@ public class RequestConfig extends FeatureConfigImpl { private boolean refund; // If token should be refunded when vote is successful private int mapCooldownMultiply; // # to multiply match length by to determine cooldown + private boolean + usePGMCooldowns; // Whether to use PGM's map cooldown storage for additional lookup private double scaleFactor; // Scaling factor for adjusting the upper bound of map size selection @@ -108,6 +111,10 @@ public int getMapCooldownMultiply() { return mapCooldownMultiply; } + public boolean isPGMCooldownsUsed() { + return usePGMCooldowns; + } + public int getLowerLimitOffset() { return lowerLimitOffset; } @@ -144,6 +151,7 @@ public void reload(Configuration config) { this.maxQueue = config.getInt(SPONSORS_LIMIT); this.refund = config.getBoolean(REFUND); this.mapCooldownMultiply = config.getInt(MAP_COOLDOWN_MULTIPLY); + this.usePGMCooldowns = config.getBoolean(USE_PGM_COOLDOWNS); this.scaleFactor = config.getDouble(SCALE_FACTOR); this.lowerLimitOffset = config.getInt(LOWER_LIMIT_OFFSET); this.upperLimitOffset = config.getInt(UPPER_LIMIT_OFFSET); diff --git a/core/src/main/java/dev/pgm/community/requests/feature/RequestFeatureBase.java b/core/src/main/java/dev/pgm/community/requests/feature/RequestFeatureBase.java index 8695b27..a14ecef 100644 --- a/core/src/main/java/dev/pgm/community/requests/feature/RequestFeatureBase.java +++ b/core/src/main/java/dev/pgm/community/requests/feature/RequestFeatureBase.java @@ -38,6 +38,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Optional; import java.util.Queue; import java.util.Set; @@ -57,7 +58,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerJoinEvent; -import org.jetbrains.annotations.Nullable; import tc.oc.pgm.api.PGM; import tc.oc.pgm.api.map.MapInfo; import tc.oc.pgm.api.map.MapOrder; @@ -68,6 +68,8 @@ import tc.oc.pgm.events.PlayerJoinMatchEvent; import tc.oc.pgm.restart.RestartManager; import tc.oc.pgm.rotation.MapPoolManager; +import tc.oc.pgm.rotation.pools.MapPool; +import tc.oc.pgm.rotation.pools.VotingPool; import tc.oc.pgm.rotation.vote.MapPoll; import tc.oc.pgm.rotation.vote.VotePoolOptions; import tc.oc.pgm.util.Audience; @@ -439,10 +441,14 @@ public void sponsor(Player player, MapInfo map) { // Check if map has a cooldown if (hasMapCooldown(map)) { MapCooldown cooldown = getMapCooldown(map); - viewer.sendWarning(text() - .append(text("This map can be sponsored in ", NamedTextColor.RED)) - .append(TemporalComponent.duration(cooldown.getTimeRemaining(), NamedTextColor.YELLOW)) - .build()); + Component cooldownWarning = cooldown != null + ? text() + .append(text("This map can be sponsored in ", NamedTextColor.RED)) + .append( + TemporalComponent.duration(cooldown.getTimeRemaining(), NamedTextColor.YELLOW)) + .build() + : text("This map is on cooldown! Please select another.", NamedTextColor.RED); + viewer.sendWarning(cooldownWarning); return; } @@ -675,8 +681,27 @@ private MapCooldown getMapCooldown(MapInfo map) { return null; } + public boolean isOnLongtermCooldown(MapInfo map) { + if (!getRequestConfig().isPGMCooldownsUsed()) return false; + + MapPool activePool = PGMUtils.getActiveMapPool(); + if (!(activePool instanceof VotingPool)) return false; + + VotingPool pool = (VotingPool) activePool; + VotingPool.VoteConstants constants = pool.constants; + var mapLibrary = PGM.get().getMapLibrary(); + + return map.getVariants().values().stream() + .map(variant -> mapLibrary.getMapById(variant.getId())) + .filter(Objects::nonNull) + .map(pool::getVoteData) + .allMatch(data -> + !data.isOnCooldown(constants) && data.getScore() > (constants.defaultScore() / 2)); + } + @Override public boolean hasMapCooldown(MapInfo map) { + if (isOnLongtermCooldown(map)) return true; if (isACooldownVariant(map)) return true; MapCooldown cooldown = getMapCooldown(map); @@ -830,7 +855,6 @@ private boolean isQueueOpen() { return sponsors.size() < getRequestConfig().getMaxQueue(); } - @Nullable private MapPoolManager getPoolManager() { MapOrder order = PGM.get().getMapOrder(); if (order instanceof MapPoolManager) { diff --git a/core/src/main/java/dev/pgm/community/utils/PGMUtils.java b/core/src/main/java/dev/pgm/community/utils/PGMUtils.java index 220e09a..45fee40 100644 --- a/core/src/main/java/dev/pgm/community/utils/PGMUtils.java +++ b/core/src/main/java/dev/pgm/community/utils/PGMUtils.java @@ -9,7 +9,6 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.Nullable; import tc.oc.pgm.api.PGM; import tc.oc.pgm.api.map.MapInfo; import tc.oc.pgm.api.match.Match; @@ -29,7 +28,7 @@ public static boolean isPGMEnabled() { return pgmPlugin != null && pgmPlugin.isEnabled() && PGM.get() != null; } - public static @Nullable Match getMatch() { + public static Match getMatch() { return isPGMEnabled() && PGM.get().getMatchManager().getMatches().hasNext() ? PGM.get().getMatchManager().getMatches().next() : null; @@ -62,7 +61,6 @@ public static boolean isMatchRunning() { return isPGMEnabled() && getMatch().isRunning(); } - @Nullable public static MapInfo getCurrentMap() { return isPGMEnabled() && getMatch() != null ? getMatch().getMap() : null; } @@ -155,7 +153,6 @@ public static void setMapPool(CommandSender sender, MapPool pool) { } } - @Nullable public static MapPoolManager getMapPoolManager() { if (isPGMEnabled()) { if (PGM.get().getMapOrder() instanceof MapPoolManager) { @@ -165,6 +162,12 @@ public static MapPoolManager getMapPoolManager() { return null; } + public static MapPool getActiveMapPool() { + MapPoolManager manager = getMapPoolManager(); + if (manager == null) return null; + return manager.getActiveMapPool(); + } + public static Optional getMapPool(String name) { if (isPGMEnabled()) { if (PGM.get().getMapOrder() instanceof MapPoolManager) { diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml index 195a038..246ef21 100644 --- a/core/src/main/resources/config.yml +++ b/core/src/main/resources/config.yml @@ -224,15 +224,16 @@ requests: cooldown: "15s" # Duration of cooldown between requests sponsors: - enabled: true # Whether /sponsor is enabled - cooldown: "30m" # Duration of cooldown between /sponsor requests - map-cooldown: 10 # How much to multiply match duration by for map cooldown - limit: 10 # Maximum number of sponsor requests allowed at one time - daily-tokens: 1 # Amount of tokens given on a daily basis (community.token.daily perm) - weekly-tokens: 1 # Amount of tokens given on a weekly basis (community.token.weekly perm) - max-tokens: 7 # Maximum amount of tokens an account can collect - refund: true # Tokens are refunded when map vote is successful - scale-factor: 0.45 # Scaling factor for adjusting the upper bound of map size selection + enabled: true # Whether /sponsor is enabled + cooldown: "30m" # Duration of cooldown between /sponsor requests + map-cooldown: 10 # How much to multiply match duration by for map cooldown + use-pgm-cooldowns: true # Whether to hook into PGMs persistent map cooldown storage + limit: 10 # Maximum number of sponsor requests allowed at one time + daily-tokens: 1 # Amount of tokens given on a daily basis (community.token.daily perm) + weekly-tokens: 1 # Amount of tokens given on a weekly basis (community.token.weekly perm) + max-tokens: 7 # Maximum amount of tokens an account can collect + refund: true # Tokens are refunded when map vote is successful + scale-factor: 0.45 # Scaling factor for adjusting the upper bound of map size selection # Sponsor bound offset used to modify avaiable maps at the end of each match lower-limit-offset: 4 # Subtracted from the current minimum