Rank Command
CRITICAL
This example is pretty advanced and would require you to have some experience with Imperat and Java.
Before writing our rank command, we would need to create a POJO that would act as a template for the rank's data.
Let's create our Rank
class:
@Getter
@Setter
public final class Rank {
private final String name;
private final List<String> permissions = new ArrayList<>();
private String prefix, suffix;
public Rank(String name) {
this.name = name;
}
}
Now let's create our manager
class that is going to manage our ranks:
public final class RankManager {
private final Map<String, Rank> ranks = new LinkedHashMap<>(); //all ranks per name here in natural order
private final Map<UUID, Rank> perPlayerRank = new HashMap<>(); //per player rank, very simple and illustrative approach
private final static Rank DEFAULT_RANK = new Rank("member");
//dependency injection
public RankManager() {
registerRank(DEFAULT_RANK);
}
public @Nullable Rank getRank(String name) {
return ranks.get(name);
}
public @Nullable Rank getPlayerRank(UUID playerUUID) {
return perPlayerRank.get(playerUUID);
}
public void setPlayerRank(UUID playerRank, Rank rank) {
if(!ranks.containsKey(rank.getName())) {
return;
}
perPlayerRank.put(playerRank, rank);
}
public void registerRank(@NotNull Rank rank) {
ranks.put(rank.getName(), rank);
}
public void updateRank(String name, Function<Rank, Rank> updater) {
ranks.computeIfPresent(name,(presentRankName, presentRank)-> updater.apply(presentRank));
}
public void removeRank(String name) {
ranks.remove(name);
for(var playerId : perPlayerRank.keySet()) {
Rank rank = getPlayerRank(playerId);
if(rank == null) continue;
if(rank.getName().equals(name)) {
//remove the rank
perPlayerRank.remove(playerId);
}
}
}
public boolean hasRank(String name) {
return ranks.get(name) != null;
}
public Collection<? extends Rank> getRanks() {
return ranks.values();
}
}
We are also going to need a parameter type for Rank
class, let's create our RankParameterType
:
import static dev.velix.imperat.exception.SourceException.ErrorLevel.SEVERE;
public class RankParameterType extends BaseParameterType<BukkitSource, Rank> {
private final RankManager rankManager;
private final SuggestionResolver<BukkitSource> ranks_suggestions;
public RankParameterType(RankManager rankManager) {
super(TypeWrap.of(Rank.class));
this.rankManager = rankManager;
ranks_suggestions = (context, parameter) -> rankManager.getRanks().stream().map(Rank::getName).toList();
}
@Override
public @Nullable Rank resolve(ExecutionContext<BukkitSource> context, @NotNull CommandInputStream<BukkitSource> commandInputStream) throws ImperatException {
String input = commandInputStream.currentRaw().orElseThrow();
Rank rank = rankManager.getRank(input.toLowerCase());
if(rank == null) {
throw new SourceException(SEVERE, "Invalid rank '%s'", input);
}else {
return rank;
}
}
@Override
public @NotNull Rank fromString(Imperat<BukkitSource> imperat, String input) {
return Objects.requireNonNull(
rankManager.getRank(input)
);
}
@Override
public SuggestionResolver<BukkitSource> getSuggestionResolver() {
return ranks_suggestions;
}
}
Now let's create our actual RankCommand
class:
@Command({"rank", "group"})// main-name='rank', alias "group"
@Permission("server.command.rank")
@Description("Manages ranks")
public class RankCommand {
/*
/rank create <rank>
/rank delete <rank>
/rank <rank> setprefix <prefix>
/rank <rank> setsuffix <suffix>
/rank <rank> setperm <permission>
/rank <rank> unsetperm <permission>
/rank <rank> give <player>
*/
@Usage
public void noArgs(BukkitSource source, CommandHelp help) {
help.display(source);
}
@Usage
public void mainUsage(BukkitSource source, @Named("rank") Rank rank, CommandHelp help) {
help.display(source);
}
@SubCommand(value = "create", attachDirectly = true)
@Permission("server.command.rank.create")
@Description("Creates a rank")
public static class CreateRankSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source) {
source.error("/rank create <rank-name>");
}
@Usage
public void createRank(BukkitSource source, @Named("rank-name") String rankName) {
if(rankManager.hasRank(rankName)) {
source.error("Rank '" + rankName + "' already exists");
}else {
//creating new Rank
Rank rank = new Rank(rankName.toLowerCase());
rankManager.registerRank(rank);
source.reply(ChatColor.GREEN + "Created rank '" + rankName + "'");
}
}
}
@SubCommand(value = "delete", attachDirectly = true)
@Permission("server.command.rank.delete")
@Description("Deletes a rank")
public static class DeleteRankSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source) {
source.error("/rank delete <rank-name>");
}
@Usage
public void deleteRank(BukkitSource source, @Named("rank-name") String rankName) {
if(!rankManager.hasRank(rankName)) {
source.error("Rank '" + rankName + "' doesn't exist");
} else {
rankManager.removeRank(rankName);
source.reply(ChatColor.GREEN + "Deleted rank '" + rankName + "'");
}
}
}
@SubCommand(value = "setprefix")
@Permission("server.command.rank.setprefix")
@Description("Sets prefix for rank")
public static class SetPrefixSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> setprefix <rank-name>");
}
@Usage
public void setRankPrefix(BukkitSource source, @Named("rank") Rank rank, @Named("prefix") String prefix) {
rank.setPrefix(prefix);
rankManager.updateRank(rank.getName(), (rankInMap)-> rank);
source.reply(ChatColor.GREEN + "Set prefix of rank '" + rank.getName() + "' to '" + prefix + ChatColor.GREEN + "'");
}
}
@SubCommand(value = "setsuffix")
@Permission("server.command.rank.setsuffix")
@Description("Sets suffix for rank")
public static class SetSuffixSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> setsuffix <suffix>");
}
@Usage
public void setRankSuffix(BukkitSource source, @Named("rank") Rank rank, @Named("suffix") String suffix) {
rank.setSuffix(suffix);
rankManager.updateRank(rank.getName(), (rankInMap)-> rank);
source.reply(ChatColor.GREEN + "Set suffix of rank '" + rank.getName() + "' to '" + suffix +"'");
}
}
@SubCommand(value = "setweight")
@Permission("server.command.rank.setweight")
@Description("Sets weight for rank")
public static class SetWeightSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> setweight <weight>");
}
@Usage
public void setRankSuffix(BukkitSource source, @Named("rank") Rank rank, @Named("weight") int weight) {
rank.setWeight(weight);
rankManager.updateRank(rank.getName(), (rankInMap)-> rank);
source.reply(ChatColor.GREEN + "Set weight of rank '" + rank.getName() + "' to '" + weight +"'");
}
}
@SubCommand(value = "setperm")
@Permission("server.command.rank.setperm")
@Description("Sets permission")
public static class AddPermissionSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> setperm <permission>");
}
@Usage
public void addPermission(BukkitSource source, @Named("rank") Rank rank, @Named("permission") String permission) {
if(rank.getPermissions().contains(permission)) {
source.error("Rank '" + rank.getName() + "' already has permission '" + permission + "'");
return;
}
rank.getPermissions().add(permission);
rankManager.updateRank(rank.getName(), (rankInMap)-> rank);
source.reply(ChatColor.GREEN + "Added permission '" + permission + "' to rank '" + rank.getName() + "'");
}
}
@SubCommand(value = "unsetperm")
@Permission("server.command.rank.unsetperm")
@Description("Unset permission")
public static class RemovePermissionSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> unsetperm <permission>");
}
@Usage
public void removePermission(BukkitSource source, @Named("rank") Rank rank, @Named("permission") String permission) {
if(!rank.getPermissions().contains(permission)) {
source.error("Rank '" + rank.getName() + "' doesn't have permission '" + permission + "'");
return;
}
rank.getPermissions().remove(permission);
rankManager.updateRank(rank.getName(), (rankInMap)-> rank);
source.reply(ChatColor.GREEN + "Removed permission '" + permission + "' from rank '" + rank.getName() + "'");
}
}
@SubCommand(value = "give")
@Permission("server.command.rank.give")
@Description("Gives a rank to a player")
public static class GiveRankSub {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.error("/rank <rank> give <player>");
}
@Usage
public void giveRank(BukkitSource source, @Named("rank") Rank rank, @Named("player") Player player) {
rankManager.setAndUpdateRank(player, rank);
//rank.updateTeam(TabRankMode.CREATE_NEW_TEAM);
source.reply(ChatColor.GREEN + "You have assigned rank '" + rank.getName() + "' to player '" + player.getName() + "'");
}
}
@SubCommand(value = "info")
@Permission("server.command.rank.info")
@Description("View rank info")
public static class SeeRankInfo {
@Dependency
private RankManager rankManager;
@Usage
public void def(BukkitSource source, @Named("rank") Rank rank) {
source.reply("&7----------- &e&l" + rank.getName().toUpperCase() + " &6&lINFO&r &7--------------------");
source.reply("&6&lPrefix: &r" + rank.getPrefix());
source.reply("&6&lSuffix: &r" + rank.getSuffix());
source.reply("&6&lWeight: &f" + rank.getWeight());
source.reply("&6&lTeam Name: &f" + rank.getTeamName());
// Players in rank
if (rank.getPlayerList().isEmpty()) {
source.reply("&6&lPlayers: &7None");
} else {
source.reply("&6&lPlayers &f(" + rank.getPlayerList().size() + ")&6: &7" +
String.join("&f, &7", rank.getPlayerList()));
}
// Permissions
if (rank.getPermissions().isEmpty()) {
source.reply("&6&lPermissions: &7None");
} else {
source.reply("&6&lPermissions &f(" + rank.getPermissions().size() + ")&6:");
for (String permission : rank.getPermissions()) {
source.reply(" &8- &f" + permission);
}
}
source.reply("&7----------------------------------------------------");
}
}
}
Main class example
Here's our main class example:
public class ExamplePlugin extends JavaPlugin {
private BukkitImperat imperat;
private RankManager rankManager;
@Override
public void onEnable() {
rankManager = new RankManager();
//setting up our imperat
imperat = BukkitImperat.builder(this)
.dependencyResolver(RankManager.class,()-> rankManager)
.parameterType(Rank.class, new RankParameterType(rankManager))
.build();
//registering rank command.
imperat.registerCommand(new RankCommand());
}
}