Skip to content

Commit 721c552

Browse files
authored
Initial update for new Paper command API & suppress new compile warnings on JDK 21 (#65)
* Initial update for new Paper command API & suppress new compile warnings on JDK 21 * Add back Paper javadoc links * Simplify modern paper handling with new registration flags api Also fixes a back-compat issue in CloudBrigadierCommand * Update cloud-build-logic * unify namespace stripping logic * resend commands after root node deletion * Implement unsafe registration and root node deletion * Add ModernPaperCommandManager with support for bootstrap registration * Update example-bukkit build script * Register bukkit captions in ModernPaperCommandManager * Update for dummy context removal * Split modern paper example to separate project * Rename PaperCommandManager to LegacyPaperCommandManager and ModernPaperCommandManager to PaperCommandManager * Simplify bootstrapper
1 parent 3f725a8 commit 721c552

50 files changed

Lines changed: 1837 additions & 571 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: actions/setup-java@v4
1919
with:
2020
distribution: 'temurin'
21-
java-version: 17
21+
java-version: 21
2222
- uses: gradle/actions/setup-gradle@v3
2323
- name: Build
2424
run: ./gradlew build

cloud-brigadier/src/main/java/org/incendo/cloud/brigadier/CloudBrigadierCommand.java

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@
2525

2626
import com.mojang.brigadier.Command;
2727
import com.mojang.brigadier.context.CommandContext;
28+
import com.mojang.brigadier.context.ParsedCommandNode;
29+
import com.mojang.brigadier.context.StringRange;
30+
import java.lang.reflect.Method;
31+
import java.util.List;
32+
import java.util.Map;
2833
import java.util.function.Function;
34+
import java.util.stream.Collectors;
2935
import org.apiguardian.api.API;
3036
import org.checkerframework.checker.nullness.qual.NonNull;
3137
import org.incendo.cloud.CommandManager;
3238
import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser;
39+
import org.incendo.cloud.type.tuple.Pair;
3340

3441
/**
3542
* Brigadier {@link Command} implementation that delegates to cloud.
@@ -79,14 +86,60 @@ public CloudBrigadierCommand(
7986
@Override
8087
public int run(final @NonNull CommandContext<S> ctx) {
8188
final S source = ctx.getSource();
82-
final String input = ctx.getInput().substring(ctx.getLastChild().getNodes().get(0).getRange().getStart());
89+
final String input = this.inputMapper.apply(
90+
ctx.getInput().substring(parsedNodes(ctx.getLastChild()).get(0).second().getStart())
91+
);
8392
final C sender = this.brigadierManager.senderMapper().map(source);
8493

8594
this.commandManager.commandExecutor().executeCommand(
8695
sender,
87-
this.inputMapper.apply(input),
96+
input,
8897
cloudContext -> cloudContext.store(WrappedBrigadierParser.COMMAND_CONTEXT_BRIGADIER_NATIVE_SENDER, source)
8998
);
9099
return com.mojang.brigadier.Command.SINGLE_SUCCESS;
91100
}
101+
102+
/**
103+
* Return type changed at some point, but information is essentially the same. This code works for both versions of the
104+
* method.
105+
*
106+
* @param commandContext command context
107+
* @param <S> source type
108+
* @return parsed nodes
109+
*/
110+
@SuppressWarnings({"unchecked", "rawtypes"})
111+
public static <S> List<Pair<com.mojang.brigadier.tree.CommandNode<S>, StringRange>> parsedNodes(
112+
final com.mojang.brigadier.context.CommandContext<S> commandContext
113+
) {
114+
try {
115+
final Method getNodesMethod = commandContext.getClass().getDeclaredMethod("getNodes");
116+
final Object nodes = getNodesMethod.invoke(commandContext);
117+
if (nodes instanceof List) {
118+
return ParsedCommandNodeHandler.toPairList((List) nodes);
119+
} else if (nodes instanceof Map) {
120+
return ((Map<com.mojang.brigadier.tree.CommandNode<S>, StringRange>) nodes).entrySet().stream()
121+
.map(entry -> Pair.of(entry.getKey(), entry.getValue()))
122+
.collect(Collectors.toList());
123+
} else {
124+
throw new IllegalStateException();
125+
}
126+
} catch (final ReflectiveOperationException ex) {
127+
throw new RuntimeException(ex);
128+
}
129+
}
130+
131+
132+
// Inner class to prevent attempting to load ParsedCommandNode when it doesn't exist
133+
@SuppressWarnings("unchecked")
134+
private static final class ParsedCommandNodeHandler {
135+
136+
private ParsedCommandNodeHandler() {
137+
}
138+
139+
private static <S> List<Pair<com.mojang.brigadier.tree.CommandNode<S>, StringRange>> toPairList(final List<?> nodes) {
140+
return ((List<ParsedCommandNode<S>>) nodes).stream()
141+
.map(n -> Pair.of(n.getNode(), n.getRange()))
142+
.collect(Collectors.toList());
143+
}
144+
}
92145
}

