324 lines
12 KiB
Java
324 lines
12 KiB
Java
/******************************************************************************
|
|
* Multiverse 2 Copyright (c) the Multiverse Team 2020. *
|
|
* Multiverse 2 is licensed under the BSD License. *
|
|
* For more information please check the README.md file included *
|
|
* with this project. *
|
|
******************************************************************************/
|
|
|
|
package com.onarandombox.MultiverseCore.commandtools;
|
|
|
|
import buscript.Buscript;
|
|
import co.aikar.commands.BukkitCommandCompletionContext;
|
|
import co.aikar.commands.CommandIssuer;
|
|
import co.aikar.commands.PaperCommandCompletions;
|
|
import co.aikar.commands.RegisteredCommand;
|
|
import co.aikar.commands.RootCommand;
|
|
import com.dumptruckman.minecraft.util.Logging;
|
|
import com.onarandombox.MultiverseCore.MultiverseCore;
|
|
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
|
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
|
|
import com.onarandombox.MultiverseCore.commandtools.flag.CommandFlag;
|
|
import com.onarandombox.MultiverseCore.commandtools.flag.CommandFlag.ValueRequirement;
|
|
import com.onarandombox.MultiverseCore.commandtools.flag.FlagGroup;
|
|
import com.onarandombox.MultiverseCore.enums.AddProperties;
|
|
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
|
|
import org.bukkit.GameRule;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.World;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Player;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.io.File;
|
|
import java.text.DecimalFormat;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* Generate tab-complete suggestion.
|
|
*/
|
|
public class MVCommandCompletions extends PaperCommandCompletions {
|
|
|
|
private final MultiverseCore plugin;
|
|
private final MVWorldManager worldManager;
|
|
|
|
private static final DecimalFormat df = new DecimalFormat();
|
|
|
|
static {
|
|
df.setMinimumFractionDigits(0);
|
|
df.setMaximumFractionDigits(2);
|
|
}
|
|
|
|
public MVCommandCompletions(@NotNull MVCommandManager manager,
|
|
@NotNull MultiverseCore plugin) {
|
|
super(manager);
|
|
this.plugin = plugin;
|
|
this.worldManager = plugin.getMVWorldManager();
|
|
|
|
registerAsyncCompletion("flags", this::suggestFlags);
|
|
registerAsyncCompletion("scripts", this::suggestScripts);
|
|
registerAsyncCompletion("subCommands", this::suggestSubCommands);
|
|
registerAsyncCompletion("MVWorlds", this::suggestMVWorlds);
|
|
registerAsyncCompletion("unloadedWorlds", this::suggestUnloadedWorlds);
|
|
registerAsyncCompletion("potentialWorlds", this::suggestPotentialWorlds);
|
|
registerAsyncCompletion("location", this::suggestLocation);
|
|
registerAsyncCompletion("destinations", this::suggestDestinations);
|
|
registerAsyncCompletion("anchors", this::suggestAnchors);
|
|
registerStaticCompletion("MVConfigs", this::suggestMVConfig);
|
|
registerStaticCompletion("gameRules", this::suggestGameRules);
|
|
registerStaticCompletion("environments", this::suggestEnvironments);
|
|
registerStaticCompletion("setProperties", this::suggestSetProperties);
|
|
registerStaticCompletion("addProperties", this::suggestAddProperties);
|
|
registerStaticCompletion("livingEntities", this::suggestEntities);
|
|
registerStaticCompletion("pasteTypes", this::suggestPasteTypes);
|
|
registerStaticCompletion("toggles", this::suggestToggles);
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestFlags(@NotNull BukkitCommandCompletionContext context) {
|
|
final MultiverseCommand command = MVCommandReflect.getCommandCompletionContextCommand(context);
|
|
if (command == null) {
|
|
Logging.warning("Unable to parse flags as MultiverseCommand not found!");
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
FlagGroup flagGroup = command.getFlagGroup();
|
|
String[] args = context.getContextValue(String[].class);
|
|
CommandFlag<?> flag = (args.length <= 1) ? null : flagGroup.getByKey(args[args.length - 2]);
|
|
|
|
if (flag == null || flag.getValueRequirement() == ValueRequirement.NONE) {
|
|
// suggest new flags.
|
|
return getRemainingFlagIdentifiers(flagGroup, args);
|
|
}
|
|
|
|
Collection<String> flagSuggestions = flag.suggestValue();
|
|
|
|
if (flag.getValueRequirement() == ValueRequirement.OPTIONAL) {
|
|
// suggest new flags and values.
|
|
flagSuggestions.addAll(getRemainingFlagIdentifiers(flagGroup, args));
|
|
return flagSuggestions;
|
|
}
|
|
// suggest new values.
|
|
return flagSuggestions == null ? Collections.emptySet() : flagSuggestions;
|
|
}
|
|
|
|
private Collection<String> getRemainingFlagIdentifiers(FlagGroup flagGroup, String[] args) {
|
|
Set<String> identifiersRemaining = new HashSet<>(flagGroup.getFlagIdentifiers());
|
|
identifiersRemaining.removeAll(Arrays.asList(args));
|
|
return identifiersRemaining;
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestScripts(@NotNull BukkitCommandCompletionContext context) {
|
|
Buscript scriptAPI = this.plugin.getScriptAPI();
|
|
if (scriptAPI == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return Arrays.stream(scriptAPI.getScriptFolder().listFiles())
|
|
.unordered()
|
|
.filter(File::isFile)
|
|
.map(File::getName)
|
|
.filter(fileName -> !fileName.equals("scripts.bin"))
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestSubCommands(@NotNull BukkitCommandCompletionContext context) {
|
|
String rootCmdName = context.getConfig();
|
|
if (rootCmdName == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
RootCommand rootCommand = this.plugin.getMVCommandManager().getRegisteredRootCommands().stream()
|
|
.unordered()
|
|
.filter(c -> c.getCommandName().equals(rootCmdName))
|
|
.findFirst()
|
|
.orElse(null);
|
|
|
|
if (rootCommand == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return rootCommand.getSubCommands().entries().stream()
|
|
.unordered()
|
|
.filter(entry -> checkPerms(context.getIssuer(), entry.getValue()))
|
|
.map(Map.Entry::getKey)
|
|
.filter(cmdName -> !cmdName.startsWith("__"))
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
private boolean checkPerms(@NotNull CommandIssuer issuer,
|
|
@NotNull RegisteredCommand<?> cmd) {
|
|
|
|
return this.plugin.getMVCommandManager().hasPermission(issuer, cmd.getRequiredPermissions());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestMVWorlds(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return this.worldManager.getMVWorlds().parallelStream()
|
|
.unordered()
|
|
.map(MultiverseWorld::getName)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestUnloadedWorlds(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return this.worldManager.getUnloadedWorlds();
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestPotentialWorlds(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
Collection<MultiverseWorld> worlds = this.worldManager.getMVWorlds();
|
|
Set<String> knownWorlds = worlds.parallelStream()
|
|
.unordered()
|
|
.map(MultiverseWorld::getName)
|
|
.collect(Collectors.toCollection(() -> new HashSet<>(worlds.size())));
|
|
|
|
return Arrays.stream(this.plugin.getServer().getWorldContainer().listFiles()).parallel()
|
|
.unordered()
|
|
.filter(File::isDirectory)
|
|
.filter(file -> !knownWorlds.contains(file.getName()))
|
|
.map(File::getName)
|
|
.filter(this.worldManager::isValidWorld)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestLocation(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
Player player = context.getPlayer();
|
|
if (player == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
DecimalFormat df = new DecimalFormat();
|
|
df.setMinimumFractionDigits(0);
|
|
df.setMaximumFractionDigits(2);
|
|
|
|
Location playerLocation = player.getLocation();
|
|
double coordValue;
|
|
switch (context.getConfig()) {
|
|
case "x":
|
|
coordValue = playerLocation.getX();
|
|
break;
|
|
case "y":
|
|
coordValue = playerLocation.getY();
|
|
break;
|
|
case "z":
|
|
coordValue = playerLocation.getZ();
|
|
break;
|
|
case "yaw":
|
|
coordValue = playerLocation.getYaw();
|
|
break;
|
|
case "pitch":
|
|
coordValue = playerLocation.getPitch();
|
|
break;
|
|
default:
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return Collections.singletonList(df.format(coordValue));
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestDestinations(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return this.plugin.getDestFactory().getIdentifiers().parallelStream()
|
|
.unordered()
|
|
.filter(id -> !id.isEmpty())
|
|
.map(id -> id + ":")
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestAnchors(@NotNull BukkitCommandCompletionContext context) {
|
|
if (isPlayerOnly(context)) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
return this.plugin.getAnchorManager().getAnchors(context.getPlayer());
|
|
}
|
|
|
|
private boolean isPlayerOnly(@NotNull BukkitCommandCompletionContext context) {
|
|
String config = context.getConfig();
|
|
return config != null && context.getPlayer() == null && config.equals("playerOnly");
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestMVConfig() {
|
|
final Set<String> configOptions = this.plugin.getMVConfig().serialize().keySet();
|
|
configOptions.remove("version");
|
|
return configOptions;
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestGameRules() {
|
|
return Arrays.stream(GameRule.values())
|
|
.map(GameRule::getName)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestEnvironments() {
|
|
return Arrays.stream(World.Environment.values())
|
|
.map(e -> e.toString().toLowerCase())
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
private Collection<String> suggestSetProperties() {
|
|
return this.worldManager.getMVWorlds().iterator().next().getAllPropertyTypes();
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestAddProperties() {
|
|
return Arrays.stream(AddProperties.values())
|
|
.map(p -> p.toString().toLowerCase())
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestEntities() {
|
|
return Arrays.stream(EntityType.values())
|
|
.filter(e -> e.isAlive() && e.isSpawnable())
|
|
.map(e -> e.toString().toLowerCase())
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestPasteTypes() {
|
|
return Arrays.stream(PasteServiceType.values())
|
|
.filter(pt -> pt != PasteServiceType.GITHUB && pt != PasteServiceType.NONE)
|
|
.map(p -> p.toString().toLowerCase())
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
@NotNull
|
|
private Collection<String> suggestToggles() {
|
|
return Arrays.asList("on", "off");
|
|
}
|
|
}
|