Implements the tab-completers for the payout commands

Implements the tab-completer for the set group payout command
Implements the tab-completer for the set player payout command
Allows specifying the name of an offline player when using the set player payout command
Implements proper un-setting of set payouts
Adds the pom file
Filters out Citizens UUIDs when getting offline players
This commit is contained in:
Kristian Knarvik 2024-01-09 00:25:51 +01:00
parent dfba6b2125
commit 36f1454cfa
10 changed files with 361 additions and 16 deletions

104
pom.xml Normal file
View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.knarcraft</groupId>
<artifactId>TimeIsMoney</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TimeIsMoney</name>
<properties>
<java.version>16</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>essentials-releases</id>
<url>https://repo.essentialsx.net/releases/</url>
</repository>
<repository>
<id>paper-repo</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.essentialsx</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.20.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -3,7 +3,9 @@ package net.knarcraft.timeismoney;
import com.earth2me.essentials.IEssentials; import com.earth2me.essentials.IEssentials;
import net.knarcraft.timeismoney.command.ReloadCommand; import net.knarcraft.timeismoney.command.ReloadCommand;
import net.knarcraft.timeismoney.command.SetGroupPaymentCommand; import net.knarcraft.timeismoney.command.SetGroupPaymentCommand;
import net.knarcraft.timeismoney.command.SetGroupPaymentTabCompleter;
import net.knarcraft.timeismoney.command.SetPlayerPaymentCommand; import net.knarcraft.timeismoney.command.SetPlayerPaymentCommand;
import net.knarcraft.timeismoney.command.SetPlayerPaymentTabCompleter;
import net.knarcraft.timeismoney.config.Configuration; import net.knarcraft.timeismoney.config.Configuration;
import net.knarcraft.timeismoney.listener.PlayerJoinListener; import net.knarcraft.timeismoney.listener.PlayerJoinListener;
import net.knarcraft.timeismoney.manager.EconomyManager; import net.knarcraft.timeismoney.manager.EconomyManager;
@ -65,8 +67,10 @@ public final class TimeIsMoney extends JavaPlugin {
ReloadCommand reloadCommand = new ReloadCommand(); ReloadCommand reloadCommand = new ReloadCommand();
registerCommand(getCommand("reload"), reloadCommand, reloadCommand); registerCommand(getCommand("reload"), reloadCommand, reloadCommand);
registerCommand(getCommand("setGroupPayout"), new SetGroupPaymentCommand(configuration), null); registerCommand(getCommand("setGroupPayout"), new SetGroupPaymentCommand(configuration),
registerCommand(getCommand("setPlayerPayout"), new SetPlayerPaymentCommand(configuration), null); new SetGroupPaymentTabCompleter());
registerCommand(getCommand("setPlayerPayout"), new SetPlayerPaymentCommand(configuration),
new SetPlayerPaymentTabCompleter());
Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this);

View File

@ -1,10 +1,12 @@
package net.knarcraft.timeismoney.command; package net.knarcraft.timeismoney.command;
import net.knarcraft.timeismoney.config.Configuration; import net.knarcraft.timeismoney.config.Configuration;
import net.knarcraft.timeismoney.util.StringHelper;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* A command for overriding payments for specific groups * A command for overriding payments for specific groups
@ -31,9 +33,14 @@ public class SetGroupPaymentCommand implements CommandExecutor {
try { try {
String group = arguments[0]; String group = arguments[0];
Double payout = Double.parseDouble(arguments[1]); if (StringHelper.isNonValue(arguments[1])) {
configuration.setGroupPayout(group, payout); setPayout(group, null);
configuration.save(); commandSender.sendMessage(String.format("Group payout for group %s has been cleared", group));
} else {
Double payout = Double.parseDouble(arguments[1]);
setPayout(group, payout);
commandSender.sendMessage(String.format("Group payout for group %s has been set to %s", group, payout));
}
return true; return true;
} catch (NumberFormatException exception) { } catch (NumberFormatException exception) {
commandSender.sendMessage("Payout must be a number"); commandSender.sendMessage("Payout must be a number");
@ -41,4 +48,15 @@ public class SetGroupPaymentCommand implements CommandExecutor {
} }
} }
/**
* Sets the payout for the given group
*
* @param group <p>The group to set payout for</p>
* @param payout <p>The payout to set</p>
*/
private void setPayout(@NotNull String group, @Nullable Double payout) {
configuration.setGroupPayout(group, payout);
configuration.save();
}
} }

