From 98965c16d2b78b7554a85949b9199e6ae57b9217 Mon Sep 17 00:00:00 2001 From: Pablete1234 Date: Mon, 27 Mar 2017 05:49:12 +0200 Subject: [PATCH] Fix dynamic rotations, make use of guice --- PGM/src/main/java/tc/oc/pgm/PGM.java | 2 - PGM/src/main/java/tc/oc/pgm/PGMManifest.java | 3 + .../java/tc/oc/pgm/commands/MapCommands.java | 27 +++---- .../java/tc/oc/pgm/map/MapModuleContext.java | 4 +- .../DynamicRotationChangeListener.java | 68 ----------------- .../pgm/rotation/DynamicRotationListener.java | 73 +++++++++++++++++++ .../tc/oc/pgm/rotation/RotationCategory.java | 5 -- .../tc/oc/pgm/rotation/RotationManager.java | 4 + .../oc/pgm/rotation/RotationProviderInfo.java | 11 +++ .../tc/oc/pgm/rotation/RotationState.java | 13 ++-- PGM/src/main/resources/config.yml | 1 + 11 files changed, 111 insertions(+), 100 deletions(-) delete mode 100644 PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationChangeListener.java create mode 100644 PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationListener.java delete mode 100644 PGM/src/main/java/tc/oc/pgm/rotation/RotationCategory.java diff --git a/PGM/src/main/java/tc/oc/pgm/PGM.java b/PGM/src/main/java/tc/oc/pgm/PGM.java index df0c30a..ac56df2 100644 --- a/PGM/src/main/java/tc/oc/pgm/PGM.java +++ b/PGM/src/main/java/tc/oc/pgm/PGM.java @@ -40,7 +40,6 @@ import tc.oc.pgm.match.MatchManager; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.polls.PollListener; import tc.oc.pgm.polls.PollManager; -import tc.oc.pgm.rotation.DynamicRotationChangeListener; import tc.oc.pgm.start.StartCommands; import tc.oc.pgm.tablist.MatchTabManager; import tc.oc.pgm.timelimit.TimeLimitCommands; @@ -200,7 +199,6 @@ public final class PGM extends JavaPlugin { this.registerEvents(new CraftingProtect()); this.registerEvents(new ObjectivesFireworkListener()); this.registerEvents(new ItemTransferListener()); - this.registerEvents(new DynamicRotationChangeListener()); } public void registerEvents(Listener listener) { diff --git a/PGM/src/main/java/tc/oc/pgm/PGMManifest.java b/PGM/src/main/java/tc/oc/pgm/PGMManifest.java index 6e36213..0d61886 100644 --- a/PGM/src/main/java/tc/oc/pgm/PGMManifest.java +++ b/PGM/src/main/java/tc/oc/pgm/PGMManifest.java @@ -4,6 +4,7 @@ import tc.oc.commons.bukkit.chat.FlairRenderer; import tc.oc.commons.bukkit.nick.UsernameRenderer; import tc.oc.commons.core.inject.HybridManifest; import tc.oc.commons.core.plugin.PluginFacetBinder; +import tc.oc.minecraft.api.event.ListenerBinder; import tc.oc.pgm.analytics.MatchAnalyticsManifest; import tc.oc.pgm.antigrief.DefuseListener; import tc.oc.pgm.chat.MatchFlairRenderer; @@ -33,6 +34,7 @@ import tc.oc.pgm.match.MatchPlayerEventRouter; import tc.oc.pgm.module.MatchModulesManifest; import tc.oc.pgm.mutation.command.MutationCommands; import tc.oc.pgm.restart.RestartListener; +import tc.oc.pgm.rotation.DynamicRotationListener; import tc.oc.pgm.settings.Settings; import tc.oc.pgm.spawns.states.State; import tc.oc.pgm.tnt.license.LicenseBroker; @@ -65,6 +67,7 @@ public final class PGMManifest extends HybridManifest { bind(MapLibrary.class).to(MapLibraryImpl.class); bind(MapLoader.class).to(MapLoaderImpl.class); + new ListenerBinder(binder()).bindListener().to(DynamicRotationListener.class); // Tourney needs this expose(MapLibrary.class); diff --git a/PGM/src/main/java/tc/oc/pgm/commands/MapCommands.java b/PGM/src/main/java/tc/oc/pgm/commands/MapCommands.java index 934c809..3fc0510 100644 --- a/PGM/src/main/java/tc/oc/pgm/commands/MapCommands.java +++ b/PGM/src/main/java/tc/oc/pgm/commands/MapCommands.java @@ -2,14 +2,11 @@ package tc.oc.pgm.commands; import java.net.URL; import java.util.List; -import java.util.Map; import java.util.Set; import javax.annotation.Nullable; -import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.Lists; import com.sk89q.bukkit.util.BukkitWrappedCommandSender; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; @@ -32,20 +29,17 @@ import tc.oc.commons.bukkit.nick.UsernameRenderer; import tc.oc.commons.core.chat.Audience; import tc.oc.commons.core.chat.Component; import tc.oc.commons.core.chat.Components; -import tc.oc.pgm.Config; import tc.oc.pgm.PGM; import tc.oc.pgm.PGMTranslations; import tc.oc.pgm.ffa.FreeForAllModule; import tc.oc.pgm.map.Contributor; import tc.oc.pgm.map.MapInfo; import tc.oc.pgm.map.PGMMap; -import tc.oc.pgm.match.MatchManager; -import tc.oc.pgm.match.Party; import tc.oc.pgm.modules.InfoModule; import tc.oc.pgm.rotation.RotationManager; +import tc.oc.pgm.rotation.RotationProviderInfo; import tc.oc.pgm.rotation.RotationState; import tc.oc.pgm.teams.TeamFactory; -import tc.oc.pgm.teams.TeamModule; public class MapCommands { @Command( @@ -234,17 +228,20 @@ public class MapCommands { @CommandPermissions("pgm.rotation.list") public static void rotations(final CommandContext args, final CommandSender sender) throws CommandException { RotationManager manager = PGM.getMatchManager().getRotationManager(); - Map rotations = manager.getRotations(); + List rotations = manager.getProviders(); int page = args.getFlagInteger('p', 1); - new PrettyPaginatedResult(PGMTranslations.get().t("command.map.rotationList.title", sender)) { - @Override public String format(String rotationName, int index) { - int activation = Config.getConfiguration().getInt("rotation.providers.file." + rotationName + ".count"); - boolean current = rotationName.equalsIgnoreCase(PGM.getMatchManager().getRotationManager().getCurrentRotationName()); - - return (current ? ChatColor.GOLD + "\u0187 " : "") + (index % 2 == 0 ? ChatColor.AQUA : ChatColor.DARK_AQUA) + rotationName + (activation > 0 ? ChatColor.GRAY + " " + PGMTranslations.get().t("command.map.rotationList.activatesWith", sender, ChatColor.RED + "" + activation + ChatColor.GRAY) : ""); + new PrettyPaginatedResult(PGMTranslations.get().t("command.map.rotationList.title", sender)) { + @Override public String format(RotationProviderInfo rotationInfo, int index) { + boolean current = manager.getCurrentRotationName().equals(rotationInfo.name); + int count = rotationInfo.count; + return (current ? ChatColor.GOLD : ChatColor.GRAY) + " \u25ba " + + (index % 2 == 0 ? ChatColor.AQUA : ChatColor.DARK_AQUA) + rotationInfo.name + + (count > 0 ? ChatColor.GRAY + " " + + PGMTranslations.get().t("command.map.rotationList.activatesWith", sender, + ChatColor.RED + "" + count + ChatColor.GRAY) : ""); } - }.display(new BukkitWrappedCommandSender(sender), Lists.newArrayList(rotations.keySet()), page); + }.display(new BukkitWrappedCommandSender(sender), rotations, page); } @Command( diff --git a/PGM/src/main/java/tc/oc/pgm/map/MapModuleContext.java b/PGM/src/main/java/tc/oc/pgm/map/MapModuleContext.java index d7602f4..4f75133 100644 --- a/PGM/src/main/java/tc/oc/pgm/map/MapModuleContext.java +++ b/PGM/src/main/java/tc/oc/pgm/map/MapModuleContext.java @@ -133,8 +133,6 @@ public class MapModuleContext extends ModuleContext { public Integer playerLimitAverage() { Range lims = playerLimits(); - int sum = lims.lowerEndpoint() + lims.upperEndpoint(); - - return ((Double) Math.floor(sum/2)).intValue(); + return (lims.lowerEndpoint() + lims.upperEndpoint()) / 2; } } diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationChangeListener.java b/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationChangeListener.java deleted file mode 100644 index 841763f..0000000 --- a/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationChangeListener.java +++ /dev/null @@ -1,68 +0,0 @@ -package tc.oc.pgm.rotation; - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.chat.TranslatableComponent; -import org.bukkit.configuration.Configuration; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import tc.oc.commons.bukkit.chat.HeaderComponent; -import tc.oc.commons.core.chat.Component; -import tc.oc.pgm.Config; -import tc.oc.pgm.PGM; -import tc.oc.pgm.cycle.CycleMatchModule; -import tc.oc.pgm.events.MatchEndEvent; -import tc.oc.pgm.match.Match; - -public class DynamicRotationChangeListener implements Listener { - - - @EventHandler - public void onMatchEnd(MatchEndEvent event) { - RotationManager rotationManager = PGM.getMatchManager().getRotationManager(); - - // Ignore if dynamic rotations are disabled or if there is only one rotation available - if (!Config.getConfiguration().getBoolean("rotation.dynamic") || rotationManager.getRotations().size() == 1) return; - - // Number of players we can assume is active - int playersOnline = event.getMatch().getServer().getOnlinePlayers().size(); - - // Get appropriate rotation - RotationCategory appr = getAppropriateRotationCategory(playersOnline, rotationManager); - - if (appr != null && !rotationManager.getCurrentRotationName().equals(appr.toString().toLowerCase())) { - rotationManager.setRotation(appr.toString().toLowerCase(), rotationManager.getRotation(appr.toString().toLowerCase())); - rotationManager.setCurrentRotationName(appr.toString().toLowerCase()); - CycleMatchModule cmm = event.getMatch().needMatchModule(CycleMatchModule.class); - cmm.startCountdown(cmm.getConfig().countdown()); - - PGM.get().getLogger().info("[Dynamic Rotations] Changing to \"" + appr.toString().toLowerCase() + "\" rotation..."); - sendRotationChangeMessage(event.getMatch()); - } - } - - /** - * Returns appropriate rotation looking at how many players (participating) are online. - * - * @param players Current participant player count. - * @param rotationManager The {@link RotationManager} - * @return any of {@link RotationCategory} - */ - private RotationCategory getAppropriateRotationCategory(int players, RotationManager rotationManager) { - Configuration config = Config.getConfiguration(); - int medium = config.getInt("rotation.providers.file.medium.count"); - int mega = config.getInt("rotation.providers.file.mega.count"); - - if (players > medium && players <= mega && rotationManager.getRotation("medium") != null) return RotationCategory.MEDIUM; - if (players > mega && rotationManager.getRotation("mega") != null) return RotationCategory.MEGA; - - return RotationCategory.MINI; - } - - private void sendRotationChangeMessage(Match match) { - match.sendMessage(new HeaderComponent(ChatColor.RED)); - match.sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.title"), ChatColor.GOLD)); - match.sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.info"), ChatColor.YELLOW)); - match.sendMessage(new HeaderComponent(ChatColor.RED)); - } -} diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationListener.java b/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationListener.java new file mode 100644 index 0000000..ae76f8b --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/rotation/DynamicRotationListener.java @@ -0,0 +1,73 @@ +package tc.oc.pgm.rotation; + +import com.google.inject.Inject; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TranslatableComponent; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import tc.oc.api.bukkit.users.OnlinePlayers; +import tc.oc.commons.bukkit.chat.Audiences; +import tc.oc.commons.bukkit.chat.HeaderComponent; +import tc.oc.commons.core.chat.Audience; +import tc.oc.commons.core.chat.Component; +import tc.oc.commons.core.logging.Loggers; +import tc.oc.commons.core.plugin.PluginFacet; +import tc.oc.pgm.PGM; +import tc.oc.pgm.events.MatchEndEvent; + +import java.util.logging.Logger; + +public class DynamicRotationListener implements PluginFacet, Listener { + + private final Logger logger; + private final Audiences audiences; + private final OnlinePlayers players; + private final ConfigurationSection config; + + @Inject DynamicRotationListener(Loggers loggers, Audiences audiences, OnlinePlayers players, Configuration config) { + this.logger = loggers.get(getClass()); + this.audiences = audiences; + this.players = players; + this.config = config.getConfigurationSection("rotation"); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onMatchEnd(MatchEndEvent event) { + RotationManager rotationManager = PGM.getMatchManager().getRotationManager(); + + // Ignore if dynamic rotations are disabled or if there is only one rotation available + if (!config.getBoolean("dynamic", false) || rotationManager.getRotations().size() <= 1) return; + + int playerCount = players.count(); + + // Get appropriate rotation + RotationProviderInfo rotation = rotationManager.getProviders().stream() + .filter(info -> playerCount >= info.count).findFirst().orElse(null); + + if (rotation == null) { + logger.warning("No valid rotation was found to accommodate " + playerCount + " players. Missing fallback?"); + } else { + RotationState rotState = rotation.provider.getRotation(rotation.name); + + if (rotState == null) { + logger.warning("'" + rotation.name + "' rotation provider doesn't have a rotation with it's own name"); + } else if (!rotationManager.getCurrentRotationName().equals(rotation.name)) { + rotationManager.setRotation(rotation.name, rotState); + rotationManager.setCurrentRotationName(rotation.name); + + logger.info("Changing to \"" + rotation.name + "\" rotation..."); + sendRotationChangeMessage(audiences.localServer()); + } + } + } + + private void sendRotationChangeMessage(Audience audience) { + audience.sendMessage(new HeaderComponent(ChatColor.RED)); + audience.sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.title"), ChatColor.GOLD)); + audience.sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.info"), ChatColor.YELLOW)); + audience.sendMessage(new HeaderComponent(ChatColor.RED)); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/RotationCategory.java b/PGM/src/main/java/tc/oc/pgm/rotation/RotationCategory.java deleted file mode 100644 index 3168b1b..0000000 --- a/PGM/src/main/java/tc/oc/pgm/rotation/RotationCategory.java +++ /dev/null @@ -1,5 +0,0 @@ -package tc.oc.pgm.rotation; - -public enum RotationCategory { - MINI, MEDIUM, MEGA -} diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/RotationManager.java b/PGM/src/main/java/tc/oc/pgm/rotation/RotationManager.java index 284080f..1ed6ec6 100644 --- a/PGM/src/main/java/tc/oc/pgm/rotation/RotationManager.java +++ b/PGM/src/main/java/tc/oc/pgm/rotation/RotationManager.java @@ -115,6 +115,10 @@ public class RotationManager { } return null; } + + public @Nonnull List getProviders() { + return ImmutableList.copyOf(this.providers); + } public void addProvider(@Nonnull RotationProvider provider, @Nonnull String name, int priority, int count) { Preconditions.checkNotNull(provider, "rotation provider"); diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/RotationProviderInfo.java b/PGM/src/main/java/tc/oc/pgm/rotation/RotationProviderInfo.java index 8983eb8..c9333f2 100644 --- a/PGM/src/main/java/tc/oc/pgm/rotation/RotationProviderInfo.java +++ b/PGM/src/main/java/tc/oc/pgm/rotation/RotationProviderInfo.java @@ -29,4 +29,15 @@ public class RotationProviderInfo implements Comparable { } return c; } + + @Override + public String toString() { + return "RotationProviderInfo{" + + "provider=" + provider.getRotations() + + ", priority=" + priority + + ", count=" + count + + ", name='" + name + '\'' + + '}'; + } + } diff --git a/PGM/src/main/java/tc/oc/pgm/rotation/RotationState.java b/PGM/src/main/java/tc/oc/pgm/rotation/RotationState.java index 8e8c315..cbea67d 100644 --- a/PGM/src/main/java/tc/oc/pgm/rotation/RotationState.java +++ b/PGM/src/main/java/tc/oc/pgm/rotation/RotationState.java @@ -5,6 +5,7 @@ import java.util.List; import javax.annotation.Nonnull; +import tc.oc.commons.core.util.Lazy; import tc.oc.pgm.map.PGMMap; import com.google.common.base.Preconditions; @@ -40,18 +41,16 @@ public final class RotationState { return this.maps; } + + private Lazy averageNeededPlayers = Lazy.from(() -> + (int) getMaps().stream().mapToInt(map -> map.getContext().playerLimitAverage()).average().orElse(0)); + /** * Gets the approximate number of players supposed to be playing the rotation maps. * @return Integer with average size of teams over all maps */ public @Nonnull Integer getAverageNeededPlayers() { - List players = new ArrayList<>(); - int total = 0; - - getMaps().stream().forEach(m -> players.add(m.getContext().playerLimitAverage())); - for (int pl : players) { total += pl; } - - return ((Double) Math.floor(total / players.size())).intValue(); + return averageNeededPlayers.get(); } /** diff --git a/PGM/src/main/resources/config.yml b/PGM/src/main/resources/config.yml index 21727da..57dafbe 100644 --- a/PGM/src/main/resources/config.yml +++ b/PGM/src/main/resources/config.yml @@ -79,6 +79,7 @@ environment: ranked: false rotation: + dynamic: false default-name: default initial-wait: 20000 providers: {}