cloud-brigadier/src/main/java/org/incendo/cloud/brigadier/suggestion/BrigadierSuggestionFactory.java

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,10 @@
2323
//
2424
package org.incendo.cloud.brigadier.suggestion;
2525

26-
import com.mojang.brigadier.context.ParsedCommandNode;
27-
import com.mojang.brigadier.context.StringRange;
2826
import com.mojang.brigadier.suggestion.Suggestions;
2927
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
30-
import com.mojang.brigadier.tree.CommandNode;
31-
import java.lang.reflect.Method;
3228
import java.util.ArrayList;
3329
import java.util.List;
34-
import java.util.Map;
3530
import java.util.Objects;
3631
import java.util.Set;
3732
import java.util.concurrent.CompletableFuture;
@@ -41,10 +36,12 @@
4136
import org.checkerframework.checker.nullness.qual.Nullable;
4237
import org.incendo.cloud.CommandManager;
4338
import org.incendo.cloud.brigadier.CloudBrigadierManager;
39+
import org.incendo.cloud.brigadier.parser.WrappedBrigadierParser;
4440
import org.incendo.cloud.component.CommandComponent;
4541
import org.incendo.cloud.context.CommandContext;
4642
import org.incendo.cloud.suggestion.SuggestionFactory;
47-
import org.incendo.cloud.type.tuple.Pair;
43+
44+
import static org.incendo.cloud.brigadier.CloudBrigadierCommand.parsedNodes;
4845

4946
/**
5047
* Produces Brigadier suggestions by invoking the Cloud suggestion provider.
@@ -82,14 +79,12 @@ public BrigadierSuggestionFactory(
8279
*
8380
* @param senderContext the brigadier context
8481
* @param parentNode the parent command node
85-
* @param component the command component to generate suggestions for
8682
* @param builder the suggestion builder to generate suggestions with
8783
* @return future that completes with the suggestions
8884
*/
8985
public @NonNull CompletableFuture<@NonNull Suggestions> buildSuggestions(
9086
final com.mojang.brigadier.context.@NonNull CommandContext<S> senderContext,
9187
final org.incendo.cloud.internal.@Nullable CommandNode<C> parentNode,
92-
final @NonNull CommandComponent<C> component,
9388
final @NonNull SuggestionsBuilder builder
9489
) {
9590
final C cloudSender = this.cloudBrigadierManager.senderMapper().map(senderContext.getSource());
@@ -98,7 +93,9 @@ public BrigadierSuggestionFactory(
9893
cloudSender,
9994
this.commandManager
10095
);
101-
String command = builder.getInput().substring(getNodes(senderContext.getLastChild()).get(0).second().getStart());
96+
commandContext.store(WrappedBrigadierParser.COMMAND_CONTEXT_BRIGADIER_NATIVE_SENDER, senderContext.getSource());
97+
String command = builder.getInput()
98+
.substring(parsedNodes(senderContext.getLastChild()).get(0).second().getStart());
10299

103100
/* Remove namespace */
104101
final String leading = command.split(" ")[0];
@@ -135,48 +132,4 @@ public BrigadierSuggestionFactory(
135132
return suggestionsBuilder.build();
136133
});
137134
}
138-
139-
/**
140-
* Return type changed at some point, but information is essentially the same. This code works for both versions of the
141-
* method.
142-
*
143-
* @param commandContext command context
144-
* @param <S> source type
145-
* @return parsed nodes
146-
*/
147-
@SuppressWarnings("unchecked")
148-
private static <S> List<Pair<CommandNode<S>, StringRange>> getNodes(
149-
final com.mojang.brigadier.context.CommandContext<S> commandContext
150-
) {
151-
try {
152-
final Method getNodesMethod = commandContext.getClass().getDeclaredMethod("getNodes");
153-
final Object nodes = getNodesMethod.invoke(commandContext);
154-
if (nodes instanceof List) {
155-
return ParsedCommandNodeHandler.toPairList((List) nodes);
156-
} else if (nodes instanceof Map) {
157-
return ((Map<CommandNode<S>, StringRange>) nodes).entrySet().stream()
158-
.map(entry -> Pair.of(entry.getKey(), entry.getValue()))
159-
.collect(Collectors.toList());
160-
} else {
161-
throw new IllegalStateException();
162-
}
163-
} catch (final ReflectiveOperationException ex) {
164-
throw new RuntimeException(ex);
165-
}
166-
}
167-
168-
169-
// Inner class to prevent attempting to load ParsedCommandNode when it doesn't exist
170-
@SuppressWarnings("unchecked")
171-
private static final class ParsedCommandNodeHandler {
172-
173-
private ParsedCommandNodeHandler() {
174-
}
175-
176-
private static <S> List<Pair<CommandNode<S>, StringRange>> toPairList(final List<?> nodes) {
177-
return ((List<ParsedCommandNode<S>>) nodes).stream()
178-
.map(n -> Pair.of(n.getNode(), n.getRange()))
179-
.collect(Collectors.toList());
180-
}
181-
}
182135
}

