Merge branch 'indev' into feature_give_command

This commit is contained in:
Vlammar 2020-12-09 21:53:06 +01:00 committed by GitHub
commit 497205fc81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 2312 additions and 101 deletions

View File

@ -36,6 +36,7 @@
package fr.moribus.imageonmap;
import fr.moribus.imageonmap.commands.maptool.*;
import fr.moribus.imageonmap.image.ImageIOExecutor;
import fr.moribus.imageonmap.image.ImageRendererExecutor;
@ -44,6 +45,7 @@ import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.migration.MigratorExecutor;
import fr.moribus.imageonmap.migration.V3Migrator;
import fr.moribus.imageonmap.ui.MapItemManager;
import fr.zcraft.zlib.components.commands.CommandWorkers;
import fr.zcraft.zlib.components.commands.Commands;
import fr.zcraft.zlib.components.gui.Gui;
import fr.zcraft.zlib.components.i18n.I18n;
@ -60,7 +62,6 @@ public final class ImageOnMap extends ZPlugin
static private final String IMAGES_DIRECTORY_NAME = "images";
static private final String MAPS_DIRECTORY_NAME = "maps";
static private ImageOnMap plugin;
private File imagesDirectory;
private final File mapsDirectory;
@ -83,6 +84,7 @@ public final class ImageOnMap extends ZPlugin
return new File(imagesDirectory, "map"+mapID+".png");
}
@SuppressWarnings ("unchecked")
@Override
public void onEnable()
@ -99,11 +101,12 @@ public final class ImageOnMap extends ZPlugin
this.setEnabled(false);
return;
}
saveDefaultConfig();
loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class);
loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class, CommandWorkers.class);
//Init all the things !
I18n.setPrimaryLocale(PluginConfiguration.LANG.get());
@ -111,16 +114,23 @@ public final class ImageOnMap extends ZPlugin
MapInitEvent.init();
MapItemManager.init();
Commands.register(
"maptool",
NewCommand.class,
ListCommand.class,
ListOtherCommand.class,
GetCommand.class,
GetOtherCommand.class,
RenameCommand.class,
DeleteCommand.class,
DeleteOtherCommand.class,
GiveCommand.class,
GetRemainingCommand.class,
ExploreCommand.class,
MigrateCommand.class
ExploreOtherCommand.class,
MigrateCommand.class,
UpdateCommand.class
);
Commands.registerShortcut("maptool", NewCommand.class, "tomap");

View File

@ -1,4 +1,5 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
@ -42,16 +43,20 @@ public enum Permissions
{
NEW("imageonmap.new", "imageonmap.userender"),
LIST("imageonmap.list"),
LISTOTHER("imageonmap.listother"),
GET("imageonmap.get"),
GETOTHER("imageonmap.getother"),
RENAME("imageonmap.rename"),
REMOVE_SPLATTER_MAP("imageonmap.removesplattermap"),
DELETE("imageonmap.delete"),
DELETEOTHER("imageonmap.deleteother"),
UPDATE("imageonmap.update"),
UPDATEOTHER("imageonmap.updateother"),
ADMINISTRATIVE("imageonmap.administrative"),
BYPASS_SIZE("imageonmap.bypasssize"),
GIVE("imageonmap.give")
;
private final String permission;
private final String[] aliases;
@ -78,4 +83,4 @@ public enum Permissions
return false;
}
}
}

View File

@ -40,10 +40,13 @@ 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 fr.zcraft.zlib.tools.PluginLogger;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class IoMCommand extends Command
@ -52,7 +55,46 @@ public abstract class IoMCommand extends Command
{
return getMapFromArgs(playerSender(), 0, true);
}
//TODO:Add the quote system to zlib and refactor this
protected ImageMap getMapFromArgs(Player player, int index) throws CommandException
{
if(args.length <= index) throwInvalidArgument(I.t("You need to give a map name."));
ImageMap map;
String mapName = args[index];
for (int i = index + 1, c = args.length; i < c; i++) {
mapName += " " + args[i];
}
String regex="((\"([^\\\"]*(\\\\\\\")*)*([^\\\\\\\"]\"))|([^\\\"\\s\\\\]*(\\\\\\s)*[\\\\]*)*\"?)";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(mapName);
StringBuilder result = new StringBuilder();
matcher.find();
result.append(matcher.group(0));
if(result!=null)
if(result.charAt(0)=='\"')
if(result.length()==1){
result.deleteCharAt(0);
}
else
if(result.charAt(result.length()-1)=='\"') {
result=result.deleteCharAt(result.length() - 1);
if(result!=null&&!result.equals("")&&result.charAt(0)=='\"')
mapName=result.deleteCharAt(0).toString();
}
mapName = mapName.trim();
map = MapManager.getMap(player.getUniqueId(), mapName);
if(map == null) error(I.t("This map does not exist."));
return map;
}
protected ImageMap getMapFromArgs(Player player, int index, boolean expand) throws CommandException
{
if(args.length <= index) throwInvalidArgument(I.t("You need to give a map name."));
@ -69,7 +111,6 @@ public abstract class IoMCommand extends Command
}
mapName = mapName.trim();
map = MapManager.getMap(player.getUniqueId(), mapName);
if(map == null) error(I.t("This map does not exist."));

View File

@ -57,6 +57,20 @@ import java.util.List;
@WithFlags ({"confirm"})
public class DeleteCommand extends IoMCommand
{
private static RawText deleteMsg(Class klass,ImageMap map){
return new RawText(I.t("You are going to delete") + " ")
.then(map.getId())
.color(ChatColor.GOLD)
.then(". " + I.t("Are you sure ? "))
.color(ChatColor.WHITE)
.then(I.t("[Confirm]"))
.color(ChatColor.GREEN)
.hover(new RawText(I.t("{red}This map will be deleted {bold}forever{red}!")))
.command(klass, map.getId(), "--confirm")
.build();
}
@Override
protected void run() throws CommandException
{
@ -64,17 +78,7 @@ public class DeleteCommand extends IoMCommand
if (!hasFlag("confirm"))
{
RawText msg = new RawText(I.t("You are going to delete") + " ")
.then(map.getId())
.color(ChatColor.GOLD)
.then(". " + I.t("Are you sure ? "))
.color(ChatColor.WHITE)
.then(I.t("[Confirm]"))
.color(ChatColor.GREEN)
.hover(new RawText(I.t("{red}This map will be deleted {bold}forever{red}!")))
.command(getClass(), map.getId(), "--confirm")
.build();
RawText msg = deleteMsg(getClass(),map);
send(msg);
}
else
@ -89,7 +93,7 @@ public class DeleteCommand extends IoMCommand
}
catch (MapManagerException ex)
{
PluginLogger.warning("A non-existent map was requested to be deleted", ex);
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
warning(I.t("This map does not exist."));
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.map.ImageMap;
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.commands.WithFlags;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.PluginLogger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
@CommandInfo (name = "deleteother", usageParameters = "<player name> <map name>")
@WithFlags ({"confirm"})
public class DeleteOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
if(args.length < 2) {
warning(I.t("Not enough parameters! Usage: /maptool deleteother <playername> <mapname>"));
return;
}
Player player = null;
UUID uuid = null;
OfflinePlayer op = null;
player = Bukkit.getPlayer(args[0]);
if(player == null){
op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) uuid = op.getUniqueId();
else warning(I.t("We've never seen that player before!"));
}
else uuid = player.getUniqueId();
if(player==null){
warning(I.t("Player not found"));
return;
}
ImageMap map = getMapFromArgs(player, 1, true);
if(player != null) MapManager.clear(player.getInventory(), map);
try
{
MapManager.deleteMap(map);
info(I.t("{gray}Map successfully deleted."));
}
catch (MapManagerException ex)
{
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
warning(ChatColor.RED+(I.t("This map does not exist.")));
}
}
@Override
protected List<String> complete() throws CommandException
{
if(args.length == 1)
return getMatchingMapNames(playerSender(), args[0]);
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.DELETEOTHER.grantedTo(sender);
}
}

View File