View File

@ -0,0 +1,35 @@
package net.knarcraft.timeismoney.command;
import net.knarcraft.timeismoney.manager.PermissionManager;
import net.knarcraft.timeismoney.util.TabCompletionHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* The tab-completer for the set group payment command
*/
public class SetGroupPaymentTabCompleter implements TabCompleter {
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
// List permission groups
return TabCompletionHelper.filterMatchingContains(List.of(PermissionManager.getPermissionGroups()),
arguments[0]);
} else if (arguments.length == 2) {
// List possible payout values
return TabCompletionHelper.filterMatchingStartsWith(List.of("clear", "null", "none", "5", "10", "100"),
arguments[1]);
}
return new ArrayList<>();
}
}

View File

@ -1,12 +1,15 @@
package net.knarcraft.timeismoney.command; package net.knarcraft.timeismoney.command;
import net.knarcraft.timeismoney.config.Configuration; import net.knarcraft.timeismoney.config.Configuration;
import net.knarcraft.timeismoney.util.StringHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID; import java.util.UUID;
@ -22,7 +25,7 @@ public class SetPlayerPaymentCommand implements CommandExecutor {
* *
* @param configuration <p>The configuration to use</p> * @param configuration <p>The configuration to use</p>
*/ */
public SetPlayerPaymentCommand(Configuration configuration) { public SetPlayerPaymentCommand(@NotNull Configuration configuration) {
this.configuration = configuration; this.configuration = configuration;
} }
@ -32,31 +35,61 @@ public class SetPlayerPaymentCommand implements CommandExecutor {
if (arguments.length < 2) { if (arguments.length < 2) {
return false; return false;
} }
String playerName = arguments[0];
// Parse the player id
UUID playerId; UUID playerId;
try { try {
playerId = UUID.fromString(arguments[0]); // Find player from UUID
playerId = UUID.fromString(playerName);
} catch (IllegalArgumentException exception) { } catch (IllegalArgumentException exception) {
Player player = Bukkit.getPlayer(arguments[0]); // Get player from player name
Player player = Bukkit.getPlayer(playerName);
if (player != null) { if (player != null) {
playerId = player.getUniqueId(); playerId = player.getUniqueId();
} else { } else {
commandSender.sendMessage("You must supply a valid name of an online player, or a UUID"); // Try to match the player name against the offline player list
return false; playerId = null;
for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) {
if (offlinePlayer.getName() != null && offlinePlayer.getName().equals(playerName)) {
playerId = offlinePlayer.getUniqueId();
}
}
if (playerId == null) {
commandSender.sendMessage("You must supply a valid name of an online player, or a UUID");
return false;
}
} }
} }
double payout; // Parse the payout value
try { try {
payout = Double.parseDouble(arguments[1]); if (StringHelper.isNonValue(arguments[1])) {
setPayout(playerId, null);
commandSender.sendMessage(String.format("Player payout for player %s has been cleared", playerName));
} else {
Double payout = Double.parseDouble(arguments[1]);
setPayout(playerId, payout);
commandSender.sendMessage(String.format("Player payout for player %s has been set to %s", playerName,
payout));
}
return true;
} catch (NumberFormatException exception) { } catch (NumberFormatException exception) {
commandSender.sendMessage("Payout must be a number"); commandSender.sendMessage("Payout must be a number");
return false; return false;
} }
}
/**
* Sets the payout for the given player
*
* @param playerId <p>The player to set payout for</p>
* @param payout <p>The payout to set</p>
*/
private void setPayout(@NotNull UUID playerId, @Nullable Double payout) {
configuration.setPlayerPayout(playerId, payout); configuration.setPlayerPayout(playerId, payout);
configuration.save(); configuration.save();
return true;
} }
} }

View File