cloud-brigadier/src/main/java/org/incendo/cloud/brigadier/suggestion/CloudDelegatingSuggestionProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ public CloudDelegatingSuggestionProvider(
6868
return this.brigadierSuggestionFactory.buildSuggestions(
6969
context,
7070
this.node.parent(),
71-
this.node.component(),
7271
builder
7372
);
7473
}

cloud-bukkit/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ dependencies {
1414
}
1515
}
1616

17+
configurations.javadocLinksSources {
18+
exclude("io.papermc.paper")
19+
}
20+
1721
spotless {
1822
java {
1923
targetExclude(file("src/main/java/cloud/commandframework/bukkit/internal/MinecraftArgumentTypes.java"))

cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/BukkitCommand.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.List;
3030
import java.util.Map;
3131
import java.util.Objects;
32-
import java.util.Optional;
3332
import java.util.logging.Level;
3433
import java.util.stream.Collectors;
3534
import org.apiguardian.api.API;
@@ -39,8 +38,8 @@
3938
import org.checkerframework.checker.nullness.qual.NonNull;
4039
import org.checkerframework.checker.nullness.qual.Nullable;
4140
import org.incendo.cloud.Command;
41+
import org.incendo.cloud.bukkit.internal.BukkitHelper;
4242
import org.incendo.cloud.component.CommandComponent;
43-
import org.incendo.cloud.description.CommandDescription;
4443
import org.incendo.cloud.internal.CommandNode;
4544
import org.incendo.cloud.permission.Permission;
4645
import org.incendo.cloud.suggestion.Suggestion;
@@ -57,20 +56,6 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
5756

5857
private boolean disabled;
5958

60-
private static @NonNull String description(final @NonNull Command<?> command) {
61-
final Optional<String> bukkitDescription = command.commandMeta().optional(BukkitCommandMeta.BUKKIT_DESCRIPTION);
62-
if (bukkitDescription.isPresent()) {
63-
return bukkitDescription.get();
64-
}
65-
66-
final CommandDescription description = command.commandDescription();
67-
if (!description.isEmpty()) {
68-
return description.description().textDescription();
69-
}
70-
71-
return command.rootComponent().description().textDescription();
72-
}
73-
7459
BukkitCommand(
7560
final @NonNull String label,
7661
final @NonNull List<@NonNull String> aliases,
@@ -80,7 +65,7 @@ final class BukkitCommand<C> extends org.bukkit.command.Command implements Plugi
8065
) {
8166
super(
8267
label,
83-
description(cloudCommand),
68+
BukkitHelper.description(cloudCommand),
8469
"",
8570
aliases
8671
);
@@ -129,7 +114,7 @@ public boolean execute(
129114

130115
@Override
131116
public @NonNull String getDescription() {
132-
return description(this.cloudCommand);
117+
return BukkitHelper.description(this.cloudCommand);
133118
}
134119

135120
@Override

0 commit comments

Comments
 (0)