@ -52,7 +52,7 @@ public class ExploreCommand extends IoMCommand
@Override
protected void run() throws CommandException
{
Gui.open(playerSender(), new MapListGui());
Gui.open(playerSender(), new MapListGui(playerSender()));
}
@Override

View File

@ -0,0 +1,90 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.gui.MapListGui;
import fr.zcraft.zlib.components.commands.CommandException;
import fr.zcraft.zlib.components.commands.CommandInfo;
import fr.zcraft.zlib.components.gui.Gui;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.PluginLogger;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandInfo (name = "exploreother")
public class ExploreOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
if(args.length < 1) {
warning(I.t("Not enough parameters! Usage: /maptool exploreother <playername>"));
return;
}
String name=args[0];
Player sender=playerSender();
offlinePlayerParameter(0, uuid -> {
if(uuid==null){
try {
throwInvalidArgument(I.t("Player not found."));
} catch (CommandException e) {
PluginLogger.error("CommandException "+e);
return;
}
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if (offlinePlayer != null) {
Gui.open(sender, new MapListGui(offlinePlayer, name));
}
else{
PluginLogger.warning(I.t("Can't find player"));
return;
}
});
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.LISTOTHER.grantedTo(sender);
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.components.commands.CommandException;
import fr.zcraft.zlib.components.commands.CommandInfo;
import fr.zcraft.zlib.components.i18n.I;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.UUID;
@CommandInfo (name = "getother", usageParameters = "<PlayerName> <MapName>")
public class GetOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
if(args.length < 2) {
warning(I.t("Not enough parameters! Usage: /maptool getother <playername> <mapname>"));
return;
}
Player player = null;
UUID uuid = null;
player = Bukkit.getPlayer(args[0]);
if(player == null){
OfflinePlayer op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) uuid = op.getUniqueId();
else warning(I.t("We've never seen that player before!"));
return;
}
else {
uuid = player.getUniqueId();
}
ImageMap map = null;
String mapName = "";
mapName = args[1];
if(args.length > 2) {
for(int i = 2; i < args.length; i++) {
mapName += (" " + args[i - 1]);
}
}
map = MapManager.getMap(uuid, mapName);
if(map!=null)
map.give(playerSender());
else{
warning(I.t("Unknown map {0}",mapName));
}
return;
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.GETOTHER.grantedTo(sender);
}
}

View File

@ -0,0 +1,136 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
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.text.RawMessage;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
@CommandInfo (name = "listother", usageParameters = "<PlayerName>")
public class ListOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
if(args.length < 1){
warning(I.t("Not enough parameters! Usage: /maptool listother <playername>"));
return;
}
Player player = null;
UUID uuid = null;
player = Bukkit.getPlayer(args[0]);
if(player == null){
OfflinePlayer op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) {
uuid = op.getUniqueId();
}
else {
warning(I.t("We've never seen that player before!"));
}
}
else{
uuid = player.getUniqueId();
}
List<ImageMap> mapList = null;
try{
mapList = MapManager.getMapList(uuid);
}
catch(Exception e){
return;
}
if(mapList.isEmpty())
{
info(I.t("No map found."));
return;
}
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++)
{
rawText = rawText.then(", ").color(ChatColor.GRAY);
rawText = addMap(rawText, mapList.get(i));
}
RawMessage.send(playerSender(), 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 RawText()
.then(map.getName()).style(ChatColor.BOLD, ChatColor.GREEN).then("\n")
.then(map.getId() + ", " + size).color(ChatColor.GRAY).then("\n\n")
.then(I.t("{white}Click{gray} to get this map"))
);
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.LISTOTHER.grantedTo(sender);
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2013 Moribus
* Copyright (C) 2015 ProkopyL <prokopylmc@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.commands.maptool;
import fr.moribus.imageonmap.Permissions;
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 org.bukkit.command.CommandSender;
import java.util.List;
@CommandInfo(name = "rename",usageParameters = "<original map name> <new map name>")
public class RenameCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(args.length != 4) {
warning(I.t("Not enough or too many arguments! Usage: /maptool rename <map name> <new map name>"));
return;
}
//if(args.length == 2)
//{
ImageMap map = getMapFromArgs();
map.rename(args[2]);
// } else {
// info(I.t("Not enough or too many arguments"));
// }
}
@Override
protected List<String> complete() throws CommandException
{
if(args.length == 1)
return getMatchingMapNames(playerSender(), args[0]);
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.RENAME.grantedTo(sender);
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.image.ImageRendererExecutor;
import fr.moribus.imageonmap.image.ImageUtils;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.components.commands.CommandException;
import fr.zcraft.zlib.components.commands.CommandInfo;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.components.worker.WorkerCallback;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.text.ActionBar;
import fr.zcraft.zlib.tools.text.MessageSender;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
@CommandInfo (name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
final Player player = playerSender();
ImageUtils.ScalingType scaling;
URL url;
if(args.length < 1) throwInvalidArgument(I.t("You must give an URL and a map name to update."));
if(args.length < 2) throwInvalidArgument(I.t("You must give a map name to update."));
switch(args[1]) {
case "stretched":
scaling = ImageUtils.ScalingType.STRETCHED;
break;
case "covered":
scaling = ImageUtils.ScalingType.COVERED;
break;
default:
scaling = ImageUtils.ScalingType.CONTAINED;
}
ImageMap map;
if(scaling.equals(ImageUtils.ScalingType.CONTAINED))
map=getMapFromArgs(player,1);
else
map=getMapFromArgs(player,2);
try
{
url = new URL(args[0]);
MapManager.load();
Integer[] size={1,1};
if(map.getType()== ImageMap.Type.POSTER)
size=map.getSize( new HashMap<String, Object>(),map.getUserUUID(),map.getId());
int width=size[0],height=size[1];
try {
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Updating..."));
ImageRendererExecutor.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
@Override
public void errored(Throwable exception) {
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());
}
});
}
finally {
ActionBar.removeMessage(player);
}
}
catch(MalformedURLException ex)
{
throwInvalidArgument(I.t("Invalid URL."));
}
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.UPDATE.grantedTo(sender);
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 2020)
*
* This software is a computer program whose purpose is to allow insertion of
* custom images in a Minecraft world.
*
* This software is governed by the CeCILL-B license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-B
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands.maptool;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.image.ImageRendererExecutor;
import fr.moribus.imageonmap.image.ImageUtils;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.components.commands.CommandException;
import fr.zcraft.zlib.components.commands.CommandInfo;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.components.worker.WorkerCallback;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.text.ActionBar;
import fr.zcraft.zlib.tools.text.MessageSender;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
@CommandInfo (name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
//TODO separer les deux update(update et update other)
final Player player = playerSender();
ImageUtils.ScalingType scaling;
URL url;
if(args.length < 1) throwInvalidArgument(I.t("You must give an URL and a map name to update."));
if(args.length < 2) throwInvalidArgument(I.t("You must give a map name to update."));
switch(args[1]) {
case "stretched":
scaling = ImageUtils.ScalingType.STRETCHED;
break;
case "covered":
scaling = ImageUtils.ScalingType.COVERED;
break;
default:
scaling = ImageUtils.ScalingType.CONTAINED;
}
ImageMap map;
if(scaling.equals(ImageUtils.ScalingType.CONTAINED))
map=getMapFromArgs(player,1);
else
map=getMapFromArgs(player,2);
try
{
url = new URL(args[0]);
MapManager.load();
Integer[] size={1,1};
if(map.getType()== ImageMap.Type.POSTER)
size=map.getSize( new HashMap<String, Object>(),map.getUserUUID(),map.getId());
int width=size[0],height=size[1];
try {
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Updating..."));
ImageRendererExecutor.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
@Override
public void errored(Throwable exception) {
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());
}
});
}
finally {
ActionBar.removeMessage(player);
}
}
catch(MalformedURLException ex)
{
throwInvalidArgument(I.t("Invalid URL."));
}
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.UPDATEOTHER.grantedTo(sender);
}
}

View File

