219 lines
9.7 KiB
Java
219 lines
9.7 KiB
Java
package tc.oc.pgm.mutation.command;
|
|
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.logging.Level;
|
|
import javax.inject.Inject;
|
|
|
|
import com.google.common.collect.Collections2;
|
|
import com.google.common.collect.Iterables;
|
|
import com.google.common.collect.Sets;
|
|
import com.sk89q.minecraft.util.commands.*;
|
|
import net.md_5.bungee.api.ChatColor;
|
|
import net.md_5.bungee.api.chat.BaseComponent;
|
|
import net.md_5.bungee.api.chat.TranslatableComponent;
|
|
import org.bukkit.command.CommandSender;
|
|
import tc.oc.commons.bukkit.chat.PlayerComponent;
|
|
import tc.oc.commons.bukkit.chat.WarningComponent;
|
|
import tc.oc.commons.bukkit.nick.IdentityProvider;
|
|
import tc.oc.commons.core.chat.Audience;
|
|
import tc.oc.minecraft.scheduler.SyncExecutor;
|
|
import tc.oc.commons.bukkit.chat.Audiences;
|
|
import tc.oc.commons.bukkit.chat.ListComponent;
|
|
import tc.oc.commons.bukkit.chat.Paginator;
|
|
import tc.oc.commons.core.chat.Component;
|
|
import tc.oc.commons.core.commands.Commands;
|
|
import tc.oc.commons.core.commands.NestedCommands;
|
|
import tc.oc.commons.core.formatting.StringUtils;
|
|
import tc.oc.commons.core.random.RandomUtils;
|
|
import tc.oc.pgm.commands.CommandUtils;
|
|
import tc.oc.pgm.match.Match;
|
|
import tc.oc.pgm.mutation.Mutation;
|
|
import tc.oc.pgm.mutation.MutationMatchModule;
|
|
import tc.oc.pgm.mutation.MutationQueue;
|
|
|
|
import static tc.oc.commons.bukkit.commands.CommandUtils.newCommandException;
|
|
|
|
/**
|
|
* Commands for {@link MutationMatchModule}.
|
|
*/
|
|
public class MutationCommands implements NestedCommands {
|
|
|
|
public static final String PERMISSION_SET = "mutation.set";
|
|
public static final String PERMISSION_LIST = "mutation.list";
|
|
|
|
public static class Parent implements Commands {
|
|
@Command(
|
|
aliases = {"mutation", "mutations", "mutate", "mt"},
|
|
desc = "Commands to manage match mutations.",
|
|
usage = "<list|enable|disable>",
|
|
min = 1,
|
|
max = -1
|
|
)
|
|
@NestedCommand(value = MutationCommands.class, executeBody = true)
|
|
public void mutate(CommandContext args, CommandSender sender) throws CommandException {}
|
|
}
|
|
|
|
private final SyncExecutor syncExecutor;
|
|
private final Audiences audiences;
|
|
private final MutationQueue mutationQueue;
|
|
private final IdentityProvider identityProvider;
|
|
|
|
@Inject MutationCommands(SyncExecutor syncExecutor, Audiences audiences, MutationQueue mutationQueue, IdentityProvider identityProvider) {
|
|
this.syncExecutor = syncExecutor;
|
|
this.audiences = audiences;
|
|
this.mutationQueue = mutationQueue;
|
|
this.identityProvider = identityProvider;
|
|
}
|
|
|
|
@Command(
|
|
aliases = {"enable", "e"},
|
|
desc = "Adds a mutation to the upcoming match." +
|
|
"You can use '?' as a wildcard or " +
|
|
"'*' to use all.",
|
|
usage = "<mutation|?|*>",
|
|
flags = "q",
|
|
min = 1,
|
|
max = 1
|
|
)
|
|
@CommandPermissions(PERMISSION_SET)
|
|
public void enable(CommandContext args, CommandSender sender) throws CommandException, SuggestException {
|
|
set(args, sender, true);
|
|
}
|
|
|
|
@Command(
|
|
aliases = {"disable", "d"},
|
|
desc = "Remove a mutation to the upcoming match." +
|
|
"You can use '?' as a wildcard or " +
|
|
"'*' to use all.",
|
|
usage = "<mutation|?|*>",
|
|
flags = "q",
|
|
min = 1,
|
|
max = 1
|
|
)
|
|
@CommandPermissions(PERMISSION_SET)
|
|
public void disable(CommandContext args, CommandSender sender) throws CommandException, SuggestException {
|
|
set(args, sender, false);
|
|
}
|
|
|
|
@Command(
|
|
aliases = {"list"},
|
|
desc = "List all the mutations options." +
|
|
"Use '-q' to see queued mutations.",
|
|
usage = "[page]",
|
|
flags = "q",
|
|
min = 0,
|
|
max = 1
|
|
)
|
|
@CommandPermissions(PERMISSION_LIST)
|
|
public void list(final CommandContext args, CommandSender sender) throws CommandException {
|
|
MutationMatchModule module = verify(sender);
|
|
final boolean queued = args.hasFlag('q');
|
|
final Collection<Mutation> active = queued ? mutationQueue.mutations() : module.mutationsActive();
|
|
new Paginator<Mutation>(Mutation.values().length / 2) {
|
|
@Override
|
|
protected BaseComponent title() {
|
|
return new TranslatableComponent(queued ? "command.mutation.list.queued" : "command.mutation.list.current");
|
|
}
|
|
@Override
|
|
protected BaseComponent entry(Mutation entry, int index) {
|
|
return new Component(new BaseComponent[] {entry.getComponent(active.contains(entry) ? ChatColor.AQUA : ChatColor.GRAY)})
|
|
.extra(new Component(" (", ChatColor.WHITE).extra(new TranslatableComponent(entry.getDescription())).extra(")"));
|
|
}
|
|
}.display(sender, Sets.newHashSet(Mutation.values()), args.getInteger(0, 1));
|
|
|
|
}
|
|
|
|
public MutationMatchModule verify(CommandSender sender) throws CommandException {
|
|
return CommandUtils.getMatchModule(MutationMatchModule.class, sender);
|
|
}
|
|
|
|
public void set(CommandContext args, final CommandSender sender, final boolean value) throws CommandException, SuggestException {
|
|
final MutationMatchModule module = verify(sender);
|
|
final Match match = module.getMatch();
|
|
String action = args.getString(0);
|
|
boolean queued = args.hasFlag('q') || match.isFinished();
|
|
// Mutations that *will* be added or removed
|
|
final Collection<Mutation> mutations = new HashSet<>();
|
|
// Mutations that *are allowed* to be added or removed
|
|
final Collection<Mutation> availableMutations = Sets.newHashSet(Mutation.values());
|
|
|
|
final Collection<Mutation> queue = queued ? mutationQueue.mutations() : module.mutationsActive();
|
|
if(value) availableMutations.removeAll(queue); else availableMutations.retainAll(queue);
|
|
// Check if all mutations have been enabled/disabled
|
|
if((queue.size() == Mutation.values().length && value) || (queue.isEmpty() && !value)) {
|
|
throw newCommandException(sender, new TranslatableComponent(value ? "command.mutation.error.enabled.all" : "command.mutation.error.disabled.all"));
|
|
}
|
|
// Suggest mutations for the user to choose
|
|
final SuggestionContext context = args.getSuggestionContext();
|
|
if(context != null) {
|
|
context.suggestArgument(0, StringUtils.complete(context.getPrefix(), availableMutations.stream().map(mutation -> mutation.name().toLowerCase())));
|
|
}
|
|
// Get which action the user wants to preform
|
|
switch (action) {
|
|
case "*": mutations.addAll(availableMutations); break;
|
|
case "?": mutations.add(Iterables.get(availableMutations, RandomUtils.safeNextInt(match.getRandom(), availableMutations.size()))); break;
|
|
default:
|
|
Mutation query = StringUtils.bestFuzzyMatch(action, Sets.newHashSet(Mutation.values()), 0.9);
|
|
if(query == null) {
|
|
throw newCommandException(sender, new TranslatableComponent("command.mutation.error.find", action));
|
|
} else if(value == queue.contains(query)) {
|
|
throw newCommandException(sender, new TranslatableComponent(value ? "command.mutation.error.enabled" : "command.mutation.error.disabled", query.getComponent(ChatColor.RED)));
|
|
} else {
|
|
mutations.add(query);
|
|
}
|
|
}
|
|
Audience origin = audiences.get(sender);
|
|
Audience all = audiences.localServer();
|
|
String message = message(!queued, value, mutations.size() == 1);
|
|
ListComponent changed = new ListComponent(Collections2.transform(mutations, Mutation.toComponent(ChatColor.AQUA)));
|
|
if(queued) {
|
|
// Send the queued changes off to the api
|
|
syncExecutor.callback(
|
|
value ? mutationQueue.mergeAll(mutations)
|
|
: mutationQueue.removeAll(mutations),
|
|
result -> {
|
|
origin.sendMessage(new Component(new TranslatableComponent(message, changed), ChatColor.WHITE));
|
|
}
|
|
);
|
|
} else {
|
|
// Make the changes immediately
|
|
for(Mutation mutation : mutations) {
|
|
try {
|
|
module.register(mutation, value);
|
|
module.mutate(mutation);
|
|
} catch(Throwable t) {
|
|
module.register(mutation, !value);
|
|
origin.sendMessage(
|
|
new WarningComponent(
|
|
"command.mutation.error.mutate",
|
|
mutation.getComponent(ChatColor.RED)
|
|
)
|
|
);
|
|
module.getLogger().log(Level.SEVERE, "Unable to enable/disable mutation", t);
|
|
return;
|
|
}
|
|
}
|
|
PlayerComponent player = new PlayerComponent(identityProvider.currentIdentity(sender));
|
|
all.sendMessage(new Component(new TranslatableComponent(message, player, changed)));
|
|
}
|
|
}
|
|
|
|
public String message(boolean now, boolean enable, boolean singular) {
|
|
if(now) {
|
|
if(enable) {
|
|
return singular ? "command.mutation.enable.now.singular" : "command.mutation.enable.now.plural";
|
|
} else {
|
|
return singular ? "command.mutation.disable.now.singular" : "command.mutation.disable.now.plural";
|
|
}
|
|
} else {
|
|
if(enable) {
|
|
return singular ? "command.mutation.enable.later.singular" : "command.mutation.enable.later.plural";
|
|
} else {
|
|
return singular ? "command.mutation.disable.later.singular" : "command.mutation.disable.later.plural";
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|