diff --git a/CHANGELOG.md b/CHANGELOG.md index ff7a255..35460de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 2101.1.1 +[2100.1.2] -### Added -* We now load a supplementary `config/ftbranks-pack.snbt` file alongside the default file - * Intended to augment existing ranks from ranks.snbt with pack-specific settings, to be created by modpack makers, and independent from the server admin settings. +### Changed +* API change for RankManager#createRank + * Added new RankManager#createRank(String, int, boolean) method, deprecated the existing RankManager#createRank(String, String, int) method + * Note: minor API break here: both methods now throw a RankException if the rank already exists, rather than blindly overwrite it + +[2100.1.1] + +### Changed +* Now loads a supplementary `config/ftbranks-pack.snbt` file alongside the default file + * Intended to augment existing ranks from `ranks.snbt` with pack-specific settings, to be created by modpack makers, independent of the server admin settings. -## 2100.1.0 +[2100.1.0] ### Changed * Ported to Minecraft 1.21. Support for Fabric and NeoForge. diff --git a/common/src/main/java/dev/ftb/mods/ftbranks/FTBRanksCommands.java b/common/src/main/java/dev/ftb/mods/ftbranks/FTBRanksCommands.java index e86aa07..8505193 100644 --- a/common/src/main/java/dev/ftb/mods/ftbranks/FTBRanksCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftbranks/FTBRanksCommands.java @@ -1,6 +1,7 @@ package dev.ftb.mods.ftbranks; import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; @@ -10,10 +11,7 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import dev.ftb.mods.ftblibrary.snbt.SNBT; -import dev.ftb.mods.ftbranks.api.FTBRanksAPI; -import dev.ftb.mods.ftbranks.api.PermissionValue; -import dev.ftb.mods.ftbranks.api.Rank; -import dev.ftb.mods.ftbranks.api.RankCondition; +import dev.ftb.mods.ftbranks.api.*; import dev.ftb.mods.ftbranks.impl.FTBRanksAPIImpl; import dev.ftb.mods.ftbranks.impl.condition.DefaultCondition; import net.minecraft.ChatFormatting; @@ -197,20 +195,18 @@ private static int listAllRanks(CommandSourceStack source) { source.sendSuccess(() -> Component.literal("- ").append(makeRankNameClicky(rank)), false); } - return 1; + return Command.SINGLE_SUCCESS; } private static int createRank(CommandSourceStack source, String name, int power) { - String id = normalizeRankName(name); - - if (FTBRanksAPIImpl.manager.getRank(id).isPresent()) { - source.sendFailure(Component.literal("Rank '" + name + "' is already taken!")); + try { + Rank rank = FTBRanksAPI.manager().createRank(name, power, false); + source.sendSuccess(() -> Component.literal("Rank '" + rank.getId() + "' created!"), false); + return Command.SINGLE_SUCCESS; + } catch (RankException e) { + source.sendFailure(Component.literal("Could not create rank '" + name + "': " + e.getMessage())); return 0; } - - FTBRanksAPIImpl.manager.createRank(id, name, power); - source.sendSuccess(() -> Component.literal("Rank '" + id + "' created!"), false); - return 1; } private static int deleteRank(CommandSourceStack source, String rankName) throws CommandSyntaxException { @@ -218,7 +214,7 @@ private static int deleteRank(CommandSourceStack source, String rankName) throws FTBRanksAPI.manager().deleteRank(rank.getId()); source.sendSuccess(() -> Component.literal("Rank '" + rank.getName() + "' deleted!"), false); - return 1; + return Command.SINGLE_SUCCESS; } private static int addRank(CommandSourceStack source, Collection players, String rankName) throws CommandSyntaxException { @@ -229,7 +225,7 @@ private static int addRank(CommandSourceStack source, Collection pl } } - return 1; + return Command.SINGLE_SUCCESS; } private static int removeRank(CommandSourceStack source, Collection players, String rankName) throws CommandSyntaxException { @@ -240,7 +236,7 @@ private static int removeRank(CommandSourceStack source, Collection } } - return 1; + return Command.SINGLE_SUCCESS; } private static int listRanksOf(CommandSourceStack source, ServerPlayer player) { @@ -252,7 +248,7 @@ private static int listRanksOf(CommandSourceStack source, ServerPlayer player) { } } - return 1; + return Command.SINGLE_SUCCESS; } private static int listPlayersWith(CommandSourceStack source, String rankName) throws CommandSyntaxException { @@ -266,7 +262,7 @@ private static int listPlayersWith(CommandSourceStack source, String rankName) t } } - return 1; + return Command.SINGLE_SUCCESS; } private static int listNodes(CommandSourceStack source, String rankName) throws CommandSyntaxException { @@ -284,7 +280,7 @@ private static int listNodes(CommandSourceStack source, String rankName) throws source.sendSuccess(() -> Component.literal("-".repeat(20)).withStyle(ChatFormatting.GREEN), false); } - return 1; + return Command.SINGLE_SUCCESS; } private static int setNode(CommandSourceStack source, String rankName, String node, String value) throws CommandSyntaxException { @@ -301,7 +297,7 @@ private static int setNode(CommandSourceStack source, String rankName, String no throw new SimpleCommandExceptionType(Component.literal(e.getMessage())).create(); } - return 1; + return Command.SINGLE_SUCCESS; } private static int setCondition(CommandSourceStack source, String rankName, String value) throws CommandSyntaxException { @@ -322,7 +318,7 @@ private static int setCondition(CommandSourceStack source, String rankName, Stri throw new SimpleCommandExceptionType(Component.literal(e.getMessage())).create(); } - return 1; + return Command.SINGLE_SUCCESS; } private static int showRank(CommandSourceStack source, String rankName) throws CommandSyntaxException { @@ -330,11 +326,18 @@ private static int showRank(CommandSourceStack source, String rankName) throws C source.sendSuccess(() -> Component.literal("=".repeat(50)).withStyle(ChatFormatting.GREEN), false); - source.sendSuccess(() -> Component.literal(String.format("Rank ID: %s, Rank Name: %s, Power: %d", rank.getId(), rank.getName(), rank.getPower())).withStyle(ChatFormatting.YELLOW), false); + source.sendSuccess(() -> Component.literal("Rank ID: ").withStyle(ChatFormatting.YELLOW) + .append(Component.literal(rank.getId()).withStyle(ChatFormatting.WHITE)) + .append(Component.literal(", Rank Name: ").withStyle(ChatFormatting.YELLOW)) + .append(Component.literal(rank.getName()).withStyle(ChatFormatting.WHITE)) + .append(Component.literal(", Power: ").withStyle(ChatFormatting.YELLOW)) + .append(Component.literal(String.valueOf(rank.getPower())).withStyle(ChatFormatting.WHITE)), + true); String condStr = rank.getCondition().asString(); Component c = condStr.isEmpty() ? - Component.literal("(none: players must be added)").withStyle(ChatFormatting.WHITE, ChatFormatting.ITALIC) : Component.literal(condStr); + Component.literal("(none: players must be added)").withStyle(ChatFormatting.WHITE, ChatFormatting.ITALIC) : + Component.literal(condStr).withStyle(ChatFormatting.WHITE); source.sendSuccess(() -> Component.literal("Condition: ").append(c).withStyle(ChatFormatting.YELLOW), false); source.sendSuccess(() -> Component.literal("Permission nodes:").withStyle(ChatFormatting.YELLOW), false); diff --git a/common/src/main/java/dev/ftb/mods/ftbranks/api/RankManager.java b/common/src/main/java/dev/ftb/mods/ftbranks/api/RankManager.java index e062cf8..b847caf 100644 --- a/common/src/main/java/dev/ftb/mods/ftbranks/api/RankManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbranks/api/RankManager.java @@ -39,9 +39,25 @@ public interface RankManager { * @param displayName rank display name * @param power rank power * @return the newly-created rank + * @deprecated use {@link #createRank(String, int, boolean)} */ + @Deprecated Rank createRank(String id, String displayName, int power); + /** + * Create a new rank with the given name & power. A canonical rank ID is derived from the name, by + * converting to lower case, then substituting the "+" symbol with "_plus" and all other non-alphanumeric characters + * with underscores. Finally, runs of multiple consecutive underscores are replaced with a single underscore. + * E.g. "Alice + Bob's rank" will be converted to "alice_plus_bob_s_rank" + * + * @param displayName rank display name + * @param power rank power + * @param forceCreate if true, any existing rank is replaced; if false, an exception is thrown if a rank exists + * @return the newly-created rank + * @throws RankException if {@code forceCreate} is false and a rank with the same canonical ID already exists + */ + Rank createRank(String displayName, int power, boolean forceCreate); + /** * Delete the rank with the given ID. * diff --git a/common/src/main/java/dev/ftb/mods/ftbranks/impl/RankManagerImpl.java b/common/src/main/java/dev/ftb/mods/ftbranks/impl/RankManagerImpl.java index 4f9dd17..9bc9289 100644 --- a/common/src/main/java/dev/ftb/mods/ftbranks/impl/RankManagerImpl.java +++ b/common/src/main/java/dev/ftb/mods/ftbranks/impl/RankManagerImpl.java @@ -79,8 +79,20 @@ public Optional getRank(String id) { } @Override - public RankImpl createRank(String id, String name, int power) { - deleteRank(id); + public Rank createRank(String id, String displayName, int power) { + return createRank(displayName, power, false); + } + + @Override + public RankImpl createRank(String name, int power, boolean forceCreate) { + String id = normalizeRankName(name); + + if (forceCreate) { + deleteRank(id); + } else if (ranks.containsKey(id)) { + throw new RankException("Rank '" + id + "' already exists"); + } + RankImpl rank = RankImpl.create(this, id, name, power, RankFileSource.SERVER); ranks.put(id, rank); rebuildSortedRanks(); @@ -89,6 +101,13 @@ public RankImpl createRank(String id, String name, int power) { return rank; } + private static String normalizeRankName(String name) { + return name.toLowerCase() + .replace("+", "_plus") + .replaceAll("[^a-z0-9_]", "_") + .replaceAll("_{2,}", "_"); + } + @Override @Nullable public RankImpl deleteRank(String id) { diff --git a/common/src/main/java/dev/ftb/mods/ftbranks/impl/condition/RankAddedCondition.java b/common/src/main/java/dev/ftb/mods/ftbranks/impl/condition/RankAddedCondition.java index 576452d..e937ba2 100644 --- a/common/src/main/java/dev/ftb/mods/ftbranks/impl/condition/RankAddedCondition.java +++ b/common/src/main/java/dev/ftb/mods/ftbranks/impl/condition/RankAddedCondition.java @@ -25,4 +25,9 @@ public boolean isRankActive(ServerPlayer player) { .map(rank -> rank != original && rank.isAdded(player)) .orElse(false); } + + @Override + public void save(SNBTCompoundTag tag) { + tag.putString("rank", id); + } } diff --git a/gradle.properties b/gradle.properties index f0a890b..cdac6e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ mod_id=ftbranks readable_name=FTB Ranks archives_base_name=ftb-ranks maven_group=dev.ftb.mods -mod_version=2101.1.1 +mod_version=2101.1.2 mod_author=FTB Team minecraft_version=1.21.1