@ -0,0 +1,59 @@
package net.knarcraft.timeismoney.command;
import net.knarcraft.timeismoney.util.TabCompletionHelper;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* The tab-completer for the set player payment command
*/
public class SetPlayerPaymentTabCompleter implements TabCompleter {
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
// List online players
return TabCompletionHelper.filterMatchingContains(getPlayerNames(), arguments[0]);
} else if (arguments.length == 2) {
// List possible payout values
return TabCompletionHelper.filterMatchingStartsWith(List.of("clear", "null", "none", "5", "10", "100"),
arguments[1]);
}
return new ArrayList<>();
}
/**
* Gets names of all online players, and ids of offline players
*
* @return <p>The names and ids of all known players</p>
*/
private @NotNull List<String> getPlayerNames() {
List<String> playerNames = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers()) {
playerNames.add(player.getName());
}
for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) {
String uuid = offlinePlayer.getUniqueId().toString();
if (!uuid.startsWith("00000000-0000-0000")) {
if (offlinePlayer.getName() != null) {
playerNames.add(offlinePlayer.getName());
} else {
playerNames.add(offlinePlayer.getUniqueId().toString());
}
}
}
return playerNames;
}
}

View File

@ -142,7 +142,11 @@ public class Configuration {
* @param payout <p>The payout to set for the player</p> * @param payout <p>The payout to set for the player</p>
*/ */
public void setPlayerPayout(@NotNull UUID playerId, @Nullable Double payout) { public void setPlayerPayout(@NotNull UUID playerId, @Nullable Double payout) {
this.playerPayouts.put(playerId, payout); if (payout == null || payout < 0) {
this.playerPayouts.put(playerId, null);
} else {
this.playerPayouts.put(playerId, payout);
}
} }
/** /**
@ -152,7 +156,11 @@ public class Configuration {
* @param payout <p>The payout to set for the group</p> * @param payout <p>The payout to set for the group</p>
*/ */
public void setGroupPayout(@NotNull String groupName, @Nullable Double payout) { public void setGroupPayout(@NotNull String groupName, @Nullable Double payout) {
this.groupPayouts.put(groupName, payout); if (payout == null || payout < 0) {
this.groupPayouts.put(groupName, null);
} else {
this.groupPayouts.put(groupName, payout);
}
} }
/** /**

View File

@ -43,4 +43,13 @@ public final class PermissionManager {
return permission.getPlayerGroups(player); return permission.getPlayerGroups(player);
} }
/**
* Gets all available permission groups
*
* @return <p>All available permission groups</p>
*/
public static @NotNull String[] getPermissionGroups() {
return permission.getGroups();
}
} }

View File

@ -0,0 +1,25 @@
package net.knarcraft.timeismoney.util;
import org.jetbrains.annotations.NotNull;
/**
* A helper-class for dealing with strings
*/
public final class StringHelper {
private StringHelper() {
}
/**
* Checks whether the given string value denotes a non-value
*
* @param value <p>The string value to check</p>
* @return <p>True if the given value is a non-value</p>
*/
public static boolean isNonValue(@NotNull String value) {
return value.equalsIgnoreCase("null") || value.equalsIgnoreCase("none") ||
value.equalsIgnoreCase("clear");
}
}

View File

@ -0,0 +1,50 @@
package net.knarcraft.timeismoney.util;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class for getting string lists required for auto-completion
*/
public final class TabCompletionHelper {
private TabCompletionHelper() {
}
/**
* Finds tab complete values that contain the typed text
*
* @param values <p>The values to filter</p>
* @param typedText <p>The text the player has started typing</p>
* @return <p>The given string values that contain the player's typed text</p>
*/
public static @NotNull List<String> filterMatchingContains(@NotNull List<String> values, @NotNull String typedText) {
List<String> configValues = new ArrayList<>();
for (String value : values) {
if (value.toLowerCase().contains(typedText.toLowerCase())) {
configValues.add(value);
}
}
return configValues;
}
/**
* Finds tab complete values that match the start of the typed text
*
* @param values <p>The values to filter</p>
* @param typedText <p>The text the player has started typing</p>
* @return <p>The given string values that start with the player's typed text</p>
*/
public static @NotNull List<String> filterMatchingStartsWith(@NotNull List<String> values, @NotNull String typedText) {
List<String> configValues = new ArrayList<>();
for (String value : values) {
if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
configValues.add(value);
}
}
return configValues;
}
}