diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/accept/AcceptTPA.java b/common/src/main/java/net/superricky/tpaplusplus/commands/accept/AcceptTPA.java index bf0eb28..07fed08 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/accept/AcceptTPA.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/accept/AcceptTPA.java @@ -10,7 +10,7 @@ import net.superricky.tpaplusplus.requests.Request; import net.superricky.tpaplusplus.requests.RequestGrabUtil; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -37,8 +37,8 @@ public static void acceptFunctionality(Request request, ServerPlayer receiver) { } public static void absoluteAcceptFunctionality(Request request, ServerPlayer receiver) { - receiver.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_ACCEPTS_TPA.get(), Map.of("senders_name", request.getSender().getName().getString())))); - request.getSender().sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_GOT_ACCEPTED_TPA.get(), Map.of("receivers_name", request.getReceiver().getName().getString())))); + receiver.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_ACCEPTS_TPA.get(), Map.of("senders_name", request.getSender().getName().getString())))); + request.getSender().sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_GOT_ACCEPTED_TPA.get(), Map.of("receivers_name", request.getReceiver().getName().getString())))); RequestHelper.teleport(request); diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/block/BlockPlayer.java b/common/src/main/java/net/superricky/tpaplusplus/commands/block/BlockPlayer.java index 451559d..579b2ff 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/block/BlockPlayer.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/block/BlockPlayer.java @@ -10,7 +10,7 @@ import net.superricky.tpaplusplus.io.PlayerData; import net.superricky.tpaplusplus.io.SaveDataManager; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -27,7 +27,7 @@ public static void blockPlayer(ServerPlayer executor, ServerPlayer blockedPlayer if (executorData.hasBlockedPlayer(blockedPlayer.getUUID())) { // Executor has already blocked the other player - executor.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.ALREADY_BLOCKED_PLAYER.get(), + executor.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.ALREADY_BLOCKED_PLAYER.get(), Map.of("blocked_player", blockedPlayer.getName().getString())))); return; } @@ -47,12 +47,12 @@ public static void blockPlayer(ServerPlayer executor, ServerPlayer blockedPlayer public static void absoluteBlockPlayer(ServerPlayer executor, ServerPlayer blockedPlayer) { SaveDataManager.INSTANCE.addBlockedPlayer(executor.getUUID(), blockedPlayer.getUUID()); - executor.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_BLOCKED_PLAYER.get(), + executor.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_BLOCKED_PLAYER.get(), Map.of("blocked_player", blockedPlayer.getName().getString())))); if (Boolean.TRUE.equals(Config.SEND_BLOCKED_MESSAGES_TO_BOTH_PLAYERS.get())) { // Sending Blocked / Unblocked Messages has been enabled in the config - blockedPlayer.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.PLAYER_BLOCKED_BY_SENDER.get(), + blockedPlayer.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.PLAYER_BLOCKED_BY_SENDER.get(), Map.of("sender_name", executor.getName().getString())))); } } diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/cancel/CancelTPA.java b/common/src/main/java/net/superricky/tpaplusplus/commands/cancel/CancelTPA.java index 57903ae..1bed8c3 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/cancel/CancelTPA.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/cancel/CancelTPA.java @@ -10,7 +10,7 @@ import net.superricky.tpaplusplus.requests.Request; import net.superricky.tpaplusplus.requests.RequestGrabUtil; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -37,8 +37,8 @@ private static void cancelFunctionality(Request request, ServerPlayer sender) { } public static void absoluteCancel(Request request) { - request.getSender().sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_CANCELS_TPA.get(), Map.of("cancelled_tpa_recipient", request.getReceiver().getName().getString())))); - request.getReceiver().sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_GOT_CANCELLED_TPA.get(), Map.of("cancelling_sender_of_tpa", request.getSender().getName().getString())))); + request.getSender().sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_CANCELS_TPA.get(), Map.of("cancelled_tpa_recipient", request.getReceiver().getName().getString())))); + request.getReceiver().sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_GOT_CANCELLED_TPA.get(), Map.of("cancelling_sender_of_tpa", request.getSender().getName().getString())))); RequestHelper.getRequestSet().remove(request); } diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/deny/DenyTPA.java b/common/src/main/java/net/superricky/tpaplusplus/commands/deny/DenyTPA.java index 317e3a6..2878e79 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/deny/DenyTPA.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/deny/DenyTPA.java @@ -10,7 +10,7 @@ import net.superricky.tpaplusplus.requests.Request; import net.superricky.tpaplusplus.requests.RequestGrabUtil; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -37,8 +37,8 @@ private static void denyFunctionality(Request request, ServerPlayer receiver) { } public static void absoluteDeny(Request request) { - request.getReceiver().sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_DENIES_TPA.get(), Map.of("denied_sender_name", request.getSender().getName().getString())))); - request.getSender().sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_GOT_DENIED_TPA.get(), Map.of("receiver_who_denied", request.getReceiver().getName().getString())))); + request.getReceiver().sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_DENIES_TPA.get(), Map.of("denied_sender_name", request.getSender().getName().getString())))); + request.getSender().sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_GOT_DENIED_TPA.get(), Map.of("receiver_who_denied", request.getReceiver().getName().getString())))); RequestHelper.getRequestSet().remove(request); } diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/send/SendTPA.java b/common/src/main/java/net/superricky/tpaplusplus/commands/send/SendTPA.java index 53401a2..c3f268f 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/send/SendTPA.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/send/SendTPA.java @@ -13,7 +13,7 @@ import net.superricky.tpaplusplus.requests.Request; import net.superricky.tpaplusplus.requests.RequestHelper; import net.superricky.tpaplusplus.timeout.TimeoutManager; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -23,14 +23,14 @@ public class SendTPA { private static boolean isEitherBlocked(ServerPlayer sender, ServerPlayer receiver) { PlayerData senderData = SaveDataManager.INSTANCE.getPlayerData(sender.getUUID()); if (senderData.hasBlockedPlayer(receiver.getUUID())) { - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_BLOCKED_RECEIVER.get(), + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_BLOCKED_RECEIVER.get(), Map.of("blocked_player", receiver.getName().getString())))); return true; } PlayerData receiverData = SaveDataManager.INSTANCE.getPlayerData(receiver.getUUID()); if (receiverData.hasBlockedPlayer(sender.getUUID())) { - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_BLOCKED_SENDER.get(), + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_BLOCKED_SENDER.get(), Map.of("blocking_player", receiver.getName().getString())))); return true; } @@ -45,7 +45,7 @@ public static void sendTeleportRequest(ServerPlayer sender, ServerPlayer receive } if (RequestHelper.alreadySentTeleportRequest(sender, receiver)) { - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.ERR_ALREADY_SENT_TELEPORT_REQUEST.get(), Map.of("receiver_name", receiver.getName().getString())))); + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.ERR_ALREADY_SENT_TELEPORT_REQUEST.get(), Map.of("receiver_name", receiver.getName().getString())))); return; } @@ -53,7 +53,7 @@ public static void sendTeleportRequest(ServerPlayer sender, ServerPlayer receive PlayerData receiverData = SaveDataManager.INSTANCE.getPlayerData(receiver.getUUID()); if (receiverData.getTpToggle()) { // receiverData is not null && receiver TP toggle is enabled. - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.ERR_RECEIVER_TP_DISABLED.get(), + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.ERR_RECEIVER_TP_DISABLED.get(), Map.of("receiverName", receiver.getName().getString())))); return; } @@ -111,11 +111,11 @@ public static void absoluteSendTeleportRequest(ServerPlayer sender, ServerPlayer if (isHereRequest) { - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_SENT_TPAHERE.get(), Map.of("receivers_name", receiver.getName().getString())))); - receiver.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_GOT_TPAHERE.get(), Map.of("senders_name", sender.getName().getString())))); + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_SENT_TPAHERE.get(), Map.of("receivers_name", receiver.getName().getString())))); + receiver.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_GOT_TPAHERE.get(), Map.of("senders_name", sender.getName().getString())))); } else { - sender.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_SENT_TPA.get(), Map.of("receivers_name", receiver.getName().getString())))); - receiver.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.RECEIVER_GOT_TPA.get(), Map.of("senders_name", sender.getName().getString())))); + sender.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_SENT_TPA.get(), Map.of("receivers_name", receiver.getName().getString())))); + receiver.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.RECEIVER_GOT_TPA.get(), Map.of("senders_name", sender.getName().getString())))); } } diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/tpaplusplus/TPAPlusPlusCommand.java b/common/src/main/java/net/superricky/tpaplusplus/commands/tpaplusplus/TPAPlusPlusCommand.java index 983e35f..dfc137f 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/tpaplusplus/TPAPlusPlusCommand.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/tpaplusplus/TPAPlusPlusCommand.java @@ -13,7 +13,7 @@ import net.superricky.tpaplusplus.config.Messages; import net.superricky.tpaplusplus.network.UpdateCheckKt; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.util.Map; import java.util.Objects; @@ -78,8 +78,8 @@ private static int refactorColorSet(CommandSourceStack source, String... colorLi for (String color : colorList) { if (!ConfigReformatter.isValidColor(color)) { - source.sendFailure(Component.literal(MsgFmt.fmt(Messages.ERR_TPAPLUSPLUS_COLORS_INVALID_COLORS.get(), Map.of("invalid_color_code", color)))); - source.sendFailure(Component.literal(MsgFmt.fmt(Messages.ERR_TPAPLUSPLUS_COLORS_INVALID_COLORS_EXAMPLES.get(), Map.of("random_color_code", (Supplier) ConfigReformatter::getRandomColorCode)))); + source.sendFailure(Component.literal(MsgFmtKt.template(Messages.ERR_TPAPLUSPLUS_COLORS_INVALID_COLORS.get(), Map.of("invalid_color_code", color)))); + source.sendFailure(Component.literal(MsgFmtKt.template(Messages.ERR_TPAPLUSPLUS_COLORS_INVALID_COLORS_EXAMPLES.get(), Map.of("random_color_code", (Supplier) ConfigReformatter::getRandomColorCode)))); return 0; } } @@ -110,7 +110,7 @@ private static int refactorColorSet(CommandSourceStack source, String... colorLi } private static int version(CommandSourceStack source) { - source.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.TPAPLUSPLUS_VERSION.get(), Map.of("mod_version", TPAPlusPlus.MOD_VERSION)))); // send the mod's version to the command executor + source.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.TPAPLUSPLUS_VERSION.get(), Map.of("mod_version", TPAPlusPlus.MOD_VERSION)))); // send the mod's version to the command executor source.sendSystemMessage(Component.literal("§6Checking for updates...")); final Entity executor = source.getEntity(); diff --git a/common/src/main/java/net/superricky/tpaplusplus/commands/unblock/UnBlockPlayer.java b/common/src/main/java/net/superricky/tpaplusplus/commands/unblock/UnBlockPlayer.java index 5fb42c2..1a6aa85 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/commands/unblock/UnBlockPlayer.java +++ b/common/src/main/java/net/superricky/tpaplusplus/commands/unblock/UnBlockPlayer.java @@ -10,7 +10,7 @@ import net.superricky.tpaplusplus.io.PlayerData; import net.superricky.tpaplusplus.io.SaveDataManager; import net.superricky.tpaplusplus.requests.RequestHelper; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.time.Duration; import java.util.Map; @@ -27,7 +27,7 @@ public static void unBlockPlayer(ServerPlayer executor, ServerPlayer blockedPlay if (!executorData.hasBlockedPlayer(blockedPlayer.getUUID())) { // Executor has not blocked the other player - executor.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.HAVENT_BLOCKED_PLAYER.get(), + executor.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.HAVENT_BLOCKED_PLAYER.get(), Map.of("blocked_player", blockedPlayer.getName().getString())))); return; } @@ -47,12 +47,12 @@ public static void unBlockPlayer(ServerPlayer executor, ServerPlayer blockedPlay public static void absoluteUnBlockPlayer(ServerPlayer executor, ServerPlayer blockedPlayer) { SaveDataManager.INSTANCE.removeBlockedPlayer(executor.getUUID(), blockedPlayer.getUUID()); - executor.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.SENDER_UNBLOCKED_PLAYER.get(), + executor.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.SENDER_UNBLOCKED_PLAYER.get(), Map.of("unblocked_player", blockedPlayer.getName().getString())))); if (Boolean.TRUE.equals(Config.SEND_BLOCKED_MESSAGES_TO_BOTH_PLAYERS.get())) { // Sending Blocked / Unblocked Messages has been enabled in the config - blockedPlayer.sendSystemMessage(Component.literal(MsgFmt.fmt(Messages.PLAYER_UNBLOCKED_BY_SENDER.get(), + blockedPlayer.sendSystemMessage(Component.literal(MsgFmtKt.template(Messages.PLAYER_UNBLOCKED_BY_SENDER.get(), Map.of("sender_name", executor.getName().getString())))); } } diff --git a/common/src/main/java/net/superricky/tpaplusplus/cooldown/CooldownManager.kt b/common/src/main/java/net/superricky/tpaplusplus/cooldown/CooldownManager.kt index 5f6ea78..334af99 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/cooldown/CooldownManager.kt +++ b/common/src/main/java/net/superricky/tpaplusplus/cooldown/CooldownManager.kt @@ -5,7 +5,7 @@ import net.minecraft.network.chat.Component import net.minecraft.server.MinecraftServer import net.minecraft.server.level.ServerPlayer import net.superricky.tpaplusplus.config.Messages -import net.superricky.tpaplusplus.util.MsgFmt +import net.superricky.tpaplusplus.util.template import java.time.Duration import java.time.Instant import java.util.* @@ -47,8 +47,8 @@ object CooldownManager { } } - playerToNotify.sendSystemMessage(Component.literal(MsgFmt.fmt( - Messages.COMMAND_ON_COOLDOWN_MESSAGE.get(), mapOf( + playerToNotify.sendSystemMessage(Component.literal(Messages.COMMAND_ON_COOLDOWN_MESSAGE.get().template( + mapOf( "command_used" to cooldownData.commandOnCooldown.getCommandNameFromType(), "time_remaining" to formattedDurationText ) diff --git a/common/src/main/java/net/superricky/tpaplusplus/limitations/impl/DistanceLimitation.java b/common/src/main/java/net/superricky/tpaplusplus/limitations/impl/DistanceLimitation.java index c08413f..e8cc36a 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/limitations/impl/DistanceLimitation.java +++ b/common/src/main/java/net/superricky/tpaplusplus/limitations/impl/DistanceLimitation.java @@ -5,7 +5,7 @@ import net.superricky.tpaplusplus.config.Config; import net.superricky.tpaplusplus.config.Messages; import net.superricky.tpaplusplus.limitations.Limitation; -import net.superricky.tpaplusplus.util.MsgFmt; +import net.superricky.tpaplusplus.util.MsgFmtKt; import java.util.Map; @@ -30,13 +30,13 @@ public String getViolationMessage(ServerPlayer sender, ServerPlayer receiver) { receiver.getX(), receiver.getY(), receiver.getZ()); if (distance > Config.FURTHEST_ALLOWED_DISTANCE.get()) { - return MsgFmt.fmt(Messages.ERR_TOO_FAR_EXECUTOR.get(), - Map.of(DISTANCE_IDENTIFIER, Math.round(distance), - EXPECTED_DISTANCE_IDENTIFIER, Math.round(Config.FURTHEST_ALLOWED_DISTANCE.get()))); + return MsgFmtKt.template(Messages.ERR_TOO_FAR_EXECUTOR.get(), + Map.of(DISTANCE_IDENTIFIER, Double.toString(Math.round(distance)), + EXPECTED_DISTANCE_IDENTIFIER, Double.toString(Math.round(Config.FURTHEST_ALLOWED_DISTANCE.get())))); } else { - return MsgFmt.fmt(Messages.ERR_TOO_CLOSE_EXECUTOR.get(), - Map.of(DISTANCE_IDENTIFIER, Math.round(distance), - EXPECTED_DISTANCE_IDENTIFIER, Math.round(Config.CLOSEST_ALLOWED_DISTANCE.get()))); + return MsgFmtKt.template(Messages.ERR_TOO_CLOSE_EXECUTOR.get(), + Map.of(DISTANCE_IDENTIFIER, Double.toString(Math.round(distance)), + EXPECTED_DISTANCE_IDENTIFIER, Double.toString(Math.round(Config.CLOSEST_ALLOWED_DISTANCE.get())))); } } } diff --git a/common/src/main/java/net/superricky/tpaplusplus/timeout/TimeoutManager.kt b/common/src/main/java/net/superricky/tpaplusplus/timeout/TimeoutManager.kt index 96dfa01..70b09f1 100644 --- a/common/src/main/java/net/superricky/tpaplusplus/timeout/TimeoutManager.kt +++ b/common/src/main/java/net/superricky/tpaplusplus/timeout/TimeoutManager.kt @@ -6,7 +6,7 @@ import net.minecraft.server.MinecraftServer import net.superricky.tpaplusplus.config.Messages import net.superricky.tpaplusplus.requests.Request import net.superricky.tpaplusplus.requests.RequestHelper -import net.superricky.tpaplusplus.util.MsgFmt +import net.superricky.tpaplusplus.util.template import java.time.Duration import java.time.Instant @@ -39,9 +39,7 @@ object TimeoutManager { if (timeout.request.isHereRequest) { sender.sendSystemMessage( - Component.literal( - MsgFmt.fmt( - Messages.SENDER_TPAHERE_TIMEOUT.get(), + Component.literal(Messages.SENDER_TPAHERE_TIMEOUT.get().template( mapOf("receivers_name" to receiver.displayName.string) ) ) @@ -49,8 +47,7 @@ object TimeoutManager { receiver.sendSystemMessage( Component.literal( - MsgFmt.fmt( - Messages.RECEIVER_TPAHERE_TIMEOUT.get(), + Messages.RECEIVER_TPAHERE_TIMEOUT.get().template( mapOf("senders_name" to sender.displayName.string) ) ) @@ -61,18 +58,14 @@ object TimeoutManager { } sender.sendSystemMessage( - Component.literal( - MsgFmt.fmt( - Messages.SENDER_TPA_TIMEOUT.get(), + Component.literal(Messages.SENDER_TPA_TIMEOUT.get().template( mapOf("receivers_name" to receiver.displayName.string) ) ) ) receiver.sendSystemMessage( - Component.literal( - MsgFmt.fmt( - Messages.RECEIVER_TPA_TIMEOUT.get(), + Component.literal(Messages.RECEIVER_TPA_TIMEOUT.get().template( mapOf("senders_name" to sender.displayName.string) ) ) diff --git a/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.java b/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.java deleted file mode 100644 index ba3bd67..0000000 --- a/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.superricky.tpaplusplus.util; - -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A utility class to format messages with a basic implementation of f-strings, since String.format() doesn't have the flexibility that we want. - * The acronym in the class name stands for MessageFormat. An acronym is used because it doesn't reduce readability, and this method is used extensively throughout the codebase. - */ -public class MsgFmt { - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\$\\{(\\w+)}"); - - /** - * A function acting similar to "F-Strings" in other languages like Python or C#. - * This function takes a string and a map of placeholders to values, and replaces all instances of the placeholders with the values in their respective key-value store. - * The "fmt" in the function name is an acronym for "Format". - * @param formatString The string which will be formatted, containing the placeholders names. For example: "Hello, ${name}!". - * @param values A map of keywords (for example "John"), and values implementing toString(). Typically provided with Map.of() in Java, although any map will suffice. For example, a map of ("name": "John"). - * @return The formatted string after applying all placeholders (values) to the formatString. - */ - public static String fmt(String formatString, Map values) { - if (formatString == null || values == null) { - return null; - } - - StringBuilder result = new StringBuilder(formatString); - Matcher matcher = PLACEHOLDER_PATTERN.matcher(formatString); - - while (matcher.find()) { - String placeholder = matcher.group(1); - Object value = values.get(placeholder); - - if (value == null) { - throw new IllegalArgumentException("Missing value for placeholder: " + placeholder); - } - - int start = result.indexOf("${" + placeholder + "}"); - int end = start + placeholder.length() + 3; // +3 for "${" and "}" - result.replace(start, end, value.toString()); - - // Reset matcher to account for the replaced text - matcher.reset(result); - } - - return result.toString(); - } - - private MsgFmt() { - } -} diff --git a/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.kt b/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.kt new file mode 100644 index 0000000..66fa43f --- /dev/null +++ b/common/src/main/java/net/superricky/tpaplusplus/util/MsgFmt.kt @@ -0,0 +1,70 @@ +package net.superricky.tpaplusplus.util + +import com.mojang.logging.LogUtils +import java.util.function.Supplier +import java.util.regex.Matcher + +private val TEMPLATE_PATTERN = """(\\)?\$\{(\w+)}""".toRegex().toPattern() +private val LOGGER = LogUtils.getLogger() + +/** + * The string this is called on will be templated similar to Kotlin's templating, but at runtime. + * Placeholders are declared in the format of ${placeholder name}. They can be escaped with backslashes like so: \${placeholder name}. + * If a replacement for a placeholder is not found, it will leave the placeholder untouched — as if it was escaped. + * A string can contain the same placeholder multiple times, but only one replacement. However, a replacement can be a lambda or Supplier. + * Useful for user-inputted strings. + * @param replacements A map of placeholders (for example "name"), and their replacement (for example "John"). + * Placeholders in this map only contain the name of the placeholder, not the ${} surrounding it. + * If replacement is a Supplier or a zero-parameter lambda, it will be automatically unwrapped here into a string. + * Suppliers or lambdas should not return null. If they do, they will be treated as if the replacement was not found. + * For anything that isn't a String, Supplier, or Lambda, its toString() method will be called. + * @return The templated string. + */ +fun String.template(replacements: Map): String { + val sb = StringBuilder() + val matcher = TEMPLATE_PATTERN.matcher(this) + + while (matcher.find()) { + val group = matcher.group() + + if (matcher.group(1) != null) { + val consumedBackslashGroup = group.substring(1) + matcher.appendReplacement(sb, Matcher.quoteReplacement(consumedBackslashGroup)) + continue + } + + val placeholder = matcher.group(2) + val unsafeReplacement = replacements[placeholder] + val replacement = getReplacementTypeSafe(group, placeholder, unsafeReplacement) + + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)) + } + matcher.appendTail(sb) + return sb.toString() +} + +private fun getReplacementTypeSafe(group: String, placeholder: String, unsafeReplacement: Any?): String { + when (unsafeReplacement) { + is String -> { + return unsafeReplacement + } + is Supplier<*> -> { + val unknownSupplierResult = unsafeReplacement.get() + if (unknownSupplierResult == null) { + LOGGER.warn("Attempted to unwrap Supplier \"$unsafeReplacement\" but got null. Refusing to template placeholder $placeholder") + return group + } + return unknownSupplierResult.toString() + } + is Function0<*> -> { + val unknownLambdaResult = unsafeReplacement.invoke() + if (unknownLambdaResult == null) { + LOGGER.warn("Attempted to unwrap Lambda \"$unsafeReplacement\" but got null. Refusing to template placeholder $placeholder") + return group + } + return unknownLambdaResult.toString() + } + is Nothing? -> return group + else -> return unsafeReplacement.toString() + } +} \ No newline at end of file diff --git a/common/src/test/java/net/superricky/tpaplusplus/config/formatters/MsgFmtTest.java b/common/src/test/java/net/superricky/tpaplusplus/config/formatters/MsgFmtTest.java index 3150f87..16a8cb9 100644 --- a/common/src/test/java/net/superricky/tpaplusplus/config/formatters/MsgFmtTest.java +++ b/common/src/test/java/net/superricky/tpaplusplus/config/formatters/MsgFmtTest.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.Map; -import static net.superricky.tpaplusplus.util.MsgFmt.fmt; +import static net.superricky.tpaplusplus.util.MsgFmtKt.template; import static org.junit.jupiter.api.Assertions.*; public class MsgFmtTest { @@ -14,44 +14,61 @@ public class MsgFmtTest { public void testBasicReplacement() { Map values = new HashMap<>(); values.put("name", "John"); - String result = fmt("Hello, ${name}!", values); + String result = template("Hello, ${name}!", values); assertEquals("Hello, John!", result); } + @Test + public void testEscapingPlaceholders() { + Map values = new HashMap<>(); + values.put("name", "John"); + String result = template("Hello, \\${name}!", values); + assertEquals("Hello, ${name}!", result); + } + + @Test + public void testEscapingPlaceholderBackslashRemoval() { + Map values = new HashMap<>(); + values.put("name", "John"); + String result = template("Hello, \\\\${name}!", values); + assertEquals("Hello, \\${name}!", result); + } + + // TODO: Test Suppliers and Lambdas + @Test public void testMultiplePlaceholders() { Map values = new HashMap<>(); values.put("name", "John"); values.put("age", 30); - String result = fmt("Name: ${name}, Age: ${age}", values); + String result = template("Name: ${name}, Age: ${age}", values); assertEquals("Name: John, Age: 30", result); } @Test - public void testEmptyString() { - String result = fmt("", new HashMap<>()); - assertEquals("", result); - } + public void testNoPlaceholders() { + Map values = new HashMap<>(); + values.put("name", "John"); - @SuppressWarnings("ConstantValue") - @Test - public void testNullFormatString() { - String result = fmt(null, new HashMap<>()); - assertNull(result); + String result = template("Hello there!", values); + + assertEquals("Hello there!", result); } - @SuppressWarnings("ConstantValue") @Test - public void testNullValues() { - String result = fmt("Hello, ${name}!", null); - assertNull(result); + public void testEmptyString() { + String result = template("", new HashMap<>()); + assertEquals("", result); } @Test - public void testMissingPlaceholderValue() { + public void testMissingPlaceholderReplacement() { Map values = new HashMap<>(); values.put("name", "John"); - assertThrows(IllegalArgumentException.class, () -> fmt("Hello, ${name}. Your balance is ${balance}.", values)); + + String result = template("Hello, ${name}. Your balance is ${balance}.", values); + + assertEquals("Hello, John. Your balance is ${balance}.", result); } @Test @@ -62,7 +79,7 @@ public void testTooManyPlaceholders() { values.put("age", 46); values.put("favouriteColor", "Red"); - String result = fmt("Hello, ${name}! You are ${age} years old", values); + String result = template("Hello, ${name}! You are ${age} years old", values); assertEquals("Hello, John! You are 46 years old", result); } @@ -72,7 +89,7 @@ public void testRepeatedPlaceholders() { Map values = new HashMap<>(); values.put("name", "John"); - String result = fmt("Hello, ${name}! How are you, ${name}?", values); + String result = template("Hello, ${name}! How are you, ${name}?", values); assertEquals("Hello, John! How are you, John?", result); }