diff --git a/src/main/java/org/mvplugins/multiverse/portals/MVPortalNodes.java b/src/main/java/org/mvplugins/multiverse/portals/MVPortalNodes.java index 34ef7e61..ef1c461c 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/MVPortalNodes.java +++ b/src/main/java/org/mvplugins/multiverse/portals/MVPortalNodes.java @@ -2,15 +2,15 @@ import org.bukkit.Material; import org.bukkit.entity.Player; -import org.mvplugins.multiverse.core.MultiverseCoreApi; import org.mvplugins.multiverse.core.config.node.ConfigNode; import org.mvplugins.multiverse.core.config.node.Node; import org.mvplugins.multiverse.core.config.node.NodeGroup; -import org.mvplugins.multiverse.core.destination.DestinationsProvider; import org.mvplugins.multiverse.core.exceptions.MultiverseException; +import org.mvplugins.multiverse.core.locale.message.Message; import org.mvplugins.multiverse.external.vavr.control.Try; import org.mvplugins.multiverse.portals.action.ActionHandler; import org.mvplugins.multiverse.portals.action.ActionHandlerProvider; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.MultiverseRegion; import java.util.Collections; @@ -74,17 +74,20 @@ private N node(N node) { .stringParser((sender, input, type) -> { if (input.equals("@selected-region")) { if (!(sender instanceof Player player)) { - return Try.failure(new MultiverseException("You can only use '@selected-region' as a player.")); + return Try.failure(new MultiverseException( + Message.of(MVPi18n.PORTALCONFIG_LOCATION_PLAYERSONLY))); } MultiverseRegion region = plugin.getPortalSession(player).getSelectedRegion(); if (region == null) { - return Try.failure(new MultiverseException("You must select a region first. See `/mvp wand` for more info.")); + return Try.failure(new MultiverseException( + Message.of(MVPi18n.PORTALCONFIG_LOCATION_SELECTIONREQUIRED))); } return Try.success(region.toString()); } PortalLocation portalLocation = PortalLocation.parseLocation(input); if (!portalLocation.isValidLocation()) { - return Try.failure(new MultiverseException("Invalid location format. The portal location must be in the format `WORLD:X,Y,Z:X,Y,Z`.")); + return Try.failure(new MultiverseException( + Message.of(MVPi18n.PORTALCONFIG_LOCATION_INVALID))); } return Try.success(portalLocation.toString()); }) diff --git a/src/main/java/org/mvplugins/multiverse/portals/MultiversePortals.java b/src/main/java/org/mvplugins/multiverse/portals/MultiversePortals.java index 86b5ee00..dda60680 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/MultiversePortals.java +++ b/src/main/java/org/mvplugins/multiverse/portals/MultiversePortals.java @@ -98,6 +98,8 @@ public void onEnable() { Logging.setDebugLevel(coreConfig.get().getGlobalDebug()); + this.setUpLocales(); + // Register our commands this.registerCommands(); diff --git a/src/main/java/org/mvplugins/multiverse/portals/PortalPlayerSession.java b/src/main/java/org/mvplugins/multiverse/portals/PortalPlayerSession.java index c5c2f4f5..42bd1816 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/PortalPlayerSession.java +++ b/src/main/java/org/mvplugins/multiverse/portals/PortalPlayerSession.java @@ -11,13 +11,16 @@ import com.dumptruckman.minecraft.util.Logging; import org.bukkit.entity.LivingEntity; -import org.mvplugins.multiverse.core.economy.MVEconomist; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; +import org.mvplugins.multiverse.core.command.MVCommandManager; +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.portals.config.PortalsConfig; import org.mvplugins.multiverse.portals.enums.MoveType; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.DisplayUtils; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -25,6 +28,8 @@ import org.mvplugins.multiverse.portals.utils.MultiverseRegion; import org.mvplugins.multiverse.portals.utils.PortalManager; +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; + public class PortalPlayerSession { private final MultiversePortals plugin; private final PortalsConfig portalsConfig; @@ -32,6 +37,7 @@ public class PortalPlayerSession { private final WorldManager worldManager; private final DisplayUtils displayUtils; private final Player player; + private final MVCommandIssuer issuer; private MVPortal portalSelection = null; private MVPortal standingIn = null; @@ -52,6 +58,7 @@ public PortalPlayerSession(MultiversePortals plugin, Player p) { this.worldManager = plugin.getServiceLocator().getService(WorldManager.class); this.displayUtils = plugin.getServiceLocator().getService(DisplayUtils.class); this.player = p; + this.issuer = plugin.getServiceLocator().getService(MVCommandManager.class).getCommandIssuer(p); this.setLocation(p.getLocation()); this.lastTeleportTime = new Date(new Date().getTime() - this.portalsConfig.getPortalCooldown()); } @@ -68,10 +75,9 @@ public MVPortal getSelectedPortal() { public void setDebugMode(boolean debugMode) { this.debugMode = debugMode; if (this.debugMode) { - this.player.sendMessage("Portal debug mode " + ChatColor.GREEN + "ENABLED"); - this.player.sendMessage("Use " + ChatColor.DARK_AQUA + "/mvp debug" + ChatColor.WHITE + " to disable."); + this.issuer.sendInfo(MVPi18n.DEBUG_ENABLED); } else { - this.player.sendMessage("Portal debug mode " + ChatColor.RED + "DISABLED"); + this.issuer.sendInfo(MVPi18n.DEBUG_DISABLED); } } @@ -145,12 +151,16 @@ public boolean setLeftClickSelection(Vector v, LoadedMultiverseWorld world) { } this.leftClick = v; this.leftClickWorld = world; - String message = ChatColor.AQUA + "First position set to: (" + v.getBlockX() + ", " + v.getBlockY() + ", " + v.getBlockZ() + ")"; + String position = "(" + v.getBlockX() + ", " + v.getBlockY() + ", " + v.getBlockZ() + ")"; if (this.leftClickWorld == this.rightClickWorld && this.rightClick != null) { MultiverseRegion tempReg = new MultiverseRegion(this.leftClick, this.rightClick, this.leftClickWorld); - message += ChatColor.GOLD + " (" + tempReg.getArea() + " blocks)"; + this.issuer.sendInfo(MVPi18n.SELECTION_FIRST_AREA, + replace("{position}").with(position), + Replace.COUNT.with(tempReg.getArea())); + } else { + this.issuer.sendInfo(MVPi18n.SELECTION_FIRST, + replace("{position}").with(position)); } - this.player.sendMessage(message); return true; } @@ -160,12 +170,16 @@ public boolean setRightClickSelection(Vector v, LoadedMultiverseWorld world) { } this.rightClick = v; this.rightClickWorld = world; - String message = ChatColor.AQUA + "Second position set to: (" + v.getBlockX() + ", " + v.getBlockY() + ", " + v.getBlockZ() + ")"; + String position = "(" + v.getBlockX() + ", " + v.getBlockY() + ", " + v.getBlockZ() + ")"; if (this.leftClickWorld == this.rightClickWorld && this.leftClick != null) { MultiverseRegion tempReg = new MultiverseRegion(this.leftClick, this.rightClick, this.leftClickWorld); - message += ChatColor.GOLD + " (" + tempReg.getArea() + " blocks)"; + this.issuer.sendInfo(MVPi18n.SELECTION_SECOND_AREA, + replace("{position}").with(position), + Replace.COUNT.with(tempReg.getArea())); + } else { + this.issuer.sendInfo(MVPi18n.SELECTION_SECOND, + replace("{position}").with(position)); } - this.player.sendMessage(message); return true; } @@ -180,27 +194,27 @@ public MultiverseRegion getSelectedRegion() { return new MultiverseRegion(minPoint, maxPoint, this.worldManager.getLoadedWorld(minPoint.getWorld().getName()).getOrNull()); } else { - this.player.sendMessage("You haven't finished your selection."); + this.issuer.sendError(MVPi18n.SELECTION_WORLDEDIT_INCOMPLETE); return null; } } else { - this.player.sendMessage("You must have a WorldEdit selection to do this."); + this.issuer.sendError(MVPi18n.SELECTION_WORLDEDIT_REQUIRED); return null; } } // They're using our crappy selection: if (this.leftClick == null) { - this.player.sendMessage("You need to LEFT click on a block with your wand!"); + this.issuer.sendError(MVPi18n.SELECTION_LEFT_REQUIRED); return null; } if (this.rightClick == null) { - this.player.sendMessage("You need to RIGHT click on a block with your wand!"); + this.issuer.sendError(MVPi18n.SELECTION_RIGHT_REQUIRED); return null; } if (!this.leftClickWorld.equals(this.rightClickWorld)) { - this.player.sendMessage("You need to select both coords in the same world!"); - this.player.sendMessage("Left Click Position was in:" + this.leftClickWorld.getAlias()); - this.player.sendMessage("Right Click Position was in:" + this.rightClickWorld.getAlias()); + this.issuer.sendError(MVPi18n.SELECTION_SAMEWORLD_REQUIRED, + replace("{leftWorld}").with(this.leftClickWorld.getAlias()), + replace("{rightWorld}").with(this.rightClickWorld.getAlias())); return null; } return new MultiverseRegion(this.leftClick, this.rightClick, this.leftClickWorld); @@ -251,13 +265,13 @@ public boolean showDebugInfo() { return false; } - displayUtils.showStaticInfo(this.player, this.standingIn, "You are currently standing in "); + displayUtils.showStaticInfo(this.player, this.standingIn, MVPi18n.PORTALINFO_DEBUGHEADER); return true; } public boolean showDebugInfo(MVPortal portal) { if (portal.playerCanEnterPortal(this.player)) { - displayUtils.showStaticInfo(this.player, portal, "Portal Info "); + displayUtils.showStaticInfo(this.player, portal, MVPi18n.PORTALINFO_HEADER); } Logging.info("Player " + this.player.getName() + " walked through" + portal.getName() + " with debug on."); return true; @@ -276,7 +290,7 @@ public void setTeleportTime(Date date) { public boolean checkAndSendCooldownMessage() { long cooldownMs = this.getRemainingTeleportCooldown(); if (cooldownMs > 0) { - this.player.sendMessage(this.getCooldownMessage(cooldownMs)); + this.issuer.sendError(this.getCooldownMessage(cooldownMs)); return true; } @@ -303,11 +317,9 @@ private long getRemainingTeleportCooldown() { * @param cooldownMs The cooldown time in milliseconds. * @return A message to be sent to a player, informing them about the remaining cooldown time. */ - private String getCooldownMessage(long cooldownMs) { - return "There is a portal " + ChatColor.AQUA + "cooldown " - + ChatColor.WHITE + "in effect. Please try again in " - + ChatColor.GOLD + this.formatCooldownTime(cooldownMs) - + ChatColor.WHITE + "."; + private Message getCooldownMessage(long cooldownMs) { + return Message.of(MVPi18n.PORTAL_COOLDOWN, + replace("{cooldown}").with(formatCooldownTime(cooldownMs))); } /** diff --git a/src/main/java/org/mvplugins/multiverse/portals/action/ActionHandlerProvider.java b/src/main/java/org/mvplugins/multiverse/portals/action/ActionHandlerProvider.java index 69eb7288..f7466392 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/action/ActionHandlerProvider.java +++ b/src/main/java/org/mvplugins/multiverse/portals/action/ActionHandlerProvider.java @@ -4,15 +4,19 @@ import org.bukkit.command.CommandSender; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.utils.result.Attempt; import org.mvplugins.multiverse.external.jetbrains.annotations.ApiStatus; import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.external.vavr.control.Option; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; + /** * Provides various actions that can be performed when a portal is used. This extends to more than just teleporting. *
@@ -68,8 +72,9 @@ public void registerHandlerType(@NotNull ActionHandlerType handlerType) { return Option.of(handlerTypeMap.get(name)) .map(Attempt::, ActionFailureReason>success) .getOrElse(() -> Attempt.failure(ActionFailureReason.INSTANCE, - Message.of("Unknown action type '" + name + "'. Supported types are: " - + String.join(", ", handlerTypeMap.keySet())))); + Message.of(MVPi18n.ACTION_UNKNOWN_TYPE, + Replace.NAME.with(name), + replace("{types}").with(String.join(", ", handlerTypeMap.keySet()))))); } /** diff --git a/src/main/java/org/mvplugins/multiverse/portals/action/types/CommandActionHandler.java b/src/main/java/org/mvplugins/multiverse/portals/action/types/CommandActionHandler.java index fae95706..16b8e093 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/action/types/CommandActionHandler.java +++ b/src/main/java/org/mvplugins/multiverse/portals/action/types/CommandActionHandler.java @@ -1,6 +1,5 @@ package org.mvplugins.multiverse.portals.action.types; -import org.bukkit.ChatColor; import org.bukkit.entity.Entity; import org.mvplugins.multiverse.core.locale.message.Message; import org.mvplugins.multiverse.core.utils.result.Attempt; @@ -26,8 +25,7 @@ final class CommandActionHandler extends ActionHandler { @@ -43,8 +45,8 @@ final class MultiverseDestinationActionHandler extends ActionHandler parseHandler(@NotNull CommandSender sender, @NotNull String action) { if (action.isEmpty()) { - return Attempt.failure(ActionFailureReason.INSTANCE, Message.of("Please specific a multiverse destination as the portal's action.")); + return Attempt.failure(ActionFailureReason.INSTANCE, + Message.of(MVPi18n.ACTION_MULTIVERSEDESTINATION_INVALID)); } return destinationsProvider.parseDestination(sender, action) .transform(ActionFailureReason.INSTANCE) diff --git a/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandler.java b/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandler.java index b19d8692..538465bb 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandler.java +++ b/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandler.java @@ -2,10 +2,10 @@ import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; -import org.bukkit.ChatColor; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.utils.result.Attempt; import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.mvplugins.multiverse.external.vavr.control.Try; @@ -13,6 +13,8 @@ import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.action.ActionFailureReason; import org.mvplugins.multiverse.portals.action.ActionHandler; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + final class ServerActionHandler extends ActionHandler { @@ -28,7 +30,8 @@ final class ServerActionHandler extends ActionHandler runAction(@NotNull MVPortal portal, @NotNull Entity entity) { if (!(entity instanceof Player player)) { - return Attempt.failure(ActionFailureReason.INSTANCE, Message.of("Only players can teleport between servers!")); + return Attempt.failure(ActionFailureReason.INSTANCE, + Message.of(MVPi18n.ACTION_SERVER_PLAYERSONLY)); } return Try .run(() -> { @@ -39,14 +42,14 @@ final class ServerActionHandler extends ActionHandlersuccess) .recover(ex -> Attempt.failure(ActionFailureReason.INSTANCE, - Message.of("An error occurred while sending plugin message to proxy: " + ex.getLocalizedMessage()))) + Message.of(MVPi18n.ACTION_SERVER_PROXYERROR, Replace.ERROR.with(ex)))) .getOrElse(() -> Attempt.failure(ActionFailureReason.INSTANCE, - Message.of("An unknown error occurred while sending plugin message to proxy."))); + Message.of(MVPi18n.ACTION_SERVER_PROXYUNKNOWNERROR))); } @Override public Message actionDescription(Entity entity) { - return Message.of(ChatColor.AQUA + "Transfer to " + ChatColor.GOLD + serverName + ChatColor.AQUA + " server"); + return Message.of(MVPi18n.ACTION_SERVER_DESCRIPTION, Replace.NAME.with(serverName)); } @Override diff --git a/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandlerType.java b/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandlerType.java index 9748a9f2..7f1655b6 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandlerType.java +++ b/src/main/java/org/mvplugins/multiverse/portals/action/types/ServerActionHandlerType.java @@ -9,6 +9,7 @@ import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.action.ActionFailureReason; import org.mvplugins.multiverse.portals.action.ActionHandlerType; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import java.util.Collection; @@ -30,7 +31,7 @@ final class ServerActionHandlerType extends ActionHandlerType [value]") - @Description("Allows you to set Global MV Portals Variables.") + @Description("{@@mv-portals.config.description}") void onConfigCommand( @NotNull MVCommandIssuer issuer, @Optional @Syntax("") - @Description("The property to set or get info of.") + @Description("{@@mv-portals.config.property.description}") String property, @Optional @Syntax("[value]") - @Description("The value to set.") + @Description("{@@mv-portals.config.value.description}") String value ) { if (value == null) { @@ -53,26 +53,26 @@ void onConfigCommand( private void showConfigValue(MVCommandIssuer issuer, String name) { portalsConfig.getStringPropertyHandle().getProperty(name) - .onSuccess(value -> issuer.sendMessage(MVCorei18n.CONFIG_SHOW_SUCCESS, - MessageReplacement.Replace.NAME.with(name), - MessageReplacement.Replace.VALUE.with(value))) - .onFailure(e -> issuer.sendMessage(MVCorei18n.CONFIG_SHOW_ERROR, - MessageReplacement.Replace.NAME.with(name), - MessageReplacement.Replace.ERROR.with(e))); + .onSuccess(value -> issuer.sendInfo(MVCorei18n.CONFIG_SHOW_SUCCESS, + Replace.NAME.with(name), + Replace.VALUE.with(value))) + .onFailure(e -> issuer.sendError(MVCorei18n.CONFIG_SHOW_ERROR, + Replace.NAME.with(name), + Replace.ERROR.with(e))); } private void updateConfigValue(MVCommandIssuer issuer, String name, String value) { portalsConfig.getStringPropertyHandle().setPropertyString(issuer.getIssuer(), name, value) .onSuccess(ignore -> { portalsConfig.save(); - issuer.sendMessage(MVCorei18n.CONFIG_SET_SUCCESS, - MessageReplacement.Replace.NAME.with(name), - MessageReplacement.Replace.VALUE.with(value)); + issuer.sendInfo(MVCorei18n.CONFIG_SET_SUCCESS, + Replace.NAME.with(name), + Replace.VALUE.with(value)); }) - .onFailure(e -> issuer.sendMessage(MVCorei18n.CONFIG_SET_ERROR, - MessageReplacement.Replace.NAME.with(name), - MessageReplacement.Replace.VALUE.with(value), - MessageReplacement.Replace.ERROR.with(e))); + .onFailure(e -> issuer.sendError(MVCorei18n.CONFIG_SET_ERROR, + Replace.NAME.with(name), + Replace.VALUE.with(value), + Replace.ERROR.with(e))); } @Service diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/CreateCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/CreateCommand.java index 901c1293..3f770520 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/CreateCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/CreateCommand.java @@ -1,9 +1,10 @@ package org.mvplugins.multiverse.portals.commands; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; import org.mvplugins.multiverse.core.destination.DestinationInstance; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; @@ -20,9 +21,11 @@ import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.PortalLocation; import org.mvplugins.multiverse.portals.PortalPlayerSession; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.MultiverseRegion; import org.mvplugins.multiverse.portals.utils.PortalManager; + @Service class CreateCommand extends PortalsCommand { @@ -30,7 +33,8 @@ class CreateCommand extends PortalsCommand { private final PortalManager portalManager; @Inject - CreateCommand(@NotNull MultiversePortals plugin, @NotNull PortalManager portalManager) { + CreateCommand(@NotNull MultiversePortals plugin, + @NotNull PortalManager portalManager) { this.plugin = plugin; this.portalManager = portalManager; } @@ -39,8 +43,10 @@ class CreateCommand extends PortalsCommand { @CommandPermission("multiverse.portal.create") @CommandCompletion("@empty @mvworlds|@destinations") @Syntax(" [destination]") - @Description("Creates a new portal, assuming you have a region selected.") + @Description("{@@mv-portals.create.description}") void onCreateCommand( + @NotNull MVCommandIssuer issuer, + @Flags("resolve=issuerOnly") Player player, @@ -48,10 +54,12 @@ void onCreateCommand( LoadedMultiverseWorld world, @Syntax("") + @Description("{@@mv-portals.create.name.description}") String portalName, @Optional @Syntax("[destination]") + @Description("{@@mv-portals.create.destination.description}") DestinationInstance destination ) { // todo: maybe make a CommandContext for PortalPlayerSession @@ -63,21 +71,20 @@ void onCreateCommand( } if (!MVPortal.PORTAL_NAME_PATTERN.matcher(portalName).matches()) { - player.sendMessage(String.format("%sInvalid portal name. It must not contain dot or special characters.", ChatColor.RED)); + issuer.sendError(MVPi18n.CREATE_INVALIDNAME); return; } MVPortal portal = this.portalManager.getPortal(portalName); PortalLocation location = new PortalLocation(region.getMinimumPoint(), region.getMaximumPoint(), world); if (this.portalManager.addPortal(world, portalName, player.getName(), location)) { - player.sendMessage("New portal (" + ChatColor.DARK_AQUA + portalName + ChatColor.WHITE + ") created and selected!"); + issuer.sendInfo(MVPi18n.CREATE_SUCCESS, Replace.NAME.with(portalName)); // If the portal did not exist, ie: we're creating it. // we have to re select it, because it would be null portal = this.portalManager.getPortal(portalName); } else { - player.sendMessage("New portal (" + ChatColor.DARK_AQUA + portalName + ChatColor.WHITE + ") was NOT created!"); - player.sendMessage("It already existed and has been selected."); + issuer.sendError(MVPi18n.CREATE_ALREADYEXISTS, Replace.NAME.with(portalName)); } ps.selectPortal(portal); @@ -85,7 +92,7 @@ void onCreateCommand( portal.setAction(destination.toString()); this.plugin.savePortalsConfig(); } else { - player.sendMessage(ChatColor.RED + "Portal action not set. Use " + ChatColor.DARK_AQUA + "/mvp modify action " + ChatColor.RED + " to set one."); + issuer.sendError(MVPi18n.CREATE_ACTIONNOTSET); } // todo: Automatically get exact destination from player location @@ -101,8 +108,9 @@ private final static class LegacyAlias extends CreateCommand implements LegacyAl @Override @CommandAlias("mvpcreate|mvpc") - void onCreateCommand(Player player, LoadedMultiverseWorld world, String portalName, DestinationInstance destination) { - super.onCreateCommand(player, world, portalName, destination); + void onCreateCommand(MVCommandIssuer issuer, Player player, LoadedMultiverseWorld world, String portalName, + DestinationInstance destination) { + super.onCreateCommand(issuer, player, world, portalName, destination); } } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/DebugCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/DebugCommand.java index 292c0860..a8163c80 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/DebugCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/DebugCommand.java @@ -2,7 +2,6 @@ import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; -import org.mvplugins.multiverse.core.command.MVCommandManager; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -32,7 +31,7 @@ class DebugCommand extends PortalsCommand { @CommandPermission("multiverse.portal.debug") @CommandCompletion("on|off") @Syntax("[on|off]") - @Description("Instead of teleporting you to a place when you walk into a portal you will see the details about it. This command toggles.") + @Description("{@@mv-portals.debug.description}") void onDebugCommand( @Flags("resolve=issuerOnly") Player player, @@ -40,6 +39,7 @@ void onDebugCommand( @Optional @Single @Syntax("[on|off]") + @Description("{@@mv-portals.debug.toggle.description}") String toggle ) { PortalPlayerSession ps = this.plugin.getPortalSession(player); diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/InfoCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/InfoCommand.java index 513ff124..30a3dff2 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/InfoCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/InfoCommand.java @@ -3,7 +3,6 @@ import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; import org.mvplugins.multiverse.core.command.MVCommandIssuer; -import org.mvplugins.multiverse.core.command.MVCommandManager; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -16,6 +15,7 @@ import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; import org.mvplugins.multiverse.portals.MultiversePortals; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.DisplayUtils; @Service @@ -34,20 +34,20 @@ class InfoCommand extends PortalsCommand { @CommandPermission("multiverse.portal.info") @CommandCompletion("@mvportals") @Syntax("[portal]") - @Description("Displays information about a portal.") + @Description("{@@mv-portals.info.description}") void onInfoCommand( @NotNull MVCommandIssuer issuer, @Flags("resolve=issuerAware") @Syntax("[portal]") - @Description("The portal to show info") + @Description("{@@mv-portals.info.portal.description}") MVPortal portal ) { if(issuer.isPlayer()) { Player p = issuer.getPlayer(); this.plugin.getPortalSession(p).showDebugInfo(portal); } else { - displayUtils.showStaticInfo(issuer.getIssuer(), portal, "Portal Info: "); + displayUtils.showStaticInfo(issuer.getIssuer(), portal, MVPi18n.PORTALINFO_COMMANDHEADER); } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/ListCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/ListCommand.java index e0bc64d8..a97a0604 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/ListCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/ListCommand.java @@ -1,8 +1,10 @@ package org.mvplugins.multiverse.portals.commands; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.world.MultiverseWorld; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; @@ -17,12 +19,15 @@ import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.DisplayUtils; import org.mvplugins.multiverse.portals.utils.PortalManager; import java.util.ArrayList; import java.util.List; +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; + @Service class ListCommand extends PortalsCommand { @@ -33,7 +38,9 @@ class ListCommand extends PortalsCommand { private final DisplayUtils displayUtils; @Inject - ListCommand(@NotNull PortalManager portalManager, @NotNull WorldManager worldManager, @NotNull DisplayUtils displayUtils) { + ListCommand(@NotNull PortalManager portalManager, + @NotNull WorldManager worldManager, + @NotNull DisplayUtils displayUtils) { this.portalManager = portalManager; this.worldManager = worldManager; this.displayUtils = displayUtils; @@ -43,18 +50,18 @@ class ListCommand extends PortalsCommand { @CommandPermission("multiverse.portal.list") @CommandCompletion("@empty @empty") @Syntax("[filter/world] [page]") - @Description("Displays a listing of all portals that you can enter.") + @Description("{@@mv-portals.list.description}") void onListCommand( - @NotNull CommandSender sender, + @NotNull MVCommandIssuer issuer, @Optional @Syntax("[filter/world]") - @Description("Filter by name or world") + @Description("{@@mv-portals.list.filter.description}") String filterOrWorld, @Default("1") @Syntax("[page]") - @Description("Page to display") + @Description("{@@mv-portals.list.page.description}") int page ) { String filter = filterOrWorld; @@ -64,49 +71,59 @@ void onListCommand( filter = null; } - List portals = new ArrayList<>(getPortals(sender, world, filter, page)); + List portals = new ArrayList<>(getPortals(issuer, world, filter, page)); if (portals.isEmpty() && filter == null) { - page = (int) Math.ceil(1F * getPortals(sender, world, filter).size() / ITEMS_PER_PAGE); - portals.addAll(getPortals(sender, world, filter, page)); - } - - String titleString = ChatColor.AQUA + String.valueOf(getPortals(sender, world, filter).size()) + " Portals"; - if (world != null) { - titleString += " in " + ChatColor.YELLOW + world.getAlias(); - } - if (filter != null) { - titleString += ChatColor.GOLD + " [" + filter + "]"; + page = (int) Math.ceil(1F * getPortals(issuer, world, filter).size() / ITEMS_PER_PAGE); + portals.addAll(getPortals(issuer, world, filter, page)); } - titleString += ChatColor.GOLD + " - Page " + page + "/" + (int) Math.ceil(1F * getPortals(sender, world, filter).size() / ITEMS_PER_PAGE); - sender.sendMessage(ChatColor.AQUA + "--- " + titleString + ChatColor.AQUA + " ---"); + int portalCount = getPortals(issuer, world, filter).size(); + int totalPages = (int) Math.ceil(1F * portalCount / ITEMS_PER_PAGE); + Message worldMessage = world == null + ? Message.of("") + : Message.of(MVPi18n.LIST_HEADER_WORLD, Replace.WORLD.with(world.getAlias())); + Message filterMessage = filter == null + ? Message.of("") + : Message.of(MVPi18n.LIST_HEADER_FILTER, replace("{filter}").with(filter)); + issuer.sendInfo(MVPi18n.LIST_HEADER, + Replace.COUNT.with(portalCount), + Replace.WORLD.with(worldMessage), + replace("{filter}").with(filterMessage), + replace("{page}").with(page), + replace("{totalPages}").with(totalPages)); for (String portal : portals) { - sender.sendMessage(portal); + issuer.sendInfo(portal); } } - private List getPortals(CommandSender sender, MultiverseWorld world, String filter) { + private List getPortals(MVCommandIssuer issuer, MultiverseWorld world, String filter) { List portals = new ArrayList<>(); if (filter == null) { filter = ""; } - for (MVPortal portal : (world == null) ? this.portalManager.getPortals(sender) : this.portalManager.getPortals(sender, world)) { - String destination = displayUtils.formatActionAsMVDestination(portal); + CommandSender sender = issuer.getIssuer(); + for (MVPortal portal : (world == null) + ? this.portalManager.getPortals(sender) + : this.portalManager.getPortals(sender, world)) { + String destination = displayUtils.formatActionAsMVDestinationMessage(portal).formatted( + issuer); if (portal.getName().toLowerCase().contains(filter.toLowerCase()) || destination.toLowerCase().contains(filter.toLowerCase())) { - portals.add(ChatColor.YELLOW + portal.getName() + ChatColor.AQUA + " -> " + ChatColor.GOLD + destination); + portals.add(Message.of(MVPi18n.LIST_ENTRY, + Replace.NAME.with(portal.getName()), + Replace.DESTINATION.with(destination)).formatted(issuer)); } } java.util.Collections.sort(portals); return portals; } - private List getPortals(CommandSender sender, MultiverseWorld world, String filter, int page) { + private List getPortals(MVCommandIssuer issuer, MultiverseWorld world, String filter, int page) { List portals = new ArrayList<>(); - for (int i = 0; i < getPortals(sender, world, filter).size(); i++) { + for (int i = 0; i < getPortals(issuer, world, filter).size(); i++) { if ((i >= (page * ITEMS_PER_PAGE) - ITEMS_PER_PAGE && i <= (page * ITEMS_PER_PAGE) - 1)) { - portals.add(getPortals(sender, world, filter).get(i)); + portals.add(getPortals(issuer, world, filter).get(i)); } } return portals; @@ -121,8 +138,8 @@ private final static class LegacyAlias extends ListCommand implements LegacyAlia @Override @CommandAlias("mvplist|mvpl") - void onListCommand(CommandSender sender, String filterOrWorld, int page) { - super.onListCommand(sender, filterOrWorld, page); + void onListCommand(MVCommandIssuer issuer, String filterOrWorld, int page) { + super.onListCommand(issuer, filterOrWorld, page); } } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/ModifyCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/ModifyCommand.java index 30c0633f..c1441486 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/ModifyCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/ModifyCommand.java @@ -1,9 +1,9 @@ package org.mvplugins.multiverse.portals.commands; import com.dumptruckman.minecraft.util.Logging; -import org.bukkit.ChatColor; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; import org.mvplugins.multiverse.core.locale.message.LocalizableMessage; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.core.command.MVCommandIssuer; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; @@ -12,7 +12,6 @@ import org.mvplugins.multiverse.external.acf.commands.annotation.ConsumesRest; import org.mvplugins.multiverse.external.acf.commands.annotation.Description; import org.mvplugins.multiverse.external.acf.commands.annotation.Flags; -import org.mvplugins.multiverse.external.acf.commands.annotation.Single; import org.mvplugins.multiverse.external.acf.commands.annotation.Subcommand; import org.mvplugins.multiverse.external.acf.commands.annotation.Syntax; import org.mvplugins.multiverse.external.jakarta.inject.Inject; @@ -20,6 +19,9 @@ import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; import org.mvplugins.multiverse.portals.MultiversePortals; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @Service class ModifyCommand extends PortalsCommand { @@ -37,29 +39,29 @@ class ModifyCommand extends PortalsCommand { @CommandPermission("multiverse.portal.modify") @CommandCompletion("@mvportals @portalpropertynames @portalpropertyvalues") @Syntax("[portal] ") - @Description("Allows you to modify all values that can be set.") + @Description("{@@mv-portals.modify.description}") public void onModifyCommand( MVCommandIssuer issuer, @Flags("resolve=issuerAware") @Syntax("[portal]") - @Description("The portal to modify.") + @Description("{@@mv-portals.modify.portal.description}") MVPortal portal, @Syntax("") - @Description("The property to modify.") + @Description("{@@mv-portals.modify.property.description}") String property, @ConsumesRest @Syntax("") - @Description("The value to set.") + @Description("{@@mv-portals.modify.value.description}") String value ) { //todo: remove this in 6.0 if (property.equalsIgnoreCase("dest") || property.equalsIgnoreCase("destination")) { if (value.equalsIgnoreCase("here") && !worldManager.isWorld("here")) { Logging.warning("Using 'here' as a destination is deprecated and will be removed in a future version. Use 'e:@here' instead."); - issuer.sendError("Using 'here' as a destination is deprecated and will be removed in a future version. Use 'e:@here' instead."); + issuer.sendError(MVPi18n.MODIFY_HEREDEPRECATED); value = "e:@here"; } } @@ -69,24 +71,25 @@ public void onModifyCommand( stringPropertyHandle.setPropertyString(issuer.getIssuer(), property, value) .onSuccess(ignore -> { if (!this.plugin.savePortalsConfig()) { - issuer.sendError("Could not save portals configuration file!"); + issuer.sendError(MVPi18n.MODIFY_SAVEFAILED); return; } - issuer.sendMessage(ChatColor.GREEN + "Property " + ChatColor.AQUA + property + ChatColor.GREEN - + " of Portal " + ChatColor.YELLOW + portal.getName() + ChatColor.GREEN + " was set to " - + ChatColor.AQUA + stringPropertyHandle.getProperty(property).getOrNull()); + issuer.sendInfo(MVPi18n.MODIFY_SUCCESS, + Replace.NAME.with(property), + replace("{portal}").with(portal.getName()), + Replace.VALUE.with(stringPropertyHandle.getProperty(property).getOrNull())); if (property.equalsIgnoreCase("action-type")) { - issuer.sendError("Please note that changing the action type &edoes NOT modify &cthe action itself. " - + "You need to modify the action property as well to ensure the portal works as expected."); + issuer.sendError(MVPi18n.MODIFY_ACTIONTYPEWARNING); } }).onFailure(failure -> { - issuer.sendError("Property " + ChatColor.AQUA + property + ChatColor.RED + " of Portal " - + ChatColor.YELLOW + portal.getName() + ChatColor.RED + " was NOT set to " - + ChatColor.AQUA + finalValue); + issuer.sendError(MVPi18n.MODIFY_FAILURE, + Replace.NAME.with(property), + replace("{portal}").with(portal.getName()), + Replace.VALUE.with(finalValue)); if (failure instanceof LocalizableMessage localizableMessage) { issuer.sendError(localizableMessage.getLocalizableMessage()); } else { - issuer.sendError(failure.getMessage()); + issuer.sendError(MVPi18n.GENERIC_ERROR_DETAILS, Replace.ERROR.with(failure.getMessage())); } }); } diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/RemoveCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/RemoveCommand.java index 065d007f..eeaa21ec 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/RemoveCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/RemoveCommand.java @@ -1,9 +1,8 @@ package org.mvplugins.multiverse.portals.commands; -import org.bukkit.ChatColor; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; import org.mvplugins.multiverse.core.command.MVCommandIssuer; -import org.mvplugins.multiverse.core.command.MVCommandManager; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -14,6 +13,7 @@ import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.PortalManager; @Service @@ -30,21 +30,21 @@ class RemoveCommand extends PortalsCommand { @CommandPermission("multiverse.portal.remove") @CommandCompletion("@mvportals") @Syntax("") - @Description("Removes a existing portal.") + @Description("{@@mv-portals.remove.description}") void onRemoveCommand( MVCommandIssuer issuer, @Syntax("") - @Description("The name of the portal to remove.") + @Description("{@@mv-portals.remove.name.description}") String portalName ) { if (!this.portalManager.isPortal(portalName)) { - issuer.sendMessage("The portal Portal " + ChatColor.DARK_AQUA + portalName + ChatColor.WHITE + " does NOT exist!"); + issuer.sendError(MVPi18n.REMOVE_NOTFOUND, Replace.NAME.with(portalName)); return; } MVPortal portal = this.portalManager.removePortal(portalName, true); - issuer.sendMessage("Portal " + ChatColor.DARK_AQUA + portal.getName() + ChatColor.WHITE + " was removed successfully!"); + issuer.sendInfo(MVPi18n.REMOVE_SUCCESS, Replace.NAME.with(portal.getName())); } @Service diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/SelectCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/SelectCommand.java index 5fc9757c..12ab2228 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/SelectCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/SelectCommand.java @@ -1,8 +1,9 @@ package org.mvplugins.multiverse.portals.commands; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -17,6 +18,9 @@ import org.mvplugins.multiverse.portals.MVPortal; import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.config.PortalsConfig; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @Service class SelectCommand extends PortalsCommand { @@ -25,7 +29,8 @@ class SelectCommand extends PortalsCommand { private final PortalsConfig portalsConfig; @Inject - SelectCommand(@NotNull MultiversePortals plugin, @NotNull PortalsConfig portalsConfig) { + SelectCommand(@NotNull MultiversePortals plugin, + @NotNull PortalsConfig portalsConfig) { this.plugin = plugin; this.portalsConfig = portalsConfig; } @@ -34,29 +39,31 @@ class SelectCommand extends PortalsCommand { @CommandPermission("multiverse.portal.select,multiverse.portal.create") @CommandCompletion("@mvportals") @Syntax("") - @Description("Selects a portal so you can perform multiple modifications on it.") + @Description("{@@mv-portals.select.description}") void onSelectCommand( + @NotNull MVCommandIssuer issuer, + @Flags("resolve=issuerOnly") Player player, @Optional @Syntax("") - @Description("The portal to select") + @Description("{@@mv-portals.select.portal.description}") MVPortal portal ) { if (portal == null) { MVPortal selected = this.plugin.getPortalSession(player).getSelectedPortal(); if (this.plugin.getPortalSession(player).getSelectedPortal() == null) { - player.sendMessage("You have not selected a portal yet!"); - player.sendMessage("Use a " + ChatColor.GREEN + portalsConfig.getWandMaterial() + ChatColor.WHITE + " to do so!"); + issuer.sendError(MVPi18n.SELECT_NONE, + replace("{wandMaterial}").with(portalsConfig.getWandMaterial())); return; } - player.sendMessage("You have selected: " + ChatColor.DARK_AQUA + selected.getName()); + issuer.sendInfo(MVPi18n.SELECT_CURRENT, Replace.NAME.with(selected.getName())); return; } this.plugin.getPortalSession(player).selectPortal(portal); - player.sendMessage("Portal: " + ChatColor.DARK_AQUA + portal.getName() + ChatColor.WHITE + " has been selected."); + issuer.sendInfo(MVPi18n.SELECT_SUCCESS, Replace.NAME.with(portal.getName())); } @Service @@ -68,8 +75,8 @@ private final static class LegacyAlias extends SelectCommand implements LegacyAl @Override @CommandAlias("mvpselect|mvps") - void onSelectCommand(Player player, MVPortal portal) { - super.onSelectCommand(player, portal); + void onSelectCommand(MVCommandIssuer issuer, Player player, MVPortal portal) { + super.onSelectCommand(issuer, player, portal); } } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/commands/WandCommand.java b/src/main/java/org/mvplugins/multiverse/portals/commands/WandCommand.java index ba9382be..7a99d4d6 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/commands/WandCommand.java +++ b/src/main/java/org/mvplugins/multiverse/portals/commands/WandCommand.java @@ -1,9 +1,9 @@ package org.mvplugins.multiverse.portals.commands; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.mvplugins.multiverse.core.command.LegacyAliasCommand; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandAlias; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandCompletion; import org.mvplugins.multiverse.external.acf.commands.annotation.CommandPermission; @@ -19,6 +19,9 @@ import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.WorldEditConnection; import org.mvplugins.multiverse.portals.config.PortalsConfig; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @Service class WandCommand extends PortalsCommand { @@ -27,7 +30,8 @@ class WandCommand extends PortalsCommand { private final PortalsConfig portalsConfig; @Inject - WandCommand(@NotNull MultiversePortals plugin, @NotNull PortalsConfig portalsConfig) { + WandCommand(@NotNull MultiversePortals plugin, + @NotNull PortalsConfig portalsConfig) { this.plugin = plugin; this.portalsConfig = portalsConfig; } @@ -36,15 +40,17 @@ class WandCommand extends PortalsCommand { @CommandPermission("multiverse.portal.givewand") @CommandCompletion("enable|disable|toggle") @Syntax("[enable|disable|toggle]") - @Description("Gives you the wand that MV uses. This will only work if you are NOT using WorldEdit.") + @Description("{@@mv-portals.wand.description}") void onWandCommand( + @NotNull MVCommandIssuer issuer, + @Flags("resolve=issuerOnly") Player player, @Optional @Single @Syntax("[enable|disable|toggle]") - @Description("Enable, disable, or toggle the wand.") + @Description("{@@mv-portals.wand.action.description}") String action ) { if (action != null) { @@ -55,27 +61,29 @@ void onWandCommand( } else if (action.equals("toggle")) { this.plugin.setWandEnabled(!this.plugin.isWandEnabled()); } else { - player.sendMessage(ChatColor.RED + "You must specify one of 'enable,' 'disable,' or 'toggle!'"); + issuer.sendError(MVPi18n.WAND_INVALIDACTION); } return; } WorldEditConnection worldEdit = plugin.getWorldEditConnection(); if (worldEdit != null && worldEdit.isConnected()) { - player.sendMessage(ChatColor.GREEN + "Cool!" + ChatColor.WHITE + " You're using" + ChatColor.AQUA + " WorldEdit! "); - player.sendMessage("Just use " + ChatColor.GOLD + "the WorldEdit wand " + ChatColor.WHITE + "to perform portal selections!"); + issuer.sendInfo(MVPi18n.WAND_WORLDEDIT); return; } ItemStack wand = new ItemStack(portalsConfig.getWandMaterial(), 1); if (player.getInventory().getItemInMainHand().getAmount() == 0) { player.getInventory().setItemInMainHand(wand); - player.sendMessage("You have been given a " + ChatColor.GREEN + "Multiverse Portal Wand(" + wand.getType() + ")!"); + issuer.sendInfo(MVPi18n.WAND_GIVEN, + replace("{wandMaterial}").with(wand.getType())); } else { if (player.getInventory().addItem(wand).isEmpty()) { - player.sendMessage("A " + ChatColor.GREEN + "Multiverse Portal Wand(" + wand.getType() + ")" + ChatColor.WHITE + " has been placed in your inventory."); + issuer.sendInfo(MVPi18n.WAND_INVENTORY, + replace("{wandMaterial}").with(wand.getType())); } else { - player.sendMessage("Your Inventory is full. A " + ChatColor.GREEN + "Multiverse Portal Wand(" + wand.getType() + ")" + ChatColor.WHITE + " has been placed dropped nearby."); + issuer.sendInfo(MVPi18n.WAND_DROPPED, + replace("{wandMaterial}").with(wand.getType())); player.getWorld().dropItemNaturally(player.getLocation(), wand); } } @@ -90,8 +98,8 @@ private final static class LegacyAlias extends WandCommand implements LegacyAlia @Override @CommandAlias("mvpwand|mvpw") - void onWandCommand(Player player, String action) { - super.onWandCommand(player, action); + void onWandCommand(MVCommandIssuer issuer, Player player, String action) { + super.onWandCommand(issuer, player, action); } } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/destination/PortalDestination.java b/src/main/java/org/mvplugins/multiverse/portals/destination/PortalDestination.java index 5545e9b3..25a1e770 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/destination/PortalDestination.java +++ b/src/main/java/org/mvplugins/multiverse/portals/destination/PortalDestination.java @@ -5,6 +5,7 @@ import org.mvplugins.multiverse.core.destination.DestinationSuggestionPacket; import org.mvplugins.multiverse.core.locale.MVCorei18n; import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.core.teleportation.LocationManipulation; import org.mvplugins.multiverse.core.utils.result.Attempt; import org.mvplugins.multiverse.core.utils.result.FailureReason; @@ -15,10 +16,12 @@ import org.mvplugins.multiverse.external.jetbrains.annotations.Nullable; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.PortalManager; import java.util.Collection; + @Service public class PortalDestination implements Destination { @@ -40,13 +43,15 @@ public class PortalDestination implements Destination getDestinationInstance(@Nullable String destinationParams) { String[] items = destinationParams.split(":"); if (items.length > 3) { - return Attempt.failure(InstanceFailureReason.INVALID_FORMAT, Message.of("Invalid format! Expected format is: p:portalName:[direction]")); + return Attempt.failure(InstanceFailureReason.INVALID_FORMAT, + Message.of(MVPi18n.DESTINATION_PORTAL_INVALIDFORMAT)); } String portalName = items[0]; MVPortal portal = portalManager.getPortal(portalName); if (portal == null) { - return Attempt.failure(InstanceFailureReason.PORTAL_NOT_FOUND, Message.of("Portal '" + portalName + "' does not exist!")); + return Attempt.failure(InstanceFailureReason.PORTAL_NOT_FOUND, + Message.of(MVPi18n.DESTINATION_PORTAL_NOTFOUND, Replace.NAME.with(portalName))); } String direction = (items.length == 2) ? items[1] : null; diff --git a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPCoreListener.java b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPCoreListener.java index c3b4583b..557d55e4 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPCoreListener.java +++ b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPCoreListener.java @@ -11,6 +11,7 @@ import com.dumptruckman.minecraft.util.Logging; import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventMethod; +import org.mvplugins.multiverse.core.command.MVCommandManager; import org.mvplugins.multiverse.core.event.MVConfigReloadEvent; import org.mvplugins.multiverse.core.event.MVDebugModeEvent; import org.mvplugins.multiverse.core.event.MVDumpsDebugInfoEvent; @@ -23,6 +24,7 @@ import org.mvplugins.multiverse.portals.MultiversePortals; import org.mvplugins.multiverse.portals.config.PortalsConfig; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import org.mvplugins.multiverse.portals.utils.PortalManager; @Service @@ -30,12 +32,17 @@ final class MVPCoreListener implements PortalsListener { private final MultiversePortals plugin; private final PortalsConfig config; private final PortalManager portalManager; + private final MVCommandManager commandManager; @Inject - MVPCoreListener(@NotNull MultiversePortals plugin, @NotNull PortalManager portalManager, @NotNull PortalsConfig config) { + MVPCoreListener(@NotNull MultiversePortals plugin, + @NotNull PortalManager portalManager, + @NotNull PortalsConfig config, + @NotNull MVCommandManager commandManager) { this.plugin = plugin; this.portalManager = portalManager; this.config = config; + this.commandManager = commandManager; } /** @@ -95,7 +102,7 @@ void portalTouchEvent(MVPlayerTouchedPortalEvent event) { return; } // They can see it, is it val - event.getPlayer().sendMessage("This Multiverse Portal does not have a valid destination!"); + commandManager.getCommandIssuer(event.getPlayer()).sendError(MVPi18n.PORTAL_DESTINATION_INVALID); event.setCanUseThisPortal(false); } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerMoveListener.java b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerMoveListener.java index a7d68ff6..d382a375 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerMoveListener.java +++ b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerMoveListener.java @@ -22,7 +22,6 @@ import org.mvplugins.multiverse.portals.config.PortalsConfig; import org.mvplugins.multiverse.portals.enums.MoveType; import org.mvplugins.multiverse.portals.event.MVPortalEvent; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventPriority; @@ -74,7 +73,7 @@ void playerMove(PlayerMoveEvent event) { player.setFallDistance(0); if (!portal.isFrameValid(loc)) { - player.sendMessage("This portal's frame is made of an " + ChatColor.RED + "incorrect material. You should exit it now."); + helper.sendInvalidFrameMessage(player); return; } if (ps.checkAndSendCooldownMessage()) { diff --git a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerPortalListener.java b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerPortalListener.java index 6e971f15..0a6c9e19 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerPortalListener.java +++ b/src/main/java/org/mvplugins/multiverse/portals/listeners/MVPPlayerPortalListener.java @@ -1,7 +1,6 @@ package org.mvplugins.multiverse.portals.listeners; import com.dumptruckman.minecraft.util.Logging; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerPortalEvent; @@ -70,7 +69,7 @@ void playerPortal(PlayerPortalEvent event) { } if (!portal.isFrameValid(playerPortalLoc)) { - player.sendMessage("This portal's frame is made of an " + ChatColor.RED + "incorrect material." + ChatColor.RED + " You should exit it now."); + helper.sendInvalidFrameMessage(player); event.setCancelled(true); return; } diff --git a/src/main/java/org/mvplugins/multiverse/portals/listeners/PortalListenerHelper.java b/src/main/java/org/mvplugins/multiverse/portals/listeners/PortalListenerHelper.java index 787ef938..e5d1df56 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/listeners/PortalListenerHelper.java +++ b/src/main/java/org/mvplugins/multiverse/portals/listeners/PortalListenerHelper.java @@ -3,6 +3,10 @@ import com.dumptruckman.minecraft.util.Logging; import org.bukkit.Material; import org.mvplugins.multiverse.core.economy.MVEconomist; +import org.mvplugins.multiverse.core.command.MVCommandIssuer; +import org.mvplugins.multiverse.core.command.MVCommandManager; +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; import org.mvplugins.multiverse.external.jakarta.inject.Inject; import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; @@ -10,18 +14,24 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.mvplugins.multiverse.portals.config.PortalsConfig; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @Service final class PortalListenerHelper { private final PortalsConfig portalsConfig; private final MVEconomist economist; + private final MVCommandManager commandManager; @Inject PortalListenerHelper(@NotNull PortalsConfig portalsConfig, - @NotNull MVEconomist economist) { + @NotNull MVEconomist economist, + @NotNull MVCommandManager commandManager) { this.portalsConfig = portalsConfig; this.economist = economist; + this.commandManager = commandManager; } boolean isWithinSameBlock(Location from, Location to) { @@ -60,8 +70,11 @@ PortalUseResult checkPlayerCanUsePortal(MVPortal portal, Player player) { } if (price > 0D && !economist.isPlayerWealthyEnough(player, price, currency)) { - player.sendMessage(economist.getNSFMessage(currency, - "You need " + economist.formatPrice(price, currency) + " to enter the " + portal.getName() + " portal.")); + MVCommandIssuer issuer = commandManager.getCommandIssuer(player); + Message message = Message.of(MVPi18n.PORTAL_INSUFFICIENTFUNDS, + replace("{price}").with(economist.formatPrice(price, currency)), + Replace.NAME.with(portal.getName())); + player.sendMessage(economist.getNSFMessage(currency, message.formatted(issuer))); stateFailure(player.getDisplayName(), portal.getName()); return PortalUseResult.CANNOT_USE; } @@ -72,6 +85,10 @@ void payPortalEntryFee(MVPortal portal, Player player) { economist.payEntryFee(player, portal.getPrice(), portal.getCurrency()); } + void sendInvalidFrameMessage(Player player) { + commandManager.getCommandIssuer(player).sendError(MVPi18n.PORTAL_FRAME_INVALID); + } + enum PortalUseResult { CANNOT_USE(false, false), FREE_USE(true, false), diff --git a/src/main/java/org/mvplugins/multiverse/portals/locale/MVPi18n.java b/src/main/java/org/mvplugins/multiverse/portals/locale/MVPi18n.java new file mode 100644 index 00000000..c474d7c4 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/portals/locale/MVPi18n.java @@ -0,0 +1,191 @@ +package org.mvplugins.multiverse.portals.locale; + +import java.util.Locale; + +import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement; +import org.mvplugins.multiverse.external.acf.locales.MessageKey; +import org.mvplugins.multiverse.external.acf.locales.MessageKeyProvider; +import org.mvplugins.multiverse.external.jetbrains.annotations.ApiStatus; +import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; + +/** + * All translation keys for Multiverse-Portals. + * + * @since 5.3 + */ +@ApiStatus.AvailableSince("5.3") +@ApiStatus.Internal +public enum MVPi18n implements MessageKeyProvider { + // BEGIN CHECKSTYLE-SUPPRESSION: JavadocVariable + + // /mvp config + CONFIG_DESCRIPTION, + CONFIG_PROPERTY_DESCRIPTION, + CONFIG_VALUE_DESCRIPTION, + + // /mvp create + CREATE_DESCRIPTION, + CREATE_NAME_DESCRIPTION, + CREATE_DESTINATION_DESCRIPTION, + CREATE_INVALIDNAME, + CREATE_SUCCESS, + CREATE_ALREADYEXISTS, + CREATE_ACTIONNOTSET, + + // /mvp debug + DEBUG_DESCRIPTION, + DEBUG_TOGGLE_DESCRIPTION, + DEBUG_ENABLED, + DEBUG_DISABLED, + + // /mvp info + INFO_DESCRIPTION, + INFO_PORTAL_DESCRIPTION, + + // /mvp list + LIST_DESCRIPTION, + LIST_FILTER_DESCRIPTION, + LIST_PAGE_DESCRIPTION, + LIST_HEADER, + LIST_HEADER_WORLD, + LIST_HEADER_FILTER, + LIST_ENTRY, + + // /mvp modify + MODIFY_DESCRIPTION, + MODIFY_PORTAL_DESCRIPTION, + MODIFY_PROPERTY_DESCRIPTION, + MODIFY_VALUE_DESCRIPTION, + MODIFY_HEREDEPRECATED, + MODIFY_SAVEFAILED, + MODIFY_SUCCESS, + MODIFY_ACTIONTYPEWARNING, + MODIFY_FAILURE, + + // /mvp remove + REMOVE_DESCRIPTION, + REMOVE_NAME_DESCRIPTION, + REMOVE_NOTFOUND, + REMOVE_SUCCESS, + + // /mvp select + SELECT_DESCRIPTION, + SELECT_PORTAL_DESCRIPTION, + SELECT_NONE, + SELECT_CURRENT, + SELECT_SUCCESS, + + // /mvp wand + WAND_DESCRIPTION, + WAND_ACTION_DESCRIPTION, + WAND_INVALIDACTION, + WAND_WORLDEDIT, + WAND_GIVEN, + WAND_INVENTORY, + WAND_DROPPED, + + // Command contexts + CONTEXT_PORTAL_PLAYERSELECTIONREQUIRED, + CONTEXT_PORTAL_NOTFOUND, + + // Portal selection + SELECTION_FIRST, + SELECTION_FIRST_AREA, + SELECTION_SECOND, + SELECTION_SECOND_AREA, + SELECTION_WORLDEDIT_INCOMPLETE, + SELECTION_WORLDEDIT_REQUIRED, + SELECTION_LEFT_REQUIRED, + SELECTION_RIGHT_REQUIRED, + SELECTION_SAMEWORLD_REQUIRED, + + // Portal information + PORTALINFO_HEADER, + PORTALINFO_COMMANDHEADER, + PORTALINFO_DEBUGHEADER, + PORTALINFO_CUSTOMHEADER, + PORTALINFO_COORDINATES, + PORTALINFO_WORLD_ERROR, + PORTALINFO_ACTIONTYPE, + PORTALINFO_ACTION, + PORTALINFO_ACTION_NOTSET, + PORTALINFO_CHECKDESTINATIONSAFETY, + PORTALINFO_TELEPORTNONPLAYERS, + PORTALINFO_PRICE, + PORTALINFO_PRICE_FREE, + PORTALINFO_PLAYERACTION, + PORTALINFO_ACTIONERROR, + + // Portal destinations + DESTINATION_WORLD, + DESTINATION_LOCATION, + DESTINATION_RAW, + DESTINATION_INVALIDLOCATION, + DESTINATION_INVALID, + DESTINATION_PORTAL_INVALIDFORMAT, + DESTINATION_PORTAL_NOTFOUND, + + // Portal actions + ACTION_UNKNOWN_TYPE, + ACTION_COMMAND_INVALID, + ACTION_COMMAND_SELF, + ACTION_COMMAND_OPERATOR, + ACTION_COMMAND_CONSOLE, + ACTION_MULTIVERSEDESTINATION_INVALID, + ACTION_MULTIVERSEDESTINATION_DESCRIPTION, + ACTION_SERVER_INVALID, + ACTION_SERVER_PLAYERSONLY, + ACTION_SERVER_PROXYERROR, + ACTION_SERVER_PROXYUNKNOWNERROR, + ACTION_SERVER_DESCRIPTION, + + // Portal use + PORTAL_FRAME_INVALID, + PORTAL_DESTINATION_INVALID, + PORTAL_INSUFFICIENTFUNDS, + PORTAL_COOLDOWN, + PORTAL_FILL_INVALIDSIZE, + + // Portal configuration + PORTALCONFIG_LOCATION_PLAYERSONLY, + PORTALCONFIG_LOCATION_SELECTIONREQUIRED, + PORTALCONFIG_LOCATION_INVALID, + + // Generic + GENERIC_TRUE, + GENERIC_FALSE, + GENERIC_ERROR_DETAILS; + + // END CHECKSTYLE-SUPPRESSION: JavadocVariable + + private final MessageKey key = MessageKey.of("mv-portals." + this.name().replace('_', '.') + .toLowerCase(Locale.ENGLISH)); + + /** + * {@inheritDoc} + * + * @since 5.3 + */ + @Override + @ApiStatus.AvailableSince("5.3") + public MessageKey getMessageKey() { + return this.key; + } + + /** + * Creates a message with a non-localized fallback and replacements. + * + * @param nonLocalizedMessage The non-localized fallback message. + * @param replacements The replacements. + * @return A new localizable message. + * + * @since 5.3 + */ + @ApiStatus.AvailableSince("5.3") + @NotNull public Message bundle( + @NotNull String nonLocalizedMessage, + @NotNull MessageReplacement... replacements) { + return Message.of(this, nonLocalizedMessage, replacements); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/portals/locale/package-info.java b/src/main/java/org/mvplugins/multiverse/portals/locale/package-info.java new file mode 100644 index 00000000..01378839 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/portals/locale/package-info.java @@ -0,0 +1,4 @@ +/** + * Locale keys for Multiverse-Portals. + */ +package org.mvplugins.multiverse.portals.locale; diff --git a/src/main/java/org/mvplugins/multiverse/portals/utils/DisplayUtils.java b/src/main/java/org/mvplugins/multiverse/portals/utils/DisplayUtils.java index 22c0bca4..55d1bbc1 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/utils/DisplayUtils.java +++ b/src/main/java/org/mvplugins/multiverse/portals/utils/DisplayUtils.java @@ -5,7 +5,10 @@ import org.mvplugins.multiverse.core.command.MVCommandManager; import org.mvplugins.multiverse.core.economy.MVEconomist; import org.mvplugins.multiverse.core.locale.message.Message; +import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace; +import org.mvplugins.multiverse.external.acf.locales.MessageKeyProvider; import org.mvplugins.multiverse.core.utils.result.Attempt; +import org.mvplugins.multiverse.core.utils.text.ChatTextFormatter; import org.mvplugins.multiverse.core.world.MultiverseWorld; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.external.jakarta.inject.Inject; @@ -13,10 +16,10 @@ import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.mvplugins.multiverse.portals.action.ActionFailureReason; import org.mvplugins.multiverse.portals.action.ActionHandler; +import org.mvplugins.multiverse.portals.locale.MVPi18n; import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @@ -37,60 +40,104 @@ public class DisplayUtils { this.commandManager = commandManager; } + /** + * Shows information about a portal using a custom, non-localized header. + * + * @param sender The recipient of the portal information. + * @param portal The portal to describe. + * @param message The custom header text. + */ public void showStaticInfo(CommandSender sender, MVPortal portal, String message) { + commandManager.getCommandIssuer(sender).sendInfo(MVPi18n.PORTALINFO_CUSTOMHEADER, + replace("{header}").with(message), + Replace.NAME.with(portal.getName())); + showStaticInfoBody(sender, portal); + } + + /** + * Shows information about a portal using the given localized header. + * + * @param sender The recipient of the portal information. + * @param portal The portal to describe. + * @param headerKey The locale key for the header. + * + * @since 5.3 + */ + @ApiStatus.AvailableSince("5.3") + public void showStaticInfo(CommandSender sender, MVPortal portal, MessageKeyProvider headerKey) { MVCommandIssuer issuer = commandManager.getCommandIssuer(sender); - issuer.sendMessage(ChatColor.AQUA + "--- " + message + ChatColor.DARK_AQUA + portal.getName() + ChatColor.AQUA + " ---"); + issuer.sendInfo(headerKey, Replace.NAME.with(portal.getName())); + showStaticInfoBody(sender, portal); + } + + private void showStaticInfoBody(CommandSender sender, MVPortal portal) { + MVCommandIssuer issuer = commandManager.getCommandIssuer(sender); String[] locParts = portal.getPortalLocation().toString().split(":"); - issuer.sendMessage(ChatColor.WHITE + "Coords: " + ChatColor.GOLD + locParts[1] + ChatColor.WHITE + " to " - + ChatColor.GOLD + locParts[2] + ChatColor.WHITE + " in " + ChatColor.GOLD - + portal.getMultiverseWorld().map(MultiverseWorld::getName).getOrElse(ChatColor.RED + "!!ERROR!!")); - issuer.sendMessage(ChatColor.WHITE + "Configured Action Type: " + ChatColor.GOLD + portal.getActionType()); + issuer.sendInfo(MVPi18n.PORTALINFO_COORDINATES, + replace("{fromLocation}").with(locParts[1]), + replace("{toLocation}").with(locParts[2]), + Replace.WORLD.with(portal.getMultiverseWorld() + .map(MultiverseWorld::getName) + .map(Message::of) + .getOrElse(Message.of(MVPi18n.PORTALINFO_WORLD_ERROR)))); + issuer.sendInfo(MVPi18n.PORTALINFO_ACTIONTYPE, + replace("{actionType}").with(portal.getActionType())); if (portal.getAction().isEmpty()) { - issuer.sendMessage(ChatColor.WHITE + "Configured Action: " + ChatColor.RED + ChatColor.ITALIC + "NOT SET!"); + issuer.sendInfo(MVPi18n.PORTALINFO_ACTION_NOTSET); } else { - issuer.sendMessage(ChatColor.WHITE + "Configured Action: " + ChatColor.GOLD + portal.getAction()); + issuer.sendInfo(MVPi18n.PORTALINFO_ACTION, + replace("{action}").with(portal.getAction())); } Attempt, ActionFailureReason> actionHandler = portal.getActionHandler(); - issuer.sendMessage(ChatColor.WHITE + "Check Destination Safety: " + formatBoolean(portal.getCheckDestinationSafety())); - issuer.sendMessage(ChatColor.WHITE + "Teleport Non Players: " + formatBoolean(portal.getTeleportNonPlayers())); + issuer.sendInfo(MVPi18n.PORTALINFO_CHECKDESTINATIONSAFETY, + Replace.VALUE.with(formatBoolean(portal.getCheckDestinationSafety()))); + issuer.sendInfo(MVPi18n.PORTALINFO_TELEPORTNONPLAYERS, + Replace.VALUE.with(formatBoolean(portal.getTeleportNonPlayers()))); showPortalPriceInfo(portal, sender); if (sender instanceof Entity entity) { actionHandler.map(handler -> handler.actionDescription(entity)) - .onSuccess(actionMessage -> { - issuer.sendMessage(""); - issuer.sendMessage(Message.of(ChatColor.WHITE + "Your action when using Portal: {action}", - replace("{action}").with(actionMessage))); - }); + .onSuccess(actionMessage -> issuer.sendInfo(MVPi18n.PORTALINFO_PLAYERACTION, + replace("{action}").with(actionMessage))); } - actionHandler.onFailure(failure -> { - issuer.sendMessage(""); - issuer.sendError(failure.getFailureMessage()); - }); + actionHandler.onFailure(failure -> issuer.sendError(MVPi18n.PORTALINFO_ACTIONERROR, + Replace.ERROR.with(failure.getFailureMessage()))); } - private String formatBoolean(Boolean bool) { - return bool ? ChatColor.GREEN + "true" : ChatColor.RED + "false"; + private Message formatBoolean(Boolean bool) { + return Message.of(bool ? MVPi18n.GENERIC_TRUE : MVPi18n.GENERIC_FALSE); } @ApiStatus.AvailableSince("5.2") public String formatActionAsMVDestination(MVPortal portal) { + return ChatTextFormatter.colorize( + formatActionAsMVDestinationMessage(portal).formatted(commandManager.getLocales())); + } + + /** + * Formats a portal action as a localizable Multiverse destination description. + * + * @param portal The portal whose action should be formatted. + * @return The localizable destination description. + * + * @since 5.3 + */ + @ApiStatus.AvailableSince("5.3") + public Message formatActionAsMVDestinationMessage(MVPortal portal) { String[] split = portal.getAction().split(":", 2); String destination = split.length == 2 ? split[1] : ""; String destType = split.length == 2 ? split[0] : ""; if (destType.equals("w")) { MultiverseWorld destWorld = worldManager.getWorld(destination).getOrNull(); if (destWorld != null) { - return "(World) " + ChatColor.DARK_AQUA + destination; + return Message.of(MVPi18n.DESTINATION_WORLD, Replace.DESTINATION.with(destination)); } } if (destType.equals("p")) { // todo: I think should use instance check instead of destType prefix - // String targetWorldName = portalManager.getPortal(portal.getDestination().getName()).getWorld().getName(); - // destination = "(Portal) " + ChatColor.DARK_AQUA + portal.getDestination().getName() + ChatColor.GRAY + " (" + targetWorldName + ")"; } if (destType.equals("e")) { String destinationWorld = portal.getAction().split(":")[1]; @@ -103,23 +150,28 @@ public String formatActionAsMVDestination(MVPortal portal) { z = (int) Double.parseDouble(targetParts[2]); } catch (NumberFormatException e) { e.printStackTrace(); - return ChatColor.RED + "Invalid Exact World Location!"; + return Message.of(MVPi18n.DESTINATION_INVALIDLOCATION); } - return "(Location) " + ChatColor.DARK_AQUA + destinationWorld + ", " + x + ", " + y + ", " + z; + return Message.of(MVPi18n.DESTINATION_LOCATION, + Replace.WORLD.with(destinationWorld), + Replace.LOCATION.with(x + ", " + y + ", " + z)); } if (destType.equals("i")) { - return ChatColor.RED + "Invalid Destination!"; + return Message.of(MVPi18n.DESTINATION_INVALID); } - return ChatColor.DARK_AQUA + portal.getAction(); + return Message.of(MVPi18n.DESTINATION_RAW, Replace.DESTINATION.with(portal.getAction())); } public void showPortalPriceInfo(MVPortal portal, CommandSender sender) { + MVCommandIssuer issuer = commandManager.getCommandIssuer(sender); if (portal.getPrice() > 0D) { - sender.sendMessage("Price: " + ChatColor.GREEN + economist.formatPrice(portal.getPrice(), portal.getCurrency())); + issuer.sendInfo(MVPi18n.PORTALINFO_PRICE, + Replace.VALUE.with(economist.formatPrice(portal.getPrice(), portal.getCurrency()))); } else if (portal.getPrice() < 0D) { - sender.sendMessage("Price: " + ChatColor.GREEN + economist.formatPrice(-portal.getPrice(), portal.getCurrency())); + issuer.sendInfo(MVPi18n.PORTALINFO_PRICE, + Replace.VALUE.with(economist.formatPrice(-portal.getPrice(), portal.getCurrency()))); } else { - sender.sendMessage("Price: " + ChatColor.GREEN + "FREE!"); + issuer.sendInfo(MVPi18n.PORTALINFO_PRICE_FREE); } } } diff --git a/src/main/java/org/mvplugins/multiverse/portals/utils/PortalFiller.java b/src/main/java/org/mvplugins/multiverse/portals/utils/PortalFiller.java index f10b338f..5e49d309 100644 --- a/src/main/java/org/mvplugins/multiverse/portals/utils/PortalFiller.java +++ b/src/main/java/org/mvplugins/multiverse/portals/utils/PortalFiller.java @@ -9,7 +9,6 @@ import com.dumptruckman.minecraft.util.Logging; import org.bukkit.Axis; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -17,24 +16,32 @@ import org.bukkit.entity.Player; import org.mvplugins.multiverse.core.teleportation.LocationManipulation; +import org.mvplugins.multiverse.core.command.MVCommandManager; import org.mvplugins.multiverse.external.jakarta.inject.Inject; import org.mvplugins.multiverse.external.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; import org.mvplugins.multiverse.portals.MVPortal; +import org.mvplugins.multiverse.portals.locale.MVPi18n; + +import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace; @Service public class PortalFiller { private final LocationManipulation locationManipulation; + private final MVCommandManager commandManager; @Inject - PortalFiller(@NotNull LocationManipulation locationManipulation) { + PortalFiller(@NotNull LocationManipulation locationManipulation, + @NotNull MVCommandManager commandManager) { this.locationManipulation = locationManipulation; + this.commandManager = commandManager; } public boolean fillRegion(MultiverseRegion r, Location l, Material type, Player player) { if (r.getWidth() != 1 && r.getDepth() != 1) { - player.sendMessage("Cannot fill portal, It needs a width or depth of " + ChatColor.GOLD + "1" + ChatColor.WHITE + - ". w:[" + ChatColor.AQUA + r.getWidth() + ChatColor.WHITE + "] d:[" + ChatColor.AQUA + r.getDepth() + ChatColor.WHITE + "]"); + commandManager.getCommandIssuer(player).sendError(MVPi18n.PORTAL_FILL_INVALIDSIZE, + replace("{width}").with(r.getWidth()), + replace("{depth}").with(r.getDepth())); } return this.fillRegion(r, l, type); } diff --git a/src/main/resources/multiverse-portals_en.properties b/src/main/resources/multiverse-portals_en.properties new file mode 100644 index 00000000..f89a111f --- /dev/null +++ b/src/main/resources/multiverse-portals_en.properties @@ -0,0 +1,137 @@ +# Config command +mv-portals.config.description=Allows you to set Global MV Portals Variables. +mv-portals.config.property.description=The property to set or get info of. +mv-portals.config.value.description=The value to set. + +# Create command +mv-portals.create.description=Creates a new portal, assuming you have a region selected. +mv-portals.create.name.description=Name of the portal to create. +mv-portals.create.destination.description=Optional destination for the portal. +mv-portals.create.invalidname=&cInvalid portal name. It must not contain dot or special characters. +mv-portals.create.success=New portal (&3{name}&f) created and selected! +mv-portals.create.alreadyexists=New portal (&3{name}&f) was NOT created!\nIt already existed and has been selected. +mv-portals.create.actionnotset=&cPortal action not set. Use &3/mvp modify action &c to set one. + +# Debug command +mv-portals.debug.description=Instead of teleporting you to a place when you walk into a portal you will see the details about it. This command toggles. +mv-portals.debug.toggle.description=Enables, disables, or toggles portal debug mode. +mv-portals.debug.enabled=Portal debug mode &aENABLED\n&fUse &3/mvp debug&f to disable. +mv-portals.debug.disabled=Portal debug mode &cDISABLED + +# Info command +mv-portals.info.description=Displays information about a portal. +mv-portals.info.portal.description=The portal to show info + +# List command +mv-portals.list.description=Displays a listing of all portals that you can enter. +mv-portals.list.filter.description=Filter by name or world +mv-portals.list.page.description=Page to display +mv-portals.list.header=&b--- &b{count} Portals{world}{filter} &6- Page {page}/{totalPages}&b --- +mv-portals.list.header.world=\ in &e{world} +mv-portals.list.header.filter=\ &6[{filter}] +mv-portals.list.entry=&e{name} &b-> &6{destination} + +# Modify command +mv-portals.modify.description=Allows you to modify all values that can be set. +mv-portals.modify.portal.description=The portal to modify. +mv-portals.modify.property.description=The property to modify. +mv-portals.modify.value.description=The value to set. +mv-portals.modify.heredeprecated=Using 'here' as a destination is deprecated and will be removed in a future version. Use 'e:@here' instead. +mv-portals.modify.savefailed=Could not save portals configuration file! +mv-portals.modify.success=&aProperty &b{name}&a of Portal &e{portal}&a was set to &b{value} +mv-portals.modify.actiontypewarning=Please note that changing the action type &edoes NOT modify &cthe action itself. You need to modify the action property as well to ensure the portal works as expected. +mv-portals.modify.failure=Property &b{name}&c of Portal &e{portal}&c was NOT set to &b{value} + +# Remove command +mv-portals.remove.description=Removes a existing portal. +mv-portals.remove.name.description=The name of the portal to remove. +mv-portals.remove.notfound=The portal Portal &3{name}&f does NOT exist! +mv-portals.remove.success=Portal &3{name}&f was removed successfully! + +# Select command +mv-portals.select.description=Selects a portal so you can perform multiple modifications on it. +mv-portals.select.portal.description=The portal to select +mv-portals.select.none=You have not selected a portal yet!\nUse a &a{wandMaterial}&f to do so! +mv-portals.select.current=You have selected: &3{name} +mv-portals.select.success=Portal: &3{name}&f has been selected. + +# Wand command +mv-portals.wand.description=Gives you the wand that MV uses. This will only work if you are NOT using WorldEdit. +mv-portals.wand.action.description=Enable, disable, or toggle the wand. +mv-portals.wand.invalidaction=&cYou must specify one of 'enable,' 'disable,' or 'toggle!' +mv-portals.wand.worldedit=&aCool!&f You're using&b WorldEdit! \n&fJust use &6the WorldEdit wand &fto perform portal selections! +mv-portals.wand.given=You have been given a &aMultiverse Portal Wand({wandMaterial})! +mv-portals.wand.inventory=A &aMultiverse Portal Wand({wandMaterial})&f has been placed in your inventory. +mv-portals.wand.dropped=Your Inventory is full. A &aMultiverse Portal Wand({wandMaterial})&f has been placed dropped nearby. + +# Command contexts +mv-portals.context.portal.playerselectionrequired=This command can only be used by a player that has selected a portal with `/mvp select`. +mv-portals.context.portal.notfound=The portal '{name}' doesn't exist or you're not allowed to use it! + +# Portal selection +mv-portals.selection.first=&bFirst position set to: {position} +mv-portals.selection.first.area=&bFirst position set to: {position}&6 ({count} blocks) +mv-portals.selection.second=&bSecond position set to: {position} +mv-portals.selection.second.area=&bSecond position set to: {position}&6 ({count} blocks) +mv-portals.selection.worldedit.incomplete=You haven't finished your selection. +mv-portals.selection.worldedit.required=You must have a WorldEdit selection to do this. +mv-portals.selection.left.required=You need to LEFT click on a block with your wand! +mv-portals.selection.right.required=You need to RIGHT click on a block with your wand! +mv-portals.selection.sameworld.required=You need to select both coords in the same world!\nLeft Click Position was in:{leftWorld}\nRight Click Position was in:{rightWorld} + +# Portal information +mv-portals.portalinfo.header=&b--- Portal Info &3{name}&b --- +mv-portals.portalinfo.commandheader=&b--- Portal Info: &3{name}&b --- +mv-portals.portalinfo.debugheader=&b--- You are currently standing in &3{name}&b --- +mv-portals.portalinfo.customheader=&b--- {header}&3{name}&b --- +mv-portals.portalinfo.coordinates=&fCoords: &6{fromLocation}&f to &6{toLocation}&f in &6{world} +mv-portals.portalinfo.world.error=&c!!ERROR!! +mv-portals.portalinfo.actiontype=&fConfigured Action Type: &6{actionType} +mv-portals.portalinfo.action=&fConfigured Action: &6{action} +mv-portals.portalinfo.action.notset=&fConfigured Action: &c&oNOT SET! +mv-portals.portalinfo.checkdestinationsafety=&fCheck Destination Safety: {value} +mv-portals.portalinfo.teleportnonplayers=&fTeleport Non Players: {value} +mv-portals.portalinfo.price=Price: &a{value} +mv-portals.portalinfo.price.free=Price: &aFREE! +mv-portals.portalinfo.playeraction=\n&fYour action when using Portal: {action} +mv-portals.portalinfo.actionerror=\n{error} + +# Portal destinations +mv-portals.destination.world=(World) &3{destination} +mv-portals.destination.location=(Location) &3{world}, {location} +mv-portals.destination.raw=&3{destination} +mv-portals.destination.invalidlocation=&cInvalid Exact World Location! +mv-portals.destination.invalid=&cInvalid Destination! +mv-portals.destination.portal.invalidformat=Invalid format! Expected format is: p:portalName:[direction] +mv-portals.destination.portal.notfound=Portal '{name}' does not exist! + +# Portal actions +mv-portals.action.unknown.type=Unknown action type '{name}'. Supported types are: {types} +mv-portals.action.command.invalid=Please specific a valid command to run as the portal's action. +mv-portals.action.command.self=&bRuns command myself &6/{command} +mv-portals.action.command.operator=&bRuns command as operator &6/{command} +mv-portals.action.command.console=&bRuns command from console &6/{command} +mv-portals.action.multiversedestination.invalid=Please specific a multiverse destination as the portal's action. +mv-portals.action.multiversedestination.description=&bTeleports to &6{destination} +mv-portals.action.server.invalid=Please specific a server name as the portal's action. +mv-portals.action.server.playersonly=Only players can teleport between servers! +mv-portals.action.server.proxyerror=An error occurred while sending plugin message to proxy: {error} +mv-portals.action.server.proxyunknownerror=An unknown error occurred while sending plugin message to proxy. +mv-portals.action.server.description=&bTransfer to &6{name}&b server + +# Portal use +mv-portals.portal.frame.invalid=This portal's frame is made of an &cincorrect material. You should exit it now. +mv-portals.portal.destination.invalid=This Multiverse Portal does not have a valid destination! +mv-portals.portal.insufficientfunds=You need {price} to enter the {name} portal. +mv-portals.portal.cooldown=There is a portal &bcooldown &fin effect. Please try again in &6{cooldown}&f. +mv-portals.portal.fill.invalidsize=Cannot fill portal, It needs a width or depth of &61&f. w:[&b{width}&f] d:[&b{depth}&f] + +# Portal configuration +mv-portals.portalconfig.location.playersonly=You can only use '@selected-region' as a player. +mv-portals.portalconfig.location.selectionrequired=You must select a region first. See `/mvp wand` for more info. +mv-portals.portalconfig.location.invalid=Invalid location format. The portal location must be in the format `WORLD:X,Y,Z:X,Y,Z`. + +# Generic +mv-portals.generic.true=&atrue +mv-portals.generic.false=&cfalse +mv-portals.generic.error.details={error}