mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2025-02-01 12:11:34 +01:00
Merge pull request #26 from zDevelopers/feature-i18n
Internationalization of the plugin + French translation.
This commit is contained in:
commit
bc34f8cda5
@ -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();
|
||||
|
@ -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<Locale> LANG = item("lang", Locale.class);
|
||||
|
||||
static public ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
|
||||
|
||||
static public ConfigurationItem<Integer> MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ 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;
|
||||
@ -45,11 +46,11 @@ public class ListCommand extends IoMCommand
|
||||
|
||||
if(mapList.isEmpty())
|
||||
{
|
||||
info("No map found.");
|
||||
info(I.t("No map found."));
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage(ChatColor.WHITE + "" + ChatColor.BOLD + mapList.size() + " maps found.");
|
||||
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));
|
||||
@ -65,7 +66,7 @@ public class ListCommand extends IoMCommand
|
||||
|
||||
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map)
|
||||
{
|
||||
final String size = map.getType() == ImageMap.Type.SINGLE ? "1×1" : ((PosterMap) map).getColumnCount() + "×" + ((PosterMap) map).getRowCount();
|
||||
final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" : ((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount();
|
||||
|
||||
return rawText
|
||||
.then(map.getId())
|
||||
@ -75,7 +76,7 @@ public class ListCommand extends IoMCommand
|
||||
.title(ChatColor.GREEN + "" + ChatColor.BOLD + map.getName())
|
||||
.lore(ChatColor.GRAY + map.getId() + ", " + size)
|
||||
.lore("")
|
||||
.lore(ChatColor.WHITE + "Click" + ChatColor.GRAY + " to get this map")
|
||||
.lore(I.t("{white}Click{gray} to get this map"))
|
||||
.hideAttributes()
|
||||
.item()
|
||||
);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<ImageMap>()
|
||||
{
|
||||
@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());
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ImageMap>
|
||||
{
|
||||
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 <URL> [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 <URL> [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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
||||
}
|
||||
|
@ -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."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
@ -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<String>(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<OldSavedMap> remainingMaps = new ArrayDeque<>();
|
||||
ArrayDeque<OldSavedPoster> 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 ***** */
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 in one shot.")))
|
||||
.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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
560
src/main/resources/i18n/fr_FR.po
Normal file
560
src/main/resources/i18n/fr_FR.po
Normal file
@ -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 <EMAIL@ADDRESS>, 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 <URL> [resize]"
|
||||
"{gray}!"
|
||||
msgstr ""
|
||||
"{gray}Commencez par en créer une nouvelle avec {white}/tomap <URL> [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})."
|
Loading…
Reference in New Issue
Block a user