Skip to content

Commit 01ebd00

Browse files
committed
add UUIDArgument
1 parent 217affe commit 01ebd00

File tree

5 files changed

+302
-8
lines changed

5 files changed

+302
-8
lines changed

bukkit/src/main/java/net/kunmc/lab/commandlib/ArgumentBuilder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
import org.jetbrains.annotations.NotNull;
1515
import org.jetbrains.annotations.Nullable;
1616

17-
import java.util.ArrayList;
18-
import java.util.Collection;
19-
import java.util.List;
20-
import java.util.Map;
17+
import java.util.*;
2118
import java.util.function.Consumer;
2219
import java.util.function.Predicate;
2320
import java.util.function.Supplier;
@@ -990,6 +987,16 @@ public ArgumentBuilder unparsedArgumentWith(@NotNull String name,
990987
return this;
991988
}
992989

990+
public ArgumentBuilder uuidArgument(@NotNull String name) {
991+
return uuidArgumentWith(name, option -> {
992+
});
993+
}
994+
995+
public ArgumentBuilder uuidArgumentWith(@NotNull String name, @Nullable Consumer<Argument.Option<UUID>> options) {
996+
arguments.add(new UUIDArgument(name, options));
997+
return this;
998+
}
999+
9931000
/**
9941001
* Set command's process.<br>
9951002
* If arguments are not added, process set by this wouldn't work. Then you should override {@link net.kunmc.lab.commandlib.Command#execute(CommandContext)}

bukkit/src/main/java/net/kunmc/lab/commandlib/argument/OfflinePlayerArgument.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public OfflinePlayerArgument(String name) {
2020

2121
public OfflinePlayerArgument(String name, Consumer<Option<OfflinePlayer>> options) {
2222
super(name, StringArgumentType.string());
23+
2324
setSuggestionAction(sb -> {
2425
Arrays.stream(Bukkit.getOfflinePlayers())
2526
.filter(x -> filter() == null || filter().test(x))
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package net.kunmc.lab.commandlib.argument;
2+
3+
import com.google.common.collect.Lists;
4+
import com.mojang.brigadier.arguments.StringArgumentType;
5+
import com.mojang.brigadier.context.CommandContext;
6+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
7+
import net.kunmc.lab.commandlib.Argument;
8+
import net.kunmc.lab.commandlib.SuggestionBuilder;
9+
import net.kunmc.lab.commandlib.argument.exception.IncorrectArgumentInputException;
10+
import net.kyori.adventure.text.Component;
11+
import net.kyori.adventure.text.format.TextColor;
12+
import net.md_5.bungee.api.ChatColor;
13+
import net.minecraft.server.v1_16_R3.CommandListenerWrapper;
14+
import org.bukkit.Bukkit;
15+
import org.bukkit.OfflinePlayer;
16+
17+
import java.util.*;
18+
import java.util.function.Consumer;
19+
import java.util.stream.Collectors;
20+
21+
public class UUIDArgument extends Argument<UUID> {
22+
private static final List<String> uuidChars = Collections.unmodifiableList(Lists.newArrayList("a",
23+
"b",
24+
"c",
25+
"d",
26+
"e",
27+
"f",
28+
"A",
29+
"B",
30+
"C",
31+
"D",
32+
"E",
33+
"F",
34+
"1",
35+
"2",
36+
"3",
37+
"4",
38+
"5",
39+
"6",
40+
"7",
41+
"8",
42+
"9"));
43+
44+
public UUIDArgument(String name) {
45+
this(name, option -> {
46+
});
47+
}
48+
49+
public UUIDArgument(String name, Consumer<Option<UUID>> options) {
50+
super(name, StringArgumentType.string());
51+
52+
setSuggestionAction(sb -> {
53+
Map<String, UUID> nameToUUID = Arrays.stream(Bukkit.getOfflinePlayers())
54+
.filter(x -> x.getName() != null)
55+
.filter(x -> filter() == null || filter().test(x.getUniqueId()))
56+
.filter(x -> sb.getLatestInput()
57+
.isEmpty() || x.getName()
58+
.contains(sb.getLatestInput()))
59+
.collect(Collectors.toMap(OfflinePlayer::getName,
60+
OfflinePlayer::getUniqueId));
61+
nameToUUID.forEach((key, value) -> sb.suggest(key, value.toString()));
62+
63+
if (nameToUUID.isEmpty()) {
64+
suggestUUID(sb);
65+
}
66+
});
67+
setOptions(options);
68+
}
69+
70+
@Override
71+
public UUID cast(Object parsedArgument) {
72+
return ((UUID) parsedArgument);
73+
}
74+
75+
@Override
76+
public UUID parse(CommandContext<CommandListenerWrapper> ctx) throws CommandSyntaxException, IncorrectArgumentInputException {
77+
String s = StringArgumentType.getString(ctx, name);
78+
79+
OfflinePlayer p = Bukkit.getOfflinePlayerIfCached(s);
80+
if (p != null) {
81+
return p.getUniqueId();
82+
}
83+
84+
try {
85+
return UUID.fromString(s);
86+
} catch (IllegalArgumentException e) {
87+
throw new IncorrectArgumentInputException(Component.text(s + " is not found.")
88+
.color(TextColor.color(ChatColor.RED.getColor()
89+
.getRGB())),
90+
Component.text(s + " is not valid UUID.")
91+
.color(TextColor.color(ChatColor.RED.getColor()
92+
.getRGB())));
93+
}
94+
}
95+
96+
private void suggestUUID(SuggestionBuilder sb) {
97+
String s = sb.getLatestInput();
98+
if (s.isEmpty()) {
99+
return;
100+
}
101+
if (!isValidInput(s)) {
102+
return;
103+
}
104+
105+
if (s.length() == 8 || s.length() == 13 || s.length() == 18 || s.length() == 23) {
106+
sb.suggest(s + "-");
107+
return;
108+
}
109+
110+
uuidChars.stream()
111+
.map(x -> s + x)
112+
.forEach(sb::suggest);
113+
}
114+
115+
private boolean isValidInput(String s) {
116+
if (s.length() > 36) {
117+
return false;
118+
}
119+
120+
for (int i = 0; i < s.length(); i++) {
121+
String c = String.valueOf(s.charAt(i));
122+
123+
if (i == 8 || i == 13 || i == 18 || i == 23) {
124+
if (!c.equals("-")) {
125+
return false;
126+
}
127+
continue;
128+
}
129+
130+
if (!uuidChars.contains(c)) {
131+
return false;
132+
}
133+
}
134+
135+
return true;
136+
}
137+
}

forge/src/main/java/net/kunmc/lab/commandlib/ArgumentBuilder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
import org.jetbrains.annotations.NotNull;
1616
import org.jetbrains.annotations.Nullable;
1717

18-
import java.util.ArrayList;
19-
import java.util.Collection;
20-
import java.util.List;
21-
import java.util.Map;
18+
import java.util.*;
2219
import java.util.function.Consumer;
2320
import java.util.function.Predicate;
2421
import java.util.function.Supplier;
@@ -1017,6 +1014,16 @@ public ArgumentBuilder unparsedArgumentWith(@NotNull String name,
10171014
return this;
10181015
}
10191016

1017+
public ArgumentBuilder uuidArgument(@NotNull String name) {
1018+
return uuidArgumentWith(name, option -> {
1019+
});
1020+
}
1021+
1022+
public ArgumentBuilder uuidArgumentWith(@NotNull String name, @Nullable Consumer<Argument.Option<UUID>> options) {
1023+
arguments.add(new UUIDArgument(name, options));
1024+
return this;
1025+
}
1026+
10201027
/**
10211028
* Set command's process.<br>
10221029
* If arguments are not added, process set by this wouldn't work. Then you should override {@link net.kunmc.lab.commandlib.Command#execute(CommandContext)}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package net.kunmc.lab.commandlib.argument;
2+
3+
import com.google.common.collect.Lists;
4+
import com.mojang.authlib.GameProfile;
5+
import com.mojang.brigadier.arguments.StringArgumentType;
6+
import com.mojang.brigadier.context.CommandContext;
7+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
8+
import net.kunmc.lab.commandlib.Argument;
9+
import net.kunmc.lab.commandlib.SuggestionBuilder;
10+
import net.kunmc.lab.commandlib.argument.exception.IncorrectArgumentInputException;
11+
import net.minecraft.command.CommandSource;
12+
import net.minecraft.server.management.PlayerProfileCache;
13+
import net.minecraft.util.text.StringTextComponent;
14+
import net.minecraft.util.text.TextFormatting;
15+
import net.minecraftforge.fml.server.ServerLifecycleHooks;
16+
17+
import java.util.*;
18+
import java.util.function.Consumer;
19+
import java.util.stream.Collectors;
20+
21+
public class UUIDArgument extends Argument<UUID> {
22+
private static final List<String> uuidChars = Collections.unmodifiableList(Lists.newArrayList("a",
23+
"b",
24+
"c",
25+
"d",
26+
"e",
27+
"f",
28+
"A",
29+
"B",
30+
"C",
31+
"D",
32+
"E",
33+
"F",
34+
"1",
35+
"2",
36+
"3",
37+
"4",
38+
"5",
39+
"6",
40+
"7",
41+
"8",
42+
"9"));
43+
44+
public UUIDArgument(String name) {
45+
this(name, option -> {
46+
});
47+
}
48+
49+
public UUIDArgument(String name, Consumer<Option<UUID>> options) {
50+
super(name, StringArgumentType.string());
51+
52+
setSuggestionAction(sb -> {
53+
Map<String, UUID> nameToUUID = sb.getHandle()
54+
.getSource()
55+
.getPlayerNames()
56+
.stream()
57+
.map(getPlayerProfileCache()::getGameProfileForUsername)
58+
.filter(Objects::nonNull)
59+
.filter(x -> Objects.nonNull(x.getName()))
60+
.filter(x -> filter() == null || filter().test(x.getId()))
61+
.filter(x -> sb.getLatestInput()
62+
.isEmpty() || x.getName()
63+
.contains(sb.getLatestInput()))
64+
.collect(Collectors.toMap(GameProfile::getName, GameProfile::getId));
65+
nameToUUID.forEach((key, value) -> sb.suggest(key, value.toString()));
66+
67+
if (nameToUUID.isEmpty()) {
68+
suggestUUID(sb);
69+
}
70+
});
71+
setOptions(options);
72+
}
73+
74+
@Override
75+
public UUID cast(Object parsedArgument) {
76+
return ((UUID) parsedArgument);
77+
}
78+
79+
@Override
80+
public UUID parse(CommandContext<CommandSource> ctx) throws CommandSyntaxException, IncorrectArgumentInputException {
81+
String s = StringArgumentType.getString(ctx, name);
82+
83+
GameProfile gameProfile = getPlayerProfileCache().getGameProfileForUsername(s);
84+
if (gameProfile != null) {
85+
return gameProfile.getId();
86+
}
87+
88+
try {
89+
return UUID.fromString(s);
90+
} catch (IllegalArgumentException e) {
91+
throw new IncorrectArgumentInputException(new StringTextComponent(TextFormatting.RED + s + " is not found."),
92+
new StringTextComponent(TextFormatting.RED + s + " is not valid UUID."));
93+
}
94+
}
95+
96+
private void suggestUUID(SuggestionBuilder sb) {
97+
String s = sb.getLatestInput();
98+
if (s.isEmpty()) {
99+
return;
100+
}
101+
if (!isValidInput(s)) {
102+
return;
103+
}
104+
105+
if (s.length() == 8 || s.length() == 13 || s.length() == 18 || s.length() == 23) {
106+
sb.suggest(s + "-");
107+
return;
108+
}
109+
110+
uuidChars.stream()
111+
.map(x -> s + x)
112+
.forEach(sb::suggest);
113+
}
114+
115+
private boolean isValidInput(String s) {
116+
if (s.length() > 36) {
117+
return false;
118+
}
119+
120+
for (int i = 0; i < s.length(); i++) {
121+
String c = String.valueOf(s.charAt(i));
122+
123+
if (i == 8 || i == 13 || i == 18 || i == 23) {
124+
if (!c.equals("-")) {
125+
return false;
126+
}
127+
continue;
128+
}
129+
130+
if (!uuidChars.contains(c)) {
131+
return false;
132+
}
133+
}
134+
135+
return true;
136+
}
137+
138+
private static PlayerProfileCache getPlayerProfileCache() {
139+
return ServerLifecycleHooks.getCurrentServer()
140+
.getPlayerProfileCache();
141+
}
142+
}

0 commit comments

Comments
 (0)