diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCaptionKeys.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCaptionKeys.java
index c3cdc438..70a9897f 100644
--- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCaptionKeys.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCaptionKeys.java
@@ -31,7 +31,7 @@
*/
public final class ArcCaptionKeys {
- private static final Collection
RECOGNIZED_CAPTIONS = new ArrayList<>(7);
+ private static final Collection RECOGNIZED_CAPTIONS = new ArrayList<>(3);
/**
* Variables: {@code {input}}.
@@ -48,26 +48,6 @@ public final class ArcCaptionKeys {
*/
public static final Caption ARGUMENT_PARSE_FAILURE_TEAM = of("argument.parse.failure.team");
- /**
- * Variables: {@code {syntax}}.
- */
- public static final Caption COMMAND_INVALID_SYNTAX = of("command.invalid.syntax");
-
- /**
- * Variables: {@code {permission}}.
- */
- public static final Caption COMMAND_INVALID_PERMISSION = of("command.invalid.permission");
-
- /**
- * Variables: {@code {command}}.
- */
- public static final Caption COMMAND_FAILURE_NO_SUCH_COMMAND = of("command.failure.no_such_command");
-
- /**
- * Variables: {@code {message}}.
- */
- public static final Caption COMMAND_FAILURE_EXECUTION = of("command.failure.execution");
-
private ArcCaptionKeys() {}
private static Caption of(final String key) {
diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/PermissionChecker.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandContextKeys.java
similarity index 72%
rename from distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/PermissionChecker.java
rename to distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandContextKeys.java
index 9d6df2f5..69061457 100644
--- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/PermissionChecker.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandContextKeys.java
@@ -18,4 +18,13 @@
*/
package com.xpdustry.distributor.command.cloud;
-public interface PermissionChecker {}
+import io.leangen.geantyref.TypeToken;
+import org.incendo.cloud.key.CloudKey;
+
+public final class ArcCommandContextKeys {
+
+ public static final CloudKey MINDUSTRY_ADMIN =
+ CloudKey.of("mindustry:admin", TypeToken.get(Boolean.class));
+
+ private ArcCommandContextKeys() {}
+}
diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java
index 5b4425da..323b5bcd 100644
--- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/ArcCommandManager.java
@@ -92,6 +92,15 @@ public ArcCommandManager(
TypeToken.get(Team.class),
params ->
new TeamParser<>(params.get(ArcParserParameters.TEAM_MODE, TeamParser.TeamMode.BASE)));
+
+ this.registerCommandPreProcessor(ctx -> {
+ final var reversed =
+ this.senderMapper().reverse(ctx.commandContext().sender());
+ ctx.commandContext()
+ .store(
+ ArcCommandContextKeys.MINDUSTRY_ADMIN,
+ reversed.isServer() || reversed.getPlayer().admin());
+ });
}
@Override
diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerInfoParser.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerInfoParser.java
index 11a1636e..43f6812e 100644
--- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerInfoParser.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerInfoParser.java
@@ -18,13 +18,7 @@
*/
package com.xpdustry.distributor.command.cloud.parser;
-import arc.Core;
-import com.xpdustry.distributor.core.DistributorProvider;
-import com.xpdustry.distributor.core.collection.ArcCollections;
-import com.xpdustry.distributor.core.player.PlayerLookup;
-import java.util.concurrent.CompletableFuture;
-import mindustry.gen.Groups;
-import mindustry.gen.Player;
+import com.xpdustry.distributor.command.cloud.ArcCommandContextKeys;
import mindustry.net.Administration;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.component.CommandComponent;
@@ -33,10 +27,9 @@
import org.incendo.cloud.parser.ArgumentParseResult;
import org.incendo.cloud.parser.ArgumentParser;
import org.incendo.cloud.parser.ParserDescriptor;
-import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider;
-public final class PlayerInfoParser implements ArgumentParser.FutureArgumentParser {
+public final class PlayerInfoParser implements ArgumentParser {
public static ParserDescriptor playerInfoParser() {
return ParserDescriptor.of(new PlayerInfoParser<>(), Administration.PlayerInfo.class);
@@ -47,33 +40,24 @@ public static CommandComponent.Builder playerI
}
@Override
- public CompletableFuture> parseFuture(
- final CommandContext ctx, final CommandInput input) {
+ public ArgumentParseResult parse(final CommandContext ctx, final CommandInput input) {
final var query = input.readString();
- return DistributorProvider.get()
- .getService(PlayerLookup.class)
- .orElseThrow()
- .findOfflinePlayers(query, true)
- .thenApply(result -> {
- if (result.isEmpty()) {
- return ArgumentParseResult.failure(
- new PlayerParseException.PlayerNotFound(PlayerInfoParser.class, query, ctx));
- } else if (result.size() > 1) {
- return ArgumentParseResult.failure(
- new PlayerParseException.TooManyPlayers(PlayerInfoParser.class, query, ctx));
- } else {
- return ArgumentParseResult.success(result.get(0));
- }
- });
+ final var result =
+ PlayerLookup.findOfflinePlayers(query, ctx.getOrDefault(ArcCommandContextKeys.MINDUSTRY_ADMIN, false));
+ if (result.isEmpty()) {
+ return ArgumentParseResult.failure(
+ new PlayerParseException.PlayerNotFound(PlayerInfoParser.class, query, ctx));
+ } else if (result.size() > 1) {
+ return ArgumentParseResult.failure(
+ new PlayerParseException.TooManyPlayers(PlayerInfoParser.class, query, ctx));
+ } else {
+ return ArgumentParseResult.success(result.iterator().next());
+ }
}
+ @SuppressWarnings("unchecked")
@Override
public @NonNull SuggestionProvider suggestionProvider() {
- return (ctx, input) -> CompletableFuture.supplyAsync(
- () -> ArcCollections.immutableList(Groups.player).stream()
- .map(Player::plainName)
- .map(Suggestion::simple)
- .toList(),
- Core.app::post);
+ return (SuggestionProvider) PlayerParser.SUGGESTION_PROVIDER;
}
}
diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/player/SimplePlayerLookup.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerLookup.java
similarity index 65%
rename from distributor-common/src/main/java/com/xpdustry/distributor/core/player/SimplePlayerLookup.java
rename to distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerLookup.java
index e7b711d8..00335d21 100644
--- a/distributor-common/src/main/java/com/xpdustry/distributor/core/player/SimplePlayerLookup.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerLookup.java
@@ -16,37 +16,27 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.xpdustry.distributor.core.player;
+package com.xpdustry.distributor.command.cloud.parser;
-import arc.Core;
import arc.util.Strings;
import com.xpdustry.distributor.core.collection.ArcCollections;
+import com.xpdustry.distributor.core.player.MUUID;
import java.text.Normalizer;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
import mindustry.Vars;
import mindustry.gen.Groups;
import mindustry.gen.Player;
import mindustry.net.Administration;
-final class SimplePlayerLookup implements PlayerLookup {
+final class PlayerLookup {
- static final SimplePlayerLookup INSTANCE = new SimplePlayerLookup();
-
- /**
- * Finds online players their its name, UUID or entity ID.
- *
- * @param query the query
- * @param admin whether the query should also search by sensitive IDs such as MUUID
- * @return the list player of matching players
- */
- @Override
- public List findOnlinePlayers(final String query, final boolean admin) {
+ public static Collection findOnlinePlayers(final String query, final boolean admin) {
if (query.startsWith("#")) {
final var id = Strings.parseInt(query.substring(1), -1);
final var players = ArcCollections.immutableList(Groups.player).stream()
@@ -83,24 +73,18 @@ public List findOnlinePlayers(final String query, final boolean admin) {
return matches == 1 ? Collections.singletonList(match) : Collections.unmodifiableList(result);
}
- @Override
- public CompletableFuture> findOfflinePlayers(
- final String query, final boolean admin) {
- return CompletableFuture.supplyAsync(
- () -> {
- final Set result = new LinkedHashSet<>();
- for (final var online : findOnlinePlayers(query, admin)) {
- result.add(online.getInfo());
- }
- if (admin && MUUID.isUuid(query)) {
- final var info = Vars.netServer.admins.getInfoOptional(query);
- if (info != null) {
- result.add(info);
- }
- }
- return List.copyOf(result);
- },
- Core.app::post);
+ static Collection findOfflinePlayers(final String query, final boolean admin) {
+ final Set result = new LinkedHashSet<>();
+ for (final var online : findOnlinePlayers(query, admin)) {
+ result.add(online.getInfo());
+ }
+ if (admin && MUUID.isUuid(query)) {
+ final var info = Vars.netServer.admins.getInfoOptional(query);
+ if (info != null) {
+ result.add(info);
+ }
+ }
+ return Collections.unmodifiableSet(result);
}
// https://stackoverflow.com/a/4122207
diff --git a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerParser.java b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerParser.java
index c3431b03..260bc3ef 100644
--- a/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerParser.java
+++ b/distributor-command-cloud/src/main/java/com/xpdustry/distributor/command/cloud/parser/PlayerParser.java
@@ -19,9 +19,8 @@
package com.xpdustry.distributor.command.cloud.parser;
import arc.Core;
-import com.xpdustry.distributor.core.DistributorProvider;
+import com.xpdustry.distributor.command.cloud.ArcCommandContextKeys;
import com.xpdustry.distributor.core.collection.ArcCollections;
-import com.xpdustry.distributor.core.player.PlayerLookup;
import java.util.concurrent.CompletableFuture;
import mindustry.gen.Groups;
import mindustry.gen.Player;
@@ -37,6 +36,13 @@
public final class PlayerParser implements ArgumentParser {
+ static SuggestionProvider> SUGGESTION_PROVIDER = (ctx, input) -> CompletableFuture.supplyAsync(
+ () -> ArcCollections.immutableList(Groups.player).stream()
+ .map(Player::plainName)
+ .map(Suggestion::simple)
+ .toList(),
+ Core.app::post);
+
public static ParserDescriptor playerParser() {
return ParserDescriptor.of(new PlayerParser<>(), Player.class);
}
@@ -48,16 +54,14 @@ public static CommandComponent.Builder playerComponent() {
@Override
public ArgumentParseResult parse(final CommandContext ctx, final CommandInput input) {
final var query = input.readString();
- final var result = DistributorProvider.get()
- .getService(PlayerLookup.class)
- .orElseThrow()
- .findOnlinePlayers(query, true);
- if (result.isEmpty()) {
+ final var players =
+ PlayerLookup.findOnlinePlayers(query, ctx.getOrDefault(ArcCommandContextKeys.MINDUSTRY_ADMIN, false));
+ if (players.isEmpty()) {
return ArgumentParseResult.failure(new PlayerParseException.PlayerNotFound(PlayerParser.class, query, ctx));
- } else if (result.size() > 1) {
+ } else if (players.size() > 1) {
return ArgumentParseResult.failure(new PlayerParseException.TooManyPlayers(PlayerParser.class, query, ctx));
} else {
- return ArgumentParseResult.success(result.get(0));
+ return ArgumentParseResult.success(players.iterator().next());
}
}
@@ -67,13 +71,9 @@ public ArgumentParseResult parse(final CommandContext ctx, final Comm
return CompletableFuture.supplyAsync(() -> this.parse(ctx, input), Core.app::post);
}
+ @SuppressWarnings("unchecked")
@Override
public @NonNull SuggestionProvider suggestionProvider() {
- return (ctx, input) -> CompletableFuture.supplyAsync(
- () -> ArcCollections.immutableList(Groups.player).stream()
- .map(Player::plainName)
- .map(Suggestion::simple)
- .toList(),
- Core.app::post);
+ return (SuggestionProvider) SUGGESTION_PROVIDER;
}
}
diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/command/CommandSender.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/command/CommandSender.java
index 651dcfd0..142880ac 100644
--- a/distributor-common/src/main/java/com/xpdustry/distributor/core/command/CommandSender.java
+++ b/distributor-common/src/main/java/com/xpdustry/distributor/core/command/CommandSender.java
@@ -37,6 +37,11 @@ public boolean isPlayer() {
public boolean isServer() {
return false;
}
+
+ @Override
+ public Player getPlayer() {
+ throw new UnsupportedOperationException();
+ }
};
}
@@ -51,10 +56,17 @@ public boolean isPlayer() {
public boolean isServer() {
return true;
}
+
+ @Override
+ public Player getPlayer() {
+ throw new UnsupportedOperationException();
+ }
};
}
boolean isPlayer();
boolean isServer();
+
+ Player getPlayer();
}
diff --git a/distributor-common/src/main/java/com/xpdustry/distributor/core/player/PlayerLookup.java b/distributor-common/src/main/java/com/xpdustry/distributor/core/player/PlayerLookup.java
deleted file mode 100644
index 6425f5ee..00000000
--- a/distributor-common/src/main/java/com/xpdustry/distributor/core/player/PlayerLookup.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Distributor, a feature-rich framework for Mindustry plugins.
- *
- * Copyright (C) 2024 Xpdustry
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package com.xpdustry.distributor.core.player;
-
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import mindustry.gen.Player;
-import mindustry.net.Administration;
-
-public interface PlayerLookup {
-
- static PlayerLookup simple() {
- return SimplePlayerLookup.INSTANCE;
- }
-
- List findOnlinePlayers(final String query, final boolean admin);
-
- CompletableFuture> findOfflinePlayers(final String query, final boolean admin);
-}