From 7f26afda20c6056b6ac9469fe533f170f73b9144 Mon Sep 17 00:00:00 2001 From: Risto Lahtela <24460436+Rsl1122@users.noreply.github.com> Date: Tue, 8 Sep 2020 12:17:39 +0300 Subject: [PATCH] Implemented more tab completion --- .../djrapitops/plan/commands/PlanCommand.java | 78 ++++++++++++++++--- .../commands/use/PlayerChatFormatter.java | 1 - .../plan/storage/database/DBType.java | 10 +++ .../queries/objects/WebUserQueries.java | 27 +++++++ 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java index d845a9c55..d498c8a50 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java @@ -21,6 +21,7 @@ import com.djrapitops.plan.commands.use.Arguments; import com.djrapitops.plan.commands.use.CMDSender; import com.djrapitops.plan.commands.use.CommandWithSubcommands; import com.djrapitops.plan.commands.use.Subcommand; +import com.djrapitops.plan.delivery.domain.auth.User; import com.djrapitops.plan.gathering.importing.ImportSystem; import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.settings.Permissions; @@ -28,8 +29,11 @@ import com.djrapitops.plan.settings.locale.Locale; import com.djrapitops.plan.settings.locale.lang.DeepHelpLang; import com.djrapitops.plan.settings.locale.lang.HelpLang; import com.djrapitops.plan.storage.database.DBSystem; +import com.djrapitops.plan.storage.database.DBType; import com.djrapitops.plan.storage.database.queries.objects.ServerQueries; import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries; +import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries; +import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.utilities.java.Lists; import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; @@ -39,13 +43,14 @@ import com.djrapitops.plugin.logging.L; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; @Singleton public class PlanCommand { private final String commandName; + private final PlanFiles files; private final Locale locale; private final ColorScheme colors; private final Confirmation confirmation; @@ -61,6 +66,7 @@ public class PlanCommand { @Inject public PlanCommand( @Named("mainCommandName") String commandName, + PlanFiles files, Locale locale, ColorScheme colors, Confirmation confirmation, @@ -74,6 +80,7 @@ public class PlanCommand { ErrorLogger errorLogger ) { this.commandName = commandName; + this.files = files; this.locale = locale; this.colors = colors; this.confirmation = confirmation; @@ -150,8 +157,8 @@ public class PlanCommand { .requirePermission(Permissions.SERVER) .description(locale.getString(HelpLang.SERVER)) .inDepthDescription(locale.getString(DeepHelpLang.SERVER)) - .onTabComplete(this::serverNames) .onCommand(linkCommands::onServerCommand) + .onTabComplete(this::serverNames) .build(); } @@ -182,8 +189,8 @@ public class PlanCommand { .requirePermission(Permissions.PLAYER_SELF) .description(locale.getString(HelpLang.PLAYER)) .inDepthDescription(locale.getString(DeepHelpLang.PLAYER)) - .onTabComplete(this::playerNames) .onCommand(linkCommands::onPlayerCommand) + .onTabComplete(this::playerNames) .build(); } @@ -216,6 +223,7 @@ public class PlanCommand { .description(locale.getString(HelpLang.INGAME)) .inDepthDescription(locale.getString(DeepHelpLang.INGAME)) .onCommand(dataUtilityCommands::onInGame) + .onTabComplete(this::playerNames) .build(); } @@ -239,9 +247,21 @@ public class PlanCommand { .description(locale.getString(HelpLang.UNREGISTER)) .inDepthDescription(locale.getString(DeepHelpLang.UNREGISTER)) .onCommand((sender, arguments) -> registrationCommands.onUnregister(commandName, sender, arguments)) + .onTabComplete(this::webUserNames) .build(); } + private List webUserNames(CMDSender sender, Arguments arguments) { + if (!sender.hasPermission(Permissions.UNREGISTER_OTHER)) { + return Collections.emptyList(); + } + + String username = arguments.concatenate(" "); + return dbSystem.getDatabase().query(WebUserQueries.matchUsers(username)) + .stream().map(User::getUsername) + .collect(Collectors.toList()); + } + private Subcommand acceptCommand() { return Subcommand.builder() .aliases("accept", "yes", "y") @@ -284,7 +304,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.DISABLE)) .inDepthDescription(locale.getString(DeepHelpLang.DISABLE)) .onCommand(statusCommands::onDisable) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? Collections.singletonList("kickcount") : Collections.emptyList() + ).build(); } private Subcommand webUsersCommand() { @@ -323,7 +345,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_BACKUP)) .inDepthDescription(locale.getString(DeepHelpLang.DB_BACKUP)) .onCommand(databaseCommands::onBackup) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? DBType.names() : Collections.emptyList() + ).build(); } private Subcommand restoreCommand() { @@ -335,9 +359,31 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_RESTORE)) .inDepthDescription(locale.getString(DeepHelpLang.DB_RESTORE)) .onCommand((sender, arguments) -> databaseCommands.onRestore(commandName, sender, arguments)) + .onTabComplete(this::getBackupFilenames) .build(); } + private List getBackupFilenames(CMDSender sender, Arguments arguments) { + if (arguments.get(1).isPresent()) { + return DBType.names(); + } + Optional firstArgument = arguments.get(0); + if (!firstArgument.isPresent()) { + return Arrays.stream(files.getDataFolder().list()) + .filter(Objects::nonNull) + .filter(fileName -> fileName.endsWith(".db") + && !fileName.equalsIgnoreCase("database.db")) + .collect(Collectors.toList()); + } + String part = firstArgument.get(); + return Arrays.stream(files.getDataFolder().list()) + .filter(Objects::nonNull) + .filter(fileName -> fileName.startsWith(part) + && fileName.endsWith(".db") + && !fileName.equalsIgnoreCase("database.db")) + .collect(Collectors.toList()); + } + private Subcommand moveCommand() { return Subcommand.builder() .aliases("move") @@ -347,6 +393,7 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_MOVE)) .inDepthDescription(locale.getString(DeepHelpLang.DB_MOVE)) .onCommand((sender, arguments) -> databaseCommands.onMove(commandName, sender, arguments)) + .onTabComplete((sender, arguments) -> DBType.names()) .build(); } @@ -358,7 +405,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_HOTSWAP)) .inDepthDescription(locale.getString(DeepHelpLang.DB_HOTSWAP)) .onCommand(databaseCommands::onHotswap) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? DBType.names() : Collections.emptyList() + ).build(); } private Subcommand clearCommand() { @@ -369,7 +418,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_CLEAR)) .inDepthDescription(locale.getString(DeepHelpLang.DB_CLEAR)) .onCommand((sender, arguments) -> databaseCommands.onClear(commandName, sender, arguments)) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? DBType.names() : Collections.emptyList() + ).build(); } private Subcommand removeCommand() { @@ -380,6 +431,7 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_REMOVE)) .inDepthDescription(locale.getString(DeepHelpLang.DB_REMOVE)) .onCommand((sender, arguments) -> databaseCommands.onRemove(commandName, sender, arguments)) + .onTabComplete(this::playerNames) .build(); } @@ -391,6 +443,7 @@ public class PlanCommand { .description(locale.getString(HelpLang.DB_UNINSTALLED)) .inDepthDescription(locale.getString(DeepHelpLang.DB_UNINSTALLED)) .onCommand(databaseCommands::onUninstalled) + .onTabComplete(this::serverNames) .build(); } @@ -402,7 +455,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.EXPORT)) .inDepthDescription(locale.getString(DeepHelpLang.EXPORT)) .onCommand(dataUtilityCommands::onExport) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? Arrays.asList("players", "server_json") : Collections.emptyList() + ).build(); } private Subcommand importCommand() { @@ -415,7 +470,9 @@ public class PlanCommand { .description(locale.getString(HelpLang.IMPORT)) .inDepthDescription(locale.getString(DeepHelpLang.IMPORT)) .onCommand(dataUtilityCommands::onImport) - .build(); + .onTabComplete((sender, arguments) -> + arguments.isEmpty() ? importerNames : Collections.emptyList() + ).build(); } private Subcommand jsonCommand() { @@ -426,6 +483,7 @@ public class PlanCommand { .description(locale.getString(HelpLang.JSON)) .inDepthDescription(locale.getString(DeepHelpLang.JSON)) .onCommand(linkCommands::onJson) + .onTabComplete(this::playerNames) .build(); } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java index cdf2d1a3a..dc48e638b 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java @@ -20,7 +20,6 @@ public class PlayerChatFormatter extends ChatFormatter { @Override public int getWidth(String part) { - // TODO refactor return com.djrapitops.plan.utilities.chat.ChatFormatter.getPxMessageWidth(part); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/DBType.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/DBType.java index 5e2e148d9..1b8eb8610 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/DBType.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/DBType.java @@ -18,6 +18,8 @@ package com.djrapitops.plan.storage.database; import com.djrapitops.plan.storage.database.sql.building.Sql; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; /** @@ -106,6 +108,14 @@ public enum DBType { return false; } + public static List names() { + List names = new ArrayList<>(); + for (DBType value : values()) { + names.add(value.name); + } + return names; + } + public Sql getSql() { return sql; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/WebUserQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/WebUserQueries.java index ab283b6cb..2a36f6bae 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/WebUserQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/WebUserQueries.java @@ -146,4 +146,31 @@ public class WebUserQueries { } }; } + + public static Query> matchUsers(String partOfUsername) { + String sql = SELECT + '*' + FROM + SecurityTable.TABLE_NAME + + LEFT_JOIN + UsersTable.TABLE_NAME + " on " + SecurityTable.LINKED_TO + "=" + UsersTable.USER_UUID + + WHERE + "LOWER(" + SecurityTable.USERNAME + ") LIKE LOWER(?)"; + return new QueryStatement>(sql) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setString(1, '%' + partOfUsername + '%'); + } + + @Override + public List processResults(ResultSet set) throws SQLException { + List users = new ArrayList<>(); + while (set.next()) { + String username = set.getString(SecurityTable.USERNAME); + String linkedTo = set.getString(UsersTable.USER_NAME); + UUID linkedToUUID = linkedTo != null ? UUID.fromString(set.getString(SecurityTable.LINKED_TO)) : null; + String passwordHash = set.getString(SecurityTable.SALT_PASSWORD_HASH); + int permissionLevel = set.getInt(SecurityTable.PERMISSION_LEVEL); + List permissions = WebUser.getPermissionsForLevel(permissionLevel); + users.add(new User(username, linkedTo != null ? linkedTo : "console", linkedToUUID, passwordHash, permissionLevel, permissions)); + } + return users; + } + }; + } } \ No newline at end of file