Skip to content
Merged

Dev #55

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ 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).

## [2111.1.0]

### Changed
* Ported to Minecraft 1.21.11

## [2101.1.3]

### Added
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false
id "me.modmuss50.mod-publish-plugin" version "0.5.1"
id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false
id "me.modmuss50.mod-publish-plugin" version "1.1.0"
}

apply from: 'https://raw.githubusercontent.com/FTBTeam/mods-meta/main/gradle/changelog.gradle'
Expand Down
59 changes: 28 additions & 31 deletions common/src/main/java/dev/ftb/mods/ftbranks/FTBRanksCommands.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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;
Expand All @@ -23,27 +22,30 @@
import net.minecraft.commands.arguments.GameProfileArgument;
import net.minecraft.nbt.StringTag;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.ClickEvent.Action;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.permissions.Permissions;
import net.minecraft.server.players.NameAndId;
import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

public class FTBRanksCommands {
public static final DynamicCommandExceptionType ERROR_UNKNOWN_RANK = new DynamicCommandExceptionType(
(object) -> Component.literal("Unknown rank: " + object.toString())
);

public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection selection) {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext ignoredContext, Commands.CommandSelection ignoredSelection) {
// source.getServer() *can* return null: https://github.com/FTBTeam/FTB-Mods-Issues/issues/766
//noinspection ConstantValue
dispatcher.register(Commands.literal("ftbranks")
.requires(source -> source.getServer() != null && source.getServer().isSingleplayer() || source.hasPermission(2))
.requires(source -> source.getServer() != null && source.getServer().isSingleplayer() || source.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER))
.then(Commands.literal("reload")
.executes(context -> reloadRanks(context.getSource()))
)
Expand Down Expand Up @@ -140,16 +142,9 @@ private static CompletableFuture<Suggestions> suggestRanks(SuggestionsBuilder bu
return SharedSuggestionProvider.suggest(FTBRanksAPI.manager().getAllRanks().stream().map(Rank::getId), builder);
}

private static String normalizeRankName(String name) {
return name.toLowerCase()
.replace("+", "_plus")
.replaceAll("[^a-z0-9_]", "_")
.replaceAll("_{2,}", "_");
}

private static int reloadRanks(CommandSourceStack source) {
try {
FTBRanksAPIImpl.manager.reload();
Objects.requireNonNull(FTBRanksAPIImpl.manager).reload();
source.sendSuccess(() -> Component.literal("Ranks reloaded from disk!"), true);

for (ServerPlayer p : source.getServer().getPlayerList().getPlayers()) {
Expand All @@ -166,7 +161,7 @@ private static int reloadRanks(CommandSourceStack source) {

private static int refreshReadme(CommandSourceStack source) {
try {
FTBRanksAPIImpl.manager.refreshReadme();
Objects.requireNonNull(FTBRanksAPIImpl.manager).refreshReadme();
} catch (IOException ex) {
ex.printStackTrace();
}
Expand All @@ -180,8 +175,8 @@ private static Component makeRankNameClicky(Rank rank) {
return Component.literal(rank.getName())
.withStyle(isDef ? ChatFormatting.AQUA : ChatFormatting.YELLOW)
.withStyle(Style.EMPTY
.withClickEvent(new ClickEvent(Action.RUN_COMMAND, "/ftbranks show_rank " + rank.getId()))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, isDef ?
.withClickEvent(new ClickEvent.RunCommand("/ftbranks show_rank " + rank.getId()))
.withHoverEvent(new HoverEvent.ShowText(isDef ?
Component.literal("Players must be explicitly added to this rank\nwith '/ftbranks add <player> " + rank.getId() + "'").withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC) :
Component.literal("Rank condition: " + rank.getCondition().asString()).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC))
)
Expand All @@ -191,7 +186,7 @@ private static Component makeRankNameClicky(Rank rank) {
private static int listAllRanks(CommandSourceStack source) {
source.sendSuccess(() -> Component.literal("Ranks:"), false);

for (Rank rank : FTBRanksAPIImpl.manager.getAllRanks()) {
for (Rank rank : Objects.requireNonNull(FTBRanksAPIImpl.manager).getAllRanks()) {
source.sendSuccess(() -> Component.literal("- ").append(makeRankNameClicky(rank)), false);
}

Expand All @@ -211,38 +206,40 @@ private static int createRank(CommandSourceStack source, String name, int power)

private static int deleteRank(CommandSourceStack source, String rankName) throws CommandSyntaxException {
Rank rank = getRank(rankName);
FTBRanksAPI.manager().deleteRank(rank.getId());
source.sendSuccess(() -> Component.literal("Rank '" + rank.getName() + "' deleted!"), false);
if (FTBRanksAPI.manager().deleteRank(rank.getId()) != null) {
source.sendSuccess(() -> Component.literal("Rank '" + rank.getName() + "' deleted!"), false);

return Command.SINGLE_SUCCESS;
return Command.SINGLE_SUCCESS;
}
return 0;
}

private static int addRank(CommandSourceStack source, Collection<GameProfile> players, String rankName) throws CommandSyntaxException {
private static int addRank(CommandSourceStack source, Collection<NameAndId> players, String rankName) throws CommandSyntaxException {
Rank rank = getRank(rankName);
for (GameProfile profile : players) {
for (NameAndId profile : players) {
if (rank.add(profile)) {
source.sendSuccess(() -> Component.literal(String.format("Player %s added to rank '%s'!", profile.getName(), rank.getName())), false);
source.sendSuccess(() -> Component.literal(String.format("Player %s added to rank '%s'!", profile.name(), rank.getName())), false);
}
}

return Command.SINGLE_SUCCESS;
}

private static int removeRank(CommandSourceStack source, Collection<GameProfile> players, String rankName) throws CommandSyntaxException {
private static int removeRank(CommandSourceStack source, Collection<NameAndId> players, String rankName) throws CommandSyntaxException {
Rank rank = getRank(rankName);
for (GameProfile profile : players) {
for (NameAndId profile : players) {
if (rank.remove(profile)) {
source.sendSuccess(() -> Component.literal(String.format("Player %s removed from rank '%s'!", profile.getName(), rank.getName())), false);
source.sendSuccess(() -> Component.literal(String.format("Player %s removed from rank '%s'!", profile.name(), rank.getName())), false);
}
}

return Command.SINGLE_SUCCESS;
}

private static int listRanksOf(CommandSourceStack source, ServerPlayer player) {
source.sendSuccess(() -> Component.literal(String.format("Ranks added to player '%s':", player.getGameProfile().getName())), false);
source.sendSuccess(() -> Component.literal(String.format("Ranks added to player '%s':", player.getGameProfile().name())), false);

for (Rank rank : FTBRanksAPIImpl.manager.getAllRanks()) {
for (Rank rank : Objects.requireNonNull(FTBRanksAPIImpl.manager).getAllRanks()) {
if (rank.isActive(player)) {
source.sendSuccess(() -> Component.literal("- ").append(makeRankNameClicky(rank)), false);
}
Expand Down Expand Up @@ -274,16 +271,16 @@ private static int listNodes(CommandSourceStack source, String rankName) throws
} else {
source.sendSuccess(() -> Component.literal(String.format("%d permission node(s) in rank '%s':", nodes.size(), rankName)).withStyle(ChatFormatting.GREEN), false);
source.sendSuccess(() -> Component.literal("-".repeat(20)).withStyle(ChatFormatting.GREEN), false);
nodes.forEach(node -> {
source.sendSuccess(() -> Component.literal(String.format("%s = %s", node, rank.getPermission(node))).withStyle(ChatFormatting.YELLOW), false);
});
nodes.forEach(node ->
source.sendSuccess(() -> Component.literal(String.format("%s = %s", node, rank.getPermission(node))).withStyle(ChatFormatting.YELLOW), false)
);
source.sendSuccess(() -> Component.literal("-".repeat(20)).withStyle(ChatFormatting.GREEN), false);
}

return Command.SINGLE_SUCCESS;
}

private static int setNode(CommandSourceStack source, String rankName, String node, String value) throws CommandSyntaxException {
private static int setNode(CommandSourceStack source, String rankName, String node, @Nullable String value) throws CommandSyntaxException {
Rank rank = getRank(rankName);

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static Component formatPlayerName(Player player, Component originalName)
FTBRanks.LOGGER.error(s);
return Component.literal("BrokenFormatting").withStyle(Style.EMPTY
.withColor(ChatFormatting.RED)
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal(s)))
.withHoverEvent(new HoverEvent.ShowText(Component.literal(s)))
);
}
} else {
Expand Down
19 changes: 9 additions & 10 deletions common/src/main/java/dev/ftb/mods/ftbranks/api/FTBRanksAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,32 @@

import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;

import java.util.Objects;

/**
* Top-level API object
*/
public abstract class FTBRanksAPI {
@Nullable
private static FTBRanksAPI instance;

/**
* Get the API instance
* @return the API
*/
public static FTBRanksAPI getInstance() {
return instance;
return Objects.requireNonNull(instance);
}

/**
* Convenience method to get the Ranks Manager instance
* @return the manager
* @throws NullPointerException if called before the Minecraft server has started
*/
public static RankManager manager() {
return instance.getManager();
return getInstance().getManager();
}

/**
Expand All @@ -35,9 +38,8 @@ public static RankManager manager() {
* @param node the node to check
* @return the permission value, or {@link PermissionValue#MISSING} if the node is not found
*/
@NotNull
public static PermissionValue getPermissionValue(ServerPlayer player, String node) {
return instance.getManager().getPermissionValue(player, node);
return manager().getPermissionValue(player, node);
}

/**
Expand All @@ -62,9 +64,6 @@ public static void setup(FTBRanksAPI theInstance) {
instance = theInstance;
}

/**
* Get the manager
* @return the manager
*/
@ApiStatus.Internal
protected abstract RankManager getManager();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.ftb.mods.ftbranks.api;

import net.minecraft.server.level.ServerPlayer;
import org.jspecify.annotations.Nullable;

import java.util.Optional;
import java.util.OptionalDouble;
Expand Down Expand Up @@ -110,7 +111,8 @@ default OptionalDouble asDouble() {
/**
* See {@link FTBRanksAPI#parsePermissionValue(String)}
*/
static PermissionValue parse(String str) {
@Nullable
static PermissionValue parse(@Nullable String str) {
return FTBRanksAPI.getInstance().parsePermissionValue(str);
}
}
22 changes: 10 additions & 12 deletions common/src/main/java/dev/ftb/mods/ftbranks/api/Rank.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package dev.ftb.mods.ftbranks.api;

import com.mojang.authlib.GameProfile;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import net.minecraft.server.players.NameAndId;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
Expand Down Expand Up @@ -57,7 +56,6 @@ public interface Rank {
* @param node the node name
* @return the permission value
*/
@NotNull
PermissionValue getPermission(String node);

/**
Expand Down Expand Up @@ -92,24 +90,24 @@ default boolean isActive(ServerPlayer player) {
* @return true if the player has been added, false otherwise
*/
default boolean isAdded(ServerPlayer player) {
return getManager().getAddedRanks(player.getGameProfile()).contains(this);
return getManager().getAddedRanks(player.nameAndId()).contains(this);
}

/**
* Add the given player game profile to this rank.
* Add the given player to this rank.
*
* @param profile the game profile
* @return true if the profile was added, false it was already present
* @param nameAndId the player's name and ID
* @return true if the player was added, false it was already present
*/
boolean add(GameProfile profile);
boolean add(NameAndId nameAndId);

/**
* Remove the given player game profile from this rank.
* Remove the given player from this rank.
*
* @param profile the game profile
* @return true if the profile was removed, false if it was not present
* @param nameAndId the player's name and ID
* @return true if the player was removed, false if it was not present
*/
boolean remove(GameProfile profile);
boolean remove(NameAndId nameAndId);

/**
* Get all the permission node names which have been defined for this rank.
Expand Down
30 changes: 8 additions & 22 deletions common/src/main/java/dev/ftb/mods/ftbranks/api/RankManager.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package dev.ftb.mods.ftbranks.api;

import com.mojang.authlib.GameProfile;
import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.minecraft.server.players.NameAndId;
import org.jspecify.annotations.Nullable;

import java.util.Collection;
import java.util.List;
Expand All @@ -32,18 +31,6 @@ public interface RankManager {
*/
Optional<Rank> getRank(String id);

/**
* Create a new rank with the given ID, name &amp; power.
*
* @param id the unique rank ID
* @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 &amp; 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
Expand All @@ -52,7 +39,7 @@ public interface RankManager {
*
* @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
* @param forceCreate if true, any existing rank is replaced (and a warning is logged); 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
*/
Expand All @@ -68,16 +55,16 @@ public interface RankManager {
Rank deleteRank(String id);

/**
* Get all the ranks to which the given game profile has been specifically added.
* Get all the ranks to which the given player has been specifically added.
*
* @param profile the game profile to check
* @return the ranks to which the profile has been added
* @param nameAndId the player's name and ID to check
* @return the ranks to which the player has been added
*/
Set<Rank> getAddedRanks(GameProfile profile);
Set<Rank> getAddedRanks(NameAndId nameAndId);

/**
* Get a list of the ranks which currently apply to the given player. Note this is distinct from the result of
* {@link #getAddedRanks(GameProfile)}, since it can include any ranks which implicitly apply to the player.
* {@link #getAddedRanks(NameAndId)}, since it can include any ranks which implicitly apply to the player.
*
* @param player the player
* @return a list of ranks
Expand Down Expand Up @@ -109,7 +96,6 @@ default List<Rank> getRanks(ServerPlayer player) {
* @param node the node name
* @return the permission value
*/
@NotNull
PermissionValue getPermissionValue(ServerPlayer player, String node);

/**
Expand Down
Loading