From 706ca5601d3632dc14b5dba3f89b1e87d6790b0f Mon Sep 17 00:00:00 2001 From: Amaury Carrade Date: Sat, 21 May 2016 18:55:32 +0200 Subject: [PATCH] Internationalization of the plugin. * NEW: the plugin can now be translated. --- .../fr/moribus/imageonmap/ImageOnMap.java | 7 +- .../imageonmap/PluginConfiguration.java | 4 + .../imageonmap/commands/IoMCommand.java | 5 +- .../maptool/DeleteConfirmCommand.java | 20 +- .../maptool/DeleteNoConfirmCommand.java | 8 +- .../commands/maptool/GetCommand.java | 5 +- .../commands/maptool/GetRemainingCommand.java | 7 +- .../commands/maptool/ListCommand.java | 5 +- .../commands/maptool/MigrateCommand.java | 5 +- .../commands/maptool/NewCommand.java | 18 +- .../imageonmap/gui/ConfirmDeleteMapGui.java | 38 +-- .../moribus/imageonmap/gui/MapDetailGui.java | 65 +++--- .../fr/moribus/imageonmap/gui/MapListGui.java | 218 ++++++++---------- .../image/ImageRendererExecutor.java | 5 +- .../fr/moribus/imageonmap/map/ImageMap.java | 27 ++- .../imageonmap/map/MapManagerException.java | 15 +- .../migration/MigratorExecutor.java | 8 +- .../imageonmap/migration/V3Migrator.java | 76 +++--- .../moribus/imageonmap/ui/MapItemManager.java | 23 +- .../imageonmap/ui/SplatterMapManager.java | 18 +- src/main/resources/config.yml | 5 + 21 files changed, 285 insertions(+), 297 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index e030b1f..428b00d 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -35,6 +35,7 @@ import fr.moribus.imageonmap.migration.V3Migrator; import fr.moribus.imageonmap.ui.MapItemManager; import fr.zcraft.zlib.components.commands.Commands; import fr.zcraft.zlib.components.gui.Gui; +import fr.zcraft.zlib.components.i18n.I18n; import fr.zcraft.zlib.core.ZPlugin; import fr.zcraft.zlib.tools.PluginLogger; @@ -81,17 +82,19 @@ public final class ImageOnMap extends ZPlugin } catch(IOException ex) { - PluginLogger.error("FATAL : " + ex.getMessage()); + PluginLogger.error("FATAL: " + ex.getMessage()); this.setEnabled(false); return; } saveDefaultConfig(); - loadComponents(Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class); + loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class); //Init all the things ! MetricsLite.startMetrics(); + I18n.setPrimaryLocale(PluginConfiguration.LANG.get()); + MapManager.init(); MapInitEvent.init(); MapItemManager.init(); diff --git a/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java b/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java index 9e317a7..3dff18e 100644 --- a/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java +++ b/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java @@ -21,11 +21,15 @@ package fr.moribus.imageonmap; import fr.zcraft.zlib.components.configuration.Configuration; import fr.zcraft.zlib.components.configuration.ConfigurationItem; +import java.util.Locale; + import static fr.zcraft.zlib.components.configuration.ConfigurationItem.item; public final class PluginConfiguration extends Configuration { + static public ConfigurationItem LANG = item("lang", Locale.class); + static public ConfigurationItem COLLECT_DATA = item("collect-data", true); static public ConfigurationItem MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server"); diff --git a/src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java b/src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java index 480502a..4497d8e 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java @@ -21,6 +21,7 @@ import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.zcraft.zlib.components.commands.Command; import fr.zcraft.zlib.components.commands.CommandException; +import fr.zcraft.zlib.components.i18n.I; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -36,7 +37,7 @@ public abstract class IoMCommand extends Command protected ImageMap getMapFromArgs(Player player, int index, boolean expand) throws CommandException { - if(args.length <= index) throwInvalidArgument("You need to give a map name."); + if(args.length <= index) throwInvalidArgument(I.t("You need to give a map name.")); ImageMap map; String mapName = args[index]; @@ -53,7 +54,7 @@ public abstract class IoMCommand extends Command map = MapManager.getMap(player.getUniqueId(), mapName); - if(map == null) error("This map does not exist."); + if(map == null) error(I.t("This map does not exist.")); return map; } diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java index 102d1b9..d7c169b 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java @@ -22,10 +22,11 @@ import fr.moribus.imageonmap.commands.IoMCommand; import fr.moribus.imageonmap.map.ImageMap; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.rawtext.RawText; +import org.bukkit.ChatColor; import java.util.List; -import org.bukkit.ChatColor; @CommandInfo (name = "delete", usageParameters = "[tool name]") public class DeleteConfirmCommand extends IoMCommand @@ -34,22 +35,15 @@ public class DeleteConfirmCommand extends IoMCommand protected void run() throws CommandException { ImageMap map = getMapFromArgs(); - - RawText hoverText = new RawText("This map will be deleted ") - .style(ChatColor.UNDERLINE) - .then("forever") - .style(ChatColor.RED, ChatColor.UNDERLINE, ChatColor.ITALIC, ChatColor.BOLD) - .then(" !") - .build(); - - RawText msg = new RawText("You are going to delete ") + + RawText msg = new RawText(I.t("You are going to delete") + " ") .then(map.getId()) .color(ChatColor.GOLD) - .then(". Are you sure ? ") + .then(". " + I.t("Are you sure ? ")) .color(ChatColor.WHITE) - .then("[Confirm]") + .then(I.t("[Confirm]")) .color(ChatColor.GREEN) - .hover(hoverText) + .hover(new RawText(I.t("{red}This map will be deleted {bold}forever{red}!"))) .command(DeleteNoConfirmCommand.class, map.getId()) .build(); diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java index d796967..6c21183 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java @@ -24,13 +24,14 @@ import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.MapManagerException; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; import org.bukkit.entity.Player; import java.util.List; -@CommandInfo (name = "delete-noconfirm", usageParameters = "[map name]") +@CommandInfo (name = "delete-noconfirm", usageParameters = "[map name]") public class DeleteNoConfirmCommand extends IoMCommand { @Override @@ -42,12 +43,12 @@ public class DeleteNoConfirmCommand extends IoMCommand try { MapManager.deleteMap(map); - info("Map successfully deleted."); + info(I.t("Map successfully deleted.")); } catch (MapManagerException ex) { PluginLogger.warning("A non-existent map was requested to be deleted", ex); - warning("This map does not exist."); + warning(I.t("This map does not exist.")); } } @@ -59,4 +60,3 @@ public class DeleteNoConfirmCommand extends IoMCommand return null; } } - diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java index 3aa4058..51c47ff 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java @@ -21,6 +21,7 @@ package fr.moribus.imageonmap.commands.maptool; import fr.moribus.imageonmap.commands.IoMCommand; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import org.bukkit.entity.Player; import java.util.List; @@ -34,8 +35,8 @@ public class GetCommand extends IoMCommand Player player = playerSender(); if(getMapFromArgs().give(player)) { - info("The requested map was too big to fit in your inventory."); - info("Use '/maptool getremaining' to get the remaining maps."); + info(I.t("The requested map was too big to fit in your inventory.")); + info(I.t("Use '/maptool getremaining' to get the remaining maps.")); } } diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java index 9fcac59..f0d7803 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java @@ -22,6 +22,7 @@ import fr.moribus.imageonmap.commands.IoMCommand; import fr.moribus.imageonmap.ui.MapItemManager; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import org.bukkit.entity.Player; @CommandInfo (name = "getremaining", aliases = {"getrest"}) @@ -34,7 +35,7 @@ public class GetRemainingCommand extends IoMCommand if(MapItemManager.getCacheSize(player) <= 0) { - info("You have no remaining map."); + info(I.t("You have no remaining map.")); return; } @@ -42,11 +43,11 @@ public class GetRemainingCommand extends IoMCommand if(givenMaps == 0) { - error("Your inventory is full ! Make some space before requesting the remaining maps."); + error(I.t("Your inventory is full ! Make some space before requesting the remaining maps.")); } else { - info("There are " + MapItemManager.getCacheSize(player) + " maps remaining."); + info(I.tn("There is {0} map remaining.", "There are {0} maps remaining.", MapItemManager.getCacheSize(player))); } } } diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java index cead4e9..50b53bc 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java @@ -23,6 +23,7 @@ import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import org.bukkit.entity.Player; import java.util.List; @@ -38,11 +39,11 @@ public class ListCommand extends IoMCommand if(mapList.isEmpty()) { - info("No map found."); + info(I.t("No map found.")); return; } - info(mapList.size() + " maps found."); + info(I.tn("{0} map found.", "{0} maps found.", mapList.size())); String sMapList = mapList.get(0).getId(); for(int i = 1, c = mapList.size(); i < c; i++) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java index 27d1c26..9f4fdcc 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java @@ -22,6 +22,7 @@ import fr.moribus.imageonmap.commands.IoMCommand; import fr.moribus.imageonmap.migration.MigratorExecutor; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import org.bukkit.command.CommandSender; @CommandInfo (name = "migrate") @@ -32,11 +33,11 @@ public class MigrateCommand extends IoMCommand { if(MigratorExecutor.isRunning()) { - error("A migration process is already running. Check console for details."); + error(I.t("A migration process is already running. Check console for details.")); } else { - info("Migration started. See console for details."); + info(I.t("Migration started. See console for details.")); MigratorExecutor.migrate(); } } diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java index c5bba85..54595ca 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java @@ -23,6 +23,7 @@ import fr.moribus.imageonmap.image.ImageRendererExecutor; import fr.moribus.imageonmap.map.ImageMap; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.worker.WorkerCallback; import fr.zcraft.zlib.tools.PluginLogger; import org.bukkit.entity.Player; @@ -40,7 +41,7 @@ public class NewCommand extends IoMCommand boolean scaling = false; URL url; - if(args.length < 1) throwInvalidArgument("You must give an URL to take the image from."); + if(args.length < 1) throwInvalidArgument(I.t("You must give an URL to take the image from.")); try { @@ -48,7 +49,7 @@ public class NewCommand extends IoMCommand } catch(MalformedURLException ex) { - throwInvalidArgument("Invalid URL."); + throwInvalidArgument(I.t("Invalid URL.")); return; } @@ -57,25 +58,26 @@ public class NewCommand extends IoMCommand if(args[1].equals("resize")) scaling = true; } - info("Rendering ..."); + info(I.t("Rendering...")); ImageRendererExecutor.Render(url, scaling, player.getUniqueId(), new WorkerCallback() { @Override public void finished(ImageMap result) { - player.sendMessage("§7Rendering finished !"); + player.sendMessage(I.t("{cst}Rendering finished !")); if(result.give(player)) { - info("The rendered map was too big to fit in your inventory."); - info("Use '/maptool getremaining' to get the remaining maps."); + info(I.t("The rendered map was too big to fit in your inventory.")); + info(I.t("Use '/maptool getremaining' to get the remaining maps.")); } } @Override public void errored(Throwable exception) { - player.sendMessage("§cMap rendering failed : " + exception.getMessage()); - PluginLogger.warning("Rendering from {0} failed : {1} : {2}", + player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage())); + + PluginLogger.warning("Rendering from {0} failed: {1}: {2}", player.getName(), exception.getClass().getCanonicalName(), exception.getMessage()); diff --git a/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java b/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java index c824a7c..a094fd8 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java @@ -24,7 +24,9 @@ import fr.moribus.imageonmap.map.MapManagerException; import fr.zcraft.zlib.components.gui.ActionGui; import fr.zcraft.zlib.components.gui.Gui; import fr.zcraft.zlib.components.gui.GuiAction; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; +import fr.zcraft.zlib.tools.items.ItemStackBuilder; import org.bukkit.ChatColor; import org.bukkit.DyeColor; import org.bukkit.Material; @@ -96,26 +98,24 @@ public class ConfirmDeleteMapGui extends ActionGui @Override protected void onUpdate() { - setTitle(mapToDelete.getName() + " » " + ChatColor.BLACK + "Confirm deletion"); + /// The title of the map deletion GUI. {0}: map name. + setTitle(I.t("{0} » {black}Confirm deletion", mapToDelete.getName())); setSize(6 * 9); - + + /* ** Item representation of the image being deleted ** */ - ItemStack beingDeleted = new ItemStack(Material.EMPTY_MAP); - ItemMeta meta = beingDeleted.getItemMeta(); - - meta.setDisplayName(ChatColor.RED + "You're about to destroy this map..."); - meta.setLore(Arrays.asList( - ChatColor.RED + "..." + ChatColor.ITALIC + "forever" + ChatColor.RED + ".", - "", - ChatColor.GRAY + "Name: " + ChatColor.WHITE + mapToDelete.getName(), - ChatColor.GRAY + "Map ID: " + ChatColor.WHITE + mapToDelete.getId(), - ChatColor.GRAY + "Maps inside: " + ChatColor.WHITE + mapToDelete.getMapsIDs().length - )); - - beingDeleted.setItemMeta(meta); - - action("", 13, beingDeleted); + action("", 13, new ItemStackBuilder(Material.EMPTY_MAP) + /// The title of the map deletion item + .title(I.t("{red}You're about to destroy this map...")) + /// The end, in the lore, of a title starting with “You're about to destroy this map...”. + .lore(I.t("{red}...{italic}forever{red}.")) + .loreLine() + .lore(I.t("{gray}Name: {white}{0}",mapToDelete.getName())) + .lore(I.t("{gray}Map ID: {white}{0}", mapToDelete.getId())) + .lore(I.t("{grayMaps inside: {white}{0}", mapToDelete.getMapsIDs().length)) + .hideAttributes() + ); /* ** Buttons ** */ @@ -175,7 +175,7 @@ public class ConfirmDeleteMapGui extends ActionGui try { MapManager.deleteMap(mapToDelete); - getPlayer().sendMessage(ChatColor.GRAY + "Map successfully deleted."); + getPlayer().sendMessage(I.t("{gray}Map successfully deleted.")); } catch (MapManagerException ex) { @@ -185,7 +185,7 @@ public class ConfirmDeleteMapGui extends ActionGui // We try to open the map list GUI, if the map was deleted, before the details GUI - // (so the grandparent GUI).. + // (so the grandparent GUI). if (getParent() != null && getParent().getParent() != null) Gui.open(getPlayer(), getParent().getParent()); else diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java index a1f2cc1..10e4454 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java @@ -25,16 +25,12 @@ import fr.moribus.imageonmap.ui.MapItemManager; import fr.zcraft.zlib.components.gui.ExplorerGui; import fr.zcraft.zlib.components.gui.Gui; import fr.zcraft.zlib.components.gui.GuiAction; -import fr.zcraft.zlib.components.gui.GuiUtils; import fr.zcraft.zlib.components.gui.PromptGui; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.Callback; -import org.bukkit.ChatColor; +import fr.zcraft.zlib.tools.items.ItemStackBuilder; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.Collections; public class MapDetailGui extends ExplorerGui @@ -52,20 +48,14 @@ public class MapDetailGui extends ExplorerGui Material partMaterial = Material.PAPER; if((y % 2 == 0 && x % 2 == 0) || (y % 2 == 1 && x % 2 == 1)) partMaterial = Material.EMPTY_MAP; - - ItemStack part = new ItemStack(partMaterial); - ItemMeta meta = part.getItemMeta(); - meta.setDisplayName(ChatColor.GREEN + "Map part"); - meta.setLore(Arrays.asList( - ChatColor.GRAY + "Column: " + ChatColor.WHITE + (y + 1), - ChatColor.GRAY + "Row: " + ChatColor.WHITE + (x + 1), - "", - ChatColor.GRAY + "» Click to get only this part" - )); - - part.setItemMeta(meta); - return part; + return new ItemStackBuilder(partMaterial) + .title(I.t("{green}Map part")) + .lore(I.t("{gray}Column: {white}{0}", y + 1)) + .lore(I.t("{gray}Row: {white}{0}", x + 1)) + .loreLine() + .lore(I.t("{gray}» {white}Click{gray} to get only this part")) + .item(); } @Override @@ -80,7 +70,7 @@ public class MapDetailGui extends ExplorerGui return MapItemManager.createMapItem((PosterMap)map, x, y); } - throw new IllegalStateException("Unsupported map type : " + map.getType()); + throw new IllegalStateException("Unsupported map type: " + map.getType()); } @Override @@ -96,7 +86,8 @@ public class MapDetailGui extends ExplorerGui @Override protected void onUpdate() { - setTitle("Your maps » " + ChatColor.BLACK + map.getName()); + /// Title of the map details GUI + setTitle(I.t("Your maps » {black}{0}", map.getName())); setKeepHorizontalScrollingSpace(true); if(map instanceof PosterMap) @@ -105,18 +96,17 @@ public class MapDetailGui extends ExplorerGui setData(null); // Fallback to the empty view item. - action("rename", getSize() - 7, GuiUtils.makeItem(Material.BOOK_AND_QUILL, ChatColor.BLUE + "Rename this image", Arrays.asList( - ChatColor.GRAY + "Click here to rename this image;", - ChatColor.GRAY + "this is used for your own organization." - ))); + action("rename", getSize() - 7, new ItemStackBuilder(Material.BOOK_AND_QUILL) + .title(I.t("{blue}Rename this image")) + .longLore(I.t("{gray}Click here to rename this image; this is used for your own organization.")) + ); - action("delete", getSize() - 6, GuiUtils.makeItem(Material.BARRIER, ChatColor.RED + "Delete this image", Arrays.asList( - ChatColor.GRAY + "Deletes this map " + ChatColor.WHITE + "forever" + ChatColor.GRAY + ".", - ChatColor.GRAY + "This action cannot be undone!", - "", - ChatColor.GRAY + "You will be asked to confirm your", - ChatColor.GRAY + "choice if you click here." - ))); + action("delete", getSize() - 6, new ItemStackBuilder(Material.BARRIER) + .title("{red}Delete this image") + .longLore(I.t("{gray}Deletes this map {white}forever{gray}. This action cannot be undone!")) + .loreLine() + .longLore(I.t("{gray}You will be asked to confirm your choice if you click here.")) + ); // To keep the controls centered, the back button is shifted to the right when the @@ -126,9 +116,10 @@ public class MapDetailGui extends ExplorerGui if(map instanceof PosterMap && ((PosterMap) map).getColumnCount() <= INVENTORY_ROW_SIZE) backSlot++; - action("back", backSlot, GuiUtils.makeItem(Material.EMERALD, ChatColor.GREEN + "« Back", Collections.singletonList( - ChatColor.GRAY + "Go back to the list." - ))); + action("back", backSlot, new ItemStackBuilder(Material.EMERALD) + .title(I.t("{green}« Back")) + .lore(I.t("{gray}Go back to the list.")) + ); } @@ -142,12 +133,12 @@ public class MapDetailGui extends ExplorerGui { if (newName == null || newName.isEmpty()) { - getPlayer().sendMessage(ChatColor.RED + "Map names can't be empty."); + getPlayer().sendMessage(I.t("{ce}Map names can't be empty.")); return; } map.rename(newName); - getPlayer().sendMessage(ChatColor.GRAY + "Map successfully renamed."); + getPlayer().sendMessage(I.t("{cs}Map successfully renamed.")); } }, map.getName(), this); } diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java index f39791d..f8b70a7 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package fr.moribus.imageonmap.gui; import fr.moribus.imageonmap.PluginConfiguration; @@ -27,153 +26,128 @@ import fr.moribus.imageonmap.ui.MapItemManager; import fr.moribus.imageonmap.ui.SplatterMapManager; import fr.zcraft.zlib.components.gui.ExplorerGui; import fr.zcraft.zlib.components.gui.Gui; -import fr.zcraft.zlib.components.gui.GuiUtils; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.items.ItemStackBuilder; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.util.Arrays; -import java.util.Locale; public class MapListGui extends ExplorerGui { - private final NumberFormat bigNumbersFormatter = new DecimalFormat("###,###,###,###", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + @Override + protected ItemStack getViewItem(ImageMap map) + { + String mapDescription; + if (map instanceof SingleMap) + /// Displayed subtitle description of a single map on the list GUI + mapDescription = I.t("{white}Single map"); + else + /// Displayed subtitle description of a poster map on the list GUI (columns × rows in english) + mapDescription = I.t("{white}Poster map ({0} × {1})", ((PosterMap) map).getColumnCount(), ((PosterMap) map).getRowCount()); + return new ItemStackBuilder(Material.MAP) + /// Displayed title of a map on the list GUI + .title(I.t("{green}{bold}{0}", map.getName())) - @Override - protected ItemStack getViewItem(ImageMap map) - { - String mapDescription; - if (map instanceof SingleMap) - mapDescription = "Single map"; - else - mapDescription = "Poster map (" + ((PosterMap) map).getColumnCount() + "×" + ((PosterMap) map).getRowCount() + ")"; + .lore(mapDescription) + .loreLine() + /// Map ID displayed in the tooltip of a map on the list GUI + .lore(I.t("{gray}Map ID: {0}", map.getId())) + .loreLine() + .lore(I.t("{gray}» {white}Left-click{gray} to get this map")) + .lore(I.t("{gray}» {white}Right-click{gray} for details and options")) - ItemStack icon = GuiUtils.makeItem(Material.MAP, ChatColor.GREEN + "" + ChatColor.BOLD + map.getName(), Arrays.asList( - ChatColor.WHITE + mapDescription, - "", - ChatColor.GRAY + "Map ID: " + map.getId(), - "", - ChatColor.GRAY + "» Left-click to get this map", - ChatColor.GRAY + "» Right-click for details and options" - )); + .item(); + } - return GuiUtils.hideItemAttributes(icon); - } + @Override + protected ItemStack getEmptyViewItem() + { + return new ItemStackBuilder(Material.BARRIER) + .title(I.t("{red}You don't have any map.")) + .longLore(I.t("{gray}Get started by creating a new one using {white}/tomap [resize]{gray}!")) + .item(); + } - @Override - protected ItemStack getEmptyViewItem() - { - ItemStack empty = new ItemStack(Material.BARRIER); - ItemMeta meta = empty.getItemMeta(); + @Override + protected void onRightClick(ImageMap data) + { + Gui.open(getPlayer(), new MapDetailGui(data), this); + } - meta.setDisplayName(ChatColor.RED + "You don't have any map."); - meta.setLore(Arrays.asList( - ChatColor.GRAY + "Get started by creating a new one", - ChatColor.GRAY + "using " + ChatColor.WHITE + "/tomap [resize]" + ChatColor.GRAY + "!" - )); + @Override + protected ItemStack getPickedUpItem(ImageMap map) + { + if (map instanceof SingleMap) + { + return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); + } + else if (map instanceof PosterMap) + { + return SplatterMapManager.makeSplatterMap((PosterMap) map); + } - empty.setItemMeta(meta); - return empty; - } + MapItemManager.give(getPlayer(), map); + return null; + } - @Override - protected void onRightClick(ImageMap data) - { - Gui.open(getPlayer(), new MapDetailGui(data), this); - } + @Override + protected void onUpdate() + { + ImageMap[] maps = MapManager.getMaps(getPlayer().getUniqueId()); + setData(maps); + /// The maps list GUI title + setTitle(I.t("{black}Your maps {reset}({0})", maps.length)); - @Override - protected ItemStack getPickedUpItem(ImageMap map) - { - if (map instanceof SingleMap) - { - return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); - } - else if(map instanceof PosterMap) - { - return SplatterMapManager.makeSplatterMap((PosterMap) map); - } - - MapItemManager.give(getPlayer(), map); - return null; - } - - @Override - protected void onUpdate() - { - ImageMap[] maps = MapManager.getMaps(getPlayer().getUniqueId()); - setData(maps); - setTitle(ChatColor.BLACK + "Your maps " + ChatColor.RESET + "(" + maps.length + ")"); - - setKeepHorizontalScrollingSpace(true); + setKeepHorizontalScrollingSpace(true); /* ** Statistics ** */ - int imagesCount = MapManager.getMapList(getPlayer().getUniqueId()).size(); - int mapPartCount = MapManager.getMapPartCount(getPlayer().getUniqueId()); + int imagesCount = MapManager.getMapList(getPlayer().getUniqueId()).size(); + int mapPartCount = MapManager.getMapPartCount(getPlayer().getUniqueId()); - int mapGlobalLimit = PluginConfiguration.MAP_GLOBAL_LIMIT.get(); - int mapPersonalLimit = PluginConfiguration.MAP_PLAYER_LIMIT.get(); + int mapGlobalLimit = PluginConfiguration.MAP_GLOBAL_LIMIT.get(); + int mapPersonalLimit = PluginConfiguration.MAP_PLAYER_LIMIT.get(); - int mapPartGloballyLeft = mapGlobalLimit - MapManager.getMapCount(); - int mapPartPersonallyLeft = mapPersonalLimit - mapPartCount; + int mapPartGloballyLeft = mapGlobalLimit - MapManager.getMapCount(); + int mapPartPersonallyLeft = mapPersonalLimit - mapPartCount; - int mapPartLeft; - if (mapGlobalLimit <= 0 && mapPersonalLimit <= 0) - mapPartLeft = -1; - else if (mapGlobalLimit <= 0) - mapPartLeft = mapPartPersonallyLeft; - else if (mapPersonalLimit <= 0) - mapPartLeft = mapPartGloballyLeft; - else - mapPartLeft = Math.min(mapPartGloballyLeft, mapPartPersonallyLeft); + int mapPartLeft; + if (mapGlobalLimit <= 0 && mapPersonalLimit <= 0) + mapPartLeft = -1; + else if (mapGlobalLimit <= 0) + mapPartLeft = mapPartPersonallyLeft; + else if (mapPersonalLimit <= 0) + mapPartLeft = mapPartGloballyLeft; + else + mapPartLeft = Math.min(mapPartGloballyLeft, mapPartPersonallyLeft); - double percentageUsed = mapPartLeft < 0 ? 0 : ((double) mapPartCount) / ((double) (mapPartCount + mapPartLeft)) * 100; + double percentageUsed = mapPartLeft < 0 ? 0 : ((double) mapPartCount) / ((double) (mapPartCount + mapPartLeft)) * 100; - ItemStackBuilder statistics = new ItemStackBuilder(Material.ENCHANTED_BOOK) - .title(ChatColor.BLUE, "Usage statistics") - .lore( "", - getStatisticText("Images rendered", imagesCount), - getStatisticText("Minecraft maps used", mapPartCount)); - - if(mapPartLeft >= 0) - { - statistics.lore("", ChatColor.BLUE + "Minecraft maps limits"); - - statistics.lore("", - getStatisticText("Server-wide limit", mapGlobalLimit, true), - getStatisticText("Per-player limit", mapPersonalLimit, true)) - - .lore("", - getStatisticText("Current consumption", ((int) Math.rint(percentageUsed)) + " %"), - getStatisticText("Maps left", mapPartLeft)); - } - - statistics.hideAttributes(); + ItemStackBuilder statistics = new ItemStackBuilder(Material.ENCHANTED_BOOK) + .title(I.t("{blue}Usage statistics")) + .loreLine() + .lore(I.tn("{white}{0}{gray} image rendered", "{white}{0}{gray} images rendered", imagesCount)) + .lore(I.tn("{white}{0}{gray} Minecraft map used", "{white}{0}{gray} Minecraft maps used", mapPartCount)); - action("", getSize() - 5, statistics); - } + if(mapPartLeft >= 0) + { + statistics + .lore("", I.t("{blue}Minecraft maps limits"), "") + .lore(mapGlobalLimit == 0 + ? I.t("{gray}Server-wide limit: {white}unlimited") + : I.t("{gray}Server-wide limit: {white}{0}", mapGlobalLimit)) + .lore(mapPersonalLimit == 0 + ? I.t("{gray}Per-player limit: {white}unlimited") + : I.t("{gray}Per-player limit: {white}{0}", mapPersonalLimit)) + .loreLine() + .lore(I.t("{white}{0} %{gray} of your quota used", (int) Math.rint(percentageUsed))) + .lore(I.tn("{white}{0}{gray} map left", "{white}{0}{gray} maps left", mapPartLeft)); + } - private String getStatisticText(String title, Integer value) - { - return getStatisticText(title, value, false); - } + statistics.hideAttributes(); - private String getStatisticText(String title, Integer value, boolean zeroIsUnlimited) - { - return getStatisticText(title, zeroIsUnlimited && value <= 0 ? "unlimited" : bigNumbersFormatter.format(value)); - } - - private String getStatisticText(String title, String value) - { - return ChatColor.GRAY + title + ": " + ChatColor.WHITE + value; - } + action("", getSize() - 5, statistics); + } } diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index f689f2d..a4bb967 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -20,6 +20,7 @@ package fr.moribus.imageonmap.image; import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.components.worker.Worker; import fr.zcraft.zlib.components.worker.WorkerAttributes; import fr.zcraft.zlib.components.worker.WorkerCallback; @@ -69,13 +70,13 @@ public class ImageRendererExecutor extends Worker final int httpCode = httpConnection.getResponseCode(); if((httpCode / 100) != 2) { - throw new IOException("HTTP error : " + httpCode + " " + httpConnection.getResponseMessage()); + throw new IOException(I.t("HTTP error : {0} {1}", httpCode, httpConnection.getResponseMessage())); } } final InputStream stream = connection.getInputStream(); final BufferedImage image = ImageIO.read(stream); - if (image == null) throw new IOException("The given URL is not a valid image"); + if (image == null) throw new IOException(I.t("The given URL is not a valid image")); if (scaling) return RenderSingle(image, playerUUID); else return RenderPoster(image, playerUUID); diff --git a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java index ef46e64..bd71fad 100644 --- a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java @@ -18,25 +18,30 @@ package fr.moribus.imageonmap.map; -import fr.moribus.imageonmap.ui.*; -import org.bukkit.*; -import org.bukkit.configuration.*; -import org.bukkit.configuration.serialization.*; -import org.bukkit.entity.*; -import org.bukkit.inventory.*; +import fr.moribus.imageonmap.ui.MapItemManager; +import fr.zcraft.zlib.components.i18n.I; +import org.bukkit.Material; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public abstract class ImageMap implements ConfigurationSerializable { - static public enum Type + public enum Type { - SINGLE, POSTER; - }; + SINGLE, POSTER + } static public final int WIDTH = 128; static public final int HEIGHT = 128; - static public final String DEFAULT_NAME = "Map"; + + /// The default display name of a map + static public final String DEFAULT_NAME = I.t("Map"); private String id; private final UUID userUUID; diff --git a/src/main/java/fr/moribus/imageonmap/map/MapManagerException.java b/src/main/java/fr/moribus/imageonmap/map/MapManagerException.java index b7cf91a..7fc3c49 100644 --- a/src/main/java/fr/moribus/imageonmap/map/MapManagerException.java +++ b/src/main/java/fr/moribus/imageonmap/map/MapManagerException.java @@ -18,18 +18,21 @@ package fr.moribus.imageonmap.map; +import fr.zcraft.zlib.components.i18n.I; + import java.text.MessageFormat; public class MapManagerException extends Exception { public enum Reason { - MAXIMUM_PLAYER_MAPS_EXCEEDED("You have too many maps (maximum : {0})."), - MAXIMUM_SERVER_MAPS_EXCEEDED("The server ImageOnMap limit has been reached."), - IMAGEMAP_DOES_NOT_EXIST("The given map does not exist."); + MAXIMUM_PLAYER_MAPS_EXCEEDED(I.t("You have too many maps (maximum : {0}).")), + MAXIMUM_SERVER_MAPS_EXCEEDED(I.t("The server ImageOnMap limit has been reached.")), + IMAGEMAP_DOES_NOT_EXIST(I.t("The given map does not exist.")); private final String reasonString; - private Reason(String reasonString) + + Reason(String reasonString) { this.reasonString = reasonString; } @@ -39,7 +42,8 @@ public class MapManagerException extends Exception return MessageFormat.format(reasonString, arguments); } } - + + private final Reason reason; public MapManagerException(Reason reason, Object ...arguments) @@ -49,5 +53,4 @@ public class MapManagerException extends Exception } public Reason getReason() { return reason; } - } diff --git a/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java b/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java index 84909d2..c9d1fab 100644 --- a/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java @@ -19,6 +19,7 @@ package fr.moribus.imageonmap.migration; import fr.moribus.imageonmap.ImageOnMap; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; @@ -30,7 +31,7 @@ public class MigratorExecutor { if(isRunning()) { - PluginLogger.error("Migration is already running."); + PluginLogger.error(I.t("Migration is already running.")); return; } migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration"); @@ -46,14 +47,15 @@ public class MigratorExecutor { if(isRunning()) { - PluginLogger.info("Waiting for migration to finish ..."); + PluginLogger.info(I.t("Waiting for migration to finish...")); + try { migratorThread.join(); } catch(InterruptedException ex) { - PluginLogger.error("Migration thread has been interrupted while wating to finish. It may not have ended correctly."); + PluginLogger.error(I.t("Migration thread has been interrupted while waiting to finish. It may not have ended correctly.")); } } } diff --git a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java b/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java index 047a428..6f5f716 100644 --- a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java +++ b/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java @@ -20,6 +20,7 @@ package fr.moribus.imageonmap.migration; import fr.moribus.imageonmap.ImageOnMap; import fr.moribus.imageonmap.map.MapManager; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.mojang.UUIDFetcher; import org.bukkit.configuration.InvalidConfigurationException; @@ -41,8 +42,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; /** * This class represents and executes the ImageOnMap v3.x migration process @@ -171,8 +170,8 @@ public class V3Migrator implements Runnable } catch(Exception ex) { - PluginLogger.error("Error while preparing migration"); - PluginLogger.error("Aborting migration. No change has been made.", ex); + PluginLogger.error(I.t("Error while preparing migration")); + PluginLogger.error(I.t("Aborting migration. No change has been made."), ex); return; } @@ -184,11 +183,9 @@ public class V3Migrator implements Runnable } catch(Exception ex) { - PluginLogger.error("Error while migrating", ex); - PluginLogger.error("Aborting migration. Some changes may already have been made."); - PluginLogger.error("Before trying to migrate again, you must recover player files from the backups, and then move the backups away from the plugin directory to avoid overwriting them."); - - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex); + PluginLogger.error(I.t("Error while migrating"), ex); + PluginLogger.error(I.t("Aborting migration. Some changes may already have been made.")); + PluginLogger.error(I.t("Before trying to migrate again, you must recover player files from the backups, and then move the backups away from the plugin directory to avoid overwriting them.")); } } @@ -200,22 +197,22 @@ public class V3Migrator implements Runnable */ private boolean spotFilesToMigrate() { - PluginLogger.info("Looking for configuration files to migrate ..."); + PluginLogger.info(I.t("Looking for configuration files to migrate...")); if(!oldPostersFile.exists()) oldPostersFile = null; - else PluginLogger.info("Detected former posters file {0}", OLD_POSTERS_FILE_NAME); + else PluginLogger.info(I.t("Detected former posters file {0}", OLD_POSTERS_FILE_NAME)); if(!oldMapsFile.exists()) oldMapsFile = null; - else PluginLogger.info("Detected former maps file {0}", OLD_MAPS_FILE_NAME); + else PluginLogger.info(I.t("Detected former maps file {0}", OLD_MAPS_FILE_NAME)); if(oldPostersFile == null && oldMapsFile == null) { - PluginLogger.info("There is nothing to migrate. Stopping."); + PluginLogger.info(I.t("There is nothing to migrate. Stopping.")); return false; } else { - PluginLogger.info("Done."); + PluginLogger.info(I.t("Done.")); return true; } } @@ -229,9 +226,9 @@ public class V3Migrator implements Runnable if((backupsPrev3Directory.exists() && backupsPrev3Directory.list().length == 0) || (backupsPostv3Directory.exists() && backupsPostv3Directory.list().length == 0)) { - PluginLogger.error("Backup directories already exists."); - PluginLogger.error("This means that a migration has already been done, or may not have ended well."); - PluginLogger.error("To start a new migration, you must move away the backup directories so they are not overwritten."); + PluginLogger.error(I.t("Backup directories already exists.")); + PluginLogger.error(I.t("This means that a migration has already been done, or may not have ended well.")); + PluginLogger.error(I.t("To start a new migration, you must move away the backup directories so they are not overwritten.")); return true; } @@ -345,22 +342,22 @@ public class V3Migrator implements Runnable */ private void fetchUUIDs() throws IOException, InterruptedException { - PluginLogger.info("Fetching UUIDs from Mojang ..."); + PluginLogger.info(I.t("Fetching UUIDs from Mojang ...")); try { usersUUIDs = UUIDFetcher.fetch(new ArrayList(userNamesToFetch)); } catch(IOException ex) { - PluginLogger.error("An error occurred while fetching the UUIDs from Mojang", ex); + PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang"), ex); throw ex; } catch(InterruptedException ex) { - PluginLogger.error("The migration worker has been interrupted", ex); + PluginLogger.error(I.t("The migration worker has been interrupted"), ex); throw ex; } - PluginLogger.info("Fetching done. {0} UUIDs have been retrieved.", usersUUIDs.size()); + PluginLogger.info(I.tn("Fetching done. {0} UUID have been retrieved.", "Fetching done. {0} UUIDs have been retrieved.", usersUUIDs.size())); } /** @@ -371,8 +368,8 @@ public class V3Migrator implements Runnable { if(usersUUIDs.size() == userNamesToFetch.size()) return true; int remainingUsersCount = userNamesToFetch.size() - usersUUIDs.size(); - PluginLogger.info("Mojang did not find UUIDs for {0} players at the current time.", remainingUsersCount); - PluginLogger.info("The Mojang servers limit requests rate at one per second, this may take some time..."); + PluginLogger.info(I.tn("Mojang did not find UUIDs for {0} player at the current time.", "Mojang did not find UUIDs for {0} players at the current time.", remainingUsersCount)); + PluginLogger.info(I.t("The Mojang servers limit requests rate at one per second, this may take some time...")); try { @@ -380,35 +377,36 @@ public class V3Migrator implements Runnable } catch(IOException ex) { - PluginLogger.error("An error occurred while fetching the UUIDs from Mojang"); + PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang")); throw ex; } catch(InterruptedException ex) { - PluginLogger.error("The migration worker has been interrupted"); + PluginLogger.error(I.t("The migration worker has been interrupted")); throw ex; } if(usersUUIDs.size() != userNamesToFetch.size()) { - PluginLogger.warning("Mojang did not find player data for {0} players", - userNamesToFetch.size() - usersUUIDs.size()); - PluginLogger.warning("The following players do not exist or do not have paid accounts :"); + PluginLogger.warning(I.tn("Mojang did not find player data for {0} player", "Mojang did not find player data for {0} players", + userNamesToFetch.size() - usersUUIDs.size())); + PluginLogger.warning(I.t("The following players do not exist or do not have paid accounts :")); String missingUsersList = ""; for(String user : userNamesToFetch) { - if(!usersUUIDs.containsKey(user)) missingUsersList += user + ","; + if(!usersUUIDs.containsKey(user)) missingUsersList += user + ", "; } missingUsersList = missingUsersList.substring(0, missingUsersList.length()); PluginLogger.info(missingUsersList); } + if(usersUUIDs.size() <= 0) { - PluginLogger.info("Mojang could not find any of the registered players."); - PluginLogger.info("There is nothing to migrate. Stopping."); + PluginLogger.info(I.t("Mojang could not find any of the registered players.")); + PluginLogger.info(I.t("There is nothing to migrate. Stopping.")); return false; } @@ -417,7 +415,7 @@ public class V3Migrator implements Runnable private void mergeMapData() { - PluginLogger.info("Merging map data ..."); + PluginLogger.info(I.t("Merging map data ...")); ArrayDeque remainingMaps = new ArrayDeque<>(); ArrayDeque remainingPosters = new ArrayDeque<>(); @@ -458,25 +456,25 @@ public class V3Migrator implements Runnable private void saveChanges() { - PluginLogger.info("Saving changes ..."); + PluginLogger.info(I.t("Saving changes ...")); MapManager.save(); } private void cleanup() throws IOException { - PluginLogger.info("Cleaning up old data files ..."); + PluginLogger.info(I.t("Cleaning up old data files ...")); //Cleaning maps file if(oldMapsFile != null) { if(mapsToMigrate.isEmpty()) { - PluginLogger.info("Deleting old map data file ..."); + PluginLogger.info(I.t("Deleting old map data file ...")); oldMapsFile.delete(); } else { - PluginLogger.info("{0} maps could not be migrated.", mapsToMigrate.size()); + PluginLogger.info(I.tn("{0} map could not be migrated.", "{0} maps could not be migrated.", mapsToMigrate.size())); YamlConfiguration mapConfig = new YamlConfiguration(); mapConfig.set("IdCount", mapsToMigrate.size()); @@ -494,12 +492,12 @@ public class V3Migrator implements Runnable { if(postersToMigrate.isEmpty()) { - PluginLogger.info("Deleting old poster data file ..."); + PluginLogger.info(I.t("Deleting old poster data file ...")); oldPostersFile.delete(); } else { - PluginLogger.info("{0} posters could not be migrated.", postersToMigrate.size()); + PluginLogger.info(I.tn("{0} poster could not be migrated.", "{0} posters could not be migrated.", postersToMigrate.size())); YamlConfiguration posterConfig = new YamlConfiguration(); posterConfig.set("IdCount", postersToMigrate.size()); @@ -512,7 +510,7 @@ public class V3Migrator implements Runnable } } - PluginLogger.info("Data that has not been migrated will be kept in the old data files."); + PluginLogger.info(I.t("Data that has not been migrated will be kept in the old data files.")); } /* ****** Utils ***** */ diff --git a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java index 01ae66f..9131539 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java @@ -22,12 +22,18 @@ import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.PosterMap; import fr.moribus.imageonmap.map.SingleMap; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.core.ZLib; import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemUtils; +import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -35,11 +41,6 @@ import java.util.ArrayDeque; import java.util.HashMap; import java.util.Queue; import java.util.UUID; -import org.bukkit.GameMode; -import org.bukkit.entity.ItemFrame; -import org.bukkit.event.EventHandler; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; public class MapItemManager implements Listener { @@ -113,9 +114,8 @@ public class MapItemManager implements Listener String mapName; if(map.hasColumnData()) { - mapName = map.getName() + - " (row " + x + - ", column " + y + ")"; + /// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column. + mapName = I.t("{0} (row {1}, column {2})", map.getName(), x, y); } else { @@ -150,9 +150,7 @@ public class MapItemManager implements Listener { return MapItemManager.createMapItem( ((PosterMap) map).getMapIdAt(x, y), - map.getName() + - " (row " + (y + 1) + - ", column " + (x + 1) + ")" + I.t("{0} (row {1}, column {2})", map.getName(), y + 1, x + 1) ); } else @@ -193,8 +191,7 @@ public class MapItemManager implements Listener { PosterMap poster = (PosterMap) map; int index = poster.getIndex(item.getDurability()); - return map.getName() + " (row " + (poster.getRowAt(index)) + - ", column " + (poster.getColumnAt(index)) + ")"; + return I.t("{0} (row {1}, column {2})", map.getName(), poster.getRowAt(index), poster.getColumnAt(index)); } } diff --git a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java index c693c7d..8d93952 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java @@ -22,6 +22,7 @@ import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.PosterMap; import fr.zcraft.zlib.components.gui.GuiUtils; +import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.items.GlowEffect; import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.world.FlatLocation; @@ -40,16 +41,19 @@ abstract public class SplatterMapManager { return new ItemStackBuilder(Material.MAP) .data(map.getMapIdAt(0)) - .title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, "Splatter Map") + .title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map")) .loreLine(ChatColor.GRAY, map.getId()) .loreLine() - .loreLine(ChatColor.BLUE, "Item frames needed") - .loreLine(ChatColor.GRAY, map.getColumnCount() + " × " + map.getRowCount()) + /// Title in a splatter map tooltip + .loreLine(ChatColor.BLUE, I.t("Item frames needed")) + /// Size of a map stored in a splatter map + .loreLine(ChatColor.GRAY, I.t("{0} × {1}", map.getColumnCount(), map.getRowCount())) .loreLine() - .loreLine(ChatColor.BLUE, "How to use this?") - .lore(GuiUtils.generateLore(ChatColor.GRAY + "Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map.")) + /// Title in a splatter map tooltip + .loreLine(ChatColor.BLUE, I.t("How to use this?")) + .lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."))) .loreLine() - .lore(GuiUtils.generateLore(ChatColor.GRAY + "Shift-click one of the placed maps to remove the whole poster at a single time.")) + .lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster at a single time."))) .glow() .hideAttributes() .item(); @@ -94,7 +98,7 @@ abstract public class SplatterMapManager if(!wall.isValid()) { - player.sendMessage(ChatColor.RED + "There is not enough space to place this map (" + poster.getColumnCount() + "x" + poster.getRowCount() + ")"); + player.sendMessage(I.t("{ce}There is not enough space to place this map ({0} × {1}).", poster.getColumnCount(), poster.getRowCount())); return false; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0aa0f21..5ffe7d4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,11 @@ ### ImageOnMap configuration file +# Plugin language. Empty: system language. +# Available: en_US (default, fallback) and fr_FR. +lang: + + # Allows collection of anonymous statistics on plugin environment and usage # The statistics are publicly visible here: http://mcstats.org/plugin/ImageOnMap collect-data: true