@ -168,12 +168,13 @@ public class ConfirmDeleteMapGui extends ActionGui
@GuiAction ("cancel")
protected void cancel()
{
close();
close();
}
@GuiAction ("delete")
protected void delete()
{
// Does the player still have the permission to delete a map?
if (!Permissions.DELETE.grantedTo(getPlayer()))
{

View File

@ -47,21 +47,25 @@ import fr.zcraft.zlib.components.gui.GuiAction;
import fr.zcraft.zlib.components.gui.PromptGui;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.Callback;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
public class MapDetailGui extends ExplorerGui<Integer>
{
private final ImageMap map;
private OfflinePlayer p;
private String name;
public MapDetailGui(ImageMap map)
{
this.map = map;
public MapDetailGui(ImageMap map, OfflinePlayer p, String name){
this.map=map;
this.p=p;
this.name=name;
}
@Override
protected ItemStack getViewItem(int x, int y)
{
@ -102,7 +106,7 @@ public class MapDetailGui extends ExplorerGui<Integer>
if (map instanceof SingleMap)
{
return MapItemManager.createMapItem((SingleMap)map);
return MapItemManager.createMapItem((SingleMap)map,true);
}
else if (map instanceof PosterMap)
{
@ -136,7 +140,12 @@ public class MapDetailGui extends ExplorerGui<Integer>
protected void onUpdate()
{
/// Title of the map details GUI
setTitle(I.t(getPlayerLocale(), "Your maps » {black}{0}", map.getName()));
if(p.getUniqueId().equals(getPlayer().getUniqueId())) {
setTitle(I.t(getPlayerLocale(), "Your maps » {black}{0}", map.getName()));
}
else{
setTitle(I.t(getPlayerLocale(), "{1}'s maps » {black}{0}", map.getName(),name));
}
setKeepHorizontalScrollingSpace(true);
if (map instanceof PosterMap)
@ -242,7 +251,6 @@ public class MapDetailGui extends ExplorerGui<Integer>
update();
return;
}
Gui.open(getPlayer(), new ConfirmDeleteMapGui(map), this);
}

View File

@ -49,12 +49,25 @@ import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
public class MapListGui extends ExplorerGui<ImageMap>
{
private OfflinePlayer p;
private String name;
public MapListGui(Player sender){
this.p=sender;
this.name=sender.getName();
}
public MapListGui(OfflinePlayer p,String name){
this.p=p;
this.name=name;
}
@Override
protected ItemStack getViewItem(ImageMap map)
{
@ -106,23 +119,29 @@ public class MapListGui extends ExplorerGui<ImageMap>
@Override
protected ItemStack getEmptyViewItem()
{
ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER)
.title(I.tl(getPlayerLocale(), "{red}You don't have any map."));
ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER);
if(p.getUniqueId().equals(getPlayer().getUniqueId())) {
if (Permissions.NEW.grantedTo(getPlayer()))
builder.longLore(I.tl(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!"));
else
builder.longLore(I.tl(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one."));
builder.title(I.tl(getPlayerLocale(), "{red}You don't have any map."));
if (Permissions.NEW.grantedTo(getPlayer()))
builder.longLore(I.tl(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!"));
else
builder.longLore(I.tl(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one."));
}
else{
builder.title(I.tl(getPlayerLocale(), "{red}{0} doesn't have any map.",name));
}
return builder.item();
}
@Override
protected void onRightClick(ImageMap data)
{
Gui.open(getPlayer(), new MapDetailGui(data), this);
Gui.open(getPlayer(), new MapDetailGui(data,getPlayer(),name), this);
}
@Override
protected ItemStack getPickedUpItem(ImageMap map)
{
@ -131,7 +150,7 @@ public class MapListGui extends ExplorerGui<ImageMap>
if (map instanceof SingleMap)
{
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false);
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false,true);
}
else if (map instanceof PosterMap)
{
@ -151,19 +170,22 @@ public class MapListGui extends ExplorerGui<ImageMap>
@Override
protected void onUpdate()
{
ImageMap[] maps = MapManager.getMaps(getPlayer().getUniqueId());
ImageMap[] maps = MapManager.getMaps(p.getUniqueId());
setData(maps);
/// The maps list GUI title
setTitle(I.tl(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length));
//Equal if the person who send the command is the owner of the mapList
if(p.getUniqueId().equals(getPlayer().getUniqueId()))
setTitle(I.tl(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length));
else
setTitle(I.tl(getPlayerLocale(), "{black}{1}'s maps {reset}({0})", maps.length, name ));
setKeepHorizontalScrollingSpace(true);
/* ** Statistics ** */
int imagesCount = MapManager.getMapList(getPlayer().getUniqueId()).size();
int mapPartCount = MapManager.getMapPartCount(getPlayer().getUniqueId());
int imagesCount = MapManager.getMapList(p.getUniqueId()).size();
int mapPartCount = MapManager.getMapPartCount(p.getUniqueId());
int mapGlobalLimit = PluginConfiguration.MAP_GLOBAL_LIMIT.get();
int mapPersonalLimit = PluginConfiguration.MAP_PLAYER_LIMIT.get();

View File

@ -68,7 +68,6 @@ public class ImageRendererExecutor extends Worker {
if (connection instanceof HttpURLConnection) {
final HttpURLConnection httpConnection = (HttpURLConnection) connection;
final int httpCode = httpConnection.getResponseCode();
if ((httpCode / 100) != 2) {
throw new IOException(I.t("HTTP error: {0} {1}", httpCode, httpConnection.getResponseMessage()));
}
@ -76,8 +75,30 @@ public class ImageRendererExecutor extends Worker {
return connection;
}
static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback<ImageMap> callback) {
submitQuery(new WorkerRunnable<ImageMap>() {
static private void checkSizeLimit(final UUID playerUUID, final BufferedImage image) throws IOException {
if ((PluginConfiguration.LIMIT_SIZE_X.get() > 0 || PluginConfiguration.LIMIT_SIZE_Y.get() > 0) && !Permissions.BYPASS_SIZE.grantedTo(Bukkit.getPlayer(playerUUID)))
{
if (PluginConfiguration.LIMIT_SIZE_X.get() > 0)
{
if (image.getWidth() > PluginConfiguration.LIMIT_SIZE_X.get())
throw new IOException(I.t("The image is too wide!"));
}
if (PluginConfiguration.LIMIT_SIZE_Y.get() > 0)
{
if (image.getHeight() > PluginConfiguration.LIMIT_SIZE_Y.get())
throw new IOException(I.t("The image is too tall!"));
}
}
}
private enum extension{
png, jpg, jpeg, gif
}
static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback<ImageMap> callback)
{
submitQuery(new WorkerRunnable<ImageMap>()
{
@Override
public ImageMap run() throws Throwable {
@ -110,29 +131,16 @@ public class ImageRendererExecutor extends Worker {
}
//If not an Imgur link
else {
//Try connecting
URLConnection connection = connecting(url);
final InputStream stream = connection.getInputStream();
image = ImageIO.read(stream);
}
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
// Limits are in place and the player does NOT have rights to avoid them.
if ((PluginConfiguration.LIMIT_SIZE_X.get() > 0 || PluginConfiguration.LIMIT_SIZE_Y.get() > 0) && !Permissions.BYPASS_SIZE.grantedTo(Bukkit.getPlayer(playerUUID))) {
if (PluginConfiguration.LIMIT_SIZE_X.get() > 0) {
if (image.getWidth() > PluginConfiguration.LIMIT_SIZE_X.get())
throw new IOException(I.t("The image is too wide!"));
}
if (PluginConfiguration.LIMIT_SIZE_Y.get() > 0) {
if (image.getHeight() > PluginConfiguration.LIMIT_SIZE_Y.get())
throw new IOException(I.t("The image is too tall!"));
}
}
checkSizeLimit(playerUUID, image);
if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) {
ImageMap ret = renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID);
image.flush();//Safe to free
@ -140,13 +148,62 @@ public class ImageRendererExecutor extends Worker {
}
final BufferedImage resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
image.flush();//Safe to free
return renderPoster(resizedImage, playerUUID);
}
}, callback);
}
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable {
public static void update(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final ImageMap map, final int width, final int height, WorkerCallback<ImageMap> callback) {
submitQuery(new WorkerRunnable<ImageMap>()
{
@Override
public ImageMap run() throws Throwable
{
final URLConnection connection = connecting(url);
final InputStream stream = connection.getInputStream();
final BufferedImage image = ImageIO.read(stream);
stream.close();
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
// Limits are in place and the player does NOT have rights to avoid them.
checkSizeLimit(playerUUID, image);
updateMap(scaling.resize(image, width*128, height*128),playerUUID,map.getMapsIDs());
return map;
}
}, callback);
}
static private void updateMap(final BufferedImage image, final UUID playerUUID,int[] mapsIDs) throws Throwable
{
final PosterImage poster = new PosterImage(image);
poster.splitImages();
ImageIOExecutor.saveImage(mapsIDs, poster);
if (PluginConfiguration.SAVE_FULL_IMAGE.get())
{
ImageIOExecutor.saveImage(ImageMap.getFullImageFile(mapsIDs[0], mapsIDs[mapsIDs.length - 1]), image);
}
submitToMainThread(new Callable<Void>()
{
@Override
public Void call() throws Exception
{
Renderer.installRenderer(poster, mapsIDs);
return null;
}
});
}
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
{
MapManager.checkMapLimit(1, playerUUID);
final Future<Integer> futureMapID = submitToMainThread(new Callable<Integer>() {
@Override
@ -178,6 +235,8 @@ public class ImageRendererExecutor extends Worker {
}
});
poster.splitImages();
final int[] mapsIDs = futureMapsIds.get();
ImageIOExecutor.saveImage(mapsIDs, poster);
final int[] mapsIDs = futureMapsIds.get();

View File

@ -40,6 +40,7 @@ import fr.moribus.imageonmap.ImageOnMap;
import fr.moribus.imageonmap.ui.MapItemManager;
import fr.zcraft.zlib.components.i18n.I;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
@ -47,6 +48,7 @@ import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -150,7 +152,23 @@ public abstract class ImageMap implements ConfigurationSerializable
this.postSerialize(map);
return map;
}
static public Integer[] getSize(Map<String, Object> map, UUID playerUUID, String id){
ConfigurationSection section=MapManager.getPlayerMapStore(playerUUID).getToolConfig().getConfigurationSection("PlayerMapStore");
if(section == null) return null;
List<Map<String, Object>> list = (List<Map<String, Object>>) section.getList("mapList");
if(list == null) return null;
for(Map<String, Object> tMap : list)
{
if(tMap.get("id").equals(id)) {
return new Integer[]{(Integer)tMap.get("columns"), (Integer)tMap.get("rows")};
}
}
return null;
}
static protected <T> T getFieldValue(Map<String, Object> map, String fieldName) throws InvalidConfigurationException
{
T value = getNullableFieldValue(map, fieldName);

View File

@ -106,7 +106,7 @@ abstract public class MapManager
addMap(newMap);
return newMap;
}
static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException
{
ImageMap newMap;
@ -122,7 +122,7 @@ abstract public class MapManager
addMap(newMap);
return newMap;
}
static public int[] getNewMapsIds(int amount)
{
int[] mapsIds = new int[amount];
@ -161,7 +161,7 @@ abstract public class MapManager
getPlayerMapStore(map.getUserUUID()).deleteMap(map);
ImageIOExecutor.deleteImage(map);
}
static public void notifyModification(UUID playerUUID)
{
getPlayerMapStore(playerUUID).notifyModification();
@ -376,7 +376,7 @@ abstract public class MapManager
}
}
static private PlayerMapStore getPlayerMapStore(UUID playerUUID)
static public PlayerMapStore getPlayerMapStore(UUID playerUUID)
{
PlayerMapStore store;
synchronized(playerMaps)

View File

@ -256,7 +256,7 @@ public class PlayerMapStore implements ConfigurationSerializable
private FileConfiguration mapConfig = null;
private File mapsFile = null;
private FileConfiguration getToolConfig()
public FileConfiguration getToolConfig()
{
if(mapConfig == null) load();

View File

@ -36,6 +36,7 @@
package fr.moribus.imageonmap.ui;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.map.PosterMap;
@ -45,6 +46,7 @@ import fr.zcraft.zlib.core.ZLib;
import fr.zcraft.zlib.tools.items.ItemStackBuilder;
import fr.zcraft.zlib.tools.items.ItemUtils;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -87,7 +89,7 @@ public class MapItemManager implements Listener
static public boolean give(Player player, SingleMap map)
{
return give(player, createMapItem(map));
return give(player, createMapItem(map,true));
}
static public boolean give(Player player, PosterMap map)
@ -137,12 +139,16 @@ public class MapItemManager implements Listener
return !given;
}
static public ItemStack createMapItem(SingleMap map)
{
return createMapItem(map.getMapsIDs()[0], map.getName(), false);
}
static public ItemStack createMapItem(SingleMap map, boolean goldTitle)
{
return createMapItem(map.getMapsIDs()[0], map.getName(), false, goldTitle);
}
static public ItemStack createMapItem(PosterMap map, int index)
{
return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true);
@ -165,20 +171,31 @@ public class MapItemManager implements Listener
return I.t("{0} (part {1})", map.getName(), index + 1);
}
static public ItemStack createMapItem(int mapID, String text, boolean isMapPart)
static public ItemStack createMapItem(int mapID, String text, boolean isMapPart, boolean goldTitle)
{
final ItemStack mapItem = new ItemStackBuilder(Material.FILLED_MAP)
.title(text)
.hideAttributes()
.item();
ItemStack mapItem;
if(goldTitle) {
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
.title( ChatColor.GOLD, text)
.hideAttributes()
.item();
}
else{
mapItem= new ItemStackBuilder(Material.FILLED_MAP)
.title(text)
.hideAttributes()
.item();
}
final MapMeta meta = (MapMeta) mapItem.getItemMeta();
meta.setMapId(mapID);
meta.setColor(isMapPart ? Color.LIME : Color.GREEN);
mapItem.setItemMeta(meta);
return mapItem;
}
static public ItemStack createMapItem(int mapID, String text, boolean isMapPart)
{
return createMapItem( mapID, text, isMapPart,false);
}
/**
* Returns the item to place to display the (col;row) part of the given poster.
@ -247,18 +264,22 @@ public class MapItemManager implements Listener
if (frame.getItem().getType() != Material.AIR) return;
if (!MapManager.managesMap(mapItem)) return;
if (SplatterMapManager.hasSplatterAttributes(mapItem))
{
if (!SplatterMapManager.placeSplatterMap(frame, player,event)){
event.setCancelled(true); //In case of an error allow to cancel map placement
return;}
return;
}
if(frame.getFacing()!= BlockFace.UP&&frame.getFacing()!= BlockFace.DOWN)
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
}
else
{
if(frame.getFacing()!= BlockFace.UP&&frame.getFacing()!= BlockFace.DOWN)
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
// If the item has a display name, bot not one from an anvil by the player, we remove it
// If it is not displayed on hover on the wall.
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName() && mapItem.getItemMeta().getDisplayName().startsWith("§r"))
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName() && mapItem.getItemMeta().getDisplayName().startsWith("§6"))
{
final ItemStack frameItem = mapItem.clone();
@ -285,17 +306,20 @@ public class MapItemManager implements Listener
ItemStack item = frame.getItem();
if (frame.getItem().getType() != Material.FILLED_MAP) return;
if (player.isSneaking())
if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player))
{
PosterMap poster = SplatterMapManager.removeSplatterMap(frame,player);
if (poster != null)
if (player.isSneaking())
{
event.setCancelled(true);
PosterMap poster = SplatterMapManager.removeSplatterMap(frame,player);
if (poster != null)
{
event.setCancelled(true);
if (player.getGameMode() != GameMode.CREATIVE || !SplatterMapManager.hasSplatterMap(player, poster))
poster.give(player);
if (player.getGameMode() != GameMode.CREATIVE || !SplatterMapManager.hasSplatterMap(player, poster))
poster.give(player);
return;
return;
}
}
}

View File

@ -298,10 +298,7 @@ abstract public class SplatterMapManager {
frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
//Force reset of rotation
if(i==0){//First map need to be rotate one time Clockwise
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
}
else{frame.setRotation(Rotation.NONE);}
frame.setRotation(Rotation.NONE);
MapInitEvent.initMap(id);
++i;
}

View File

@ -2,7 +2,7 @@
# Plugin language. Empty: system language.
# Available: en-US (default, fallback), fr-FR, ru-RU, de-DE.
# Available: en-US (default, fallback), fr-FR, ru-RU, de-DE, zh-CN, ja-JP.
lang:

View File

@ -2,9 +2,13 @@ This command manages and creates ImagesOnMaps.
new: Creates a new ImageOnMap
delete: Deletes a map.
delete-noconfirm: Deletes a map. Deletion is permanent and made without confirmation
deleteother: Deletes another map.
get: Gives you a map.
getother: Gets another player's map.
getremaining: Gives you the remaining maps that could not fit in your inventory
list: Lists all the map you currently have.
listother: list all the map of another player.
explore: Opens a GUI to see and manage your maps.
exploreother: Opens a GUI to see and manage another player maps.
migrate: Lauches the migration process from V2.7 to V3.x.
help : Use help for more information about a command.
help : Use help for more information about a command.

View File

@ -0,0 +1,4 @@
Gets another player's map.
§6<playername>: §rThe name of the player who owns the map.
§6<mapname>: §rThe name of the map. Use /maptool listother to get map names.

View File

@ -0,0 +1,3 @@
Lists another player's maps.
§6<playername>: §rThe name of the player you want to list map from.

View File

@ -593,3 +593,12 @@ msgstr ""
#: 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}There is not enough space to place this map ({0} × {1})."
#New part, added for update (TODO add to other .po file
#: src/main/java/fr/moribus/imageonmap/commands/maptool/UpdateCommand.java:71
msgid "{ce}You must give an URL and a map name to update."
msgstr "{ce}You must give an URL and a map name to update."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/UpdateCommand.java:72
msgid "{ce}You must give a map name to update.."
msgstr "{ce}You must give a map name to update.."

View File

@ -568,3 +568,12 @@ msgstr "Carte"
#~ 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/commands/maptool/UpdateCommand.java:71
msgid "{ce}You must give an URL and a map name to update."
msgstr "{ce}Veuillez donner une URL et un nom de carte a update."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/UpdateCommand.java:72
msgid "{ce}You must give a map name to update."
msgstr "{ce}Veuillez un nom de carte a update"

View File

@ -0,0 +1,594 @@
# 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: 2020-07-27 21:02+0200\n"
"PO-Revision-Date: 2020-07-27 21:38+0200\n"
"Last-Translator: Kotlia\n"
"Language-Team: \n"
"Language: ja_JP\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 > 1);\n"
"X-Generator: Poedit 1.8.7.1\n"
#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:40
msgid "You need to give a map name."
msgstr "マップ名が必要です!"
#: 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 "このマップは存在しません"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:39
msgid "You are going to delete"
msgstr "これを削除します"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:42
msgid "Are you sure ? "
msgstr "大丈夫ですか?"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:44
msgid "[Confirm]"
msgstr "[確定]"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:46
msgid "{red}This map will be deleted {bold}forever{red}!"
msgstr "{red}このマップは {bold}復元不可能になります{red}!"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:46
msgid "Map successfully deleted."
msgstr "削除に成功しました"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:38
msgid "The requested map was too big to fit in your inventory."
msgstr "マップのサイズがインベントリに対して大きすぎます"
#: 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 "残りのマップを取得するには '/maptool getremaining' を実行して下さい。"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:38
msgid "You have no remaining map."
msgstr "残りのマップは存在しません"
#: 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 ""
"インベントリが一杯です!"
#: 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] "残り {0} 枚のマップが残っています"
msgstr[1] "残り {0} 枚のマップが残っています"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:49
msgid "No map found."
msgstr "マップが見つかりませんでした"
#: 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} 枚のマップを発見しました"
msgstr[1] "{white}{bold}{0} 枚のマップを発見しました"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:79
msgid "{white}Click{gray} to get this map"
msgstr "{gray}マップを取得するには{white}ここをクリック"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:36
msgid "A migration process is already running. Check console for details."
msgstr "移行中...コンソールで詳細を確認できます"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:40
msgid "Migration started. See console for details."
msgstr "移行開始...コンソールで詳細を確認できます"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:44
msgid "You must give an URL to take the image from."
msgstr "画像URLが必要です"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:52
msgid "Invalid URL."
msgstr "無効なURLです"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:61
msgid "Rendering..."
msgstr "レンダリング中..."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:67
msgid "Rendering finished!"
msgstr "レンダリング完了!"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:70
msgid "The rendered map was too big to fit in your inventory."
msgstr "レンダリングされたマップはインベントリに対して大きすぎます!"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:78
msgid "{ce}Map rendering failed: {0}"
msgstr "{ce}レンダリング失敗: {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}削除確認"
#. 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}このマップを破壊しようとしています..."
#. 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}永遠{red}."
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:114
msgid "{gray}Name: {white}{0}"
msgstr "{gray}名前: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:115
msgid "{gray}Map ID: {white}{0}"
msgstr "{gray}マップ ID: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:116
msgid "{gray}Maps inside: {white}{0}"
msgstr "{gray}マップ: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:178
msgid "{gray}Map successfully deleted."
msgstr "{gray}マップの削除に成功しました"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:54
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:71
msgid "{green}Map part"
msgstr "{green}マップ部分"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:55
msgid "{gray}Column: {white}{0}"
msgstr "{gray}縦: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:56
msgid "{gray}Row: {white}{0}"
msgstr "{gray}横: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:58
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:74
msgid "{gray}» {white}Click{gray} to get only this part"
msgstr "{gray}» {gray} ここだけを入手するには {white}クリック"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:72
msgid "{gray}Part: {white}{0}"
msgstr "{gray}部分: {white}{0}"
#. Title of the map details GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:114
msgid "Your maps » {black}{0}"
msgstr "あなたのマップ » {black}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:136
msgid "{blue}Rename this image"
msgstr "{blue}このイメージの名前を変更"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:137
msgid ""
"{gray}Click here to rename this image; this is used for your own "
"organization."
msgstr ""
"{gray}このイメージの名前を変更...自分のみに反映されます"
""
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:141
msgid "{red}Delete this image"
msgstr "{red}この写真を削除"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:142
msgid ""
"{gray}Deletes this map {white}forever{gray}. This action cannot be undone!"
msgstr ""
"{white}削除・永久{gray} {gray}に復旧出来ません。"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:144
msgid "{gray}You will be asked to confirm your choice if you click here."
msgstr "{gray}You will be asked to confirm your choice if you click here."
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:156
msgid "{green}« Back"
msgstr "{green}« 戻る"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:157
msgid "{gray}Go back to the list."
msgstr "{gray}表に戻る"
#. Displayed subtitle description of a single map on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:44
msgid "{white}Single map"
msgstr "{white}一つのマップ"
#. Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:52
msgid "{white}Poster map ({0} × {1})"
msgstr "{white}ポスターマップ ({0} × {1})"
#. Displayed subtitle description of a poster map without column data on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:57
msgid "{white}Poster map ({0} parts)"
msgstr "{white}ポスターマップ ({0} 部分)"
#. Displayed title of a map on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:62
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:67
msgid "{gray}Map ID: {0}"
msgstr "{gray}マップ ID: {0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:69
msgid "{gray}» {white}Left-click{gray} to get this map"
msgstr "{gray}» {white}左クリック{gray} でこのマップを入手"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:70
msgid "{gray}» {white}Right-click{gray} for details and options"
msgstr "{gray}» {white}右クリック{gray} で詳細を表示"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:79
msgid "{red}You don't have any map."
msgstr "{red}あなたはマップを持っていません!"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:80
msgid ""
"{gray}Get started by creating a new one using {white}/tomap <URL> [resize]"
"{gray}!"
msgstr ""
"{gray}まずは作ってみましょう!コマンド: {white}/tomap <URL> [resize]"
"{gray}!"
#. The maps list GUI title
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:119
msgid "{black}Your maps {reset}({0})"
msgstr "{black}あなたのマップ {reset}({0})"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:148
msgid "{blue}Usage statistics"
msgstr "{blue}あなたの統計情報"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:150
msgid "{white}{0}{gray} image rendered"
msgid_plural "{white}{0}{gray} images rendered"
msgstr[0] "{white}{0}{gray} 画像レンダリング完了"
msgstr[1] "{white}{0}{gray} 画像レンダリング完了"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:151
msgid "{white}{0}{gray} Minecraft map used"
msgid_plural "{white}{0}{gray} Minecraft maps used"
msgstr[0] "{white}{0}{gray} 使用したマップ"
msgstr[1] "{white}{0}{gray} 使用したマップ"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:156
msgid "{blue}Minecraft maps limits"
msgstr "{blue}minecraftマップリミット"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:158
msgid "{gray}Server-wide limit: {white}unlimited"
msgstr "{gray}Server-wide limit: {white}unlimited"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:159
msgid "{gray}Server-wide limit: {white}{0}"
msgstr "{gray}Server-wide limit: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:161
msgid "{gray}Per-player limit: {white}unlimited"
msgstr "{gray}Per-player limit: {white}unlimited"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:162
msgid "{gray}Per-player limit: {white}{0}"
msgstr "{gray}Per-player limit: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:164
msgid "{white}{0} %{gray} of your quota used"
msgstr "{white}{0} %{gray} of your quota used"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:165
msgid "{white}{0}{gray} map left"
msgid_plural "{white}{0}{gray} maps left"
msgstr[0] "{white}{0}{gray} map left"
msgstr[1] "{white}{0}{gray} maps left"
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:73
#, java-format
msgid "HTTP error : {0} {1}"
msgstr "HTTP error : {0} {1}"
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:79
msgid "The given URL is not a valid image"
msgstr "これは有効な画像URLではありません"
#. The default display name of a map
#: src/main/java/fr/moribus/imageonmap/map/ImageMap.java:44
msgid "Map"
msgstr "マップ"
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:29
#, java-format
msgid "You have too many maps (maximum : {0})."
msgstr "保有するマップが多すぎます! (maximum : {0})."
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:30
msgid "The server ImageOnMap limit has been reached."
msgstr "The server ImageOnMap limit has been reached."
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:31
msgid "The given map does not exist."
msgstr "マップが存在しません."
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:34
msgid "Migration is already running."
msgstr "移行は実行中です"
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:50
msgid "Waiting for migration to finish..."
msgstr "移行終了待ち..."
#: 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 ""
"Migration thread has been interrupted while waiting to finish. It may not "
"have ended correctly."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:176
msgid "Error while preparing migration"
msgstr "Error while preparing migration"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:177
msgid "Aborting migration. No change has been made."
msgstr "Aborting migration. No change has been made."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:189
msgid "Error while migrating"
msgstr "Error while migrating"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:190
msgid "Aborting migration. Some changes may already have been made."
msgstr "Aborting migration. Some changes may already have been made."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:191
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 ""
"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."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:203
msgid "Looking for configuration files to migrate..."
msgstr "Looking for configuration files to migrate..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:206
#, java-format
msgid "Detected former posters file {0}"
msgstr "Detected former posters file {0}"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:209
#, java-format
msgid "Detected former maps file {0}"
msgstr "Detected former maps file {0}"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:213
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:416
msgid "There is nothing to migrate. Stopping."
msgstr "There is nothing to migrate. Stopping."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:218
msgid "Done."
msgstr "Done."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:232
msgid "Backup directories already exists."
msgstr "Backup directories already exists."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:233
msgid ""
"This means that a migration has already been done, or may not have ended "
"well."
msgstr ""
"This means that a migration has already been done, or may not have ended "
"well."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:234
msgid ""
"To start a new migration, you must move away the backup directories so they "
"are not overwritten."
msgstr ""
"To start a new migration, you must move away the backup directories so they "
"are not overwritten."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:247
msgid "Backing up map data before migrating..."
msgstr "Backing up map data before migrating..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:271
msgid "Backup complete."
msgstr "Backup complete."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:352
msgid "Fetching UUIDs from Mojang..."
msgstr "Fetching UUIDs from Mojang..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:359
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:387
msgid "An error occurred while fetching the UUIDs from Mojang"
msgstr "An error occurred while fetching the UUIDs from Mojang"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:364
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:392
msgid "The migration worker has been interrupted"
msgstr "The migration worker has been interrupted"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:367
#, java-format
msgid "Fetching done. {0} UUID have been retrieved."
msgid_plural "Fetching done. {0} UUIDs have been retrieved."
msgstr[0] "Fetching done. {0} UUID have been retrieved."
msgstr[1] "Fetching done. {0} UUIDs have been retrieved."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:378
#, 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 did not find UUIDs for {0} player at the current time."
msgstr[1] "Mojang did not find UUIDs for {0} players at the current time."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:379
msgid ""
"The Mojang servers limit requests rate at one per second, this may take some "
"time..."
msgstr ""
"The Mojang servers limit requests rate at one per second, this may take some "
"time..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:398
#, 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 did not find player data for {0} player"
msgstr[1] "Mojang did not find player data for {0} players"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:400
msgid "The following players do not exist or do not have paid accounts :"
msgstr "The following players do not exist or do not have paid accounts :"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:415
msgid "Mojang could not find any of the registered players."
msgstr "Mojang could not find any of the registered players."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:425
msgid "Merging map data..."
msgstr "Merging map data..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:475
#, java-format
msgid "{0} registered minecraft map is missing from the save."
msgid_plural "{0} registered minecraft maps are missing from the save."
msgstr[0] "{0} registered minecraft map is missing from the save."
msgstr[1] "{0} registered minecraft maps are missing from the save."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:476
msgid ""
"These maps will not be migrated, but this could mean the save has been "
"altered or corrupted."
msgstr ""
"These maps will not be migrated, but this could mean the save has been "
"altered or corrupted."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:477
#, java-format
msgid "The following maps are missing : {0} "
msgstr "The following maps are missing : {0} "
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:483
msgid "Saving changes..."
msgstr "Saving changes..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:489
msgid "Cleaning up old data files..."
msgstr "Cleaning up old data files..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:496
msgid "Deleting old map data file..."
msgstr "Deleting old map data file..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:501
#, java-format
msgid "{0} map could not be migrated."
msgid_plural "{0} maps could not be migrated."
msgstr[0] "{0} map could not be migrated."
msgstr[1] "{0} maps could not be migrated."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:519
msgid "Deleting old poster data file..."
msgstr "Deleting old poster data file..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:524
#, java-format
msgid "{0} poster could not be migrated."
msgid_plural "{0} posters could not be migrated."
msgstr[0] "{0} poster could not be migrated."
msgstr[1] "{0} posters could not be migrated."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:537
msgid "Data that has not been migrated will be kept in the old data files."
msgstr "Data that has not been migrated will be kept in the old data files."
#. The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:139
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:215
#, java-format
msgid "{0} (part {1})"
msgstr "{0} (部分 {1})"
#. 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:145
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:213
#, java-format
msgid "{0} (row {1}, column {2})"
msgstr "{0} (横 {1}, 縦 {2})"
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:44
msgid "Splatter Map"
msgstr "拡散マップ"
#. Title in a splatter map tooltip
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:48
msgid "Item frames needed"
msgstr "アイテムフレームが必要です"
#. Size of a map stored in a splatter map
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:56
#, java-format
msgid "{0} × {1}"
msgstr "横: {0} × 縦: {1}"
#. Size of a map stored in a splatter map, including the total frames count
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:62
#, java-format
msgid "{0} × {1} (total {2} frames)"
msgstr "横: {0} × 縦: {1} (合計 {2} フレーム)"
#. Title in a splatter map tooltip
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:53
msgid "How to use this?"
msgstr "これをどうやって使いますか?"
#: 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 ""
"アイテムフレームを空にしてから、マップが必要な分のフレームを設置してから、左下のフレームを右クリックして下さい。"
#: 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 ""
"シフトクリックでマップを一括削除できます"
#: 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}このマップを設置するのに十分なスペースがありません! (横: {0} × 縦: {1})"

View File

@ -0,0 +1,595 @@
# 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-07-10 03:07+0200\n"
"PO-Revision-Date: 2016-07-10 03:08+0200\n"
"Last-Translator: Souir_Tommer\n"
"Language-Team: \n"
"Language: zh_CN\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 > 1);\n"
"X-Generator: Poedit 1.8.7.1\n"
#: src/main/java/fr/moribus/imageonmap/commands/IoMCommand.java:40
msgid "You need to give a map name."
msgstr "你需要提供名称"
#: 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 "该地图不存在"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:39
msgid "You are going to delete"
msgstr "你将要删除"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:42
msgid "Are you sure ? "
msgstr "你确定吗? "
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:44
msgid "[Confirm]"
msgstr "[确定]"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java:46
msgid "{red}This map will be deleted {bold}forever{red}!"
msgstr "{red}这个地图将会永久 {bold}删除{red}!"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteNoConfirmCommand.java:46
msgid "Map successfully deleted."
msgstr "地图已成功删除"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetCommand.java:38
msgid "The requested map was too big to fit in your inventory."
msgstr "请求的地图太大,无法容纳到您的背包中"
#: 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 "Use '/maptool getremaining' to get the remaining maps."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/GetRemainingCommand.java:38
msgid "You have no remaining map."
msgstr "你没有剩余的地图"
#: 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 ""
"你的背包已满!"
#: 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] "剩余 {0} 张地图"
msgstr[1] "剩余 {0} 张地图"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:49
msgid "No map found."
msgstr "找不到地图"
#: 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} 地图"
msgstr[1] "{white}{bold}{0} 地图"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java:79
msgid "{white}Click{gray} to get this map"
msgstr "{white}点击{gray} 得到这张地图"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:36
msgid "A migration process is already running. Check console for details."
msgstr "进程已在运行..请等待"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/MigrateCommand.java:40
msgid "Migration started. See console for details."
msgstr "开始..."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:44
msgid "You must give an URL to take the image from."
msgstr "您必须提供URL才能从中获取图像"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:52
msgid "Invalid URL."
msgstr "无效的网址"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:61
msgid "Rendering..."
msgstr "渲染..."
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:67
msgid "Rendering finished!"
msgstr "渲染完成!"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:70
msgid "The rendered map was too big to fit in your inventory."
msgstr "渲染的地图太大"
#: src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java:78
msgid "{ce}Map rendering failed: {0}"
msgstr "{ce}地图渲染失败: {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}确认删除"
#. 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}您将要销毁这张地图..."
#. 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}永久{red}."
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:114
msgid "{gray}Name: {white}{0}"
msgstr "{gray}名称: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:115
msgid "{gray}Map ID: {white}{0}"
msgstr "{gray}地图 ID: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:116
msgid "{gray}Maps inside: {white}{0}"
msgstr "{gray}地图: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java:178
msgid "{gray}Map successfully deleted."
msgstr "{gray}地图已成功删除"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:54
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:71
msgid "{green}Map part"
msgstr "{green}地图部分"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:55
msgid "{gray}Column: {white}{0}"
msgstr "{gray}高: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:56
msgid "{gray}Row: {white}{0}"
msgstr "{gray}宽: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:58
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:74
msgid "{gray}» {white}Click{gray} to get only this part"
msgstr "{gray}» {white}点击{gray} 得到这部分"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:72
msgid "{gray}Part: {white}{0}"
msgstr "{gray}部分: {white}{0}"
#. Title of the map details GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:114
msgid "Your maps » {black}{0}"
msgstr "你的地图 » {black}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:136
msgid "{blue}Rename this image"
msgstr "{blue}重命名这张图片"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:137
msgid ""
"{gray}Click here to rename this image; this is used for your own "
"organization."
msgstr ""
"{gray}点击此处重命名该图像; 这只对自己生效"
""
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:141
msgid "{red}Delete this image"
msgstr "{red}删除这张图片"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:142
msgid ""
"{gray}Deletes this map {white}forever{gray}. This action cannot be undone!"
msgstr ""
"{white}永久{gray} {gray}删除这张地图,此操作无法撤消!"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:144
msgid "{gray}You will be asked to confirm your choice if you click here."
msgstr "{gray}You will be asked to confirm your choice if you click here."
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:156
msgid "{green}« Back"
msgstr "{green}« 返回"
#: src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java:157
msgid "{gray}Go back to the list."
msgstr "{gray}返回到列表"
#. Displayed subtitle description of a single map on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:44
msgid "{white}Single map"
msgstr "{white}单张地图"
#. Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:52
msgid "{white}Poster map ({0} × {1})"
msgstr "{white}地图大小 ({0} × {1})"
#. Displayed subtitle description of a poster map without column data on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:57
msgid "{white}Poster map ({0} parts)"
msgstr "{white}地图大小 ({0} 部分)"
#. Displayed title of a map on the list GUI
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:62
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:67
msgid "{gray}Map ID: {0}"
msgstr "{gray}地图 ID: {0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:69
msgid "{gray}» {white}Left-click{gray} to get this map"
msgstr "{gray}» {white}左击{gray} 获得地图"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:70
msgid "{gray}» {white}Right-click{gray} for details and options"
msgstr "{gray}» {white}右击{gray} 打开更多设置"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:79
msgid "{red}You don't have any map."
msgstr "{red}你还没有任何地图"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:80
msgid ""
"{gray}Get started by creating a new one using {white}/tomap <URL> [resize]"
"{gray}!"
msgstr ""
"{gray}使用指令创建地图吧 {white}/tomap <URL> [resize]"
"{gray}!"
#. The maps list GUI title
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:119
msgid "{black}Your maps {reset}({0})"
msgstr "{black}你的地图 {reset}({0})"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:148
msgid "{blue}Usage statistics"
msgstr "{blue}使用状态"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:150
msgid "{white}{0}{gray} image rendered"
msgid_plural "{white}{0}{gray} images rendered"
msgstr[0] "{white}{0}{gray} 渲染地图"
msgstr[1] "{white}{0}{gray} 渲染地图"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:151
msgid "{white}{0}{gray} Minecraft map used"
msgid_plural "{white}{0}{gray} Minecraft maps used"
msgstr[0] "{white}{0}{gray} 张地图用量"
msgstr[1] "{white}{0}{gray} 张地图用量"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:156
msgid "{blue}Minecraft maps limits"
msgstr "{blue}minecraft地图限制"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:158
msgid "{gray}Server-wide limit: {white}unlimited"
msgstr "{gray}Server-wide limit: {white}unlimited"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:159
msgid "{gray}Server-wide limit: {white}{0}"
msgstr "{gray}Server-wide limit: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:161
msgid "{gray}Per-player limit: {white}unlimited"
msgstr "{gray}Per-player limit: {white}unlimited"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:162
msgid "{gray}Per-player limit: {white}{0}"
msgstr "{gray}Per-player limit: {white}{0}"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:164
msgid "{white}{0} %{gray} of your quota used"
msgstr "{white}{0} %{gray} of your quota used"
#: src/main/java/fr/moribus/imageonmap/gui/MapListGui.java:165
msgid "{white}{0}{gray} map left"
msgid_plural "{white}{0}{gray} maps left"
msgstr[0] "{white}{0}{gray} map left"
msgstr[1] "{white}{0}{gray} maps left"
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:73
#, java-format
msgid "HTTP error : {0} {1}"
msgstr "HTTP error : {0} {1}"
#: src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java:79
msgid "The given URL is not a valid image"
msgstr "指定的网址不是有效的图片"
#. The default display name of a map
#: src/main/java/fr/moribus/imageonmap/map/ImageMap.java:44
msgid "Map"
msgstr "地图"
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:29
#, java-format
msgid "You have too many maps (maximum : {0})."
msgstr "You have too many maps (maximum : {0})."
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:30
msgid "The server ImageOnMap limit has been reached."
msgstr "The server ImageOnMap limit has been reached."
#: src/main/java/fr/moribus/imageonmap/map/MapManagerException.java:31
msgid "The given map does not exist."
msgstr "地图不存在."
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:34
msgid "Migration is already running."
msgstr "迁移已在运行"
#: src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java:50
msgid "Waiting for migration to finish..."
msgstr "等待迁移完成..."
#: 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 ""
"Migration thread has been interrupted while waiting to finish. It may not "
"have ended correctly."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:176
msgid "Error while preparing migration"
msgstr "Error while preparing migration"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:177
msgid "Aborting migration. No change has been made."
msgstr "Aborting migration. No change has been made."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:189
msgid "Error while migrating"
msgstr "Error while migrating"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:190
msgid "Aborting migration. Some changes may already have been made."
msgstr "Aborting migration. Some changes may already have been made."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:191
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 ""
"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."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:203
msgid "Looking for configuration files to migrate..."
msgstr "Looking for configuration files to migrate..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:206
#, java-format
msgid "Detected former posters file {0}"
msgstr "Detected former posters file {0}"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:209
#, java-format
msgid "Detected former maps file {0}"
msgstr "Detected former maps file {0}"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:213
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:416
msgid "There is nothing to migrate. Stopping."
msgstr "There is nothing to migrate. Stopping."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:218
msgid "Done."
msgstr "Done."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:232
msgid "Backup directories already exists."
msgstr "Backup directories already exists."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:233
msgid ""
"This means that a migration has already been done, or may not have ended "
"well."
msgstr ""
"This means that a migration has already been done, or may not have ended "
"well."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:234
msgid ""
"To start a new migration, you must move away the backup directories so they "
"are not overwritten."
msgstr ""
"To start a new migration, you must move away the backup directories so they "
"are not overwritten."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:247
msgid "Backing up map data before migrating..."
msgstr "Backing up map data before migrating..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:271
msgid "Backup complete."
msgstr "Backup complete."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:352
msgid "Fetching UUIDs from Mojang..."
msgstr "Fetching UUIDs from Mojang..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:359
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:387
msgid "An error occurred while fetching the UUIDs from Mojang"
msgstr "An error occurred while fetching the UUIDs from Mojang"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:364
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:392
msgid "The migration worker has been interrupted"
msgstr "The migration worker has been interrupted"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:367
#, java-format
msgid "Fetching done. {0} UUID have been retrieved."
msgid_plural "Fetching done. {0} UUIDs have been retrieved."
msgstr[0] "Fetching done. {0} UUID have been retrieved."
msgstr[1] "Fetching done. {0} UUIDs have been retrieved."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:378
#, 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 did not find UUIDs for {0} player at the current time."
msgstr[1] "Mojang did not find UUIDs for {0} players at the current time."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:379
msgid ""
"The Mojang servers limit requests rate at one per second, this may take some "
"time..."
msgstr ""
"The Mojang servers limit requests rate at one per second, this may take some "
"time..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:398
#, 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 did not find player data for {0} player"
msgstr[1] "Mojang did not find player data for {0} players"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:400
msgid "The following players do not exist or do not have paid accounts :"
msgstr "The following players do not exist or do not have paid accounts :"
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:415
msgid "Mojang could not find any of the registered players."
msgstr "Mojang could not find any of the registered players."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:425
msgid "Merging map data..."
msgstr "Merging map data..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:475
#, java-format
msgid "{0} registered minecraft map is missing from the save."
msgid_plural "{0} registered minecraft maps are missing from the save."
msgstr[0] "{0} registered minecraft map is missing from the save."
msgstr[1] "{0} registered minecraft maps are missing from the save."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:476
msgid ""
"These maps will not be migrated, but this could mean the save has been "
"altered or corrupted."
msgstr ""
"These maps will not be migrated, but this could mean the save has been "
"altered or corrupted."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:477
#, java-format
msgid "The following maps are missing : {0} "
msgstr "The following maps are missing : {0} "
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:483
msgid "Saving changes..."
msgstr "Saving changes..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:489
msgid "Cleaning up old data files..."
msgstr "Cleaning up old data files..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:496
msgid "Deleting old map data file..."
msgstr "Deleting old map data file..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:501
#, java-format
msgid "{0} map could not be migrated."
msgid_plural "{0} maps could not be migrated."
msgstr[0] "{0} map could not be migrated."
msgstr[1] "{0} maps could not be migrated."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:519
msgid "Deleting old poster data file..."
msgstr "Deleting old poster data file..."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:524
#, java-format
msgid "{0} poster could not be migrated."
msgid_plural "{0} posters could not be migrated."
msgstr[0] "{0} poster could not be migrated."
msgstr[1] "{0} posters could not be migrated."
#: src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java:537
msgid "Data that has not been migrated will be kept in the old data files."
msgstr "Data that has not been migrated will be kept in the old data files."
#. The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:139
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:215
#, java-format
msgid "{0} (part {1})"
msgstr "{0} (部分 {1})"
#. 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:145
#: src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java:213
#, java-format
msgid "{0} (row {1}, column {2})"
msgstr "{0} (宽 {1}, 高 {2})"
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:44
msgid "Splatter Map"
msgstr "扩散地图"
#. Title in a splatter map tooltip
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:48
msgid "Item frames needed"
msgstr "展示框空间所需"
#. Size of a map stored in a splatter map
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:56
#, java-format
msgid "{0} × {1}"
msgstr "宽: {0} × 高: {1}"
#. Size of a map stored in a splatter map, including the total frames count
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:62
#, java-format
msgid "{0} × {1} (total {2} frames)"
msgstr "宽: {0} × 高: {1} (共需要 {2} 展示框)"
#. Title in a splatter map tooltip
#: src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java:53
msgid "How to use this?"
msgstr "如何使用?"
#: 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 ""
"把一样宽高的展示框全部放在墙上,然后手持此地图右键左下角的"
"展示框即可"
#: 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 ""
"潜行攻击放置的地图,即可收回整张地图"
#: 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}这里没有足够的空间 (宽: {0} × 高: {1})"

View File

@ -23,32 +23,51 @@ permissions:
imageonmap.userender: true
imageonmap.new: true
imageonmap.list: true
imageonmap.listother: true
imageonmap.get: true
imageonmap.getother: true
imageonmap.explore: true
imageonmap.exploreother: true
imageonmap.rename: true
imageonmap.removesplattermap: true
imageonmap.delete: true
imageonmap.deleteother: false
imageonmap.bypasssize: false
imageonmap.give: false
imageonmap.update: true
imageonmap.updateother: false
imageonmap.userender:
description: "Allows you to use /tomap and related commands (/maptool getremaing). Alias of imageonmap.new."
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
default: true
imageonmap.new:
description: "Allows you to use /tomap and related commands (/maptool getremaing)."
description: "Allows you to use /tomap and related commands (/maptool getremaining)."
default: true
imageonmap.list:
description: "Allows you to list the images you rendered."
default: true
description: "Allows you to list the images you rendered."
default: true
imageonmap.listother:
description: "Allows you to list the images a player have rendered."
default: false
imageonmap.get:
description: "Allows you to get a new map among the ones you already rendered, and related commands (/maptool getremaing)."
default: true
description: "Allows you to get a new map among the ones you already rendered, and related commands (/maptool getremaining)."
default: true
imageonmap.getother:
description: "Allows you to get a new map among the ones a player have already rendered."
default: false
imageonmap.explore:
description: "Allows you to open a GUI with all your maps."
default: true
description: "Allows you to open a GUI with all your maps."
default: true
imageonmap.exploreother:
description: "Allows you to open a GUI with all of the player maps."
default: false
imageonmap.rename:
description: "Allows you to rename a map you rendered in the past."
@ -61,6 +80,14 @@ permissions:
imageonmap.give:
description: "Allows you to give a map to a specified player."
default: op
imageonmap.deleteother:
description: "Allows you to delete a map a player rendered in the past."
default: false
imageonmap.removesplattermap:
description: "Allows you to remove a splatter map from a wall by sneaking and breaking a map."
default: true
imageonmap.administrative:
description: "Allows you to perform administrative tasks (like /maptool migrate)."
@ -69,3 +96,11 @@ permissions:
imageonmap.bypasssize:
description: "Allows you to create maps larger than the configured limit."
default: op
imageonmap.update:
description: "Allows you to update an existing map with a new image."
default: true
imageonmap.updateother:
description: "Allows you to update an existing map of an other player with a new image."
default: op