diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/punishment/PunishmentFormatter.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/punishment/PunishmentFormatter.java index 2d3ccd325..e0d45066f 100644 --- a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/punishment/PunishmentFormatter.java +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/punishment/PunishmentFormatter.java @@ -101,10 +101,13 @@ public BaseComponent screen(Punishment punishment) { parts.addAll(Components.repeat(Components::blank, 3)); - parts.add(new Component(new TranslatableComponent("punishment.screen.rules", Links.rulesLink()))); - - parts.add(new Component(new TranslatableComponent("punishment.screen.appeal", Links.appealLink()))); + if (!punishment.off_record()) { + parts.add(new Component(new TranslatableComponent("punishment.screen.rules", Links.rulesLink()))); + parts.add(new Component(new TranslatableComponent("punishment.screen.appeal", Links.appealLink()))); + } else { + parts.add(new Component(new TranslatableComponent("punishment.screen.off_record"))); + } return Components.join(Components.newline(), parts); } diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/tokens/TokenUtil.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/tokens/TokenUtil.java index e1b81c554..080750d52 100644 --- a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/tokens/TokenUtil.java +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/tokens/TokenUtil.java @@ -1,10 +1,13 @@ package tc.oc.commons.bukkit.tokens; +import com.sk89q.minecraft.util.commands.CommandException; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import tc.oc.api.bukkit.users.BukkitUserStore; import tc.oc.api.docs.PlayerId; import tc.oc.api.users.CreditTokensRequest; import tc.oc.api.users.UserService; +import tc.oc.commons.bukkit.commands.CommandUtils; import tc.oc.commons.bukkit.util.SyncPlayerExecutorFactory; import tc.oc.api.docs.User; @@ -23,6 +26,10 @@ public static User getUser(Player player) { return userStore.getUser(player); } + public static User getUser(CommandSender sender) throws CommandException { + return getUser(CommandUtils.senderToPlayer(sender)); + } + public static void giveMapTokens(PlayerId playerId, int count) { playerExecutorFactory.queued(playerId).callback( userService.creditTokens(playerId, CreditTokensRequest.maps(count)), diff --git a/Commons/core/src/main/i18n/templates/commons/Commons.properties b/Commons/core/src/main/i18n/templates/commons/Commons.properties index 30f03d1f1..ceb2480a3 100644 --- a/Commons/core/src/main/i18n/templates/commons/Commons.properties +++ b/Commons/core/src/main/i18n/templates/commons/Commons.properties @@ -254,6 +254,7 @@ punishment.screen.SUSPENSION = You were suspended by a staff member {0} punishment.screen.UNKNOWN = You were issued an unknown punishment by a staff member {0} punishment.screen.rules = Read our server rules at {0} punishment.screen.appeal = or contest your punishment at {0} +punishment.screen.off_record = This is not a real punishment punishment.action.WARN = warned punishment.action.KICK = kicked punishment.action.BAN = banned diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMErrors.properties b/Commons/core/src/main/i18n/templates/pgm/PGMErrors.properties index b906a0ee4..e55645828 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMErrors.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMErrors.properties @@ -135,4 +135,14 @@ rating.lowParticipation = Sorry, you haven't participated in this match enough t rating.whilePlaying = To rate the map while playing, type {0} rating.sameRating = You have already rated this map a {0}. -huddle.globalChatDisabled = Global chat is disabled during team huddle \ No newline at end of file +huddle.globalChatDisabled = Global chat is disabled during team huddle + +poll.vote.invalidValue = Accepted values: yes|no +poll.noPollRunning = There is currently no poll running! +poll.kick.exempt = You cannot poll kick this player! +poll.disabled = Polls are disabled on this server! +poll.map.alreadyset = A map has already been set! +poll.map.restarting = You cannot set a map because a restart is queued! +poll.map.notallowed = You are not allowed to set that map! +poll.map.toomanyplayers = There are too many players online to set that map! +poll.already.running = Another poll is already running! diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMMessages.properties b/Commons/core/src/main/i18n/templates/pgm/PGMMessages.properties index cb00de6b9..3afbfd89c 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMMessages.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMMessages.properties @@ -281,12 +281,12 @@ item.locked = This item cannot be removed from its slot stats.hotbar = {0} kills ({1} streak) {2} deaths {3} K/D -poll.disabled = Polls are disabled on this server! -poll.map.alreadyset = A map has already been set! -poll.map.restarting = You cannot set a map because a restart is queued! -poll.map.notallowed = You are not allowed to set that map! -poll.map.toomanyplayers = There are too many players online to set that map! +poll.vote.for = You have voted for the current poll +poll.vote.against = You have voted against the current poll poll.tutorialmessage = Use {0}/vote [yes|no] {1}to vote +poll.kick.success = {0} has been kicked! +poll.veto = Poll vetoed by {0} + announce.online = Announced server as online announce.offline = Announced server as offline diff --git a/PGM/src/main/java/tc/oc/pgm/Config.java b/PGM/src/main/java/tc/oc/pgm/Config.java index 8ab32e542..51f4368ab 100644 --- a/PGM/src/main/java/tc/oc/pgm/Config.java +++ b/PGM/src/main/java/tc/oc/pgm/Config.java @@ -59,18 +59,6 @@ public static double setNextTokenChange() { } - public static class Poll { - public static Path getPollAbleMapPath() { - Path pollPath = Paths.get(getConfiguration().getString("poll.maps.path", "default.txt")); - if(!pollPath.isAbsolute()) pollPath = PGM.getMatchManager().getPluginDataFolder().resolve(pollPath); - return pollPath; - } - - public static boolean enabled() { - return getConfiguration().getBoolean("poll.enabled", true); - } - } - public static class Broadcast { public static boolean title() { return getConfiguration().getBoolean("broadcast.title", true); diff --git a/PGM/src/main/java/tc/oc/pgm/PGM.java b/PGM/src/main/java/tc/oc/pgm/PGM.java index 9f1afcd60..5f0100cde 100644 --- a/PGM/src/main/java/tc/oc/pgm/PGM.java +++ b/PGM/src/main/java/tc/oc/pgm/PGM.java @@ -11,6 +11,7 @@ import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; import tc.oc.api.util.Permissions; +import tc.oc.commons.bukkit.channels.ChannelCommands; import tc.oc.commons.bukkit.inject.BukkitPluginManifest; import tc.oc.commons.bukkit.inventory.Slot; import tc.oc.commons.bukkit.logging.MapdevLogger; @@ -20,7 +21,6 @@ import tc.oc.minecraft.logging.BetterRaven; import tc.oc.pgm.antigrief.CraftingProtect; import tc.oc.pgm.commands.MapCommands; -import tc.oc.pgm.commands.PollCommands; import tc.oc.pgm.commands.RotationControlCommands; import tc.oc.pgm.commands.RotationEditCommands; import tc.oc.pgm.events.ConfigLoadEvent; @@ -38,9 +38,8 @@ import tc.oc.pgm.match.MatchManager; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.menu.gui.SettingMenuHelper; -import tc.oc.pgm.pollablemaps.PollableMaps; -import tc.oc.pgm.polls.PollListener; -import tc.oc.pgm.polls.PollManager; +import tc.oc.pgm.polls.PollBlacklist; +import tc.oc.pgm.polls.commands.PollCommands; import tc.oc.pgm.start.StartCommands; import tc.oc.pgm.tablist.MatchTabManager; import tc.oc.pgm.timelimit.TimeLimitCommands; @@ -88,18 +87,6 @@ public Logger getRootMapLogger() { return mapdevLogger; } - private PollManager pollManager; - - public static PollManager getPollManager() { - return pgm == null ? null : pgm.pollManager; - } - - private PollableMaps pollableMaps; - - public static PollableMaps getPollableMaps() { - return pgm == null ? null : pgm.pollableMaps; - } - public MapLibrary getMapLibrary() { return mapLibrary; } @@ -136,9 +123,6 @@ public void onEnable() { return; } - this.pollManager = new PollManager(this); - this.pollableMaps = new PollableMaps(); - this.registerListeners(); // cycle match in 0 ticks so it loads after other plugins are done @@ -194,6 +178,7 @@ public void reloadConfig() { private void setupCommands() { commands.register(MapCommands.class); + commands.register(ChannelCommands.class); commands.register(PollCommands.class); commands.register(RotationEditCommands.RotationEditParent.class); commands.register(RotationControlCommands.RotationControlParent.class); @@ -205,7 +190,6 @@ private void setupCommands() { } private void registerListeners() { - this.registerEvents(new PollListener(this.pollManager, this.matchManager)); this.registerEvents(new FormattingListener()); this.registerEvents(new CraftingProtect()); this.registerEvents(new ObjectivesFireworkListener()); diff --git a/PGM/src/main/java/tc/oc/pgm/PGMManifest.java b/PGM/src/main/java/tc/oc/pgm/PGMManifest.java index beeb6b43d..4bd8227ee 100644 --- a/PGM/src/main/java/tc/oc/pgm/PGMManifest.java +++ b/PGM/src/main/java/tc/oc/pgm/PGMManifest.java @@ -12,7 +12,6 @@ import tc.oc.pgm.chat.MatchUsernameRenderer; import tc.oc.pgm.commands.AdminCommands; import tc.oc.pgm.commands.MatchCommands; -import tc.oc.pgm.commands.PollCommands; import tc.oc.pgm.debug.PGMLeakListener; import tc.oc.pgm.development.MapDevelopmentCommands; import tc.oc.pgm.development.MapErrorTracker; @@ -35,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.polls.PollManifest; import tc.oc.pgm.restart.RestartListener; import tc.oc.pgm.rotation.DynamicRotationListener; import tc.oc.pgm.settings.Settings; @@ -63,6 +63,7 @@ protected void configure() { install(new MatchAnalyticsManifest()); install(new ListingManifest()); + install(new PollManifest()); bind(MatchManager.class); bind(MatchLoader.class); @@ -82,7 +83,6 @@ protected void configure() { final PluginFacetBinder facets = new PluginFacetBinder(binder()); facets.register(AdminCommands.class); - facets.register(PollCommands.class); facets.register(MatchNameInvalidator.class); facets.register(MapDevelopmentCommands.class); facets.register(MapErrorTracker.class); @@ -104,7 +104,6 @@ protected void configure() { facets.register(InterfaceListener.class); requestStaticInjection(State.class); - requestStaticInjection(PollCommands.class); requestStaticInjection(MatchFooterTabEntry.class); } } diff --git a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java b/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java deleted file mode 100644 index f6266c2b6..000000000 --- a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java +++ /dev/null @@ -1,237 +0,0 @@ -package tc.oc.pgm.commands; - -import com.google.common.collect.Sets; -import com.sk89q.minecraft.util.commands.Command; -import com.sk89q.minecraft.util.commands.CommandContext; -import com.sk89q.minecraft.util.commands.CommandException; -import com.sk89q.minecraft.util.commands.CommandPermissions; -import com.sk89q.minecraft.util.commands.NestedCommand; -import net.md_5.bungee.api.chat.TranslatableComponent; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import tc.oc.commons.bukkit.tokens.TokenUtil; -import tc.oc.commons.core.commands.Commands; -import tc.oc.commons.core.formatting.StringUtils; -import tc.oc.commons.core.restart.RestartManager; -import tc.oc.parse.ParseException; -import tc.oc.parse.primitive.BooleanParser; -import tc.oc.pgm.Config; -import tc.oc.pgm.PGM; -import tc.oc.pgm.map.PGMMap; -import tc.oc.pgm.mutation.Mutation; -import tc.oc.pgm.mutation.MutationMatchModule; -import tc.oc.pgm.mutation.command.MutationCommands; -import tc.oc.pgm.polls.Poll; -import tc.oc.pgm.polls.PollCustom; -import tc.oc.pgm.polls.PollEndReason; -import tc.oc.pgm.polls.PollKick; -import tc.oc.pgm.polls.PollManager; -import tc.oc.pgm.polls.PollMutation; -import tc.oc.pgm.polls.PollNextMap; - -import javax.inject.Inject; - -import java.util.List; - -import static tc.oc.commons.bukkit.commands.CommandUtils.newCommandException; - -public class PollCommands implements Commands { - - private static final String VOTE_FOR = ChatColor.GREEN + "in favor of"; - private static final String VOTE_AGAINST = ChatColor.RED + "against"; - - @Inject - private static RestartManager restartManager; - @Inject - private static BooleanParser booleanParser; - - @Command( - aliases = {"poll"}, - desc = "Poll commands", - min = 1, - max = -1 - ) - @NestedCommand({PollSubCommands.class}) - public static void pollCommand() { - } - - @Command( - aliases = {"vote"}, - desc = "Vote in a running poll.", - usage = "[yes|no]", - min = 1, - max = 1 - ) - @CommandPermissions("poll.vote") - public static void vote(CommandContext args, CommandSender sender) throws CommandException { - Player voter = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); - Poll currentPoll = PGM.getPollManager().getPoll(); - if(currentPoll != null) { - boolean vote; - try { - vote = booleanParser.parse(args.getString(0)); - } catch (ParseException e) { - throw new CommandException("Please vote yes or no!"); - } - currentPoll.vote(vote, voter.getName()); - sender.sendMessage(ChatColor.AQUA + "You voted " + (vote ? VOTE_FOR : VOTE_AGAINST) + ChatColor.AQUA + " the current poll."); - } else { - throw new CommandException("There is currently no poll running."); - } - } - - @Command( - aliases = {"veto"}, - desc = "Veto the current poll.", - min = 0, - max = 0 - ) - @CommandPermissions("poll.veto") - public static void veto(CommandContext args, CommandSender sender) throws CommandException { - PollManager pollManager = PGM.getPollManager(); - if(pollManager.isPollRunning()) { - pollManager.endPoll(PollEndReason.Cancelled); - Bukkit.getServer().broadcastMessage(ChatColor.RED + "Poll vetoed by " + sender.getName()); - } else { - throw new CommandException("There is currently no poll running."); - } - } - - public static Poll getCurrentPoll() throws CommandException { - Poll poll = PGM.getPollManager().getPoll(); - if(poll == null) { - throw new CommandException("There is currently no poll running."); - } - return poll; - } - - public static class PollSubCommands { - @Command( - aliases = {"kick"}, - desc = "Start a poll to kick another player.", - usage = "[player]", - min = 1, - max = 1 - ) - @CommandPermissions("poll.kick") - public static void pollKick(CommandContext args, CommandSender sender) throws CommandException { - Player initiator = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); - Player player = tc.oc.commons.bukkit.commands.CommandUtils.findOnlinePlayer(args, sender, 0); - - if(player.hasPermission("pgm.poll.kick.exempt") && !initiator.hasPermission("pgm.poll.kick.override")) { - throw new CommandException(player.getName() + " may not be poll kicked."); - } else { - startPoll(new PollKick(PGM.getPollManager(), Bukkit.getServer(), initiator.getName(), player.getName())); - } - } - - @Command( - aliases = {"next"}, - desc = "Start a poll to change the next map.", - usage = "[map name]", - min = 1, - max = -1 - ) - @CommandPermissions("poll.next") - public static List pollNext(CommandContext args, CommandSender sender) throws CommandException { - final String mapName = args.argsLength() > 0 ? args.getJoinedStrings(0) : ""; - if(args.getSuggestionContext() != null) { - return CommandUtils.completeMapName(mapName); - } - - if (!Config.Poll.enabled()) { - throw newCommandException(sender, new TranslatableComponent("poll.disabled")); - } - - if (restartManager.isRestartRequested()) { - throw newCommandException(sender, new TranslatableComponent("poll.map.restarting")); - } - if (PGM.getMatchManager().hasMapSet()) { - throw newCommandException(sender, new TranslatableComponent("poll.map.alreadyset")); - } - if (sender instanceof Player) { - Player player = (Player) sender; - if (TokenUtil.getUser(player).maptokens() < 1) { - throw newCommandException(sender, new TranslatableComponent("tokens.map.fail")); - } - } - - Player initiator = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); - - PGMMap nextMap = CommandUtils.getMap(args.getJoinedStrings(0), sender); - - if (!PGM.getPollableMaps().isAllowed(nextMap) && !sender.hasPermission("poll.next.override")) { - throw newCommandException(sender, new TranslatableComponent("poll.map.notallowed")); - } - - if (PGM.get().getServer().getOnlinePlayers().size() * 4 / 5 > nextMap.getDocument().max_players() && !sender.hasPermission("poll.next.override")) { - throw newCommandException(sender, new TranslatableComponent("poll.map.toomanyplayers")); - } - - startPoll(new PollNextMap(PGM.getPollManager(), Bukkit.getServer(), sender, initiator.getName(), PGM.getMatchManager(), nextMap)); - return null; - } - - @Command( - aliases = {"mutation", "mt"}, - desc = "Start a poll to set a mutation", - usage = "[mutation name]", - min = 1, - max = -1 - ) - @CommandPermissions("poll.mutation") - public static void pollMutation(CommandContext args, CommandSender sender) throws CommandException { - - if (!Config.Poll.enabled()) { - throw newCommandException(sender, new TranslatableComponent("poll.disabled")); - } - - if (sender instanceof Player) { - Player player = (Player) sender; - if (TokenUtil.getUser(player).mutationtokens() < 1) { - throw newCommandException(sender, new TranslatableComponent("tokens.mutation.fail")); - } - } - - String mutationString = args.getString(0); - MutationMatchModule module = PGM.getMatchManager().getCurrentMatch(sender).getMatchModule(MutationMatchModule.class); - - Mutation mutation = StringUtils.bestFuzzyMatch(mutationString, Sets.newHashSet(Mutation.values()), 0.9); - if(mutation == null) { - throw newCommandException(sender, new TranslatableComponent("command.mutation.error.find", mutationString)); - } else if(MutationCommands.getInstance().getMutationQueue().mutations().contains(mutation)) { - throw newCommandException(sender, new TranslatableComponent(true ? "command.mutation.error.enabled" : "command.mutation.error.disabled", mutation.getComponent(net.md_5.bungee.api.ChatColor.RED))); - } else if (!mutation.isPollable() && !sender.hasPermission("poll.mutation.override")) { - throw newCommandException(sender, new TranslatableComponent("command.mutation.error.illegal", mutationString)); - } - - startPoll(new PollMutation(PGM.getPollManager(), Bukkit.getServer(), sender, mutation, module)); - } - - @Command( - aliases = {"custom"}, - desc = "Start a poll with the supplied text", - usage = "[text...]", - min = 1, - max = -1 - ) - @CommandPermissions("poll.custom") - public static void pollCustom(CommandContext args, CommandSender sender) throws CommandException { - String text = args.getJoinedStrings(0); - Player initiator = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); - - startPoll(new PollCustom(PGM.getPollManager(), Bukkit.getServer(), initiator.getName(), text)); - } - - public static void startPoll(Poll poll) throws CommandException { - PollManager pollManager = PGM.getPollManager(); - if(pollManager.isPollRunning()) { - throw new CommandException("Another poll is already running."); - } - pollManager.startPoll(poll); - Bukkit.getServer().broadcastMessage(Poll.boldAqua + poll.getInitiator() + Poll.normalize + " has started a poll " + poll.getDescriptionMessage()); - } - } -} diff --git a/PGM/src/main/java/tc/oc/pgm/match/MatchManager.java b/PGM/src/main/java/tc/oc/pgm/match/MatchManager.java index ff95d2f35..f8054f79b 100644 --- a/PGM/src/main/java/tc/oc/pgm/match/MatchManager.java +++ b/PGM/src/main/java/tc/oc/pgm/match/MatchManager.java @@ -23,13 +23,13 @@ import tc.oc.api.minecraft.MinecraftService; import tc.oc.api.util.Permissions; import tc.oc.commons.core.logging.Loggers; -import tc.oc.pgm.PGM; import tc.oc.pgm.development.MapErrorTracker; import tc.oc.pgm.events.SetNextMapEvent; import tc.oc.pgm.map.MapLibrary; import tc.oc.pgm.map.MapLoader; import tc.oc.pgm.map.MapNotFoundException; import tc.oc.pgm.map.PGMMap; +import tc.oc.pgm.polls.PollBlacklist; import tc.oc.pgm.rotation.FileRotationProviderFactory; import tc.oc.pgm.rotation.RotationManager; import tc.oc.pgm.rotation.RotationState; @@ -50,6 +50,7 @@ public class MatchManager implements MatchFinder { private final EventBus eventBus; private final MatchLoader matchLoader; private final MinecraftService minecraftService; + private final PollBlacklist pollBlacklist; private @Nullable RotationManager rotationManager; /** Custom set next map. */ @@ -67,7 +68,8 @@ public class MatchManager implements MatchFinder { FileRotationProviderFactory fileRotationProviderFactory, EventBus eventBus, MatchLoader matchLoader, - MinecraftService minecraftService) throws MapNotFoundException { + MinecraftService minecraftService, + PollBlacklist pollBlacklist) throws MapNotFoundException { this.pluginDataFolder = pluginDataFolder; this.mapErrorTracker = mapErrorTracker; @@ -79,6 +81,7 @@ public class MatchManager implements MatchFinder { this.eventBus = eventBus; this.matchLoader = matchLoader; this.minecraftService = minecraftService; + this.pollBlacklist = pollBlacklist; } @Override @@ -118,7 +121,7 @@ public boolean loadRotations() { public Set loadMapsAndRotations() throws MapNotFoundException { Set maps = loadNewMaps(); loadRotations(); - PGM.getPollableMaps().loadPollableMaps(); + pollBlacklist.loadPollBlacklist(); return maps; } diff --git a/PGM/src/main/java/tc/oc/pgm/mutation/MutationQueue.java b/PGM/src/main/java/tc/oc/pgm/mutation/MutationQueue.java index 295702b22..ec7c4c196 100644 --- a/PGM/src/main/java/tc/oc/pgm/mutation/MutationQueue.java +++ b/PGM/src/main/java/tc/oc/pgm/mutation/MutationQueue.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.ListenableFuture; import tc.oc.api.docs.Server; import tc.oc.api.docs.virtual.ServerDoc; @@ -31,6 +32,12 @@ public Collection mutations() { .collect(Collectors.toList()); } + public Collection mutationsAvailable() { + Collection availableMutations = Sets.newHashSet(Mutation.values()); + availableMutations.removeAll(mutations()); + return availableMutations; + } + public ListenableFuture clear() { return force(Collections.emptyList()); } diff --git a/PGM/src/main/java/tc/oc/pgm/pollablemaps/PollableMaps.java b/PGM/src/main/java/tc/oc/pgm/pollablemaps/PollableMaps.java deleted file mode 100644 index 77242d5d9..000000000 --- a/PGM/src/main/java/tc/oc/pgm/pollablemaps/PollableMaps.java +++ /dev/null @@ -1,60 +0,0 @@ -package tc.oc.pgm.pollablemaps; - -import com.google.common.base.Charsets; -import com.google.common.collect.ImmutableList; -import tc.oc.pgm.Config; -import tc.oc.pgm.PGM; -import tc.oc.pgm.map.PGMMap; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -public class PollableMaps { - - private List maps; - - public PollableMaps() { - maps = new ArrayList(); - loadPollableMaps(); - } - - public List getMaps() { - return maps; - } - - public void loadPollableMaps() { - Path filepath = Config.Poll.getPollAbleMapPath(); - if (filepath == null) return; - List lines = null; - try { - lines = Files.readAllLines(filepath, Charsets.UTF_8); - } catch (IOException e) { - PGM.get().getLogger().severe("Error in reading pollable maps from file!"); - } - if (lines == null) return; - ImmutableList.Builder maps = ImmutableList.builder(); - for(String line : lines) { - line = line.trim(); - if(line.isEmpty()) { - continue; - } - - Optional map = PGM.get().getMapLibrary().getMapByNameOrId(line); - if(map.isPresent()) { - maps.add(map.get()); - } else { - PGM.get().getMapLibrary().getLogger().severe("Unknown map '" + line - + "' when parsing " + filepath.toString()); - } - } - this.maps = maps.build(); - } - - public boolean isAllowed(PGMMap map) { - return !maps.contains(map); - } -} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/Poll.java b/PGM/src/main/java/tc/oc/pgm/polls/Poll.java index c3d4dbcd8..4f0f8ae35 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/Poll.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/Poll.java @@ -1,37 +1,38 @@ package tc.oc.pgm.polls; +import com.google.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.ChatColor; -import org.bukkit.Server; +import tc.oc.api.docs.PlayerId; +import tc.oc.commons.core.chat.Audiences; import tc.oc.commons.core.chat.Components; -import java.util.HashMap; -import java.util.Map; - public abstract class Poll implements Runnable { - protected final Map votes = new HashMap(); - protected final long startTime = System.currentTimeMillis(); - protected final PollManager pollManager; - protected final Server server; - protected String initiator; - protected int timeLeftSeconds; - public static String boldAqua = ChatColor.BOLD + "" + ChatColor.AQUA; - public static String normalize = ChatColor.RESET + "" + ChatColor.DARK_AQUA; - public static String seperator = ChatColor.RESET + " | "; + public static final String boldAqua = ChatColor.BOLD + "" + ChatColor.AQUA; + public static final String normalize = ChatColor.RESET + "" + ChatColor.DARK_AQUA; + public static final String separator = ChatColor.RESET + " | "; - public Poll(PollManager pollManager, Server server, String initiator) { + protected final PollManager pollManager; + protected final PlayerId initiator; + protected final Audiences audiences; + + @Inject public Poll(PollManager pollManager, PlayerId initiator, Audiences audiences) { this.pollManager = pollManager; - this.server = server; this.initiator = initiator; - this.vote(true, initiator); - timeLeftSeconds = 60; + this.audiences = audiences; + this.voteFor(initiator); } - public String getInitiator() { + protected final Map votes = new HashMap<>(); + protected int timeLeftSeconds = 60; + + public PlayerId getInitiator() { return this.initiator; } @@ -55,9 +56,6 @@ private int getVotes(boolean filterValue) { return total; } - public long getStartTime() { - return this.startTime; - } public int getTimeLeftSeconds() { return timeLeftSeconds; @@ -78,8 +76,8 @@ public boolean isSuccessful() { public abstract String getDescriptionMessage(); public String getStatusMessage() { - String message = boldAqua + "[Poll] " + this.getTimeLeftSeconds() + normalize + " seconds left" + seperator; - message += getActionString() + seperator + formatForAgainst(); + String message = boldAqua + "[Poll] " + this.getTimeLeftSeconds() + normalize + " seconds left" + separator; + message += getActionString() + separator + formatForAgainst(); return message; } @@ -106,12 +104,16 @@ public static BaseComponent tutorialMessage() { ); } - public boolean hasVoted(String playerName) { - return this.votes.containsKey(playerName); + public boolean hasVoted(PlayerId playerId) { + return this.votes.containsKey(playerId); + } + + public void voteFor(PlayerId playerId) { + this.votes.put(playerId, true); } - public void vote(boolean yes, String playerName) { - this.votes.put(playerName, yes); + public void voteAgainst(PlayerId playerId) { + this.votes.put(playerId, false); } @Override @@ -120,8 +122,8 @@ public void run() { if(timeLeftSeconds <= 0) { this.pollManager.endPoll(PollEndReason.Completed); } else if(timeLeftSeconds % 15 == 0 || (timeLeftSeconds < 15 && timeLeftSeconds % 5 == 0)) { - this.server.broadcastMessage(this.getStatusMessage()); - this.server.broadcast(tutorialMessage()); + this.audiences.all().sendMessage(this.getStatusMessage()); + this.audiences.all().sendMessage(tutorialMessage()); } this.decrementTimeLeft(); } diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollBlacklist.java b/PGM/src/main/java/tc/oc/pgm/polls/PollBlacklist.java new file mode 100644 index 000000000..6cbbe98dc --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/PollBlacklist.java @@ -0,0 +1,73 @@ +package tc.oc.pgm.polls; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.logging.Logger; +import tc.oc.commons.core.logging.Loggers; +import tc.oc.commons.core.plugin.PluginFacet; +import tc.oc.pgm.map.MapLibrary; +import tc.oc.pgm.map.PGMMap; + +@Singleton +public class PollBlacklist implements PluginFacet { + + private List blacklistedMaps = new ArrayList<>(); + + private final MapLibrary mapLibrary; + private final PollConfig pollConfig; + private final Logger logger; + + @Inject PollBlacklist(MapLibrary mapLibrary, PollConfig pollConfig, Loggers loggers) { + this.mapLibrary = mapLibrary; + this.pollConfig = pollConfig; + this.logger = loggers.get(getClass()); + } + + @Override + public void enable() { + loadPollBlacklist(); + } + + public void loadPollBlacklist() { + Path filepath = pollConfig.getPollBlacklistPath(); + if (filepath == null) return; + List lines = null; + try { + lines = Files.readAllLines(filepath, Charsets.UTF_8); + } catch (IOException e) { + logger.severe("Error in reading poll blacklist from file!"); + } + if (lines == null) return; + ImmutableList.Builder maps = ImmutableList.builder(); + for(String line : lines) { + if (line.contains("#")) { + line = line.substring(0, line.indexOf("#")); + } + + line = line.trim(); + if(line.isEmpty()) { + continue; + } + + Optional map = mapLibrary.getMapByNameOrId(line); + if(map.isPresent()) { + maps.add(map.get()); + } else { + logger.warning("Unknown map '" + line + "' when parsing " + filepath.toString()); + } + } + this.blacklistedMaps = maps.build(); + } + + public boolean isBlacklisted(PGMMap map) { + return blacklistedMaps.contains(map); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollConfig.java b/PGM/src/main/java/tc/oc/pgm/polls/PollConfig.java new file mode 100644 index 000000000..29ada6fb3 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/PollConfig.java @@ -0,0 +1,33 @@ +package tc.oc.pgm.polls; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.nio.file.Path; +import java.nio.file.Paths; +import javax.inject.Inject; +import org.bukkit.configuration.ConfigurationSection; +import tc.oc.pgm.match.MatchManager; + +public class PollConfig { + + private final ConfigurationSection config; + private final MatchManager matchManager; + + @Inject PollConfig(ConfigurationSection config, MatchManager matchManager) { + this.config = checkNotNull(config.getConfigurationSection("poll")); + this.matchManager = matchManager; + } + + public Path getPollBlacklistPath() { + Path pollPath = Paths.get(config.getString("maps.path", "default.txt")); + if(!pollPath.isAbsolute()) { + pollPath = matchManager.getPluginDataFolder().resolve(pollPath); + } + return pollPath; + } + + public boolean enabled() { + return config.getBoolean("enabled", true); + } + +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollCustom.java b/PGM/src/main/java/tc/oc/pgm/polls/PollCustom.java deleted file mode 100644 index 4b52999f6..000000000 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollCustom.java +++ /dev/null @@ -1,28 +0,0 @@ -package tc.oc.pgm.polls; - -import org.bukkit.Server; - -public class PollCustom extends Poll { - - private String text; - - public PollCustom(PollManager pollManager, Server server, String initiator, String text) { - super(pollManager, server, initiator); - this.text = text; - } - - @Override - public void executeAction() { - //I do nothing - } - - @Override - public String getActionString() { - return boldAqua + text.substring(0, 1).toUpperCase() + text.substring(1); - } - - @Override - public String getDescriptionMessage() { - return boldAqua + text; - } -} \ No newline at end of file diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollKick.java b/PGM/src/main/java/tc/oc/pgm/polls/PollKick.java deleted file mode 100644 index a58d4b9a4..000000000 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollKick.java +++ /dev/null @@ -1,31 +0,0 @@ -package tc.oc.pgm.polls; - -import org.bukkit.ChatColor; -import org.bukkit.Server; -import org.bukkit.entity.Player; - -public class PollKick extends Poll { - private final String player; - - public PollKick(PollManager pollManager, Server server, String initiator, String player) { - super(pollManager, server, initiator); - this.player = player; - } - - @Override - public void executeAction() { - Player player = this.server.getPlayerExact(this.player); - if(player != null) player.kickPlayer(ChatColor.DARK_RED + "You were poll-kicked."); - this.server.broadcastMessage(ChatColor.RED + this.player + ChatColor.YELLOW + " has been kicked."); - } - - @Override - public String getActionString() { - return normalize + "Kick: " + boldAqua + this.player; - } - - @Override - public String getDescriptionMessage() { - return "to kick " + boldAqua + this.player; - } -} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollListener.java b/PGM/src/main/java/tc/oc/pgm/polls/PollListener.java index cbd0e029b..3956d465e 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollListener.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/PollListener.java @@ -1,33 +1,33 @@ package tc.oc.pgm.polls; +import com.google.inject.Inject; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import tc.oc.pgm.match.Match; -import tc.oc.pgm.match.MatchManager; +import tc.oc.commons.core.chat.Audience; +import tc.oc.commons.core.chat.Audiences; +import tc.oc.pgm.polls.event.PollEndEvent; public class PollListener implements Listener { - @SuppressWarnings("unused") - private final PollManager pollManager; - private final MatchManager mm; - public PollListener(PollManager pollManager, MatchManager mm) { - this.pollManager = pollManager; - this.mm = mm; + private final Audiences audiences; + + @Inject PollListener(Audiences audiences) { + this.audiences = audiences; } @EventHandler public void onPollEnd(PollEndEvent event) { if(event.getReason() == PollEndReason.Completed) { - Match match = this.mm.getCurrentMatch(); + Audience audience = audiences.localServer(); if(event.getPoll().isSuccessful()) { - match.sendMessage(Poll.normalize + "The poll " + event.getPoll().getDescriptionMessage() - + Poll.normalize + " has succeeded" + Poll.seperator); - match.sendMessage(event.getPoll().formatForAgainst()); + audience.sendMessage(Poll.normalize + "The poll " + event.getPoll().getDescriptionMessage() + + Poll.normalize + " has succeeded" + Poll.separator); + audience.sendMessage(event.getPoll().formatForAgainst()); event.getPoll().executeAction(); } else { - match.sendMessage(Poll.normalize + "The poll " + event.getPoll().getDescriptionMessage() - + Poll.normalize + " has failed" + Poll.seperator); - match.sendMessage(event.getPoll().formatForAgainst()); + audience.sendMessage(Poll.normalize + "The poll " + event.getPoll().getDescriptionMessage() + + Poll.normalize + " has failed" + Poll.separator); + audience.sendMessage(event.getPoll().formatForAgainst()); } } } diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollManager.java b/PGM/src/main/java/tc/oc/pgm/polls/PollManager.java index 0bd8a0873..64a3a1171 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollManager.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/PollManager.java @@ -1,58 +1,62 @@ package tc.oc.pgm.polls; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; -import org.bukkit.scheduler.BukkitScheduler; - -public class PollManager { - private final Plugin parent; - private final BukkitScheduler scheduler; - private final PluginManager pm; - - private Poll poll = null; - private int pollTaskId = -1; - - public PollManager(Plugin parent) { - this.parent = parent; - this.scheduler = parent.getServer().getScheduler(); - this.pm = parent.getServer().getPluginManager(); +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.sk89q.minecraft.util.commands.CommandException; +import java.time.Duration; +import org.bukkit.Bukkit; +import org.bukkit.event.EventBus; +import tc.oc.commons.core.chat.Audiences; +import tc.oc.commons.core.commands.TranslatableCommandException; +import tc.oc.commons.core.plugin.PluginFacet; +import tc.oc.commons.core.scheduler.Scheduler; +import tc.oc.commons.core.scheduler.Task; +import tc.oc.pgm.polls.event.PollEndEvent; +import tc.oc.pgm.polls.event.PollStartEvent; + +@Singleton +public class PollManager implements PluginFacet { + + private final Scheduler scheduler; + private final EventBus eventBus; + private final Audiences audiences; + + @Inject + PollManager(Scheduler scheduler, EventBus eventBus, Audiences audiences) { + this.scheduler = scheduler; + this.eventBus = eventBus; + this.audiences = audiences; } - /** - * Gets the current poll if there is one running. - * @return Current poll or null. - */ + private Poll currentPoll = null; + private Task task = null; + public Poll getPoll() { - return this.poll; + return currentPoll; } - /** - * Indicates whether or not a poll is currently running. - */ public boolean isPollRunning() { - return this.poll != null; + return this.currentPoll != null; } - /** - * Starts a new poll specified by the poll object. - */ - public void startPoll(Poll poll) { - if(!this.isPollRunning()) { - this.pollTaskId = this.scheduler.scheduleSyncRepeatingTask(this.parent, poll, 0, 5*20); - this.poll = poll; - this.pm.callEvent(new PollStartEvent(poll)); + public void startPoll(Poll poll) throws CommandException { + if(!isPollRunning()) { + task = scheduler.createRepeatingTask(Duration.ZERO, Duration.ofSeconds(5), poll); + currentPoll = poll; + eventBus.callEvent(new PollStartEvent(poll)); + audiences.localServer().sendMessage(Poll.boldAqua + poll.getInitiator().username() + Poll.normalize + " has started a poll " + poll.getDescriptionMessage()); + Bukkit.broadcastMessage(Poll.tutorialMessage()); + } else { + throw new TranslatableCommandException("poll.already.running"); } } - /** - * Ends the poll with a specified reason. - */ public void endPoll(PollEndReason reason) { if(this.isPollRunning()) { - this.pm.callEvent(new PollEndEvent(this.poll, reason)); - this.scheduler.cancelTask(this.pollTaskId); - this.pollTaskId = -1; - this.poll = null; + eventBus.callEvent(new PollEndEvent(this.currentPoll, reason)); + task.cancel(); + task = null; + currentPoll = null; } } } diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollManifest.java b/PGM/src/main/java/tc/oc/pgm/polls/PollManifest.java new file mode 100644 index 000000000..eff39bf9e --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/PollManifest.java @@ -0,0 +1,33 @@ +package tc.oc.pgm.polls; + +import com.google.inject.assistedinject.FactoryModuleBuilder; +import tc.oc.commons.core.commands.CommandBinder; +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.polls.commands.PollCommands; +import tc.oc.pgm.polls.types.PollCustom; +import tc.oc.pgm.polls.types.PollKick; +import tc.oc.pgm.polls.types.PollMutation; +import tc.oc.pgm.polls.types.PollNextMap; + +public class PollManifest extends HybridManifest { + + @Override + protected void configure() { + + final FactoryModuleBuilder fmb = new FactoryModuleBuilder(); + install(fmb.build(PollCustom.Factory.class)); + install(fmb.build(PollKick.Factory.class)); + install(fmb.build(PollNextMap.Factory.class)); + install(fmb.build(PollMutation.Factory.class)); + + final PluginFacetBinder facets = new PluginFacetBinder(binder()); + facets.register(PollManager.class); + facets.register(PollBlacklist.class); + + new CommandBinder(binder()).register(PollCommands.class); + + new ListenerBinder(binder()).bindListener().to(PollListener.class); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/commands/PollCommands.java b/PGM/src/main/java/tc/oc/pgm/polls/commands/PollCommands.java new file mode 100644 index 000000000..7552dacbe --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/commands/PollCommands.java @@ -0,0 +1,86 @@ +package tc.oc.pgm.polls.commands; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.minecraft.util.commands.NestedCommand; +import javax.inject.Inject; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.command.CommandSender; +import tc.oc.api.docs.PlayerId; +import tc.oc.commons.bukkit.chat.PlayerComponent; +import tc.oc.commons.bukkit.nick.IdentityProvider; +import tc.oc.commons.core.chat.Audiences; +import tc.oc.commons.core.chat.Component; +import tc.oc.commons.core.commands.TranslatableCommandException; +import tc.oc.pgm.commands.CommandUtils; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollEndReason; +import tc.oc.pgm.polls.PollManager; + +public class PollCommands { + + private final PollManager pollManager; + private final IdentityProvider identityProvider; + private final Audiences audiences; + + @Inject PollCommands(PollManager pollManager, IdentityProvider identityProvider, Audiences audiences){ + this.pollManager = pollManager; + this.identityProvider = identityProvider; + this.audiences = audiences; + } + + @Command( + aliases = {"poll"}, + desc = "Poll commands", + min = 1, + max = -1 + ) + @NestedCommand({PollSubCommands.class}) + public void pollCommand() { + } + + @Command( + aliases = {"vote"}, + desc = "Vote in a running poll.", + usage = "[yes|no]", + min = 1, + max = 1 + ) + @CommandPermissions("poll.vote") + public void vote(CommandContext args, CommandSender sender) throws CommandException { + PlayerId voter = CommandUtils.senderToMatchPlayer(sender).getPlayerId(); + Poll currentPoll = pollManager.getPoll(); + if(currentPoll != null) { + if(args.getString(0).equalsIgnoreCase("yes")) { + currentPoll.voteFor(voter); + sender.sendMessage(new Component(ChatColor.GREEN).translate("poll.vote.for")); + } else if (args.getString(0).equalsIgnoreCase("no")) { + currentPoll.voteAgainst(voter); + sender.sendMessage(new Component(ChatColor.RED).translate("poll.vote.against")); + } else { + throw new TranslatableCommandException("poll.vote.invalidValue"); + } + } else { + throw new TranslatableCommandException("poll.noPollRunning"); + } + } + + @Command( + aliases = {"veto"}, + desc = "Veto the current poll.", + min = 0, + max = 0 + ) + @CommandPermissions("poll.veto") + public void veto(CommandContext args, CommandSender sender) throws CommandException { + if(pollManager.isPollRunning()) { + pollManager.endPoll(PollEndReason.Cancelled); + audiences.all().sendMessage(new Component(ChatColor.RED).translate("poll.veto", new PlayerComponent(identityProvider.currentIdentity(sender)))); + } else { + throw new TranslatableCommandException("poll.noPollRunning"); + } + } + +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/commands/PollSubCommands.java b/PGM/src/main/java/tc/oc/pgm/polls/commands/PollSubCommands.java new file mode 100644 index 000000000..e7c318ed0 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/commands/PollSubCommands.java @@ -0,0 +1,190 @@ +package tc.oc.pgm.polls.commands; + +import com.google.common.collect.Sets; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import java.util.List; +import javax.inject.Inject; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import tc.oc.api.bukkit.users.OnlinePlayers; +import tc.oc.api.minecraft.users.UserStore; +import tc.oc.commons.bukkit.tokens.TokenUtil; +import tc.oc.commons.core.commands.TranslatableCommandException; +import tc.oc.commons.core.formatting.StringUtils; +import tc.oc.commons.core.restart.RestartManager; +import tc.oc.pgm.commands.CommandUtils; +import tc.oc.pgm.map.PGMMap; +import tc.oc.pgm.match.MatchManager; +import tc.oc.pgm.mutation.Mutation; +import tc.oc.pgm.mutation.MutationQueue; +import tc.oc.pgm.polls.PollBlacklist; +import tc.oc.pgm.polls.PollConfig; +import tc.oc.pgm.polls.PollManager; +import tc.oc.pgm.polls.types.PollCustom; +import tc.oc.pgm.polls.types.PollKick; +import tc.oc.pgm.polls.types.PollMutation; +import tc.oc.pgm.polls.types.PollNextMap; + +public class PollSubCommands { + + private final RestartManager restartManager; + private final MutationQueue mutationQueue; + private final PollManager pollManager; + private final PollCustom.Factory pollCustomFactory; + private final PollNextMap.Factory pollMapFactory; + private final PollMutation.Factory pollMutationFactory; + private final PollKick.Factory pollKickFactory; + private final PollBlacklist pollBlacklist; + private final UserStore userStore; + private final OnlinePlayers onlinePlayers; + private final MatchManager matchManager; + private final PollConfig pollConfig; + + private static final String VOTE_FOR = ChatColor.GREEN + "in favor of"; + private static final String VOTE_AGAINST = ChatColor.RED + "against"; + + @Inject + PollSubCommands(RestartManager restartManager, + MutationQueue mutationQueue, + PollManager pollManager, + PollCustom.Factory pollCustomFactory, + PollNextMap.Factory pollMapFactory, + PollMutation.Factory pollMutationFactory, + PollKick.Factory pollKickFactory, + PollBlacklist pollBlacklist, + UserStore userStore, + OnlinePlayers onlinePlayers, + MatchManager matchManager, + PollConfig pollConfig) { + this.restartManager = restartManager; + this.mutationQueue = mutationQueue; + this.pollManager = pollManager; + this.pollCustomFactory = pollCustomFactory; + this.pollMapFactory = pollMapFactory; + this.pollMutationFactory = pollMutationFactory; + this.pollKickFactory = pollKickFactory; + this.pollBlacklist = pollBlacklist; + this.userStore = userStore; + this.onlinePlayers = onlinePlayers; + this.matchManager = matchManager; + this.pollConfig = pollConfig; + } + + + + @Command( + aliases = {"kick"}, + desc = "Start a poll to kick another player.", + usage = "[player]", + min = 1, + max = 1 + ) + @CommandPermissions("poll.kick") + public void pollKick(CommandContext args, CommandSender sender) throws CommandException { + Player initiator = tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender); + Player player = tc.oc.commons.bukkit.commands.CommandUtils.findOnlinePlayer(args, sender, 0); + + if(player.hasPermission("pgm.poll.kick.exempt") && !initiator.hasPermission("pgm.poll.kick.override")) { + throw new TranslatableCommandException("poll.kick.exempt"); + } else { + pollManager.startPoll(pollKickFactory.create(userStore.playerId(tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender)), player)); + } + } + + @Command( + aliases = {"next"}, + desc = "Start a poll to change the next map.", + usage = "[map name]", + min = 1, + max = -1 + ) + @CommandPermissions("poll.next") + public List pollNext(CommandContext args, CommandSender sender) throws CommandException { + final String mapName = args.argsLength() > 0 ? args.getJoinedStrings(0) : ""; + if(args.getSuggestionContext() != null) { + return CommandUtils.completeMapName(mapName); + } + + if(!pollConfig.enabled()) { + throw new TranslatableCommandException("poll.disabled"); + } + + if(restartManager.isRestartRequested()) { + throw new TranslatableCommandException("poll.map.restarting"); + } + if(matchManager.hasMapSet()) { + throw new TranslatableCommandException("poll.map.alreadyset"); + } + if(TokenUtil.getUser(sender).maptokens() < 1) { + throw new TranslatableCommandException("tokens.map.fail"); + } + + PGMMap nextMap = CommandUtils.getMap(args.getJoinedStrings(0), sender); + + if(pollBlacklist.isBlacklisted(nextMap) && !sender.hasPermission("poll.next.override")) { + throw new TranslatableCommandException("poll.map.notallowed"); + } + + if(onlinePlayers.count() * 4 / 5 > nextMap.getDocument().max_players() && !sender.hasPermission("poll.next.override")) { + throw new TranslatableCommandException("poll.map.toomanyplayers"); + } + + pollManager.startPoll(pollMapFactory.create(sender, nextMap, userStore.playerId(tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender)))); + return null; + } + + @Command( + aliases = {"mutation", "mt"}, + desc = "Start a poll to set a mutation", + usage = "[mutation name]", + min = 1, + max = -1 + ) + @CommandPermissions("poll.mutation") + public List pollMutation(CommandContext args, CommandSender sender) throws CommandException { + + if(args.getSuggestionContext() != null) { + return StringUtils.complete(args.getSuggestionContext().getPrefix(), mutationQueue.mutationsAvailable().stream().map(mutation -> mutation.name().toLowerCase())); + } + + if(!pollConfig.enabled()) { + throw new TranslatableCommandException("poll.disabled"); + } + + if(TokenUtil.getUser(sender).mutationtokens() < 1) { + throw new TranslatableCommandException("tokens.mutation.fail"); + } + + String mutationString = args.getString(0); + + Mutation mutation = StringUtils.bestFuzzyMatch(mutationString, Sets.newHashSet(Mutation.values()), 0.9); + if(mutation == null) { + throw new TranslatableCommandException("command.mutation.error.find", mutationString); + } else if(mutationQueue.mutations().contains(mutation)) { + throw new TranslatableCommandException("command.mutation.error.enabled", mutation.getComponent(net.md_5.bungee.api.ChatColor.RED)); + } else if(!mutation.isPollable() && !sender.hasPermission("poll.mutation.override")) { + throw new TranslatableCommandException("command.mutation.error.illegal", mutationString); + } + + pollManager.startPoll(pollMutationFactory.create(sender, mutation, userStore.playerId(tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender)))); + return null; + } + + @Command( + aliases = {"custom"}, + desc = "Start a poll with the supplied text", + usage = "[text...]", + min = 1, + max = -1 + ) + @CommandPermissions("poll.custom") + public void pollCustom(CommandContext args, CommandSender sender) throws CommandException { + String text = args.getJoinedStrings(0); + + pollManager.startPoll(pollCustomFactory.create(text, userStore.playerId(tc.oc.commons.bukkit.commands.CommandUtils.senderToPlayer(sender)))); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollEndEvent.java b/PGM/src/main/java/tc/oc/pgm/polls/event/PollEndEvent.java similarity index 85% rename from PGM/src/main/java/tc/oc/pgm/polls/PollEndEvent.java rename to PGM/src/main/java/tc/oc/pgm/polls/event/PollEndEvent.java index 190dd26d3..17e94e3c5 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollEndEvent.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/event/PollEndEvent.java @@ -1,6 +1,8 @@ -package tc.oc.pgm.polls; +package tc.oc.pgm.polls.event; import org.bukkit.event.HandlerList; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollEndReason; /** * Called when a poll ends. diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollEvent.java b/PGM/src/main/java/tc/oc/pgm/polls/event/PollEvent.java similarity index 85% rename from PGM/src/main/java/tc/oc/pgm/polls/PollEvent.java rename to PGM/src/main/java/tc/oc/pgm/polls/event/PollEvent.java index 9f4c8ad88..924651094 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollEvent.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/event/PollEvent.java @@ -1,6 +1,7 @@ -package tc.oc.pgm.polls; +package tc.oc.pgm.polls.event; import org.bukkit.event.Event; +import tc.oc.pgm.polls.Poll; /** * Represents an event related to a poll. diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollStartEvent.java b/PGM/src/main/java/tc/oc/pgm/polls/event/PollStartEvent.java similarity index 87% rename from PGM/src/main/java/tc/oc/pgm/polls/PollStartEvent.java rename to PGM/src/main/java/tc/oc/pgm/polls/event/PollStartEvent.java index edd0508f3..787f95ca8 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollStartEvent.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/event/PollStartEvent.java @@ -1,6 +1,7 @@ -package tc.oc.pgm.polls; +package tc.oc.pgm.polls.event; import org.bukkit.event.HandlerList; +import tc.oc.pgm.polls.Poll; /** * Called when a poll first starts. diff --git a/PGM/src/main/java/tc/oc/pgm/polls/types/PollCustom.java b/PGM/src/main/java/tc/oc/pgm/polls/types/PollCustom.java new file mode 100644 index 000000000..2da760637 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/types/PollCustom.java @@ -0,0 +1,37 @@ +package tc.oc.pgm.polls.types; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import tc.oc.api.docs.PlayerId; +import tc.oc.commons.core.chat.Audiences; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollManager; + +public class PollCustom extends Poll { + + public interface Factory { + PollCustom create(String text, PlayerId initiator); + } + + private String text; + + @AssistedInject PollCustom(@Assisted String text, @Assisted PlayerId initiator, PollManager pollManager, Audiences audiences) { + super(pollManager, initiator, audiences); + this.text = text; + } + + @Override + public void executeAction() { + //I do nothing + } + + @Override + public String getActionString() { + return boldAqua + text.substring(0, 1).toUpperCase() + text.substring(1); + } + + @Override + public String getDescriptionMessage() { + return boldAqua + text; + } +} \ No newline at end of file diff --git a/PGM/src/main/java/tc/oc/pgm/polls/types/PollKick.java b/PGM/src/main/java/tc/oc/pgm/polls/types/PollKick.java new file mode 100644 index 000000000..065337668 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/polls/types/PollKick.java @@ -0,0 +1,50 @@ +package tc.oc.pgm.polls.types; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.entity.Player; +import tc.oc.api.docs.PlayerId; +import tc.oc.api.docs.virtual.PunishmentDoc; +import tc.oc.api.minecraft.users.UserStore; +import tc.oc.commons.bukkit.chat.PlayerComponent; +import tc.oc.commons.bukkit.nick.IdentityProvider; +import tc.oc.commons.bukkit.punishment.PunishmentCreator; +import tc.oc.commons.core.chat.Audiences; +import tc.oc.commons.core.chat.Component; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollManager; + +public class PollKick extends Poll { + + public interface Factory { + PollKick create(PlayerId initiator, Player player); + } + + private final PlayerId playerId; + private final IdentityProvider identityProvider; + private final PunishmentCreator punishmentCreator; + + @AssistedInject PollKick(@Assisted PlayerId initiator, @Assisted Player player, PollManager pollManager, Audiences audiences, IdentityProvider identityProvider, PunishmentCreator punishmentCreator, UserStore userStore) { + super(pollManager, initiator, audiences); + this.identityProvider = identityProvider; + this.punishmentCreator = punishmentCreator; + this.playerId = userStore.playerId(player); + } + + @Override + public void executeAction() { + punishmentCreator.create(null, playerId, "The poll to kick " + playerId.username() + " succeeded", PunishmentDoc.Type.KICK, null, false, false, true); + audiences.localServer().sendMessage(new Component(ChatColor.DARK_AQUA).translate("poll.kick.success", new PlayerComponent(identityProvider.currentIdentity(playerId)))); + } + + @Override + public String getActionString() { + return normalize + "Kick: " + boldAqua + this.playerId.username(); + } + + @Override + public String getDescriptionMessage() { + return "to kick " + boldAqua + this.playerId.username(); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollMutation.java b/PGM/src/main/java/tc/oc/pgm/polls/types/PollMutation.java similarity index 65% rename from PGM/src/main/java/tc/oc/pgm/polls/PollMutation.java rename to PGM/src/main/java/tc/oc/pgm/polls/types/PollMutation.java index 09a90129c..841453668 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollMutation.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/types/PollMutation.java @@ -1,30 +1,30 @@ -package tc.oc.pgm.polls; +package tc.oc.pgm.polls.types; +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; import org.bukkit.Bukkit; -import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import tc.oc.api.docs.PlayerId; import tc.oc.api.docs.User; import tc.oc.commons.bukkit.tokens.TokenUtil; -import tc.oc.pgm.Config; +import tc.oc.commons.core.chat.Audiences; import tc.oc.pgm.mutation.Mutation; -import tc.oc.pgm.mutation.MutationMatchModule; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollManager; public class PollMutation extends Poll { + public interface Factory { + PollMutation create(CommandSender sender, Mutation mutation, PlayerId playerId); + } + private Mutation mutation; - private CommandSender sender; - private MutationMatchModule module; - private String mutationName; private User user; - public PollMutation(PollManager pollManager, Server server, CommandSender sender, Mutation mutation, - MutationMatchModule module) { - super(pollManager, server, sender.getName()); + @AssistedInject PollMutation(@Assisted CommandSender sender, @Assisted Mutation mutation, @Assisted PlayerId playerId, PollManager pollManager, Audiences audiences) { + super(pollManager, playerId, audiences); this.mutation = mutation; - this.sender = sender; - this.module = module; - this.mutationName = mutationName; if (sender instanceof Player) { user = TokenUtil.getUser((Player)sender); } diff --git a/PGM/src/main/java/tc/oc/pgm/polls/PollNextMap.java b/PGM/src/main/java/tc/oc/pgm/polls/types/PollNextMap.java similarity index 60% rename from PGM/src/main/java/tc/oc/pgm/polls/PollNextMap.java rename to PGM/src/main/java/tc/oc/pgm/polls/types/PollNextMap.java index cfa28c92a..e0c94e718 100644 --- a/PGM/src/main/java/tc/oc/pgm/polls/PollNextMap.java +++ b/PGM/src/main/java/tc/oc/pgm/polls/types/PollNextMap.java @@ -1,24 +1,32 @@ -package tc.oc.pgm.polls; +package tc.oc.pgm.polls.types; -import org.bukkit.Server; +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import tc.oc.api.docs.PlayerId; import tc.oc.api.docs.User; import tc.oc.commons.bukkit.tokens.TokenUtil; +import tc.oc.commons.core.chat.Audiences; import tc.oc.pgm.map.PGMMap; import tc.oc.pgm.match.MatchManager; +import tc.oc.pgm.polls.Poll; +import tc.oc.pgm.polls.PollManager; public class PollNextMap extends Poll { + + public interface Factory { + PollNextMap create(CommandSender sender, PGMMap nextMap, PlayerId playerId); + } + private final MatchManager mm; private final PGMMap nextMap; - private CommandSender sender; private User user; - public PollNextMap(PollManager pollManager, Server server, CommandSender sender, String initiator, MatchManager mm, PGMMap nextMap) { - super(pollManager, server, initiator); + @AssistedInject PollNextMap(@Assisted CommandSender sender, @Assisted PGMMap nextMap, @Assisted PlayerId playerId, PollManager pollManager, Audiences audiences, MatchManager mm) { + super(pollManager, playerId, audiences); this.mm = mm; this.nextMap = nextMap; - this.sender = sender; if (sender instanceof Player) { user = TokenUtil.getUser((Player)sender); } diff --git a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MutationConfirmInterface.java b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MutationConfirmInterface.java index 1d70ed3eb..76d2014f3 100644 --- a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MutationConfirmInterface.java +++ b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MutationConfirmInterface.java @@ -1,19 +1,17 @@ package tc.oc.pgm.tokens.gui; +import com.google.inject.Inject; import com.sk89q.minecraft.util.commands.CommandException; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import tc.oc.commons.bukkit.gui.buttons.Button; import tc.oc.commons.bukkit.gui.interfaces.ChestInterface; import tc.oc.commons.bukkit.util.ItemCreator; -import tc.oc.pgm.PGM; -import tc.oc.pgm.commands.PollCommands; +import tc.oc.pgm.commands.CommandUtils; import tc.oc.pgm.mutation.Mutation; -import tc.oc.pgm.mutation.MutationMatchModule; -import tc.oc.pgm.polls.PollMutation; +import tc.oc.pgm.polls.PollManager; +import tc.oc.pgm.polls.types.PollMutation; import java.util.ArrayList; import java.util.List; @@ -21,6 +19,9 @@ public class MutationConfirmInterface extends ChestInterface { private Mutation mutation; + @Inject PollManager pollManager; + @Inject PollMutation.Factory pollMutationFactory; + public MutationConfirmInterface(Player player, Mutation mutation) { super(player, new ArrayList