Merge pull request #5 from Pablete1234/dynamic-rot
Fix dynamic rotations, make use of guice
This commit is contained in:
commit
c84a9530ab
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<String, RotationState> rotations = manager.getRotations();
|
||||
List<RotationProviderInfo> rotations = manager.getProviders();
|
||||
int page = args.getFlagInteger('p', 1);
|
||||
|
||||
new PrettyPaginatedResult<String>(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<RotationProviderInfo>(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(
|
||||
|
|
|
@ -133,8 +133,6 @@ public class MapModuleContext extends ModuleContext<MapModule, MapScoped> {
|
|||
|
||||
public Integer playerLimitAverage() {
|
||||
Range<Integer> lims = playerLimits();
|
||||
int sum = lims.lowerEndpoint() + lims.upperEndpoint();
|
||||
|
||||
return ((Double) Math.floor(sum/2)).intValue();
|
||||
return (lims.lowerEndpoint() + lims.upperEndpoint()) / 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package tc.oc.pgm.rotation;
|
||||
|
||||
public enum RotationCategory {
|
||||
MINI, MEDIUM, MEGA
|
||||
}
|
|
@ -115,6 +115,10 @@ public class RotationManager {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nonnull List<RotationProviderInfo> getProviders() {
|
||||
return ImmutableList.copyOf(this.providers);
|
||||
}
|
||||
|
||||
public void addProvider(@Nonnull RotationProvider provider, @Nonnull String name, int priority, int count) {
|
||||
Preconditions.checkNotNull(provider, "rotation provider");
|
||||
|
|
|
@ -29,4 +29,15 @@ public class RotationProviderInfo implements Comparable<RotationProviderInfo> {
|
|||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RotationProviderInfo{" +
|
||||
"provider=" + provider.getRotations() +
|
||||
", priority=" + priority +
|
||||
", count=" + count +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Integer> 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<Integer> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,6 +79,7 @@ environment:
|
|||
ranked: false
|
||||
|
||||
rotation:
|
||||
dynamic: false
|
||||
default-name: default
|
||||
initial-wait: 20000
|
||||
providers: {}
|
||||
|
|
Loading…
Reference in New Issue