-
Notifications
You must be signed in to change notification settings - Fork 1
/
SubCommandList.java
163 lines (148 loc) · 5.9 KB
/
SubCommandList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package com.github.sanctum.labyrinth.command;
import com.github.sanctum.labyrinth.LabyrinthProvider;
import com.github.sanctum.labyrinth.annotation.Ordinal;
import com.github.sanctum.labyrinth.data.container.LabyrinthCollection;
import com.github.sanctum.labyrinth.data.container.LabyrinthCollectionBase;
import com.github.sanctum.labyrinth.data.container.LabyrinthList;
import com.github.sanctum.labyrinth.interfacing.OrdinalProcedure;
import com.github.sanctum.labyrinth.library.CommandUtils;
import com.github.sanctum.labyrinth.library.StringUtils;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A class designed for easy bukkit sub command flow. Append or remove sub labels to registered commands.
*
* @author Hempfest
*/
public abstract class SubCommandList extends LabyrinthCollectionBase<SubCommand> {
protected final Crossover parent;
protected SubCommandList(@NotNull Command parent) {
this.parent = new Crossover(parent);
}
/**
* Get the main command label this sub command belongs to.
*
* @return The main command this sub command is for.
*/
public final @NotNull String getCommand() {
return parent.getLabel();
}
/**
* Get a sub command from this list by its label.
*
* @param label The label of the sub command.
* @return a sub command match or null if not found.
*/
public final @Nullable SubCommand getSubCommand(@NotNull String label) {
return stream().filter(s -> s.getLabel().equalsIgnoreCase(label)).findFirst().orElse(null);
}
/**
* Register a sub command into this list.
*
* @param subCommand The command to register.
*/
public final void register(@NotNull SubCommand subCommand) {
if (subCommand.getCommand().equalsIgnoreCase(getCommand())) {
final Command parent = CommandUtils.getCommandByLabel(subCommand.getCommand());
if (parent != null) {
final Plugin plugin = Optional.of((Plugin)JavaPlugin.getProvidingPlugin(parent.getClass())).orElseGet(() -> {
if (parent instanceof PluginCommand) {
return ((PluginCommand)parent).getPlugin();
} else return LabyrinthProvider.getInstance().getPluginInstance();
});
CommandUtils.read(entry -> {
Map<String, Command> commandMappings = entry.getValue();
CommandMap map = entry.getKey();
commandMappings.remove(parent.getName());
for (String alias : parent.getAliases()) {
if (commandMappings.containsKey(alias) && commandMappings.get(alias).getAliases().contains(alias)) {
commandMappings.remove(alias);
}
}
parent.unregister(map);
map.register(getCommand(), plugin.getName(), parent);
if (!contains(subCommand)) add(subCommand);
return this;
});
} else throw new IllegalArgumentException("Command " + subCommand.getCommand() + " either not found or not loaded yet.");
}
}
/**
* Unregister a sub command from this list.
*
* @param subCommand The command to unregister.
*/
public final void unregister(@NotNull SubCommand subCommand) {
if (subCommand.getCommand().equalsIgnoreCase(getCommand())) {
final Command parent = CommandUtils.getCommandByLabel(subCommand.getCommand());
if (parent != null) {
if (contains(subCommand)) remove(subCommand);
} else throw new IllegalArgumentException("Command " + subCommand.getCommand() + " either not found or not loaded yet.");
}
}
class Crossover extends Command {
private final Command command;
Crossover(Command pass) {
super(pass.getName());
this.command = pass;
if (!this.command.getAliases().isEmpty()) {
setAliases(this.command.getAliases());
}
if (this.command.getPermission() != null) setPermission(this.command.getPermission());
if (!this.command.getDescription().isEmpty()) setDescription(this.command.getDescription());
if (!this.command.getUsage().isEmpty()) setUsage(this.command.getUsage());
if (this.command.getPermissionMessage() != null) setPermissionMessage(this.command.getPermissionMessage());
}
@NotNull
@Override
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
LabyrinthCollection<String> labels = new LabyrinthList<>();
if (args.length > 0) {
for (SubCommand sub : SubCommandList.this) {
if (args.length == 1) {
Stream.of(sub.getLabel()).filter(s -> s.toLowerCase().startsWith(args[0].toLowerCase())).forEach(labels::add);
}
if (args[0].equalsIgnoreCase(sub.getLabel())) {
List<String> t = new LinkedList<>(Arrays.asList(args));
t.removeIf(s -> StringUtils.use(s).containsIgnoreCase(sub.getLabel()));
return sub.tab((Player) sender, alias, t.toArray(new String[0]));
}
}
}
labels.addAll(this.command.tabComplete(sender, alias, args));
return labels.stream().collect(Collectors.toList());
}
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
if (args.length > 0) {
for (SubCommand sub : SubCommandList.this) {
if (args[0].equalsIgnoreCase(sub.getLabel())) {
List<String> t = new LinkedList<>(Arrays.asList(args));
t.removeIf(s -> StringUtils.use(s).containsIgnoreCase(sub.getLabel()));
String[] realArgs = t.toArray(new String[0]);
if (sender instanceof Player) {
return sub.player((Player) sender, commandLabel, realArgs);
} else {
return sub.console(sender, commandLabel, realArgs);
}
}
}
}
return this.command.execute(sender, commandLabel, args);
}
}
}