Skip to content

Commit 61b081e

Browse files
authored
feat: improve the signs command on sponge (#1373)
### Motivation The commands on Sponge have no reasonable tab completion and would suggest parameters on commands that dont take any parameters. ### Modification Split the commands with literals only and commands with parameters into different command executors to ensure proper tab completion. ### Result Proper tab completion.
1 parent 50296fe commit 61b081e

2 files changed

Lines changed: 86 additions & 69 deletions

File tree

modules/signs/src/main/java/eu/cloudnetservice/modules/signs/platform/sponge/CommandRegistrationListener.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,31 @@ public CommandRegistrationListener(@NonNull Container<PluginContainer> platformD
4040

4141
@Listener
4242
public void handleCommandRegister(@NonNull RegisterCommandEvent<Command.Parameterized> event) {
43+
var signsCommand = new SignsCommand(() -> {
44+
var layer = InjectionLayer.findLayerOf(SignManagement.class);
45+
return layer.instance(SpongeSignManagement.class);
46+
});
47+
48+
var createCommand = Command.builder()
49+
.addParameters(
50+
Parameter.string().key(SignsCommand.TARGET_GROUP).build(),
51+
Parameter.string().key(SignsCommand.TARGET_TEMPLATE).optional().build())
52+
.executor(signsCommand::handleCreateAction)
53+
.build();
54+
var cleanupCommand = Command.builder()
55+
.addParameter(Parameter.string().key(SignsCommand.WORLD).optional().build())
56+
.executor(signsCommand::handleCleanupAction)
57+
.build();
58+
4359
event.register(
4460
this.plugin,
4561
Command.builder()
4662
.shortDescription(Component.text("Management of the signs"))
4763
.permission("cloudnet.command.cloudsign")
48-
.addParameters(
49-
Parameter.string().key(SignsCommand.ACTION).build(),
50-
Parameter.string().key(SignsCommand.TARGET_GROUP).optional().build(),
51-
Parameter.string().key(SignsCommand.TARGET_TEMPLATE).optional().build()
52-
)
53-
.executor(new SignsCommand(() -> {
54-
var layer = InjectionLayer.findLayerOf(SignManagement.class);
55-
return layer.instance(SpongeSignManagement.class);
56-
}))
64+
.addChild(createCommand, "create")
65+
.addChild(cleanupCommand, "cleanup")
66+
.addParameters(Parameter.choices("cleanupall", "removeall", "remove").key(SignsCommand.ACTION).build())
67+
.executor(signsCommand)
5768
.build(),
5869
"cloudsigns",
5970
"cs", "signs", "cloudsign");

modules/signs/src/main/java/eu/cloudnetservice/modules/signs/platform/sponge/functionality/SignsCommand.java

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
package eu.cloudnetservice.modules.signs.platform.sponge.functionality;
1818

19+
import eu.cloudnetservice.modules.signs.configuration.SignConfigurationEntry;
1920
import eu.cloudnetservice.modules.signs.configuration.SignsConfiguration;
2021
import eu.cloudnetservice.modules.signs.platform.sponge.SpongeSignManagement;
2122
import jakarta.inject.Inject;
2223
import jakarta.inject.Singleton;
2324
import java.util.Optional;
25+
import java.util.function.BiConsumer;
2426
import java.util.function.Supplier;
2527
import lombok.NonNull;
2628
import net.kyori.adventure.identity.Identity;
@@ -49,77 +51,67 @@ public SignsCommand(@NonNull Supplier<SpongeSignManagement> signManagement) {
4951
this.signManagement = signManagement;
5052
}
5153

52-
@Override
53-
public CommandResult execute(@NonNull CommandContext context) {
54-
if (!(context.subject() instanceof ServerPlayer player)) {
55-
context.sendMessage(Identity.nil(), Component.text("Only players may execute this command"));
56-
return CommandResult.success();
57-
}
58-
59-
var entry = this.signManagement.get().applicableSignConfigurationEntry();
60-
if (entry == null) {
61-
SignsConfiguration.sendMessage(
62-
"command-cloudsign-no-entry",
63-
message -> player.sendMessage(Component.text(message)));
64-
return CommandResult.success();
65-
}
54+
public @NonNull CommandResult handleCreateAction(@NonNull CommandContext context) {
55+
return this.executeCommand(context, (player, entry) -> {
56+
var targetGroup = context.requireOne(TARGET_GROUP);
57+
var targetTemplatePath = context.one(TARGET_TEMPLATE).orElse(null);
6658

67-
var type = context.one(ACTION).orElse(null);
68-
var targetGroup = context.one(TARGET_GROUP).orElse(null);
69-
var targetTemplatePath = context.one(TARGET_TEMPLATE).orElse(null);
70-
var world = context.one(WORLD).orElse(player.world().properties().name());
59+
var hit = this.getTargetBlock(player);
60+
if (hit.isEmpty()) {
61+
return;
62+
}
7163

72-
if (type != null) {
73-
if (type.equalsIgnoreCase("create") && targetGroup != null) {
74-
var hit = this.getTargetBlock(player);
75-
if (hit.isEmpty()) {
76-
return CommandResult.success();
77-
}
64+
var loc = this.signManagement.get().convertPosition(hit.get().serverLocation());
65+
var sign = this.signManagement.get().platformSignAt(loc);
66+
if (sign != null) {
67+
SignsConfiguration.sendMessage(
68+
"command-cloudsign-sign-already-exist",
69+
message -> player.sendMessage(Component.text(message)));
70+
} else {
71+
//noinspection ConstantConditions
72+
this.signManagement.get().createSign(new eu.cloudnetservice.modules.signs.Sign(
73+
targetGroup,
74+
targetTemplatePath,
75+
loc));
76+
SignsConfiguration.sendMessage(
77+
"command-cloudsign-create-success",
78+
m -> player.sendMessage(Component.text(m)),
79+
m -> m.replace("%group%", targetGroup));
80+
}
81+
});
82+
}
7883

79-
var loc = this.signManagement.get().convertPosition(hit.get().serverLocation());
80-
var sign = this.signManagement.get().platformSignAt(loc);
81-
if (sign != null) {
82-
SignsConfiguration.sendMessage(
83-
"command-cloudsign-sign-already-exist",
84-
message -> player.sendMessage(Component.text(message)));
85-
} else {
86-
//noinspection ConstantConditions
87-
this.signManagement.get().createSign(new eu.cloudnetservice.modules.signs.Sign(
88-
targetGroup,
89-
targetTemplatePath,
90-
loc));
91-
SignsConfiguration.sendMessage(
92-
"command-cloudsign-create-success",
93-
m -> player.sendMessage(Component.text(m)),
94-
m -> m.replace("%group%", targetGroup));
95-
}
84+
public @NonNull CommandResult handleCleanupAction(@NonNull CommandContext context) {
85+
return this.executeCommand(context, (player, entry) -> {
86+
var world = context.one(WORLD).orElse(player.world().properties().name());
87+
var removed = this.signManagement.get().removeMissingSigns(world);
88+
SignsConfiguration.sendMessage(
89+
"command-cloudsign-cleanup-success",
90+
m -> player.sendMessage(Component.text(m)),
91+
m -> m.replace("%amount%", Integer.toString(removed)));
92+
});
93+
}
9694

97-
return CommandResult.success();
98-
} else if (type.equalsIgnoreCase("cleanupall")) {
95+
@Override
96+
public CommandResult execute(@NonNull CommandContext context) {
97+
return this.executeCommand(context, (player, entry) -> {
98+
var type = context.requireOne(ACTION);
99+
if (type.equalsIgnoreCase("cleanupall")) {
99100
var removed = this.signManagement.get().removeAllMissingSigns();
100101
SignsConfiguration.sendMessage(
101102
"command-cloudsign-cleanup-success",
102103
m -> player.sendMessage(Component.text(m)),
103104
m -> m.replace("%amount%", Integer.toString(removed)));
104-
return CommandResult.success();
105-
} else if (type.equalsIgnoreCase("cleanup")) {
106-
var removed = this.signManagement.get().removeMissingSigns(world);
107-
SignsConfiguration.sendMessage(
108-
"command-cloudsign-cleanup-success",
109-
m -> player.sendMessage(Component.text(m)),
110-
m -> m.replace("%amount%", Integer.toString(removed)));
111-
return CommandResult.success();
112105
} else if (type.equalsIgnoreCase("removeall")) {
113106
var removed = this.signManagement.get().deleteAllSigns();
114107
SignsConfiguration.sendMessage(
115108
"command-cloudsign-bulk-remove-success",
116109
m -> player.sendMessage(Component.text(m)),
117110
m -> m.replace("%amount%", Integer.toString(removed)));
118-
return CommandResult.success();
119111
} else if (type.equalsIgnoreCase("remove")) {
120112
var hit = this.getTargetBlock(player);
121113
if (hit.isEmpty()) {
122-
return CommandResult.success();
114+
return;
123115
}
124116

125117
var loc = this.signManagement.get().convertPosition(hit.get().serverLocation());
@@ -134,17 +126,31 @@ public CommandResult execute(@NonNull CommandContext context) {
134126
"command-cloudsign-remove-not-existing",
135127
m -> player.sendMessage(Component.text(m)));
136128
}
137-
138-
return CommandResult.success();
139129
}
130+
});
131+
}
132+
133+
private @NonNull CommandResult executeCommand(
134+
@NonNull CommandContext context,
135+
@NonNull BiConsumer<ServerPlayer, SignConfigurationEntry> commandHandler
136+
) {
137+
if (!(context.subject() instanceof ServerPlayer player)) {
138+
context.sendMessage(Identity.nil(), Component.text("Only players may execute this command"));
139+
return CommandResult.success();
140+
}
141+
142+
var entry = this.signManagement.get().applicableSignConfigurationEntry();
143+
if (entry == null) {
144+
SignsConfiguration.sendMessage(
145+
"command-cloudsign-no-entry",
146+
message -> player.sendMessage(Component.text(message)));
147+
return CommandResult.success();
140148
}
141149

142-
context.sendMessage(Identity.nil(), Component.text("§7/cloudsigns create <targetGroup> [templatePath]"));
143-
context.sendMessage(Identity.nil(), Component.text("§7/cloudsigns remove"));
144-
context.sendMessage(Identity.nil(), Component.text("§7/cloudsigns removeAll"));
145-
context.sendMessage(Identity.nil(), Component.text("§7/cloudsigns cleanup [world]"));
146-
context.sendMessage(Identity.nil(), Component.text("§7/cloudsigns cleanupAll"));
150+
// call the actual command handler
151+
commandHandler.accept(player, entry);
147152

153+
// it's always a success
148154
return CommandResult.success();
149155
}
150156

0 commit comments

Comments
 (0)