diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index cf68378..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,16 +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; } - loadComponents(Gui.class, Commands.class, ImageIOExecutor.class, ImageRendererExecutor.class); + saveDefaultConfig(); + + loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class); //Init all the things ! - PluginConfiguration.init(this); MetricsLite.startMetrics(); + I18n.setPrimaryLocale(PluginConfiguration.LANG.get()); + MapManager.init(); MapInitEvent.init(); MapItemManager.init(); diff --git a/src/main/java/fr/moribus/imageonmap/MetricsLite.java b/src/main/java/fr/moribus/imageonmap/MetricsLite.java index 2bc1cef..c742518 100644 --- a/src/main/java/fr/moribus/imageonmap/MetricsLite.java +++ b/src/main/java/fr/moribus/imageonmap/MetricsLite.java @@ -55,10 +55,10 @@ public class MetricsLite /** * Starts MetricsLite, unless disabled in config */ - static public void startMetrics() { - if(!PluginConfiguration.COLLECT_DATA.getBoolean()) return; + if(!PluginConfiguration.COLLECT_DATA.get()) return; + try { MetricsLite metrics = new MetricsLite(ImageOnMap.getPlugin()); diff --git a/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java b/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java index c0a69be..3dff18e 100644 --- a/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java +++ b/src/main/java/fr/moribus/imageonmap/PluginConfiguration.java @@ -18,108 +18,20 @@ package fr.moribus.imageonmap; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.Plugin; +import fr.zcraft.zlib.components.configuration.Configuration; +import fr.zcraft.zlib.components.configuration.ConfigurationItem; -public enum PluginConfiguration +import java.util.Locale; + +import static fr.zcraft.zlib.components.configuration.ConfigurationItem.item; + + +public final class PluginConfiguration extends Configuration { - //Configuration field Names, with default values - COLLECT_DATA("collect-data", true), - MAP_GLOBAL_LIMIT("map-global-limit", 0, "Limit-map-by-server"), - MAP_PLAYER_LIMIT("map-player-limit", 0, "Limit-map-by-player"); - - private final String fieldName; - private final Object defaultValue; - private final String[] deprecatedNames; - - private PluginConfiguration(String fieldName, Object defaultValue, String ... deprecatedNames) - { - this.fieldName = fieldName; - this.defaultValue = defaultValue; - this.deprecatedNames = deprecatedNames; - } - - public Object get() - { - return getConfig().get(fieldName, defaultValue); - } - - public Object getDefaultValue() - { - return defaultValue; - } - - public boolean isDefined() - { - return getConfig().contains(fieldName); - } - - @Override - public String toString() - { - return get().toString(); - } - - public String getString() - { - return getConfig().getString(fieldName, (String)defaultValue); - } - - public int getInteger() - { - return getConfig().getInt(fieldName, (Integer)defaultValue); - } - - public boolean getBoolean() - { - return getConfig().getBoolean(fieldName, (Boolean)defaultValue); - } - - private boolean init() - { - boolean affected = false; - - if(!isDefined()) - { - getConfig().set(fieldName, defaultValue); - affected = true; - } - - for(String deprecatedName : deprecatedNames) - { - if(getConfig().contains(deprecatedName)) - { - getConfig().set(fieldName, getConfig().get(deprecatedName)); - getConfig().set(deprecatedName, null); - affected = true; - } - } - return affected; - } - - /* ===== Static API ===== */ - - static private Plugin plugin; - static public FileConfiguration getConfig() - { - return plugin.getConfig(); - } - - static public void init(Plugin plugin) - { - PluginConfiguration.plugin = plugin; - loadDefaultValues(); - } - - static private void loadDefaultValues() - { - boolean affected = false; - - for(PluginConfiguration configField : PluginConfiguration.values()) - { - if(configField.init()) affected = true; - } - - if(affected) plugin.saveConfig(); - } + 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"); + static public ConfigurationItem MAP_PLAYER_LIMIT = item("map-player-limit", 0, "Limit-map-by-player"); } 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..7bd1b72 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..c19b895 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java @@ -21,8 +21,16 @@ package fr.moribus.imageonmap.commands.maptool; import fr.moribus.imageonmap.commands.IoMCommand; import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; +import fr.moribus.imageonmap.map.PosterMap; 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 fr.zcraft.zlib.components.rawtext.RawTextPart; +import fr.zcraft.zlib.tools.items.ItemStackBuilder; +import fr.zcraft.zlib.tools.text.RawMessage; +import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.entity.Player; import java.util.List; @@ -38,17 +46,39 @@ public class ListCommand extends IoMCommand if(mapList.isEmpty()) { - info("No map found."); + info(I.t("No map found.")); return; } - info(mapList.size() + " maps found."); - - String sMapList = mapList.get(0).getId(); + info(I.tn("{white}{bold}{0} map found.", "{white}{bold}{0} maps found.", mapList.size())); + + RawTextPart rawText = new RawText(""); + rawText = addMap(rawText, mapList.get(0)); + for(int i = 1, c = mapList.size(); i < c; i++) { - sMapList += "§7,§r" + mapList.get(i).getId(); + rawText = rawText.then(", ").color(ChatColor.GRAY); + rawText = addMap(rawText, mapList.get(i)); } - player.sendMessage(sMapList); + + RawMessage.send(player, rawText.build()); + } + + private RawTextPart addMap(RawTextPart rawText, ImageMap map) + { + final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" : ((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount(); + + return rawText + .then(map.getId()) + .color(ChatColor.WHITE) + .command(GetCommand.class, map.getId()) + .hover(new ItemStackBuilder(Material.MAP) + .title(ChatColor.GREEN + "" + ChatColor.BOLD + map.getName()) + .lore(ChatColor.GRAY + map.getId() + ", " + size) + .lore("") + .lore(I.t("{white}Click{gray} to get this map")) + .hideAttributes() + .item() + ); } } 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..c478f8d 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..184ea90 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("{gray}Maps 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 b4476a3..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,154 +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.List; -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.getInteger(); - int mapPersonalLimit = PluginConfiguration.MAP_PLAYER_LIMIT.getInteger(); + 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 b51e812..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); @@ -113,7 +114,7 @@ public class ImageRendererExecutor extends Worker return MapManager.createMap(playerUUID, mapID); } - + static private ImageMap RenderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable { final PosterImage poster = new PosterImage(image); 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/MapManager.java b/src/main/java/fr/moribus/imageonmap/map/MapManager.java index 328c95f..eb59656 100644 --- a/src/main/java/fr/moribus/imageonmap/map/MapManager.java +++ b/src/main/java/fr/moribus/imageonmap/map/MapManager.java @@ -24,16 +24,17 @@ import fr.moribus.imageonmap.image.ImageIOExecutor; import fr.moribus.imageonmap.image.PosterImage; import fr.moribus.imageonmap.map.MapManagerException.Reason; import fr.zcraft.zlib.tools.PluginLogger; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitTask; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + abstract public class MapManager { static private final long SAVE_DELAY = 200; @@ -280,12 +281,11 @@ abstract public class MapManager static public void checkMapLimit(int newMapsCount, UUID userUUID) throws MapManagerException { - int limit = PluginConfiguration.MAP_GLOBAL_LIMIT.getInteger(); - if(limit > 0) - { - if(getMapCount() + newMapsCount > limit) - throw new MapManagerException(Reason.MAXIMUM_SERVER_MAPS_EXCEEDED); - } + int limit = PluginConfiguration.MAP_GLOBAL_LIMIT.get(); + + if (limit > 0 && getMapCount() + newMapsCount > limit) + throw new MapManagerException(Reason.MAXIMUM_SERVER_MAPS_EXCEEDED); + getPlayerMapStore(userUUID).checkMapLimit(newMapsCount); } 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/map/PlayerMapStore.java b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java index 2648398..54e1f6b 100644 --- a/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java +++ b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java @@ -22,6 +22,7 @@ import fr.moribus.imageonmap.ImageOnMap; import fr.moribus.imageonmap.PluginConfiguration; import fr.moribus.imageonmap.map.MapManagerException.Reason; import fr.zcraft.zlib.tools.PluginLogger; +import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; @@ -36,7 +37,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import org.bukkit.Material; public class PlayerMapStore implements ConfigurationSerializable { @@ -154,7 +154,7 @@ public class PlayerMapStore implements ConfigurationSerializable public void checkMapLimit(int newMapsCount) throws MapManagerException { - int limit = PluginConfiguration.MAP_PLAYER_LIMIT.getInteger(); + int limit = PluginConfiguration.MAP_PLAYER_LIMIT.get(); if(limit <= 0) return; if(getMapCount() + newMapsCount > limit) 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 f4037b5..ccde458 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; } @@ -244,7 +241,7 @@ public class V3Migrator implements Runnable */ private void backupMapData() throws IOException { - PluginLogger.info("Backing up map data before migrating ..."); + PluginLogger.info("Backing up map data before migrating..."); if(!backupsPrev3Directory.exists()) backupsPrev3Directory.mkdirs(); if(!backupsPostv3Directory.exists()) backupsPostv3Directory.mkdirs(); @@ -349,22 +346,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())); } /** @@ -375,8 +372,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 { @@ -384,35 +381,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; } @@ -421,7 +419,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<>(); @@ -462,25 +460,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()); @@ -498,12 +496,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()); @@ -516,7 +514,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 7fe0928..9b4c335 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java @@ -21,6 +21,8 @@ package fr.moribus.imageonmap.ui; 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; @@ -39,8 +41,19 @@ abstract public class SplatterMapManager { return new ItemStackBuilder(Material.MAP) .data(map.getMapIdAt(0)) - .title(ChatColor.GOLD, map.getName()) - .loreLine(ChatColor.GOLD, "Splatter Map") + .title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map")) + .loreLine(ChatColor.GRAY, map.getId()) + .loreLine() + /// 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() + /// 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 + I.t("Shift-click one of the placed maps to remove the whole poster in one shot."))) .glow() .hideAttributes() .item(); @@ -85,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 e69de29..5ffe7d4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -0,0 +1,18 @@ +### 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 + + +# Images rendered on maps consume Minecraft maps ID, and there are only 32 767 of them. +# You can limit the maximum number of maps a player, or the whole server, can use with ImageOnMap. +# 0 means unlimited. +map-global-limit: 0 +map-player-limit: 0 diff --git a/src/main/resources/i18n/fr_FR.po b/src/main/resources/i18n/fr_FR.po new file mode 100644 index 0000000..7dd9019 --- /dev/null +++ b/src/main/resources/i18n/fr_FR.po @@ -0,0 +1,560 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-21 20:34+0200\n" +"PO-Revision-Date: 2016-05-21 20:38+0100\n" +"Last-Translator: Amaury Carrade\n" +"Language-Team: \n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 1.7.5\n" + +#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:40 +msgid "You need to give a map name." +msgstr "Vous devez donner un nom à la carte." + +#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:57 +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:51 +msgid "This map does not exist." +msgstr "Cette carte n'existe pas." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:39 +msgid "You are going to delete" +msgstr "Vous êtes sur le point de supprimer" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:42 +msgid "Are you sure ? " +msgstr "Êtes-vous sûr ?" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:44 +msgid "[Confirm]" +msgstr "[Confirmer]" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:46 +msgid "{red}This map will be deleted {bold}forever{red}!" +msgstr "{red}Cette carte sera supprimée {bold}définitivement{red} !" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:46 +msgid "Map successfully deleted." +msgstr "Carte supprimée avec succès." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:38 +msgid "The requested map was too big to fit in your inventory." +msgstr "" +"La carte demandée est trop grosse et ne rentre pas dans votre inventaire." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:39 +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:71 +msgid "Use '/maptool getremaining' to get the remaining maps." +msgstr "Utilisez “/maptool getremaining” pour récupérer les cartes restantes." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:38 +msgid "You have no remaining map." +msgstr "Vous n'avez aucune carte restante." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:46 +msgid "" +"Your inventory is full! Make some space before requesting the remaining maps." +msgstr "" +"Votre inventaire est plein ! Faites de la place avant de demander les cartes " +"supplémentaires." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:50 +#, java-format +msgid "There is {0} map remaining." +msgid_plural "There are {0} maps remaining." +msgstr[0] "Il y a {0} carte restante." +msgstr[1] "Il y a {0} cartes restantes." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:49 +msgid "No map found." +msgstr "Aucune carte." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:53 +msgid "{white}{bold}{0} map found." +msgid_plural "{white}{bold}{0} maps found." +msgstr[0] "{white}{bold}{0} carte." +msgstr[1] "{white}{bold}{0} cartes." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:79 +msgid "{white}Click{gray} to get this map" +msgstr "{white}Cliquez{gray} pour obtenir cette carte" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:36 +msgid "A migration process is already running. Check console for details." +msgstr "" +"Un processus de migration est déjà en cours. Consultez la console pour plus " +"de détails." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:40 +msgid "Migration started. See console for details." +msgstr "Migration démarrée. Consultez la console pour plus de détails." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:44 +msgid "You must give an URL to take the image from." +msgstr "Vous devez fournir l'URL de l'image." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:52 +msgid "Invalid URL." +msgstr "URL invalide." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:61 +msgid "Rendering..." +msgstr "Rendu en cours..." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:67 +msgid "{cst}Rendering finished!" +msgstr "{cst}Rendu achevé !" + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:70 +msgid "The rendered map was too big to fit in your inventory." +msgstr "" +"La carte rendue est trop grosse et ne rentre pas dans votre inventaire." + +#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:78 +msgid "{ce}Map rendering failed: {0}" +msgstr "{ce}Impossible de faire le rendu de la carte : {0}" + +#. The title of the map deletion GUI. {0}: map name. +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:102 +msgid "{0} » {black}Confirm deletion" +msgstr "{0} » {black}Confirmation de suppression" + +#. The title of the map deletion item +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:110 +msgid "{red}You're about to destroy this map..." +msgstr "{red}Vous êtes sur le point de supprimer cette carte..." + +#. The end, in the lore, of a title starting with “You're about to destroy this map...”. +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:112 +msgid "{red}...{italic}forever{red}." +msgstr "{red}...{italic}pour toujours{red}." + +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:114 +msgid "{gray}Name: {white}{0}" +msgstr "{gray}Nom : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:115 +msgid "{gray}Map ID: {white}{0}" +msgstr "{gray}Identifiant : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:116 +msgid "{gray}Maps inside: {white}{0}" +msgstr "{gray}Cartes : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:178 +msgid "{gray}Map successfully deleted." +msgstr "{gray}Carte supprimée avec succès." + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:53 +msgid "{green}Map part" +msgstr "{green}Extrait de carte" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:54 +msgid "{gray}Column: {white}{0}" +msgstr "{gray}Colonne : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:55 +msgid "{gray}Row: {white}{0}" +msgstr "{gray}Ligne : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:57 +msgid "{gray}» {white}Click{gray} to get only this part" +msgstr "{gray}» {white}Cliquez{gray} pour récupérer cette partie" + +#. Title of the map details GUI +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:90 +msgid "Your maps » {black}{0}" +msgstr "Vos cartes » {black}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:100 +msgid "{blue}Rename this image" +msgstr "{blue}Renommer cette image" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:101 +msgid "" +"{gray}Click here to rename this image; this is used for your own " +"organization." +msgstr "" +"{gray}Cliquez ici pour renommer cette image ; ceci ne sert qu'à votre " +"organisation personnelle." + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:106 +msgid "" +"{gray}Deletes this map {white}forever{gray}. This action cannot be undone!" +msgstr "" +"{gray}Supprime cette carte {white}pour toujours{gray}. Cette action ne peut " +"être annulée !" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:108 +msgid "{gray}You will be asked to confirm your choice if you click here." +msgstr "{gray}Une confirmation sera demandée si vous cliquez ici." + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:120 +msgid "{green}« Back" +msgstr "{green}« Retour" + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:121 +msgid "{gray}Go back to the list." +msgstr "{gray}Retourner à la liste." + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:136 +msgid "{ce}Map names can't be empty." +msgstr "{ce}Les noms de cartes ne peuvent être vide." + +#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:141 +msgid "{cs}Map successfully renamed." +msgstr "{cs}Carte renommée avec succès." + +#. Displayed subtitle description of a single map on the list GUI +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:43 +msgid "{white}Single map" +msgstr "{white}Carte unique" + +#. Displayed subtitle description of a poster map on the list GUI (columns × rows in english) +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:46 +msgid "{white}Poster map ({0} × {1})" +msgstr "{white}Poster ({0} × {1})" + +#. Displayed title of a map on the list GUI +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:50 +msgid "{green}{bold}{0}" +msgstr "{green}{bold}{0}" + +#. Map ID displayed in the tooltip of a map on the list GUI +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:55 +msgid "{gray}Map ID: {0}" +msgstr "{gray}Identifiant : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:57 +msgid "{gray}» {white}Left-click{gray} to get this map" +msgstr "{gray}» {white}Cliquez droit{gray} pour récupérer cette carte" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:58 +msgid "{gray}» {white}Right-click{gray} for details and options" +msgstr "{gray}» {white}Cliquez droit{gray} pour détails et options" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:67 +msgid "{red}You don't have any map." +msgstr "{red}Vous n'avez aucune carte." + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:68 +msgid "" +"{gray}Get started by creating a new one using {white}/tomap [resize]" +"{gray}!" +msgstr "" +"{gray}Commencez par en créer une nouvelle avec {white}/tomap [resize]" +"{gray} !" + +#. The maps list GUI title +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:100 +msgid "{black}Your maps {reset}({0})" +msgstr "{black}Vos cartes {reset}({0})" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:129 +msgid "{blue}Usage statistics" +msgstr "{blue}Statistiques d'utilisation" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:131 +msgid "{white}{0}{gray} image rendered" +msgid_plural "{white}{0}{gray} images rendered" +msgstr[0] "{white}{0}{gray} image rendue" +msgstr[1] "{white}{0}{gray} images rendues" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:132 +msgid "{white}{0}{gray} Minecraft map used" +msgid_plural "{white}{0}{gray} Minecraft maps used" +msgstr[0] "{white}{0}{gray} carte Minecraft utilisée" +msgstr[1] "{white}{0}{gray} cartes Minecraft utilisées" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:137 +msgid "{blue}Minecraft maps limits" +msgstr "{blue}Limites de cartes Minecraft" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:139 +msgid "{gray}Server-wide limit: {white}unlimited" +msgstr "{gray}Limite du serveur : {white}illimité" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:140 +msgid "{gray}Server-wide limit: {white}{0}" +msgstr "{gray}Limite du serveur : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:142 +msgid "{gray}Per-player limit: {white}unlimited" +msgstr "{gray}Limite individuelle : {white}illimité" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:143 +msgid "{gray}Per-player limit: {white}{0}" +msgstr "{gray}Limite individuelle : {white}{0}" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:145 +msgid "{white}{0} %{gray} of your quota used" +msgstr "{white}{0} %{gray} de votre quota utilisé" + +#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:146 +msgid "{white}{0}{gray} map left" +msgid_plural "{white}{0}{gray} maps left" +msgstr[0] "{white}{0}{gray} carte restante" +msgstr[1] "{white}{0}{gray} cartes restantes" + +#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:73 +#, java-format +msgid "HTTP error : {0} {1}" +msgstr "Erreur HTTP : {0} {1}" + +#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:79 +msgid "The given URL is not a valid image" +msgstr "L'URL donnée n'est pas une image valide." + +#. The default display name of a map +#: src/main/java/fr/moribus/imageonmap/map/ImageMap.java:44 +msgid "Map" +msgstr "Carte" + +#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:29 +#, java-format +msgid "You have too many maps (maximum : {0})." +msgstr "Vous avez trop de cartes (maximum : {0})." + +#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:30 +msgid "The server ImageOnMap limit has been reached." +msgstr "La limite serveur de cartes a été atteinte." + +#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:31 +msgid "The given map does not exist." +msgstr "La carte donnée n'existe pas." + +#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:34 +msgid "Migration is already running." +msgstr "La migration est déjà en cours." + +#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:50 +msgid "Waiting for migration to finish..." +msgstr "Attente de la fin de la migration..." + +#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:58 +msgid "" +"Migration thread has been interrupted while waiting to finish. It may not " +"have ended correctly." +msgstr "" +"Le thread a été interrompu durant l'attente de la fin de la migration. Cette " +"dernière pourrait s'être achevée anormalement." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:173 +msgid "Error while preparing migration" +msgstr "Une erreur est survenue lors de la préparation de la migration." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:174 +msgid "Aborting migration. No change has been made." +msgstr "La migration est annulée. Aucun changement n'a été effectué." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:186 +msgid "Error while migrating" +msgstr "Erreur lors de la migration" + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:187 +msgid "Aborting migration. Some changes may already have been made." +msgstr "" +"La migration est annulée. Certains changements ont pu être effectués malgré " +"tout." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:188 +msgid "" +"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." +msgstr "" +"Avant de re-tenter la migration, vous devez récupérer les fichiers des " +"joueurs depuis la sauvegarde qu'a été effectuée automatiquement, puis " +"déplacer les sauvegardes hors du dossier du plugin afin d'éviter de les " +"écraser." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:200 +msgid "Looking for configuration files to migrate..." +msgstr "Recherche de fichiers de configuration à migrer..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:203 +#, java-format +msgid "Detected former posters file {0}" +msgstr "Vieux fichier de posters détecté : {0}" + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:206 +#, java-format +msgid "Detected former maps file {0}" +msgstr "Vieux fichier de carte détecté : {0}" + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:210 +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:409 +msgid "There is nothing to migrate. Stopping." +msgstr "Il n'y a rien à migrer. Le processus est arrêté." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:215 +msgid "Done." +msgstr "Terminé." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:229 +msgid "Backup directories already exists." +msgstr "Les répertoires de sauvegarde existe déjà." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:230 +msgid "" +"This means that a migration has already been done, or may not have ended " +"well." +msgstr "" +"Cela signifie qu'une migration a déjà été faite, ou qu'elle n'a possiblement " +"pas terminé correctement." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:231 +msgid "" +"To start a new migration, you must move away the backup directories so they " +"are not overwritten." +msgstr "" +"Pour démarrer une nouvelle migration, vous devez déplacer les répertoires de " +"sauvegarde afin qu'ils ne soit pas écrasés." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:345 +msgid "Fetching UUIDs from Mojang..." +msgstr "Récupération des UUID depuis Mojang..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:352 +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:380 +msgid "An error occurred while fetching the UUIDs from Mojang" +msgstr "" +"Une erreur est survenue lors de la récupération des UUIDs depuis Mojang." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:357 +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:385 +msgid "The migration worker has been interrupted" +msgstr "Le processus de migration a été interrompu." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:360 +#, java-format +msgid "Fetching done. {0} UUID have been retrieved." +msgid_plural "Fetching done. {0} UUIDs have been retrieved." +msgstr[0] "Récupération achevée. {0} UUID a été retrouvé." +msgstr[1] "Récupération achevée. {0} UUID ont été retrouvé." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:371 +#, java-format +msgid "Mojang did not find UUIDs for {0} player at the current time." +msgid_plural "Mojang did not find UUIDs for {0} players at the current time." +msgstr[0] "Mojang n'a pas trouvé d'UUID pour {0} joueur à l'heure actuelle." +msgstr[1] "Mojang n'a pas trouvé d'UUID pour {0} joueurs à l'heure actuelle." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:372 +msgid "" +"The Mojang servers limit requests rate at one per second, this may take some " +"time..." +msgstr "" +"Les serveurs de Mojang limitent les requêtes à une par seconde, cette étape " +"risque de durer un petit moment..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:391 +#, java-format +msgid "Mojang did not find player data for {0} player" +msgid_plural "Mojang did not find player data for {0} players" +msgstr[0] "Mojang n'a pas trouvé de données pour {0} joueur." +msgstr[1] "Mojang n'a pas trouvé de données pour {0} joueurs." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:393 +msgid "The following players do not exist or do not have paid accounts :" +msgstr "Les joueurs suivant n'existent pas ou n'ont pas de compte payant :" + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:408 +msgid "Mojang could not find any of the registered players." +msgstr "Mojang n'a pu trouver aucun des joueurs enregistrés." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:418 +msgid "Merging map data..." +msgstr "Fusion des données des cartes..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:459 +msgid "Saving changes..." +msgstr "Sauvegarde des changements..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:465 +msgid "Cleaning up old data files..." +msgstr "Nettoyage des vieux fichiers de données..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:472 +msgid "Deleting old map data file..." +msgstr "Suppression du vieux fichier de données des cartes..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:477 +#, java-format +msgid "{0} map could not be migrated." +msgid_plural "{0} maps could not be migrated." +msgstr[0] "{0} carte n'a pas pu être migrée." +msgstr[1] "{0} cartes n'ont pas pu être migrées." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:495 +msgid "Deleting old poster data file..." +msgstr "Suppression du vieux fichier de données des posters..." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:500 +#, java-format +msgid "{0} poster could not be migrated." +msgid_plural "{0} posters could not be migrated." +msgstr[0] "{0} poster n'a pas pu être migré." +msgstr[1] "{0} posters n'ont pas pu être migrés." + +#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:513 +msgid "Data that has not been migrated will be kept in the old data files." +msgstr "" +"Les données qui n'ont pas été migrées seront conservées dans les vieux " +"fichiers de donnée." + +#. The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column. +#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:118 +#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:153 +#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:194 +#, java-format +msgid "{0} (row {1}, column {2})" +msgstr "{0} (ligne {1}, colonne {2})" + +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:44 +msgid "Splatter Map" +msgstr "Poster auto-dépliant" + +#. Title in a splatter map tooltip +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:48 +msgid "Item frames needed" +msgstr "Cadres requis" + +#. Size of a map stored in a splatter map +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:50 +#, java-format +msgid "{0} × {1}" +msgstr "{0} × {1}" + +#. Title in a splatter map tooltip +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:53 +msgid "How to use this?" +msgstr "Comment l'utiliser ?" + +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:54 +msgid "" +"Place empty item frames on a wall, enough to host the whole map. Then, right-" +"click on the bottom-left frame with this map." +msgstr "" +"Placez des cadres vides sur un mur, en quantité suffisante pour accueillir " +"la carte entière. Ensuite, cliquez-droit sur le cadre en bas à gauche avec " +"cette carte." + +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:56 +msgid "" +"Shift-click one of the placed maps to remove the whole poster in one shot." +msgstr "Cliquez accroupi l'une des cartes du poster pour le retirer d'un coup." + +#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:101 +msgid "{ce}There is not enough space to place this map ({0} × {1})." +msgstr "{ce}Il n'y a pas assez d'espace pour accueillir ce poster ({0} × {1})."