Merge 7b1ecd74df
into 352774f677
This commit is contained in:
commit
a6e1d71f79
2
pom.xml
2
pom.xml
|
@ -134,7 +134,7 @@
|
|||
<dependency>
|
||||
<groupId>fr.zcraft</groupId>
|
||||
<artifactId>quartzlib</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<version>0.0.7-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap;
|
||||
|
||||
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class Argument {
|
||||
//<TODO special case with the --cancel -c type arguments
|
||||
private final String name;
|
||||
private final Type type;
|
||||
private final Status status;
|
||||
|
||||
private String content;
|
||||
private String defaultValue;
|
||||
|
||||
public Argument(String name, Type type, Status status) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Argument(String name, Type type, Status status, String defaultValue) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static Argument findArgument(String argumentName, List<Argument> args) {
|
||||
for (Argument a : args) {
|
||||
if (a.getName().equalsIgnoreCase(argumentName)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
PluginLogger.error("Can't find argument");
|
||||
return null;
|
||||
}
|
||||
//TODO add error message for the console and/or player
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static <T extends Object> T findContent(String argumentName, List<Argument> args) {
|
||||
Argument argument = Argument.findArgument(argumentName, args);
|
||||
if (argument != null) {
|
||||
return argument.getContent();
|
||||
}
|
||||
|
||||
PluginLogger.error("Error: argument {0} was not found", argumentName);
|
||||
for (Argument a : args) {
|
||||
PluginLogger.info("argument disponible {0}", a.getName());
|
||||
}
|
||||
|
||||
return argument.getDefault();
|
||||
}
|
||||
|
||||
public <T extends Object> T getDefault() {
|
||||
if (defaultValue == null) {
|
||||
return null;
|
||||
}
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
return (T) Boolean.valueOf(defaultValue);
|
||||
case INT:
|
||||
return (T) Integer.getInteger(defaultValue);
|
||||
case UUID:
|
||||
return (T) UUID.fromString(defaultValue);
|
||||
case DOUBLE:
|
||||
return (T) Double.valueOf(defaultValue);
|
||||
case STRING:
|
||||
return (T) defaultValue;
|
||||
case ONLINE_PLAYER:
|
||||
return (T) Bukkit.getPlayer(toUUID(defaultValue));
|
||||
case OFFLINE_PLAYER:
|
||||
return (T) Bukkit.getOfflinePlayer(toUUID(defaultValue));
|
||||
|
||||
default:
|
||||
PluginLogger.info("To be implemented");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Object> T getContent() {
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
return (T) Boolean.valueOf(content);
|
||||
case INT:
|
||||
return (T) Integer.getInteger(content);
|
||||
case UUID:
|
||||
return (T) UUID.fromString(content);
|
||||
case DOUBLE:
|
||||
return (T) Double.valueOf(content);
|
||||
case STRING:
|
||||
return (T) content;
|
||||
case ONLINE_PLAYER:
|
||||
return (T) Bukkit.getPlayer(toUUID(content));
|
||||
case OFFLINE_PLAYER:
|
||||
return (T) Bukkit.getOfflinePlayer(toUUID(content));
|
||||
|
||||
default:
|
||||
PluginLogger.info("To be implemented");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setEmpty() {
|
||||
this.content = "";
|
||||
}
|
||||
|
||||
private void setDefault(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
private void setContent(String content) {
|
||||
//check if added content is type compatible
|
||||
String msg = "Content wasn't parsable to type '{0}', got the following string {1}";
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
case ONLINE_PLAYER:
|
||||
case OFFLINE_PLAYER:
|
||||
case STRING:
|
||||
this.content = content;
|
||||
break;
|
||||
case DOUBLE:
|
||||
try {
|
||||
Double.valueOf(content);
|
||||
} catch (NumberFormatException e) {
|
||||
PluginLogger.warning(msg,
|
||||
"double", content);
|
||||
throw e;
|
||||
}
|
||||
this.content = content;
|
||||
break;
|
||||
case UUID:
|
||||
try {
|
||||
UUID.fromString(content);
|
||||
} catch (IllegalArgumentException e) {
|
||||
PluginLogger.warning(msg,
|
||||
"UUID", content);
|
||||
throw e;
|
||||
}
|
||||
this.content = content;
|
||||
break;
|
||||
case INT:
|
||||
try {
|
||||
Integer.parseInt(content);
|
||||
} catch (NumberFormatException e) {
|
||||
PluginLogger.warning(msg,
|
||||
"integer", content);
|
||||
throw e;
|
||||
}
|
||||
this.content = content;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private UUID toUUID(String content) {
|
||||
try {
|
||||
return UUID.fromString(content);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Bukkit.getOfflinePlayer(content).getUniqueId();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAmbiguous(List<Argument> prototype, boolean isPlayer) {
|
||||
//TODO add check on the possible type
|
||||
for (int i = 1; i < prototype.size(); i++) {
|
||||
Argument arg = prototype.get(i);
|
||||
Argument previous = prototype.get(i - 1);
|
||||
if ((arg.getStatus() == Status.OPTIONAL && previous.getStatus() == Status.OPTIONAL)
|
||||
|| (isPlayer
|
||||
&& ((arg.getStatus() == Status.OPTIONAL_FOR_PLAYER_ONLY
|
||||
&& previous.getStatus() == Status.OPTIONAL)
|
||||
|| (arg.getStatus() == Status.OPTIONAL
|
||||
&& previous.getStatus() == Status.OPTIONAL_FOR_PLAYER_ONLY)
|
||||
|| (arg.getStatus() == Status.OPTIONAL_FOR_PLAYER_ONLY
|
||||
&& previous.getStatus() == Status.OPTIONAL_FOR_PLAYER_ONLY)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<Argument> parseArguments(List<Argument> prototype, ArrayList<String> args, boolean isPlayer)
|
||||
throws Exception {
|
||||
//check if the command is not ambiguous
|
||||
if (isAmbiguous(prototype, isPlayer)) {
|
||||
throw new Exception("Parsing error, ambiguous command prototype");
|
||||
}
|
||||
// givemap Vlammar Vlammar:"carte 1" 10
|
||||
// string |string| string <int>
|
||||
List<Argument> list = new ArrayList<>();
|
||||
List<Argument> uncertain = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
boolean next = false;
|
||||
String arg = args.get(i);
|
||||
PluginLogger.info("Argument: {0}", arg);
|
||||
for (int j = i; j < prototype.size(); j++) {
|
||||
PluginLogger.info("j = {0}", j);
|
||||
Argument a = prototype.get(j);
|
||||
PluginLogger.info("argument name: \n{0}", a.toString());
|
||||
switch (a.status) {
|
||||
case OBLIGATORY:
|
||||
PluginLogger.info("OBLIGATORY");
|
||||
if (uncertain.isEmpty()) {
|
||||
PluginLogger.info(a.getName());
|
||||
list.add(a);
|
||||
a.setContent(arg);
|
||||
PluginLogger.info("argument : \n{0}", a.toString());
|
||||
next = true;
|
||||
} else {
|
||||
for (Argument l : uncertain) {
|
||||
//if size doesnt match or
|
||||
try {
|
||||
PluginLogger.info("test pour l'erreur");
|
||||
PluginLogger.info(a.getContent());
|
||||
a.setContent(a.content); //todo erreur ?
|
||||
PluginLogger.info("argument : \n{0}", a.toString());
|
||||
} catch (Exception e) {
|
||||
//shift to the right
|
||||
}
|
||||
}
|
||||
PluginLogger.info(a.getName());
|
||||
list.add(a);
|
||||
uncertain = new ArrayList<>();
|
||||
}
|
||||
break;
|
||||
case OPTIONAL:
|
||||
PluginLogger.info("OPTIONAL");
|
||||
PluginLogger.info(a.getName());
|
||||
uncertain.add(a);
|
||||
PluginLogger.info("argument : \n{0}", a.toString());
|
||||
break;
|
||||
case OPTIONAL_FOR_PLAYER_ONLY:
|
||||
PluginLogger.info("OPTIONAL_FOR_PLAYER_ONLY");
|
||||
if (!isPlayer) {
|
||||
PluginLogger.info(a.getName());
|
||||
list.add(a);
|
||||
a.setContent(arg);
|
||||
PluginLogger.info("argument : \n{0}", a.toString());
|
||||
next = true;
|
||||
} else {
|
||||
PluginLogger.info(a.getName());
|
||||
uncertain.add(a);
|
||||
PluginLogger.info("argument : \n{0}", a.toString());
|
||||
break;
|
||||
//Str Str Str Int
|
||||
//<player name> [playerFrom] [playerFrom]:<map name> <quantity >
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Status does not exist");
|
||||
}
|
||||
if (next) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{ name: " + name + ";\ntype: " + type + ";\nstatus: " + status + ";\ncontent: " + content + " }";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -44,6 +44,7 @@ import fr.moribus.imageonmap.commands.maptool.GetRemainingCommand;
|
|||
import fr.moribus.imageonmap.commands.maptool.GiveCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.ListCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.NewCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.RemotePlacingCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.RenameCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.UpdateCommand;
|
||||
import fr.moribus.imageonmap.image.ImageIOExecutor;
|
||||
|
@ -60,18 +61,24 @@ import fr.zcraft.quartzlib.tools.PluginLogger;
|
|||
import fr.zcraft.quartzlib.tools.UpdateChecker;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
|
||||
public final class ImageOnMap extends QuartzPlugin {
|
||||
private static final String IMAGES_DIRECTORY_NAME = "images";
|
||||
private static final String RENDERS_DIRECTORY_NAME = "renders";
|
||||
private static final String MAPS_DIRECTORY_NAME = "maps";
|
||||
private static ImageOnMap plugin;
|
||||
private final File mapsDirectory;
|
||||
private File imagesDirectory;
|
||||
|
||||
private File rendersDirectory;
|
||||
private File mapsDirectory;
|
||||
private CommandWorkers commandWorker;
|
||||
|
||||
public ImageOnMap() {
|
||||
imagesDirectory = new File(this.getDataFolder(), IMAGES_DIRECTORY_NAME);
|
||||
rendersDirectory = new File(this.getDataFolder(), RENDERS_DIRECTORY_NAME);
|
||||
mapsDirectory = new File(this.getDataFolder(), MAPS_DIRECTORY_NAME);
|
||||
plugin = this;
|
||||
}
|
||||
|
@ -84,6 +91,10 @@ public final class ImageOnMap extends QuartzPlugin {
|
|||
return imagesDirectory;
|
||||
}
|
||||
|
||||
public File getRendersDirectory() {
|
||||
return rendersDirectory;
|
||||
}
|
||||
|
||||
public File getMapsDirectory() {
|
||||
return mapsDirectory;
|
||||
}
|
||||
|
@ -92,20 +103,33 @@ public final class ImageOnMap extends QuartzPlugin {
|
|||
return new File(imagesDirectory, "map" + mapID + ".png");
|
||||
}
|
||||
|
||||
public File getRenderFile(int mapID) {
|
||||
return new File(rendersDirectory, "render" + mapID + ".png");
|
||||
}
|
||||
|
||||
public CommandWorkers getCommandWorker() {
|
||||
return commandWorker;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String,File> checkDirs() throws IOException {
|
||||
Map<String, File> dirs = new HashMap<>();
|
||||
dirs.put("mapsDirectory", checkPluginDirectory(mapsDirectory));
|
||||
dirs.put("rendersDirectory", checkPluginDirectory(rendersDirectory));
|
||||
dirs.put("imagesDirectory", checkPluginDirectory(imagesDirectory));
|
||||
return dirs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Creating the images and maps directories if necessary
|
||||
try {
|
||||
//imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this));
|
||||
checkPluginDirectory(mapsDirectory);
|
||||
checkPluginDirectory(imagesDirectory);
|
||||
Map<String, File> directories = checkDirs();
|
||||
mapsDirectory = directories.get("mapsDirectory");
|
||||
rendersDirectory = directories.get("rendersDirectory");
|
||||
imagesDirectory = directories.get("imagesDirectory");
|
||||
} catch (final IOException ex) {
|
||||
PluginLogger.error("FATAL: " + ex.getMessage());
|
||||
//disable the plugin
|
||||
this.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
@ -123,9 +147,9 @@ public final class ImageOnMap extends QuartzPlugin {
|
|||
MapInitEvent.init();
|
||||
MapItemManager.init();
|
||||
|
||||
|
||||
String commandGroupName = "maptool";
|
||||
Commands.register(
|
||||
"maptool",
|
||||
commandGroupName,
|
||||
NewCommand.class,
|
||||
ListCommand.class,
|
||||
GetCommand.class,
|
||||
|
@ -135,19 +159,21 @@ public final class ImageOnMap extends QuartzPlugin {
|
|||
GetRemainingCommand.class,
|
||||
ExploreCommand.class,
|
||||
//MigrateCommand.class,//Removed for now doesn't work nor is useful, maybe useful later on
|
||||
UpdateCommand.class
|
||||
UpdateCommand.class,
|
||||
RemotePlacingCommand.class
|
||||
);
|
||||
|
||||
Commands.registerShortcut("maptool", NewCommand.class, "tomap");
|
||||
Commands.registerShortcut("maptool", ExploreCommand.class, "maps");
|
||||
Commands.registerShortcut("maptool", GiveCommand.class, "givemap");
|
||||
Commands.registerShortcut(commandGroupName, NewCommand.class, "tomap");
|
||||
Commands.registerShortcut(commandGroupName, ExploreCommand.class, "maps");
|
||||
Commands.registerShortcut(commandGroupName, GiveCommand.class, "givemap");
|
||||
Commands.registerShortcut(commandGroupName, RemotePlacingCommand.class, "placemap");
|
||||
|
||||
if (PluginConfiguration.CHECK_FOR_UPDATES.get()) {
|
||||
UpdateChecker.boot("imageonmap.26585");
|
||||
}
|
||||
|
||||
if (PluginConfiguration.COLLECT_DATA.get()) {
|
||||
final Metrics metrics = new Metrics(this,5920);
|
||||
final Metrics metrics = new Metrics(this, 5920);
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("rendered-images", MapManager::getImagesCount));
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("used-minecraft-maps", MapManager::getMapCount));
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -62,7 +62,8 @@ public enum Permissions {
|
|||
BYPASS_IMAGE_LIMIT("imageonmap.bypassimagelimit"),
|
||||
BYPASS_MAP_LIMIT("imageonmap.bypassmaplimit"),
|
||||
GIVE("imageonmap.give"),
|
||||
BYPASS_WHITELIST("imageonmap.bypasswhitelist");
|
||||
BYPASS_WHITELIST("imageonmap.bypasswhitelist"),
|
||||
REMOTE_PLACING("imageonmap.remoteplacing");
|
||||
|
||||
private final String permission;
|
||||
private final String[] aliases;
|
||||
|
@ -79,6 +80,12 @@ public enum Permissions {
|
|||
* @return {@code true} if this permission is granted to the permissible.
|
||||
*/
|
||||
public boolean grantedTo(Permissible permissible) {
|
||||
//true only if not a player. If the console or a command block as send the command we can assume that it has
|
||||
//enough privilege
|
||||
if (permissible == null || permissible.isOp()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (permissible.hasPermission(permission)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -103,17 +110,13 @@ public enum Permissions {
|
|||
String prefix = String.format("imageonmap.%slimit.", type.name());
|
||||
for (PermissionAttachmentInfo pai : perms) {
|
||||
String permString = pai.getPermission().toLowerCase();
|
||||
if (permString.startsWith(prefix)) {
|
||||
if (pai.getValue()) {
|
||||
try {
|
||||
int limit = Integer.parseInt(permString.split(prefix)[1].trim());
|
||||
return limit;
|
||||
} catch (Exception e) {
|
||||
PluginLogger.warning(
|
||||
I.t("The correct syntax for setting map limit node is: ImageOnMap.mapLimit.X "
|
||||
+ "where you can replace X with the limit of map a player is allowed to have"));
|
||||
}
|
||||
|
||||
if (permString.startsWith(prefix) && pai.getValue()) {
|
||||
try {
|
||||
return Integer.parseInt(permString.split(prefix)[1].trim());
|
||||
} catch (Exception e) {
|
||||
PluginLogger.warning(
|
||||
I.t("The correct syntax for setting map limit node is: ImageOnMap.mapLimit.X "
|
||||
+ "where you can replace X with the limit of map a player is allowed to have"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -46,22 +46,24 @@ import java.util.Locale;
|
|||
|
||||
|
||||
public final class PluginConfiguration extends Configuration {
|
||||
public static ConfigurationItem<Locale> LANG = item("lang", Locale.class);
|
||||
public static final ConfigurationItem<Locale> LANG = item("lang", Locale.class);
|
||||
|
||||
public static ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
|
||||
public static final ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
|
||||
|
||||
public static ConfigurationItem<Boolean> CHECK_FOR_UPDATES = item("check-for-updates", true);
|
||||
public static final ConfigurationItem<Boolean> CHECK_FOR_UPDATES = item("check-for-updates", true);
|
||||
|
||||
public static ConfigurationItem<Integer> MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server");
|
||||
public static ConfigurationItem<Integer> MAP_PLAYER_LIMIT = item("map-player-limit", 0, "Limit-map-by-player");
|
||||
public static final ConfigurationItem<Integer> MAP_GLOBAL_LIMIT =
|
||||
item("map-global-limit", 0, "Limit-map-by-server");
|
||||
public static final ConfigurationItem<Integer> MAP_PLAYER_LIMIT =
|
||||
item("map-player-limit", 0, "Limit-map-by-player");
|
||||
|
||||
public static ConfigurationItem<Boolean> SAVE_FULL_IMAGE = item("save-full-image", true);
|
||||
public static final ConfigurationItem<Boolean> SAVE_FULL_IMAGE = item("save-full-image", true);
|
||||
|
||||
|
||||
public static ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
|
||||
public static ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
|
||||
public static final ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
|
||||
public static final ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
|
||||
|
||||
public static ConfigurationList<String> IMAGES_HOSTNAMES_WHITELIST =
|
||||
public static final ConfigurationList<String> IMAGES_HOSTNAMES_WHITELIST =
|
||||
list("images-hostnames-whitelist", String.class);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap;
|
||||
|
||||
public enum Status {
|
||||
OBLIGATORY, OPTIONAL, OPTIONAL_FOR_PLAYER_ONLY
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap;
|
||||
|
||||
public enum Type {
|
||||
STRING, INT, DOUBLE, BOOLEAN, UUID, ONLINE_PLAYER,OFFLINE_PLAYER
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -46,14 +46,34 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public abstract class IoMCommand extends Command {
|
||||
protected UUID getPlayerUUID(String playerName) {
|
||||
return Bukkit.getOfflinePlayer(playerName).getUniqueId();
|
||||
}
|
||||
|
||||
private boolean checkTooArguments(boolean bool, String msg) throws CommandException {
|
||||
if (bool) {
|
||||
throwInvalidArgument(msg);
|
||||
}
|
||||
return bool;
|
||||
}
|
||||
|
||||
protected boolean checkTooManyArguments(boolean bool) throws CommandException {
|
||||
return checkTooArguments(bool, I.t("Too many parameters!"));
|
||||
}
|
||||
|
||||
protected boolean checkTooFewArguments(boolean bool) throws CommandException {
|
||||
return checkTooArguments(bool, I.t("Too few parameters!"));
|
||||
}
|
||||
|
||||
protected boolean checkArguments(boolean bool1, boolean bool2) throws CommandException {
|
||||
return !(checkTooManyArguments(bool1) || checkTooFewArguments(bool2));
|
||||
}
|
||||
|
||||
protected boolean checkHostnameWhitelist(final URL url) {
|
||||
final List<String> hostnames = PluginConfiguration.IMAGES_HOSTNAMES_WHITELIST.get()
|
||||
|
@ -72,39 +92,6 @@ public abstract class IoMCommand extends Command {
|
|||
.anyMatch(h -> h.equalsIgnoreCase(url.getHost()));
|
||||
}
|
||||
|
||||
protected void retrieveUUID(final String arg, final Consumer<UUID> consumer) {
|
||||
// If it is being removed we may have to use Mojang services
|
||||
consumer.accept(Bukkit.getOfflinePlayer(arg).getUniqueId());
|
||||
}
|
||||
|
||||
protected ImageMap getMapFromArgs() throws CommandException {
|
||||
return getMapFromArgs(playerSender(), 0, true);
|
||||
}
|
||||
|
||||
protected ImageMap getMapFromArgs(final Player player, final int index, boolean expand) throws CommandException {
|
||||
if (args.length <= index) {
|
||||
throwInvalidArgument(I.t("You need to give a map name."));
|
||||
}
|
||||
|
||||
ImageMap map;
|
||||
String mapName = args[index];
|
||||
|
||||
if (expand) {
|
||||
for (int i = index + 1, c = args.length; i < c; i++) {
|
||||
mapName += " " + args[i];
|
||||
}
|
||||
}
|
||||
|
||||
mapName = mapName.trim();
|
||||
map = MapManager.getMap(player.getUniqueId(), mapName);
|
||||
|
||||
if (map == null) {
|
||||
error(I.t("This map does not exist."));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
protected ArrayList<String> getArgs() {
|
||||
ArrayList<String> arguments = new ArrayList<>();
|
||||
|
||||
|
@ -175,4 +162,5 @@ public abstract class IoMCommand extends Command {
|
|||
|
||||
return matches;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -50,6 +50,7 @@ import fr.zcraft.quartzlib.tools.PluginLogger;
|
|||
import fr.zcraft.quartzlib.tools.text.RawMessage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -76,56 +77,76 @@ public class DeleteCommand extends IoMCommand {
|
|||
ArrayList<String> arguments = getArgs();
|
||||
final boolean confirm = hasFlag("confirm");
|
||||
|
||||
if (arguments.size() > 3 || (arguments.size() > 2 && !confirm)) {
|
||||
throwInvalidArgument(I.t("Too many parameters!"));
|
||||
return;
|
||||
}
|
||||
if (arguments.size() < 1) {
|
||||
throwInvalidArgument(I.t("Too few parameters!"));
|
||||
boolean isTooMany = arguments.size() > 3 || (arguments.size() > 2 && !confirm);
|
||||
boolean isTooFew = arguments.isEmpty();
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String playerName;
|
||||
final String mapName;
|
||||
final Player sender = playerSender();
|
||||
final Player sender;
|
||||
Player playerSender;
|
||||
try {
|
||||
playerSender = playerSender();
|
||||
} catch (CommandException ignored) {
|
||||
if (arguments.size() != 2) {
|
||||
throwInvalidArgument(I.t("Player name is required from the console"));
|
||||
}
|
||||
playerSender = null;
|
||||
}
|
||||
|
||||
sender = playerSender;
|
||||
boolean notPlayer = sender == null;
|
||||
if (arguments.size() == 2 || arguments.size() == 3) {
|
||||
if (!Permissions.DELETEOTHER.grantedTo(sender)) {
|
||||
throwNotAuthorized();
|
||||
return;
|
||||
}
|
||||
|
||||
playerName = arguments.get(0);
|
||||
mapName = arguments.get(1);
|
||||
} else {
|
||||
playerName = sender.getName();
|
||||
mapName = arguments.get(0);
|
||||
}
|
||||
|
||||
retrieveUUID(playerName, uuid -> {
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm) {
|
||||
RawText msg = deleteMsg(getClass(), playerName, map);
|
||||
RawMessage.send(sender, msg);
|
||||
UUID uuid = getPlayerUUID(playerName);
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
if (map == null) {
|
||||
final String msg = "This map does not exist.";
|
||||
if (notPlayer) {
|
||||
PluginLogger.warning("" + msg);
|
||||
} else {
|
||||
if (sender != null && sender.isOnline() && sender.getInventory() != null) {
|
||||
MapManager.clear(sender.getInventory(), map);
|
||||
}
|
||||
|
||||
try {
|
||||
MapManager.deleteMap(map);
|
||||
success(sender, I.t("Map successfully deleted."));
|
||||
} catch (MapManagerException ex) {
|
||||
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
}
|
||||
warning(sender, I.t(msg));
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm && !notPlayer) {
|
||||
RawText msg = deleteMsg(getClass(), playerName, map);
|
||||
|
||||
if (notPlayer) {
|
||||
PluginLogger.info("" + msg.toFormattedText());
|
||||
} else {
|
||||
RawMessage.send(sender, msg);
|
||||
}
|
||||
} else {
|
||||
if (sender != null && sender.isOnline()) {
|
||||
MapManager.clear(sender.getInventory(), map);
|
||||
}
|
||||
try {
|
||||
MapManager.deleteMap(map);
|
||||
String msg = I.t("Map successfully deleted.");
|
||||
if (sender != null) {
|
||||
success(sender, msg);
|
||||
} else {
|
||||
PluginLogger.info(msg);
|
||||
}
|
||||
} catch (MapManagerException ex) {
|
||||
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -43,8 +43,6 @@ import fr.moribus.imageonmap.gui.MapListGui;
|
|||
import fr.zcraft.quartzlib.components.commands.CommandException;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
||||
import fr.zcraft.quartzlib.components.gui.Gui;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import java.util.ArrayList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
@ -57,13 +55,14 @@ public class ExploreCommand extends IoMCommand {
|
|||
@Override
|
||||
protected void run() throws CommandException {
|
||||
ArrayList<String> arguments = getArgs();
|
||||
if (arguments.size() > 1) {
|
||||
throwInvalidArgument(I.t("Too many parameters!"));
|
||||
boolean isTooMany = arguments.size() > 1;
|
||||
boolean isTooFew = false;
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
final String playerName;
|
||||
|
||||
final Player sender = playerSender();
|
||||
|
||||
if (arguments.size() == 1) {
|
||||
if (!Permissions.LISTOTHER.grantedTo(sender)) {
|
||||
throwNotAuthorized();
|
||||
|
@ -74,14 +73,10 @@ public class ExploreCommand extends IoMCommand {
|
|||
playerName = sender.getName();
|
||||
}
|
||||
|
||||
retrieveUUID(playerName, uuid -> {
|
||||
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
|
||||
if (sender.isOnline()) {
|
||||
Gui.open(sender, new MapListGui(offlinePlayer, playerName));
|
||||
}
|
||||
|
||||
});
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
|
||||
if (sender.isOnline()) {
|
||||
Gui.open(sender, new MapListGui(offlinePlayer, playerName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,7 +36,6 @@
|
|||
|
||||
package fr.moribus.imageonmap.commands.maptool;
|
||||
|
||||
import fr.moribus.imageonmap.ImageOnMap;
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.commands.IoMCommand;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
|
@ -46,23 +45,22 @@ import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
|||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@CommandInfo(name = "get",usageParameters = "[player name]:<map name>")
|
||||
@CommandInfo(name = "get", usageParameters = "[player name]:<map name>")
|
||||
public class GetCommand extends IoMCommand {
|
||||
@Override
|
||||
protected void run() throws CommandException {
|
||||
ArrayList<String> arguments = getArgs();
|
||||
|
||||
if (arguments.size() > 2) {
|
||||
throwInvalidArgument(I.t("Too many parameters!"));
|
||||
return;
|
||||
}
|
||||
if (arguments.size() < 1) {
|
||||
throwInvalidArgument(I.t("Too few parameters!"));
|
||||
boolean isTooMany = arguments.size() > 2;
|
||||
boolean isTooFew = arguments.isEmpty();
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String playerName;
|
||||
final String mapName;
|
||||
final Player sender = playerSender();
|
||||
|
@ -79,28 +77,23 @@ public class GetCommand extends IoMCommand {
|
|||
mapName = arguments.get(1);
|
||||
}
|
||||
|
||||
UUID uuid = getPlayerUUID(playerName);
|
||||
if (!sender.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.give(sender)) {
|
||||
info(I.t("The requested map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
|
||||
retrieveUUID(playerName, uuid -> {
|
||||
|
||||
if (!sender.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.give(sender)) {
|
||||
info(I.t("The requested map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,55 +36,87 @@
|
|||
|
||||
package fr.moribus.imageonmap.commands.maptool;
|
||||
|
||||
import fr.moribus.imageonmap.Argument;
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.Status;
|
||||
import fr.moribus.imageonmap.Type;
|
||||
import fr.moribus.imageonmap.commands.IoMCommand;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandException;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@CommandInfo(name = "give", usageParameters = "<player name> [playerFrom]:<map name>")
|
||||
@CommandInfo(name = "give", usageParameters = "<player name> [playerFrom]:<map name> [quantity]")
|
||||
public class GiveCommand extends IoMCommand {
|
||||
protected List<Argument> commandPrototype() {
|
||||
Argument target = new Argument("target", Type.STRING, Status.OBLIGATORY);
|
||||
Argument from = new Argument("from", Type.STRING, Status.OPTIONAL_FOR_PLAYER_ONLY);
|
||||
Argument mapName = new Argument("mapName", Type.STRING, Status.OBLIGATORY);
|
||||
Argument quantity = new Argument("quantity", Type.INT, Status.OPTIONAL, "1");
|
||||
|
||||
List<Argument> list = new ArrayList<>();
|
||||
list.add(target);
|
||||
list.add(from);
|
||||
list.add(mapName);
|
||||
list.add(quantity);
|
||||
|
||||
return list;
|
||||
}
|
||||
// /givemap Vlammar "Carte 1" 10
|
||||
// /maptool give Vlammar Vlammar:"Carte"
|
||||
|
||||
@Override
|
||||
protected void run() throws CommandException {
|
||||
|
||||
if (args.length < 2) {
|
||||
throwInvalidArgument(I.t("You must give a valid player name and a map name."));
|
||||
return;
|
||||
}
|
||||
|
||||
List<Argument> cmdProto = commandPrototype();
|
||||
ArrayList<String> arguments = getArgs();
|
||||
Boolean isPlayer = sender != null;
|
||||
List<Argument> args;
|
||||
try {
|
||||
args = Argument.parseArguments(cmdProto, arguments, isPlayer);
|
||||
} catch (Exception e) {
|
||||
PluginLogger.error("Error while parsing command");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.size() > 3) {
|
||||
throwInvalidArgument(I.t("Too many parameters!"));
|
||||
|
||||
boolean isTooMany = arguments.size() > 4;
|
||||
boolean isTooFew = arguments.size() < 2;
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
if (arguments.size() < 1) {
|
||||
throwInvalidArgument(I.t("Too few parameters!"));
|
||||
|
||||
final String mapName = Argument.findContent("mapName", args);
|
||||
final String from = Argument.findContent("from", args);
|
||||
final String playerName = Argument.findContent("target", args);
|
||||
final int quantity = Argument.findContent("quantity", args);
|
||||
|
||||
PluginLogger.info("quantity {0}", quantity);
|
||||
if (mapName == null || from == null || playerName == null) {
|
||||
PluginLogger.error("Error one argument is null, check argument names");
|
||||
return;
|
||||
}
|
||||
final String mapName;
|
||||
final String from;
|
||||
final String playerName;
|
||||
final Player playerSender;
|
||||
Player playerSender1;
|
||||
try {
|
||||
playerSender1 = playerSender();
|
||||
} catch (CommandException ignored) {
|
||||
if (arguments.size() == 2) {
|
||||
throwInvalidArgument(I.t("Player name is required from the console"));
|
||||
throwInvalidArgument(I.t("Player name is required for the console"));
|
||||
}
|
||||
playerSender1 = null;
|
||||
}
|
||||
playerSender = playerSender1;
|
||||
if (arguments.size() == 2) {
|
||||
/*if (arguments.size() == 2) {
|
||||
from = playerSender.getName();
|
||||
playerName = arguments.get(0);
|
||||
mapName = arguments.get(1);
|
||||
|
@ -98,26 +130,25 @@ public class GiveCommand extends IoMCommand {
|
|||
playerName = "";
|
||||
mapName = "";
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
final Player sender = playerSender();
|
||||
UUID uuid = getPlayerUUID(from);
|
||||
UUID uuid2 = getPlayerUUID(playerName);
|
||||
|
||||
retrieveUUID(from, uuid -> {
|
||||
final ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
final ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
retrieveUUID(playerName, uuid2 -> {
|
||||
if (Bukkit.getPlayer((uuid2)) != null && Bukkit.getPlayer((uuid2)).isOnline()
|
||||
&& map.give(Bukkit.getPlayer(uuid2))) {
|
||||
info(I.t("The requested map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (Bukkit.getPlayer((uuid2)) != null && Bukkit.getPlayer((uuid2)).isOnline()
|
||||
&& map.give(Bukkit.getPlayer(uuid2), quantity)) {
|
||||
info(I.t("The requested map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -46,9 +46,11 @@ import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
|||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.components.rawtext.RawText;
|
||||
import fr.zcraft.quartzlib.components.rawtext.RawTextPart;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.text.RawMessage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -58,49 +60,73 @@ public class ListCommand extends IoMCommand {
|
|||
@Override
|
||||
protected void run() throws CommandException {
|
||||
ArrayList<String> arguments = getArgs();
|
||||
if (arguments.size() > 1) {
|
||||
throwInvalidArgument(I.t("Too many parameters!"));
|
||||
|
||||
|
||||
boolean isTooMany = arguments.size() > 1;
|
||||
boolean isTooFew = false;
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String playerName;
|
||||
final boolean isHuman = (sender instanceof Player);
|
||||
if (arguments.size() == 1) {
|
||||
if (!Permissions.LISTOTHER.grantedTo(sender)) {
|
||||
if (!Permissions.LISTOTHER.grantedTo(sender) && isHuman) {
|
||||
throwNotAuthorized();
|
||||
return;
|
||||
}
|
||||
|
||||
playerName = arguments.get(0);
|
||||
} else {
|
||||
playerName = playerSender().getName();
|
||||
}
|
||||
|
||||
final Player sender = playerSender();
|
||||
|
||||
|
||||
retrieveUUID(playerName, uuid -> {
|
||||
List<ImageMap> mapList = MapManager.getMapList(uuid);
|
||||
if (mapList.isEmpty()) {
|
||||
info(sender, I.t("No map found."));
|
||||
if (isHuman) {
|
||||
playerName = playerSender().getName();
|
||||
} else {
|
||||
PluginLogger.warning(I.t("You must give a player name"));
|
||||
return;
|
||||
}
|
||||
String message = I.tn("{white}{bold}{0} map found.",
|
||||
"{white}{bold}{0} maps found.",
|
||||
mapList.size());
|
||||
|
||||
info(sender, I.tn("{white}{bold}{0} map found.", "{white}{bold}{0} maps found.", mapList.size()));
|
||||
|
||||
RawTextPart rawText = new RawText("");
|
||||
rawText = addMap(rawText, mapList.get(0));
|
||||
|
||||
//TODO pagination chat
|
||||
for (int i = 1, c = mapList.size(); i < c; i++) {
|
||||
rawText = rawText.then(", ").color(ChatColor.GRAY);
|
||||
rawText = addMap(rawText, mapList.get(i));
|
||||
}
|
||||
final Player playerSender;
|
||||
if (isHuman) {
|
||||
playerSender = playerSender();
|
||||
} else {
|
||||
playerSender = null;
|
||||
}
|
||||
UUID uuid = getPlayerUUID(playerName);
|
||||
List<ImageMap> mapList = MapManager.getMapList(uuid);
|
||||
if (mapList.isEmpty()) {
|
||||
String msg = I.t("No map found.");
|
||||
if (isHuman) {
|
||||
info(playerSender, msg);
|
||||
} else {
|
||||
PluginLogger.info(msg);
|
||||
}
|
||||
RawMessage.send(sender, rawText.build());
|
||||
return;
|
||||
}
|
||||
String msg = I.tn("{white}{bold}{0} map found.",
|
||||
"{white}{bold}{0} maps found.",
|
||||
mapList.size());
|
||||
if (isHuman) {
|
||||
info(playerSender,
|
||||
msg); //TODO merge those into a common info(isHuman,msg) that print to a sender or the console
|
||||
} else {
|
||||
PluginLogger.info(msg);
|
||||
}
|
||||
|
||||
RawTextPart rawText = new RawText("");
|
||||
rawText = addMap(rawText, mapList.get(0));
|
||||
|
||||
//TODO pagination chat
|
||||
for (int i = 1, c = mapList.size(); i < c; i++) {
|
||||
rawText = rawText.then(", ").color(ChatColor.GRAY);
|
||||
rawText = addMap(rawText, mapList.get(i));
|
||||
}
|
||||
if (isHuman) {
|
||||
RawMessage.send(playerSender, rawText.build());
|
||||
} else {
|
||||
PluginLogger.info(rawText.build().toPlainText());
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -38,6 +38,7 @@ package fr.moribus.imageonmap.commands.maptool;
|
|||
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.commands.IoMCommand;
|
||||
import fr.moribus.imageonmap.gui.RenderGui;
|
||||
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
||||
import fr.moribus.imageonmap.image.ImageUtils;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
|
@ -45,6 +46,7 @@ import fr.moribus.imageonmap.map.MapManager;
|
|||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandException;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
||||
import fr.zcraft.quartzlib.components.gui.Gui;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.components.worker.WorkerCallback;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
|
@ -79,6 +81,7 @@ public class NewCommand extends IoMCommand {
|
|||
|
||||
@Override
|
||||
protected void run() throws CommandException {
|
||||
//TODO check if not too many args
|
||||
final Player player = playerSender();
|
||||
ImageUtils.ScalingType scaling = ImageUtils.ScalingType.NONE;
|
||||
URL url;
|
||||
|
@ -121,66 +124,73 @@ public class NewCommand extends IoMCommand {
|
|||
throwInvalidArgument(I.t("Invalid URL."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length >= 2) {
|
||||
if (args.length >= 3) {
|
||||
try {
|
||||
if (args.length >= 4) {
|
||||
width = Integer.parseInt(args[2]);
|
||||
height = Integer.parseInt(args[3]);
|
||||
} else {
|
||||
String[] size;
|
||||
if (args[2].contains("*") && !args[2].contains("x")) {
|
||||
size = args[2].split("\\*");
|
||||
width = Integer.parseInt(size[0]);
|
||||
height = Integer.parseInt(size[1]);
|
||||
}
|
||||
if (!args[2].contains("*") && args[2].contains("x")) {
|
||||
size = args[2].split("x");
|
||||
width = Integer.parseInt(size[0]);
|
||||
height = Integer.parseInt(size[1]);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
|
||||
throwInvalidArgument(I.t("resize dimension as to be in format <n m> or <nxm> or <n*m>."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
scaling = resizeMode();
|
||||
}
|
||||
if (width < 0 || height < 0) {
|
||||
throwInvalidArgument(I.t("You need to specify a valid size. e.g. resize 4 5"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering..."));
|
||||
ImageRendererExecutor
|
||||
.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>() {
|
||||
@Override
|
||||
public void finished(ImageMap result) {
|
||||
ActionBar.removeMessage(player);
|
||||
MessageSender
|
||||
.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("Rendering finished!"));
|
||||
|
||||
if (result.give(player)
|
||||
&& (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) {
|
||||
info(I.t("The rendered map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
boolean isPlayer = sender != null;
|
||||
// TODO Add a per-player toggle for the GUI.
|
||||
if (args.length < 2 && isPlayer) {
|
||||
Gui.open(player, new RenderGui(url));
|
||||
} else {
|
||||
//ImageRendererExecutor.renderAndNotify(url, scaling, player.getUniqueId(), width, height);
|
||||
if (args.length >= 2) {
|
||||
if (args.length >= 3) {
|
||||
try {
|
||||
if (args.length >= 4) {
|
||||
width = Integer.parseInt(args[2]);
|
||||
height = Integer.parseInt(args[3]);
|
||||
} else {
|
||||
String[] size;
|
||||
if (args[2].contains("*") && !args[2].contains("x")) {
|
||||
size = args[2].split("\\*");
|
||||
width = Integer.parseInt(size[0]);
|
||||
height = Integer.parseInt(size[1]);
|
||||
}
|
||||
if (!args[2].contains("*") && args[2].contains("x")) {
|
||||
size = args[2].split("x");
|
||||
width = Integer.parseInt(size[0]);
|
||||
height = Integer.parseInt(size[1]);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
|
||||
throwInvalidArgument(I.t("resize dimension as to be in format <n m> or <nxm> or <n*m>."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
scaling = resizeMode();
|
||||
}
|
||||
if (width < 0 || height < 0) {
|
||||
throwInvalidArgument(I.t("You need to specify a valid size. e.g. resize 4 5"));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering..."));
|
||||
ImageRendererExecutor
|
||||
.render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>() {
|
||||
@Override
|
||||
public void finished(ImageMap result) {
|
||||
ActionBar.removeMessage(player);
|
||||
MessageSender
|
||||
.sendActionBarMessage(player,
|
||||
ChatColor.DARK_GREEN + I.t("Rendering finished!"));
|
||||
|
||||
@Override
|
||||
public void errored(Throwable exception) {
|
||||
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
|
||||
if (result.give(player)
|
||||
&& (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) {
|
||||
info(I.t("The rendered map was too big to fit in your inventory."));
|
||||
info(I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
}
|
||||
|
||||
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
|
||||
player.getName(),
|
||||
exception.getClass().getCanonicalName(),
|
||||
exception.getMessage());
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
ActionBar.removeMessage(player);
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 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.zcraft.quartzlib.components.commands.CommandException;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@CommandInfo(name = "RemotePlacing", usageParameters = "[player name]:map name position rotation")
|
||||
public class RemotePlacingCommand extends IoMCommand {
|
||||
@Override
|
||||
protected void run() throws CommandException {
|
||||
//if wall => need position and direction N/S/E/W
|
||||
//else if floor or ceiling => same + rotation
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(CommandSender sender) {
|
||||
return Permissions.REMOTE_PLACING.grantedTo(sender);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -34,24 +34,6 @@
|
|||
* knowledge of the CeCILL license and that you accept its terms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -70,25 +52,25 @@ public class RenameCommand extends IoMCommand {
|
|||
|
||||
@Override
|
||||
protected void run() throws CommandException {
|
||||
ArrayList<String> arguments = getArgs();
|
||||
|
||||
ArrayList<String> argList = getArgs();
|
||||
|
||||
if (argList.size() != 2) {
|
||||
warning(I.t("Not enough or too many arguments! Usage: /maptool rename <map name> <new map name>"));
|
||||
boolean isTooMany = arguments.size() > 2;
|
||||
boolean isTooFew = arguments.size() < 2;
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImageMap map = MapManager.getMap(playerSender().getUniqueId(), argList.get(0));
|
||||
String oldName = arguments.get(0);
|
||||
ImageMap map = MapManager.getMap(playerSender().getUniqueId(), oldName);
|
||||
if (map == null) {
|
||||
error(I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
map.rename(argList.get(1));
|
||||
String newName = arguments.get(1);
|
||||
map.rename(newName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> complete() throws CommandException {
|
||||
|
||||
if (args.length == 1) {
|
||||
return getMatchingMapNames(playerSender(), args[0]);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -52,6 +52,7 @@ import fr.zcraft.quartzlib.tools.text.MessageSender;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -62,17 +63,10 @@ public class UpdateCommand extends IoMCommand {
|
|||
protected void run() throws CommandException {
|
||||
//TODO fix the issue where to many quick usage of offlineNameFetch will return null
|
||||
ArrayList<String> arguments = getArgs();
|
||||
String warningMsg;
|
||||
if (arguments.size() > 4) {
|
||||
warningMsg = "Too many parameters!"
|
||||
+ " Usage: /maptool update [player name]:<map name> <new url> [stretched|covered]";
|
||||
warning(I.t(warningMsg));
|
||||
return;
|
||||
}
|
||||
if (arguments.size() < 2) {
|
||||
warningMsg =
|
||||
"Too few parameters! Usage: /maptool update [player name]:<map name> <new url> [stretched|covered]";
|
||||
warning(I.t(warningMsg));
|
||||
|
||||
boolean isTooMany = arguments.size() > 4;
|
||||
boolean isTooFew = arguments.size() < 2;
|
||||
if (!checkArguments(isTooMany, isTooFew)) {
|
||||
return;
|
||||
}
|
||||
final String playerName;
|
||||
|
@ -139,87 +133,83 @@ public class UpdateCommand extends IoMCommand {
|
|||
}
|
||||
}
|
||||
|
||||
final ImageUtils.ScalingType scaling;
|
||||
final ImageUtils.ScalingType scaling = ImageUtils.scalingTypeFromName(resize);//TODO test if nothing broke
|
||||
// because I went from 3 to 4 by adding the none as default instead of the contained one.
|
||||
|
||||
switch (resize) {
|
||||
UUID uuid = getPlayerUUID(playerName);
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
case "stretched":
|
||||
scaling = ImageUtils.ScalingType.STRETCHED;
|
||||
break;
|
||||
case "covered":
|
||||
scaling = ImageUtils.ScalingType.COVERED;
|
||||
break;
|
||||
default:
|
||||
scaling = ImageUtils.ScalingType.CONTAINED;
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO passer en static
|
||||
//ImageOnMap.getPlugin().getCommandWorker().offlineNameFetch(playerName, uuid -> {
|
||||
retrieveUUID(playerName, uuid -> {
|
||||
|
||||
ImageMap map = MapManager.getMap(uuid, mapName);
|
||||
|
||||
if (map == null) {
|
||||
warning(sender, I.t("This map does not exist."));
|
||||
URL url1;
|
||||
try {
|
||||
url1 = new URL(url);
|
||||
if (!Permissions.BYPASS_WHITELIST.grantedTo(playerSender) && !checkHostnameWhitelist(url1)) {
|
||||
throwInvalidArgument(I.t("This hosting website is not trusted, if you think that this is an error "
|
||||
+ " contact your server administrator"));
|
||||
return;
|
||||
}
|
||||
|
||||
URL url1;
|
||||
try {
|
||||
url1 = new URL(url);
|
||||
if (!Permissions.BYPASS_WHITELIST.grantedTo(playerSender) && !checkHostnameWhitelist(url1)) {
|
||||
throwInvalidArgument(I.t("This hosting website is not trusted, if you think that this is an error "
|
||||
+ " contact your server administrator"));
|
||||
return;
|
||||
}
|
||||
//TODO replace by a check of the load status.(if not loaded load the mapmanager)
|
||||
MapManager.load(false);//we don't want to spam the console each time we reload the mapManager
|
||||
|
||||
//TODO replace by a check of the load status.(if not loaded load the mapmanager)
|
||||
MapManager.load(false);//we don't want to spam the console each time we reload the mapManager
|
||||
|
||||
Integer[] size = {1, 1};
|
||||
if (map.getType() == ImageMap.Type.POSTER) {
|
||||
size = map.getSize(map.getUserUUID(), map.getId());
|
||||
}
|
||||
|
||||
int width = size[0];
|
||||
int height = size[1];
|
||||
try {
|
||||
if (playerSender != null) {
|
||||
ActionBar.sendPermanentMessage(playerSender, ChatColor.DARK_GREEN + I.t("Updating..."));
|
||||
}
|
||||
ImageRendererExecutor
|
||||
.update(url1, scaling, uuid, map, width, height, new WorkerCallback<ImageMap>() {
|
||||
@Override
|
||||
public void finished(ImageMap result) {
|
||||
if (playerSender != null) {
|
||||
ActionBar.removeMessage(playerSender);
|
||||
MessageSender.sendActionBarMessage(playerSender,
|
||||
ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errored(Throwable exception) {
|
||||
if (playerSender != null) {
|
||||
playerSender
|
||||
.sendMessage(
|
||||
I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
|
||||
}
|
||||
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
|
||||
playerSender.getName(),
|
||||
exception.getClass().getCanonicalName(),
|
||||
exception.getMessage());
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
if (playerSender != null) {
|
||||
ActionBar.removeMessage(playerSender);
|
||||
}
|
||||
}
|
||||
} catch (MalformedURLException | CommandException ex) {
|
||||
warning(sender, I.t("Invalid URL."));
|
||||
Integer[] size = {1, 1};
|
||||
if (map.getType() == ImageMap.Type.POSTER) {
|
||||
size = map.getSize(map.getUserUUID(), map.getId());
|
||||
}
|
||||
});
|
||||
|
||||
if (size.length == 0) {
|
||||
size = new Integer[] {1, 1};
|
||||
}
|
||||
int width = size[0];
|
||||
int height = size[1];
|
||||
try {
|
||||
String msg = I.t("Updating...");
|
||||
if (playerSender != null) {
|
||||
//TODO tester si player humain
|
||||
ActionBar.sendPermanentMessage(playerSender, ChatColor.DARK_GREEN + msg);
|
||||
} else {
|
||||
PluginLogger.info(msg);
|
||||
}
|
||||
ImageRendererExecutor
|
||||
.update(url1, scaling, uuid, map, width, height, new WorkerCallback<ImageMap>() {
|
||||
@Override
|
||||
public void finished(ImageMap result) {
|
||||
String msg = I.t("The map was updated using the new image!");
|
||||
if (playerSender != null) {
|
||||
//TODO tester si player humain
|
||||
ActionBar.removeMessage(playerSender);
|
||||
MessageSender.sendActionBarMessage(playerSender,
|
||||
ChatColor.DARK_GREEN + msg);
|
||||
} else {
|
||||
PluginLogger.info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errored(Throwable exception) {
|
||||
if (playerSender != null) {
|
||||
playerSender
|
||||
.sendMessage(
|
||||
I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
|
||||
}
|
||||
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
|
||||
playerSender.getName(),
|
||||
exception.getClass().getCanonicalName(),
|
||||
exception.getMessage());
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
if (playerSender != null) {
|
||||
ActionBar.removeMessage(playerSender);
|
||||
}
|
||||
}
|
||||
} catch (MalformedURLException | CommandException ex) {
|
||||
warning(sender, I.t("Invalid URL."));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -39,7 +39,6 @@ package fr.moribus.imageonmap.gui;
|
|||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.map.SingleMap;
|
||||
import fr.moribus.imageonmap.ui.MapItemManager;
|
||||
import fr.zcraft.quartzlib.components.gui.ExplorerGui;
|
||||
import fr.zcraft.quartzlib.components.gui.Gui;
|
||||
|
@ -57,8 +56,8 @@ import org.bukkit.inventory.ItemStack;
|
|||
|
||||
public class MapDetailGui extends ExplorerGui<Integer> {
|
||||
private final ImageMap map;
|
||||
private OfflinePlayer offplayer;
|
||||
private String name;
|
||||
private final OfflinePlayer offplayer;
|
||||
private final String name;
|
||||
|
||||
public MapDetailGui(ImageMap map, OfflinePlayer p, String name) {
|
||||
super();
|
||||
|
@ -105,9 +104,7 @@ public class MapDetailGui extends ExplorerGui<Integer> {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (map instanceof SingleMap) {
|
||||
return MapItemManager.createMapItem((SingleMap) map, true);
|
||||
} else if (map instanceof PosterMap) {
|
||||
if (map instanceof PosterMap) {
|
||||
return MapItemManager.createMapItem((PosterMap) map, x, y);
|
||||
}
|
||||
|
||||
|
@ -124,15 +121,11 @@ public class MapDetailGui extends ExplorerGui<Integer> {
|
|||
return MapItemManager.createMapItem(poster, poster.getIndex(mapId));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getEmptyViewItem() {
|
||||
if (map instanceof SingleMap) {
|
||||
return getViewItem(0, 0);
|
||||
} else {
|
||||
/* @Override
|
||||
protected ItemStack getEmptyViewItem() {
|
||||
return super.getEmptyViewItem();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
protected void onUpdate() {
|
||||
/// Title of the map details GUI
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -41,7 +41,6 @@ import fr.moribus.imageonmap.PluginConfiguration;
|
|||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.map.SingleMap;
|
||||
import fr.moribus.imageonmap.ui.MapItemManager;
|
||||
import fr.moribus.imageonmap.ui.SplatterMapManager;
|
||||
import fr.zcraft.quartzlib.components.gui.ExplorerGui;
|
||||
|
@ -72,19 +71,14 @@ public class MapListGui extends ExplorerGui<ImageMap> {
|
|||
@Override
|
||||
protected ItemStack getViewItem(ImageMap map) {
|
||||
String mapDescription;
|
||||
if (map instanceof SingleMap) {
|
||||
/// Displayed subtitle description of a single map on the list GUI
|
||||
mapDescription = I.tl(getPlayerLocale(), "{white}Single map");
|
||||
PosterMap poster = (PosterMap) map;
|
||||
if (poster.hasColumnData()) {
|
||||
/// Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
|
||||
mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} × {1})", poster.getColumnCount(),
|
||||
poster.getRowCount());
|
||||
} else {
|
||||
PosterMap poster = (PosterMap) map;
|
||||
if (poster.hasColumnData()) {
|
||||
/// Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
|
||||
mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} × {1})", poster.getColumnCount(),
|
||||
poster.getRowCount());
|
||||
} else {
|
||||
/// Displayed subtitle description of a poster map without column data on the list GUI
|
||||
mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount());
|
||||
}
|
||||
/// Displayed subtitle description of a poster map without column data on the list GUI
|
||||
mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount());
|
||||
}
|
||||
|
||||
ItemStackBuilder builder = new ItemStackBuilder(Material.FILLED_MAP)
|
||||
|
@ -147,9 +141,7 @@ public class MapListGui extends ExplorerGui<ImageMap> {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (map instanceof SingleMap) {
|
||||
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false, true);
|
||||
} else if (map instanceof PosterMap) {
|
||||
if (map instanceof PosterMap) {
|
||||
PosterMap poster = (PosterMap) map;
|
||||
|
||||
if (poster.hasColumnData()) {
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
|
||||
package fr.moribus.imageonmap.gui;
|
||||
|
||||
import fr.moribus.imageonmap.image.ImageUtils;
|
||||
import fr.zcraft.quartzlib.components.gui.ActionGui;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
|
||||
import fr.zcraft.quartzlib.tools.items.TextualBanners;
|
||||
import java.net.URL;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
|
||||
|
||||
public class RenderGui extends ActionGui {
|
||||
final URL url;
|
||||
|
||||
boolean resize = false;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
boolean originalSizeLoaded = false;
|
||||
int originalWidth = 0;
|
||||
int originalHeight = 0;
|
||||
|
||||
ImageUtils.ScalingType scaling = ImageUtils.ScalingType.NONE;
|
||||
|
||||
public RenderGui(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdate() {
|
||||
setTitle(I.t("Image Editor"));
|
||||
setHeight(6);
|
||||
|
||||
action("toggle_resize", 0, new ItemStackBuilder(Material.PAINTING)
|
||||
.title(ChatColor.LIGHT_PURPLE, ChatColor.BOLD + I.t("Resize image"))
|
||||
.loreLine(ChatColor.DARK_GRAY, resize ? I.t("Enabled") : I.t("Disabled"))
|
||||
.loreSeparator()
|
||||
.longLore(ChatColor.GRAY,
|
||||
I.t("You can automatically resize the image to a certain number of blocks (or item frames)."))
|
||||
.loreSeparator()
|
||||
.loreLine(ChatColor.BLUE, I.t("Original size (in blocks)"))
|
||||
.loreLine(ChatColor.GRAY,
|
||||
originalSizeLoaded ? I.t("{0} × {1}", originalWidth, originalHeight) : I.t("Loading..."))
|
||||
.loreSeparator()
|
||||
.longLore(resize ? I.t("{gray}» {white}Click{gray} to disable resize") :
|
||||
I.t("{gray}» {white}Click{gray} to enable resize"))
|
||||
);
|
||||
|
||||
injectSizeEditor(2, true);
|
||||
injectSizeEditor(11, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the size editor in the GUI.
|
||||
*
|
||||
* @param slot The slot where the editor must start.
|
||||
* @param isWidth True to inject a width-size editor; false to inject a height-editor.
|
||||
*/
|
||||
private void injectSizeEditor(int slot, final boolean isWidth) {
|
||||
final String action_key = isWidth ? "width_" : "height_";
|
||||
final String currentSize = ChatColor.DARK_GRAY + I.t("Current size: {0} × {1}", width, height);
|
||||
|
||||
action(action_key + "_decrement_10", slot++, getBannerButton(false, true, resize)
|
||||
.title(ChatColor.RED, I.t("- 10"))
|
||||
.loreLine(currentSize)
|
||||
.loreSeparator()
|
||||
.longLore(isWidth
|
||||
? I.t("{gray}» {white}Click{gray} to decrease the image's width by 10 blocks")
|
||||
: I.t("{gray}» {white}Click{gray} to decrease the image's height by 10 blocks")
|
||||
)
|
||||
);
|
||||
|
||||
action(action_key + "_decrement_1", slot++, getBannerButton(false, false, resize)
|
||||
.title(ChatColor.RED, I.t("- 1"))
|
||||
.loreLine(currentSize)
|
||||
.loreSeparator()
|
||||
.longLore(isWidth
|
||||
? I.t("{gray}» {white}Click{gray} to decrease the image's width by one block")
|
||||
: I.t("{gray}» {white}Click{gray} to decrease the image's height by one block")
|
||||
)
|
||||
);
|
||||
|
||||
action(action_key + "_increment_1", slot++, getBannerButton(true, false, resize)
|
||||
.title(ChatColor.GREEN, I.t("+ 1"))
|
||||
.loreLine(currentSize)
|
||||
.loreSeparator()
|
||||
.longLore(isWidth
|
||||
? I.t("{gray}» {white}Click{gray} to increase the image's width by one block")
|
||||
: I.t("{gray}» {white}Click{gray} to increase the image's height by one block")
|
||||
)
|
||||
);
|
||||
|
||||
action(action_key + "_increment_10", slot++, getBannerButton(true, true, resize)
|
||||
.title(ChatColor.GREEN, I.t("+ 10"))
|
||||
.loreLine(currentSize)
|
||||
.loreSeparator()
|
||||
.longLore(isWidth
|
||||
? I.t("{gray}» {white}Click{gray} to increase the image's width by 10 blocks")
|
||||
: I.t("{gray}» {white}Click{gray} to increase the image's height by 10 blocks")
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/*(action_key + "_set_values", slot++, getBannerButton(false, false, resize)
|
||||
.title(ChatColor.BLUE, I.t("set the size"))
|
||||
.loreLine(currentSize)
|
||||
.loreSeparator()
|
||||
.longLore(isWidth
|
||||
? I.t("{gray}» {white}Click{gray} to set the image's width")
|
||||
: I.t("{gray}» {white}Click{gray} to set the image's height")
|
||||
)
|
||||
);*/
|
||||
slot++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a banner for the +/- buttons.
|
||||
* + are green, - are red
|
||||
* short steps are light, long steps are dark
|
||||
* disabled banners are in grayscale
|
||||
*
|
||||
* @param positive true for a + banner
|
||||
* @param longStep true for a darker banner
|
||||
* @param disabled true for a grayscale banner
|
||||
* @return The banner in a builder.
|
||||
*/
|
||||
private ItemStackBuilder getBannerButton(boolean positive, boolean longStep, boolean disabled) {
|
||||
//final char symbol = positive ? '+' : '-'; //TODO this need rework have something that work but need QL update
|
||||
final char symbol = positive ? '*' : '-';
|
||||
final DyeColor background;
|
||||
|
||||
if (disabled) {
|
||||
background = longStep ? DyeColor.BLACK : DyeColor.GRAY;
|
||||
} else {
|
||||
if (positive) {
|
||||
background = longStep ? DyeColor.GREEN : DyeColor.LIME;
|
||||
} else {
|
||||
background = longStep ? DyeColor.RED : DyeColor.PINK;
|
||||
}
|
||||
}
|
||||
|
||||
return new ItemStackBuilder(TextualBanners.getCharBanner(symbol, background, DyeColor.BLACK));
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,15 +36,20 @@
|
|||
|
||||
package fr.moribus.imageonmap.image;
|
||||
|
||||
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.PluginConfiguration;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.components.worker.Worker;
|
||||
import fr.zcraft.quartzlib.components.worker.WorkerAttributes;
|
||||
import fr.zcraft.quartzlib.components.worker.WorkerCallback;
|
||||
import fr.zcraft.quartzlib.components.worker.WorkerRunnable;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.text.ActionBar;
|
||||
import fr.zcraft.quartzlib.tools.text.MessageSender;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -56,9 +61,46 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.Future;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@WorkerAttributes(name = "Image Renderer", queriesMainThread = true)
|
||||
public class ImageRendererExecutor extends Worker {
|
||||
public static void renderAndNotify(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID,
|
||||
final int width, final int height) {
|
||||
final Player player = Bukkit.getPlayer(playerUUID);
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering..."));
|
||||
|
||||
render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback<ImageMap>() {
|
||||
@Override
|
||||
public void finished(ImageMap result) {
|
||||
ActionBar.removeMessage(player);
|
||||
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("Rendering finished!"));
|
||||
|
||||
if (result.give(player) && (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) {
|
||||
player.sendMessage(ChatColor.GRAY + I.t("The rendered map was too big to fit in your inventory."));
|
||||
player.sendMessage(ChatColor.GRAY + I.t("Use '/maptool getremaining' to get the remaining maps."));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errored(Throwable exception) {
|
||||
ActionBar.removeMessage(player);
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static URLConnection connecting(URL url) throws IOException {
|
||||
final URLConnection connection = url.openConnection();
|
||||
connection.addRequestProperty("User-Agent",
|
||||
|
@ -94,6 +136,7 @@ public class ImageRendererExecutor extends Worker {
|
|||
public static 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 {
|
||||
|
||||
|
@ -144,14 +187,11 @@ public class ImageRendererExecutor extends Worker {
|
|||
}
|
||||
// Limits are in place and the player does NOT have rights to avoid them.
|
||||
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
|
||||
return ret;
|
||||
}
|
||||
final BufferedImage resizedImage =
|
||||
scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
|
||||
final BufferedImage resizedImage;
|
||||
|
||||
resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
|
||||
image.flush();//Safe to free
|
||||
|
||||
return renderPoster(resizedImage, playerUUID);
|
||||
}
|
||||
}, callback);
|
||||
|
@ -204,27 +244,6 @@ public class ImageRendererExecutor extends Worker {
|
|||
});
|
||||
}
|
||||
|
||||
private static ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable {
|
||||
MapManager.checkMapLimit(1, playerUUID);
|
||||
final Future<Integer> futureMapID = submitToMainThread(new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return MapManager.getNewMapsIds(1)[0];
|
||||
}
|
||||
});
|
||||
|
||||
final int mapID = futureMapID.get();
|
||||
ImageIOExecutor.saveImage(mapID, image);
|
||||
submitToMainThread(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
Renderer.installRenderer(image, mapID);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return MapManager.createMap(playerUUID, mapID);
|
||||
}
|
||||
|
||||
private static ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable {
|
||||
final PosterImage poster = new PosterImage(image);
|
||||
final int mapCount = poster.getImagesCount();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -125,6 +125,29 @@ public class ImageUtils {
|
|||
|
||||
}
|
||||
|
||||
public static ScalingType scalingTypeFromName(String resize) {
|
||||
switch (resize) {
|
||||
case "stretch":
|
||||
case "stretched":
|
||||
case "resize-stretched":
|
||||
return ScalingType.STRETCHED;
|
||||
|
||||
case "cover":
|
||||
case "covered":
|
||||
case "resize-covered":
|
||||
return ScalingType.COVERED;
|
||||
|
||||
case "contain":
|
||||
case "contained":
|
||||
case "resize-contained":
|
||||
case "resize":
|
||||
return ScalingType.CONTAINED;
|
||||
|
||||
default:
|
||||
return ScalingType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ScalingType {
|
||||
NONE,
|
||||
CONTAINED,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.map;
|
||||
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.xml.crypto.Data;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
|
||||
public class DATReader {
|
||||
|
||||
public boolean saveData(String filePath) {
|
||||
try {
|
||||
BukkitObjectOutputStream out =
|
||||
new BukkitObjectOutputStream(new GZIPOutputStream(new FileOutputStream(filePath)));
|
||||
out.writeObject(this);
|
||||
out.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
PluginLogger.error("" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean loadData(String filePath) {
|
||||
try {
|
||||
BukkitObjectInputStream in =
|
||||
new BukkitObjectInputStream(new GZIPInputStream(new FileInputStream(filePath)));
|
||||
Data data = (Data) in.readObject();
|
||||
PluginLogger.info("loaded data" + data);
|
||||
in.close();
|
||||
return true;
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
package tutorial;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
|
||||
|
||||
public class Data implements Serializable {
|
||||
private static transient final long serialVersionUID = -1681012206529286330L;
|
||||
|
||||
public final HashMap<Location, String> blockSnapShot;
|
||||
public final HashSet<UUID> previouslyOnlinePlayers;
|
||||
|
||||
// Can be used for saving
|
||||
public Data(HashMap<Location, String> blockSnapShot, HashSet<UUID> previouslyOnlinePlayers) {
|
||||
this.blockSnapShot = blockSnapShot;
|
||||
this.previouslyOnlinePlayers = previouslyOnlinePlayers;
|
||||
}
|
||||
// Can be used for loading
|
||||
public Data(Data loadedData) {
|
||||
this.blockSnapShot = loadedData.blockSnapShot;
|
||||
this.previouslyOnlinePlayers = loadedData.previouslyOnlinePlayers;
|
||||
}
|
||||
|
||||
public boolean saveData(String filePath) {
|
||||
try {
|
||||
BukkitObjectOutputStream out =
|
||||
new BukkitObjectOutputStream(new GZIPOutputStream(new FileOutputStream(filePath)));
|
||||
out.writeObject(this);
|
||||
out.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static Data loadData(String filePath) {
|
||||
try {
|
||||
BukkitObjectInputStream in =
|
||||
new BukkitObjectInputStream(new GZIPInputStream(new FileInputStream(filePath)));
|
||||
Data data = (Data) in.readObject();
|
||||
in.close();
|
||||
return data;
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static void getBlocksPlayersAndSave() {
|
||||
// HashMap used for storing blocks
|
||||
HashMap<Location, String> blockSnapShot = new HashMap<Location, String>();
|
||||
// HashSet used for storing the online players
|
||||
HashSet<UUID> previouslyOnlinePlayers = new HashSet<UUID>();
|
||||
// Grabs the spawn location of the first world the server finds
|
||||
Location spawnLocation = Bukkit.getServer().getWorlds().iterator().next().getSpawnLocation();
|
||||
// One variable to store our blockLocation
|
||||
Location blockLocation;
|
||||
// Variables to store our x y z coordinates
|
||||
int x, y, z;
|
||||
// We will first retrieve all the currently online players
|
||||
Bukkit.getServer().getOnlinePlayers().forEach(player -> previouslyOnlinePlayers.add(player.getUniqueId()));
|
||||
// Next we will retrieve all block data in a 64 by 64 radius around the spawn.
|
||||
|
||||
// While looping, using the new keyword and making declarations like "int x = 0;"
|
||||
// will create garbage, and that garbage will start to pile up if the loop is
|
||||
// extensive. We will take as much of a load off of the garbage collector as we
|
||||
// can here by re-assigning x,y,z not re-declaring, and re-assigning the declared
|
||||
// blockLocation to retrieve the block data. (we are going to store 262,144 blocks...)
|
||||
for (x = 0; x <= 32; x++) {
|
||||
for (y = 0; y <= 32; y++) {
|
||||
for(z = 0; z <= 32; z++) {
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() - x,
|
||||
spawnLocation.getY() - y,
|
||||
spawnLocation.getZ() - z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() + x,
|
||||
spawnLocation.getY() - y,
|
||||
spawnLocation.getZ() - z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() - x,
|
||||
spawnLocation.getY() + y,
|
||||
spawnLocation.getZ() - z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() - x,
|
||||
spawnLocation.getY() - y,
|
||||
spawnLocation.getZ() + z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() + x,
|
||||
spawnLocation.getY() + y,
|
||||
spawnLocation.getZ() + z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() - x,
|
||||
spawnLocation.getY() + y,
|
||||
spawnLocation.getZ() + z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() + x,
|
||||
spawnLocation.getY() - y,
|
||||
spawnLocation.getZ() + z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
blockSnapShot.put(blockLocation = new Location(spawnLocation.getWorld(),
|
||||
spawnLocation.getX() + x,
|
||||
spawnLocation.getY() + y,
|
||||
spawnLocation.getZ() - z), blockLocation.getBlock().getBlockData().getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally we save the retrieved data to a file
|
||||
|
||||
// You will most likely want to change the file location to your some other directory,
|
||||
// like your plugin's data directory, instead of the Tutorial's.
|
||||
new Data(blockSnapShot, previouslyOnlinePlayers).saveData("Tutorial.data");
|
||||
Bukkit.getServer().getLogger().log(Level.INFO, "Data Saved");
|
||||
}
|
||||
public static void welcomePlayersAndResetBlocks() {
|
||||
// Load the data from disc using our loadData method.
|
||||
Data data = new Data(Data.loadData("Tutorial.data"));
|
||||
// For each player that is current online send them a message
|
||||
data.previouslyOnlinePlayers.forEach(playerId -> {
|
||||
if (Bukkit.getServer().getPlayer(playerId).isOnline()) {
|
||||
Bukkit.getServer().getPlayer(playerId).
|
||||
sendMessage("Thanks for coming back after downtime. Hope you see the spawn blocks change!");
|
||||
}
|
||||
});
|
||||
// Change all of the blocks around the spawn to what we have saved in our file.
|
||||
data.blockSnapShot.keySet().forEach(location ->
|
||||
location.getBlock().setBlockData(Bukkit.getServer().createBlockData(data.blockSnapShot.get(location))));
|
||||
Bukkit.getServer().getLogger().log(Level.INFO, "Data loaded");
|
||||
}
|
||||
}*/
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -91,7 +91,7 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
}
|
||||
|
||||
public static ImageMap fromConfig(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
|
||||
Type mapType;
|
||||
Type mapType;//TODO refactor this
|
||||
try {
|
||||
mapType = Type.valueOf((String) map.get("type"));
|
||||
} catch (ClassCastException ex) {
|
||||
|
@ -100,7 +100,6 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
|
||||
switch (mapType) {
|
||||
case SINGLE:
|
||||
return new SingleMap(map, userUUID);
|
||||
case POSTER:
|
||||
return new PosterMap(map, userUUID);
|
||||
default:
|
||||
|
@ -114,11 +113,11 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
MapManager.getPlayerMapStore(playerUUID).getToolConfig().getConfigurationSection("PlayerMapStore");
|
||||
|
||||
if (section == null) {
|
||||
return null;
|
||||
return new Integer[0];
|
||||
}
|
||||
List<Map<String, Object>> list = (List<Map<String, Object>>) section.getList("mapList");
|
||||
if (list == null) {
|
||||
return null;
|
||||
return new Integer[0];
|
||||
}
|
||||
|
||||
for (Map<String, Object> tmpMap : list) {
|
||||
|
@ -126,7 +125,7 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
return new Integer[] {(Integer) tmpMap.get("columns"), (Integer) tmpMap.get("rows")};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return new Integer[0];
|
||||
}
|
||||
|
||||
protected static <T> T getFieldValue(Map<String, Object> map, String fieldName)
|
||||
|
@ -149,6 +148,7 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
|
||||
public abstract int[] getMapsIDs();
|
||||
|
||||
public abstract int getFirstMapID();
|
||||
/* ====== Serialization methods ====== */
|
||||
|
||||
public abstract boolean managesMap(int mapID);
|
||||
|
@ -172,6 +172,14 @@ public abstract class ImageMap implements ConfigurationSerializable {
|
|||
return MapItemManager.give(player, this);
|
||||
}
|
||||
|
||||
public boolean give(Player player, int quantity) {
|
||||
boolean bool = true;
|
||||
for (int i = 0; i < quantity; i++) {
|
||||
bool = bool && MapItemManager.give(player, this);
|
||||
}
|
||||
return bool;
|
||||
}
|
||||
|
||||
protected abstract void postSerialize(Map<String, Object> map);
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,82 +1,56 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.map;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
public class SingleMap extends ImageMap {
|
||||
protected final int mapID;
|
||||
|
||||
public SingleMap(UUID ownerUUID, int mapID, String id, String name) {
|
||||
super(ownerUUID, Type.SINGLE, id, name);
|
||||
this.mapID = mapID;
|
||||
}
|
||||
|
||||
public SingleMap(UUID ownerUUID, int mapID) {
|
||||
this(ownerUUID, mapID, null, null);
|
||||
}
|
||||
|
||||
public SingleMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
|
||||
super(map, userUUID, Type.SINGLE);
|
||||
mapID = getFieldValue(map, "mapID");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getMapsIDs() {
|
||||
return new int[] {mapID};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean managesMap(int mapID) {
|
||||
return this.mapID == mapID;
|
||||
}
|
||||
|
||||
/* ====== Serialization methods ====== */
|
||||
|
||||
@Override
|
||||
public int getMapCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postSerialize(Map<String, Object> map) {
|
||||
map.put("mapID", mapID);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* 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 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.map;
|
||||
|
||||
public class MapIndexes {
|
||||
|
||||
private final int columnIndex;
|
||||
private final int rowIndex;
|
||||
|
||||
public MapIndexes(int rowIndex, int columnIndex) {
|
||||
this.rowIndex = rowIndex;
|
||||
this.columnIndex = columnIndex;
|
||||
}
|
||||
|
||||
public int getColumnIndex() {
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
public int getRowIndex() {
|
||||
return rowIndex;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -45,6 +45,7 @@ import fr.zcraft.quartzlib.tools.PluginLogger;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
|
@ -101,8 +102,10 @@ public abstract class MapManager {
|
|||
}
|
||||
|
||||
public static ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException {
|
||||
ImageMap newMap = new SingleMap(playerUUID, mapID);
|
||||
addMap(newMap);
|
||||
//ImageMap newMap = new SingleMap(playerUUID, mapID);
|
||||
int[] ids = new int[] {mapID};
|
||||
ImageMap newMap = new PosterMap(playerUUID, ids, 1, 1);
|
||||
addMap(newMap);//TODO refactor this
|
||||
return newMap;
|
||||
}
|
||||
|
||||
|
@ -110,7 +113,8 @@ public abstract class MapManager {
|
|||
ImageMap newMap;
|
||||
|
||||
if (image.getImagesCount() == 1) {
|
||||
newMap = new SingleMap(playerUUID, mapsIDs[0]);
|
||||
newMap = new PosterMap(playerUUID, mapsIDs, 1, 1);//TODO refactor this
|
||||
//newMap = new SingleMap(playerUUID, mapsIDs[0]);
|
||||
} else {
|
||||
newMap = new PosterMap(playerUUID, mapsIDs, image.getColumns(), image.getLines());
|
||||
}
|
||||
|
@ -157,7 +161,7 @@ public abstract class MapManager {
|
|||
public static void notifyModification(UUID playerUUID) {
|
||||
getPlayerMapStore(playerUUID).notifyModification();
|
||||
if (autosaveTask == null) {
|
||||
Bukkit.getScheduler().runTaskLater(ImageOnMap.getPlugin(), new AutosaveRunnable(), SAVE_DELAY);
|
||||
Bukkit.getScheduler().runTaskLater(ImageOnMap.getPlugin(), new AutoSaveRunnable(), SAVE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,7 +272,7 @@ public abstract class MapManager {
|
|||
//Loading
|
||||
public static void load(boolean verbose) {
|
||||
int loadedFilesCount = 0;
|
||||
for (File file : ImageOnMap.getPlugin().getMapsDirectory().listFiles()) {
|
||||
for (File file : Objects.requireNonNull(ImageOnMap.getPlugin().getMapsDirectory().listFiles())) {
|
||||
UUID uuid = getUUIDFromFile(file);
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
|
@ -373,7 +377,7 @@ public abstract class MapManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static class AutosaveRunnable implements Runnable {
|
||||
private static class AutoSaveRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (playerMaps) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -54,10 +54,11 @@ import org.bukkit.configuration.file.FileConfiguration;
|
|||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerMapStore implements ConfigurationSerializable {
|
||||
private final UUID playerUUID;
|
||||
private final ArrayList<ImageMap> mapList = new ArrayList<ImageMap>();
|
||||
private final ArrayList<ImageMap> mapList = new ArrayList<>();
|
||||
private boolean modified = false;
|
||||
private int mapCount = 0;
|
||||
private FileConfiguration mapConfig = null;
|
||||
|
@ -67,6 +68,7 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
this.playerUUID = playerUUID;
|
||||
}
|
||||
|
||||
//TODO maybe usefull to merge with the other manages map
|
||||
public synchronized boolean managesMap(int mapID) {
|
||||
for (ImageMap map : mapList) {
|
||||
if (map.managesMap(mapID)) {
|
||||
|
@ -83,13 +85,7 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
if (item.getType() != Material.FILLED_MAP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ImageMap map : mapList) {
|
||||
if (map.managesMap(item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return managesMap(MapManager.getMapIdFromItemStack(item));
|
||||
}
|
||||
|
||||
public synchronized void addMap(ImageMap map) throws MapManagerException {
|
||||
|
@ -108,33 +104,27 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
}
|
||||
|
||||
public synchronized void deleteMap(ImageMap map) throws MapManagerException {
|
||||
remove_Map(map);
|
||||
delete_Map(map);
|
||||
notifyModification();
|
||||
}
|
||||
|
||||
private void remove_Map(ImageMap map) throws MapManagerException {
|
||||
private void delete_Map(ImageMap map) throws MapManagerException {
|
||||
if (!mapList.remove(map)) {
|
||||
throw new MapManagerException(Reason.IMAGEMAP_DOES_NOT_EXIST);
|
||||
}
|
||||
mapCount -= map.getMapCount();
|
||||
}
|
||||
|
||||
public synchronized boolean mapExists(String id) {
|
||||
for (ImageMap map : mapList) {
|
||||
if (map.getId().equals(id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public synchronized boolean mapExists(String mapId) {
|
||||
return getMap(mapId) != null;
|
||||
}
|
||||
|
||||
public String getNextAvailableMapID(String mapId) {
|
||||
//TODO check if the value is always greater than the id count
|
||||
if (!mapExists(mapId)) {
|
||||
return mapId;
|
||||
}
|
||||
int id = 0;
|
||||
|
||||
do {
|
||||
id++;
|
||||
} while (mapExists(mapId + "-" + id));
|
||||
|
@ -143,11 +133,12 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
}
|
||||
|
||||
public synchronized List<ImageMap> getMapList() {
|
||||
return new ArrayList(mapList);
|
||||
return new ArrayList<>(mapList);
|
||||
}
|
||||
|
||||
//TODO refactor to arraylist instead of an array
|
||||
public synchronized ImageMap[] getMaps() {
|
||||
return mapList.toArray(new ImageMap[mapList.size()]);
|
||||
return mapList.toArray(new ImageMap[0]);
|
||||
}
|
||||
|
||||
public synchronized ImageMap getMap(String mapId) {
|
||||
|
@ -156,7 +147,6 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -202,9 +192,9 @@ public class PlayerMapStore implements ConfigurationSerializable {
|
|||
/* ****** Configuration Files management ***** */
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
ArrayList<Map> list = new ArrayList<Map>();
|
||||
public @NotNull Map<String, Object> serialize() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
ArrayList<Map> list = new ArrayList<>();
|
||||
synchronized (this) {
|
||||
for (ImageMap tmpMap : mapList) {
|
||||
list.add(tmpMap.serialize());
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,11 +36,17 @@
|
|||
|
||||
package fr.moribus.imageonmap.map;
|
||||
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.world.WorldUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PosterMap extends ImageMap {
|
||||
protected final int[] mapsIDs;
|
||||
|
@ -76,6 +82,16 @@ public class PosterMap extends ImageMap {
|
|||
return mapsIDs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstMapID() {
|
||||
int first = -1;
|
||||
for (int id : mapsIDs) {
|
||||
if (first == -1 || first > id) {
|
||||
first = id;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
/* ====== Serialization methods ====== */
|
||||
|
||||
@Override
|
||||
|
@ -158,6 +174,7 @@ public class PosterMap extends ImageMap {
|
|||
|
||||
|
||||
public int getMapIdAtReverseZ(int index, BlockFace orientation, BlockFace bf) {
|
||||
//TODO maybe a bug there why don't use orientation?
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
switch (bf) {
|
||||
|
@ -177,7 +194,6 @@ public class PosterMap extends ImageMap {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public boolean hasColumnData() {
|
||||
return rowCount != 0 && columnCount != 0;
|
||||
}
|
||||
|
@ -193,8 +209,87 @@ public class PosterMap extends ImageMap {
|
|||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid map ID");
|
||||
}
|
||||
|
||||
public int getSortedIndex(int mapID) {
|
||||
int[] ids = mapsIDs.clone();
|
||||
Arrays.sort(ids);
|
||||
for (int i : ids) {
|
||||
PluginLogger.info("" + i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mapsIDs.length; i++) {
|
||||
if (ids[i] == mapID) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid map ID");
|
||||
}
|
||||
|
||||
public MapIndexes getIndexes(int mapID) {
|
||||
int index = getSortedIndex(mapID);
|
||||
PluginLogger.info(rowCount + " " + columnCount + " " + index);
|
||||
return new MapIndexes(index / columnCount, index % columnCount);
|
||||
}
|
||||
|
||||
public Location findLocationFirstFrame(ItemFrame frame, Player player) {
|
||||
final ImageMap map = MapManager.getMap(frame.getItem());
|
||||
if (!(map instanceof PosterMap)) {
|
||||
return null;
|
||||
}
|
||||
PosterMap poster = (PosterMap) map;
|
||||
if (!poster.hasColumnData()) {
|
||||
return null;
|
||||
}
|
||||
int mapID = MapManager.getMapIdFromItemStack(frame.getItem());
|
||||
|
||||
BlockFace bf = WorldUtils.get4thOrientation(player.getLocation());
|
||||
|
||||
MapIndexes mapindexes = getIndexes(mapID);
|
||||
int row = mapindexes.getRowIndex();
|
||||
int column = mapindexes.getColumnIndex();
|
||||
Location loc = frame.getLocation();
|
||||
PluginLogger.info("\n\nlocalization of the initial clicked frame " + loc);
|
||||
PluginLogger.info("row " + row + " col " + column);
|
||||
switch (frame.getFacing().getOppositeFace()) {
|
||||
case UP:
|
||||
case DOWN:
|
||||
switch (bf) {
|
||||
case NORTH:
|
||||
loc.add(-row, 0, column);
|
||||
break;
|
||||
case SOUTH:
|
||||
loc.add(row, 0, -column);
|
||||
break;
|
||||
case WEST:
|
||||
loc.add(row, 0, column);
|
||||
break;
|
||||
case EAST:
|
||||
loc.add(-row, 0, -column);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
loc.add(0, row, -column);
|
||||
break;
|
||||
case WEST:
|
||||
loc.add(0, row, column);
|
||||
break;
|
||||
case NORTH:
|
||||
loc.add(-column, row, 0);
|
||||
break;
|
||||
case SOUTH:
|
||||
loc.add(column, row, 0);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
PluginLogger.info("\n\nlocalization of the first frame " + loc);
|
||||
return loc;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,11 +36,10 @@
|
|||
|
||||
package fr.moribus.imageonmap.migration;
|
||||
|
||||
import fr.moribus.imageonmap.ImageOnMap;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
|
||||
|
||||
//TODO need to support new render folder and write on maps automatically
|
||||
public class MigratorExecutor {
|
||||
private static Thread migratorThread;
|
||||
|
||||
|
@ -49,7 +48,7 @@ public class MigratorExecutor {
|
|||
PluginLogger.error(I.t("Migration is already running."));
|
||||
return;
|
||||
}
|
||||
migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration");
|
||||
//migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration");
|
||||
migratorThread.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.migration;
|
||||
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.SingleMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
class OldSavedMap {
|
||||
private final short mapId;
|
||||
private final String mapName;
|
||||
private final String userName;
|
||||
|
||||
public OldSavedMap(Object rawData) throws InvalidConfigurationException {
|
||||
List<String> data;
|
||||
try {
|
||||
data = (List<String>) rawData;
|
||||
} catch (ClassCastException ex) {
|
||||
throw new InvalidConfigurationException("Invalid map data : " + ex.getMessage());
|
||||
}
|
||||
|
||||
if (data.size() < 3) {
|
||||
throw new InvalidConfigurationException("Map data too short (given : " + data.size() + ", expected 3)");
|
||||
}
|
||||
try {
|
||||
mapId = Short.parseShort(data.get(0));
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new InvalidConfigurationException("Invalid map ID : " + ex.getMessage());
|
||||
}
|
||||
|
||||
mapName = data.get(1);
|
||||
userName = data.get(2);
|
||||
}
|
||||
|
||||
public ImageMap toImageMap(UUID userUUID) {
|
||||
return new SingleMap(userUUID, mapId, null, mapName);
|
||||
}
|
||||
|
||||
public void serialize(Configuration configuration) {
|
||||
ArrayList<String> data = new ArrayList<String>();
|
||||
data.add(Short.toString(mapId));
|
||||
data.add(mapName);
|
||||
data.add(userName);
|
||||
configuration.set(mapName, data);
|
||||
}
|
||||
|
||||
public boolean isMapValid() {
|
||||
return MapManager.mapIdExists(mapId);
|
||||
}
|
||||
|
||||
public short getMapId() {
|
||||
return mapId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.migration;
|
||||
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
|
||||
class OldSavedPoster {
|
||||
private final String userName;
|
||||
private final String posterName;
|
||||
private final short[] mapsIds;
|
||||
|
||||
public OldSavedPoster(Object rawData, String key) throws InvalidConfigurationException {
|
||||
posterName = key;
|
||||
List<String> data;
|
||||
try {
|
||||
data = (List<String>) rawData;
|
||||
} catch (ClassCastException ex) {
|
||||
throw new InvalidConfigurationException("Invalid map data : " + ex.getMessage());
|
||||
}
|
||||
|
||||
if (data.size() < 2) {
|
||||
throw new InvalidConfigurationException(
|
||||
"Poster data too short (given : " + data.size() + ", expected at least 2)");
|
||||
}
|
||||
userName = data.get(0);
|
||||
mapsIds = new short[data.size() - 1];
|
||||
|
||||
for (int i = 1, c = data.size(); i < c; i++) {
|
||||
try {
|
||||
mapsIds[i - 1] = Short.parseShort(data.get(i));
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new InvalidConfigurationException("Invalid map ID : " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(OldSavedMap map) {
|
||||
short mapId = map.getMapId();
|
||||
|
||||
for (short mapsId : mapsIds) {
|
||||
if (mapsId == mapId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ImageMap toImageMap(UUID userUUID) {
|
||||
// Converts the maps IDs to int as MC 1.13.2+ uses integer ids
|
||||
final int[] mapsIdsInt = new int[mapsIds.length];
|
||||
Arrays.setAll(mapsIdsInt, i -> mapsIds[i]);
|
||||
|
||||
return new PosterMap(userUUID, mapsIdsInt, null, "poster", 0, 0);
|
||||
}
|
||||
|
||||
public void serialize(Configuration configuration) {
|
||||
ArrayList<String> data = new ArrayList<String>();
|
||||
data.add(userName);
|
||||
|
||||
for (short mapId : mapsIds) {
|
||||
data.add(Short.toString(mapId));
|
||||
}
|
||||
|
||||
configuration.set(posterName, data);
|
||||
|
||||
}
|
||||
|
||||
public boolean isMapValid() {
|
||||
for (short mapId : mapsIds) {
|
||||
if (!MapManager.mapIdExists(mapId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public short[] getMapsIds() {
|
||||
return mapsIds;
|
||||
}
|
||||
}
|
|
@ -1,619 +0,0 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
*
|
||||
* 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 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
|
||||
* 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 license and that you accept its terms.
|
||||
*/
|
||||
|
||||
package fr.moribus.imageonmap.migration;
|
||||
|
||||
import fr.moribus.imageonmap.ImageOnMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.mojang.UUIDFetcher;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* This class represents and executes the ImageOnMap v3.x migration process
|
||||
*/
|
||||
public class V3Migrator implements Runnable {
|
||||
/**
|
||||
* The name of the former images directory
|
||||
*/
|
||||
private static final String OLD_IMAGES_DIRECTORY_NAME = "Image";
|
||||
|
||||
/**
|
||||
* The name of the former file that contained all the maps definitions (including posters)
|
||||
*/
|
||||
private static final String OLD_MAPS_FILE_NAME = "map.yml";
|
||||
|
||||
/**
|
||||
* The name of the former file that contained all the posters definitions
|
||||
*/
|
||||
private static final String OLD_POSTERS_FILE_NAME = "poster.yml";
|
||||
|
||||
/**
|
||||
* The name of the backup directory that will contain the pre-v3 files that
|
||||
* were present before the migration started
|
||||
*/
|
||||
private static final String BACKUPS_PREV3_DIRECTORY_NAME = "backups_pre-v3";
|
||||
|
||||
/**
|
||||
* The name of the backup directory that will contain the post-v3 files that
|
||||
* were present before the migration started
|
||||
*/
|
||||
private static final String BACKUPS_POSTV3_DIRECTORY_NAME = "backups_post-v3";
|
||||
/**
|
||||
* The plugin that is running the migration
|
||||
*/
|
||||
private final ImageOnMap plugin;
|
||||
/**
|
||||
* The backup directory that will contain the pre-v3 files that
|
||||
* were present before the migration started
|
||||
*/
|
||||
private final File backupsPrev3Directory;
|
||||
/**
|
||||
* The backup directory that will contain the post-v3 files that
|
||||
* were present before the migration started
|
||||
*/
|
||||
private final File backupsPostv3Directory;
|
||||
/**
|
||||
* The list of all the posters to migrate
|
||||
*/
|
||||
private final ArrayDeque<OldSavedPoster> postersToMigrate;
|
||||
/**
|
||||
* The list of all the single maps to migrate
|
||||
*/
|
||||
private final ArrayDeque<OldSavedMap> mapsToMigrate;
|
||||
/**
|
||||
* The set of all the user names to retreive the UUID from Mojang
|
||||
*/
|
||||
private final HashSet<String> userNamesToFetch;
|
||||
/**
|
||||
* The former file that contained all the posters definitions
|
||||
*/
|
||||
private File oldPostersFile;
|
||||
/**
|
||||
* The former file that contained all the maps definitions (including posters)
|
||||
*/
|
||||
private File oldMapsFile;
|
||||
/**
|
||||
* The map of all the usernames and their corresponding UUIDs
|
||||
*/
|
||||
private Map<String, UUID> usersUUIDs;
|
||||
/**
|
||||
* Defines if the migration process is currently running
|
||||
*/
|
||||
private boolean isRunning = false;
|
||||
|
||||
public V3Migrator(ImageOnMap plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
|
||||
oldPostersFile = new File(dataFolder, OLD_POSTERS_FILE_NAME);
|
||||
oldMapsFile = new File(dataFolder, OLD_MAPS_FILE_NAME);
|
||||
|
||||
backupsPrev3Directory = new File(dataFolder, BACKUPS_PREV3_DIRECTORY_NAME);
|
||||
backupsPostv3Directory = new File(dataFolder, BACKUPS_POSTV3_DIRECTORY_NAME);
|
||||
|
||||
postersToMigrate = new ArrayDeque<>();
|
||||
mapsToMigrate = new ArrayDeque<>();
|
||||
userNamesToFetch = new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the former images directory of a given plugin
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return the corresponding 'Image' directory
|
||||
*/
|
||||
public static File getOldImagesDirectory(Plugin plugin) {
|
||||
return new File(plugin.getDataFolder(), OLD_IMAGES_DIRECTORY_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a standard file copy, and checks the integrity of the destination
|
||||
* file after the copy
|
||||
*
|
||||
* @param sourceFile The file to copy
|
||||
* @param destinationFile The destination file
|
||||
* @throws IOException If the copy failed, if the integrity check failed, or if the destination file already exists
|
||||
*/
|
||||
private static void verifiedBackupCopy(File sourceFile, File destinationFile) throws IOException {
|
||||
if (destinationFile.exists()) {
|
||||
throw new IOException(
|
||||
"Backup copy failed : destination file (" + destinationFile.getName() + ") already exists.");
|
||||
}
|
||||
|
||||
long sourceSize = sourceFile.length();
|
||||
String sourceCheckSum = fileCheckSum(sourceFile, "SHA1");
|
||||
|
||||
Path sourcePath = Paths.get(sourceFile.getAbsolutePath());
|
||||
Path destinationPath = Paths.get(destinationFile.getAbsolutePath());
|
||||
Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
long destinationSize = destinationFile.length();
|
||||
String destinationCheckSum = fileCheckSum(destinationFile, "SHA1");
|
||||
|
||||
if (sourceSize != destinationSize || !sourceCheckSum.equals(destinationCheckSum)) {
|
||||
throw new IOException("Backup copy failed : source and destination files ("
|
||||
+ sourceFile.getName()
|
||||
+ ") differ after copy.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ****** Actions ***** */
|
||||
|
||||
/**
|
||||
* Calculates the checksum of a given file
|
||||
*
|
||||
* @param file The file to calculate the checksum of
|
||||
* @param algorithmName The name of the algorithm to use
|
||||
* @return The resulting checksum in hexadecimal format
|
||||
* @throws IOException
|
||||
**/
|
||||
private static String fileCheckSum(File file, String algorithmName) throws IOException {
|
||||
MessageDigest instance;
|
||||
try {
|
||||
instance = MessageDigest.getInstance(algorithmName);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new IOException(
|
||||
"Could not check file integrity because of NoSuchAlgorithmException : " + ex.getMessage());
|
||||
}
|
||||
|
||||
FileInputStream inputStream = new FileInputStream(file);
|
||||
|
||||
byte[] data = new byte[1024];
|
||||
int read = 0;
|
||||
|
||||
while ((read = inputStream.read(data)) != -1) {
|
||||
instance.update(data);
|
||||
}
|
||||
|
||||
byte[] hashBytes = instance.digest();
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
char hexChar;
|
||||
for (int i = 0; i < hashBytes.length; i++) {
|
||||
hexChar = Integer.toHexString((hashBytes[i] & 0xff) + 0x100).charAt(0);
|
||||
buffer.append(hexChar);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the full migration
|
||||
*/
|
||||
private void migrate() {
|
||||
try {
|
||||
if (!spotFilesToMigrate()) {
|
||||
return;
|
||||
}
|
||||
if (checkForExistingBackups()) {
|
||||
return;
|
||||
}
|
||||
if (!loadOldFiles()) {
|
||||
return;
|
||||
}
|
||||
backupMapData();
|
||||
fetchUUIDs();
|
||||
if (!fetchMissingUUIDs()) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
PluginLogger.error(I.t("Error while preparing migration"));
|
||||
PluginLogger.error(I.t("Aborting migration. No change has been made."), ex);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mergeMapData();
|
||||
saveChanges();
|
||||
cleanup();
|
||||
} catch (Exception ex) {
|
||||
PluginLogger.error(I.t("Error while migrating"), ex);
|
||||
PluginLogger.error(I.t("Aborting migration. Some changes may already have been made."));
|
||||
PluginLogger.error(I.t(
|
||||
"Before trying to migrate again, you must recover player files from the backups,"
|
||||
+ " and then move the backups away from the plugin directory to avoid overwriting them."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is any of the former files to be migrated
|
||||
*
|
||||
* @return true if any former map or poster file exists, false otherwise
|
||||
*/
|
||||
private boolean spotFilesToMigrate() {
|
||||
PluginLogger.info(I.t("Looking for configuration files to migrate..."));
|
||||
|
||||
if (!oldPostersFile.exists()) {
|
||||
oldPostersFile = null;
|
||||
} else {
|
||||
PluginLogger.info(I.t("Detected former posters file {0}", OLD_POSTERS_FILE_NAME));
|
||||
}
|
||||
|
||||
if (!oldMapsFile.exists()) {
|
||||
oldMapsFile = null;
|
||||
} else {
|
||||
PluginLogger.info(I.t("Detected former maps file {0}", OLD_MAPS_FILE_NAME));
|
||||
}
|
||||
|
||||
if (oldPostersFile == null && oldMapsFile == null) {
|
||||
PluginLogger.info(I.t("There is nothing to migrate. Stopping."));
|
||||
return false;
|
||||
} else {
|
||||
PluginLogger.info(I.t("Done."));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any existing backup directories exists
|
||||
*
|
||||
* @return true if a non-empty backup directory exists, false otherwise
|
||||
*/
|
||||
private boolean checkForExistingBackups() {
|
||||
if ((backupsPrev3Directory.exists() && backupsPrev3Directory.list().length == 0)
|
||||
|| (backupsPostv3Directory.exists() && backupsPostv3Directory.list().length == 0)) {
|
||||
PluginLogger.error(I.t("Backup directories already exists."));
|
||||
PluginLogger.error(I.t("This means that a migration has already been done,"
|
||||
+ " or may not have ended well."));
|
||||
PluginLogger.error(I.t(
|
||||
"To start a new migration,"
|
||||
+ " you must move away the backup directories so they are not overwritten."));
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates backups of the former map files, and of the existing map stores
|
||||
*
|
||||
* @throws IOException
|
||||
**/
|
||||
private void backupMapData() throws IOException {
|
||||
PluginLogger.info(I.t("Backing up map data before migrating..."));
|
||||
|
||||
if (!backupsPrev3Directory.exists()) {
|
||||
backupsPrev3Directory.mkdirs();
|
||||
}
|
||||
if (!backupsPostv3Directory.exists()) {
|
||||
backupsPostv3Directory.mkdirs();
|
||||
}
|
||||
|
||||
if (oldMapsFile != null && oldMapsFile.exists()) {
|
||||
File oldMapsFileBackup = new File(backupsPrev3Directory, oldMapsFile.getName());
|
||||
verifiedBackupCopy(oldMapsFile, oldMapsFileBackup);
|
||||
}
|
||||
|
||||
if (oldPostersFile != null && oldPostersFile.exists()) {
|
||||
File oldPostersFileBackup = new File(backupsPrev3Directory, oldPostersFile.getName());
|
||||
verifiedBackupCopy(oldPostersFile, oldPostersFileBackup);
|
||||
}
|
||||
|
||||
File backupFile;
|
||||
for (File mapFile : plugin.getMapsDirectory().listFiles()) {
|
||||
backupFile = new File(backupsPostv3Directory, mapFile.getName());
|
||||
verifiedBackupCopy(mapFile, backupFile);
|
||||
}
|
||||
|
||||
PluginLogger.info(I.t("Backup complete."));
|
||||
}
|
||||
|
||||
/**
|
||||
* An utility function to check if a map is actually part of a loaded poster
|
||||
*
|
||||
* @param map The single map.
|
||||
* @return true if the map is part of a poster, false otherwise
|
||||
*/
|
||||
private boolean posterContains(OldSavedMap map) {
|
||||
for (OldSavedPoster poster : postersToMigrate) {
|
||||
if (poster.contains(map)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the former files into the corresponding arrays
|
||||
* Also fetches the names of all the users that have maps
|
||||
*
|
||||
* @return true if any of the files contained readable map data, false otherwise
|
||||
*/
|
||||
private boolean loadOldFiles() {
|
||||
if (oldPostersFile != null) {
|
||||
FileConfiguration oldPosters = YamlConfiguration.loadConfiguration(oldPostersFile);
|
||||
|
||||
OldSavedPoster oldPoster;
|
||||
for (String key : oldPosters.getKeys(false)) {
|
||||
if ("IdCount".equals(key)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
oldPoster = new OldSavedPoster(oldPosters.get(key), key);
|
||||
postersToMigrate.add(oldPoster);
|
||||
if (!userNamesToFetch.contains(oldPoster.getUserName())) {
|
||||
userNamesToFetch.add(oldPoster.getUserName());
|
||||
}
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
PluginLogger.warning("Could not read poster data for key {0}", ex, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oldMapsFile != null) {
|
||||
FileConfiguration oldMaps = YamlConfiguration.loadConfiguration(oldMapsFile);
|
||||
OldSavedMap oldMap;
|
||||
|
||||
for (String key : oldMaps.getKeys(false)) {
|
||||
try {
|
||||
if ("IdCount".equals(key)) {
|
||||
continue;
|
||||
}
|
||||
oldMap = new OldSavedMap(oldMaps.get(key));
|
||||
|
||||
if (!posterContains(oldMap)) {
|
||||
mapsToMigrate.add(oldMap);
|
||||
}
|
||||
|
||||
if (!userNamesToFetch.contains(oldMap.getUserName())) {
|
||||
userNamesToFetch.add(oldMap.getUserName());
|
||||
}
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
PluginLogger.warning("Could not read poster data for key '{0}'", ex, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (postersToMigrate.size() > 0) || (mapsToMigrate.size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all the needed UUIDs from Mojang's UUID conversion service
|
||||
*
|
||||
* @throws IOException if the fetcher could not connect to Mojang's servers
|
||||
* @throws InterruptedException if the thread was interrupted while fetching UUIDs
|
||||
*/
|
||||
private void fetchUUIDs() throws IOException, InterruptedException {
|
||||
PluginLogger.info(I.t("Fetching UUIDs from Mojang..."));
|
||||
try {
|
||||
usersUUIDs = UUIDFetcher.fetch(new ArrayList<String>(userNamesToFetch));
|
||||
} catch (IOException ex) {
|
||||
PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang"), ex);
|
||||
throw ex;
|
||||
} catch (InterruptedException ex) {
|
||||
PluginLogger.error(I.t("The migration worker has been interrupted"), ex);
|
||||
throw ex;
|
||||
}
|
||||
PluginLogger.info(I.tn("Fetching done. {0} UUID have been retrieved.",
|
||||
"Fetching done. {0} UUIDs have been retrieved.", usersUUIDs.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the UUIDs that could not be retrieved via Mojang's standard API
|
||||
*
|
||||
* @return true if at least one UUID has been retrieved, false otherwise
|
||||
*/
|
||||
private boolean fetchMissingUUIDs() throws IOException, InterruptedException {
|
||||
if (usersUUIDs.size() == userNamesToFetch.size()) {
|
||||
return true;
|
||||
}
|
||||
int remainingUsersCount = userNamesToFetch.size() - usersUUIDs.size();
|
||||
PluginLogger.info(I.tn("Mojang did not find UUIDs for {0} player at the current time.",
|
||||
"Mojang did not find UUIDs for {0} players at the current time.", remainingUsersCount));
|
||||
PluginLogger.info(I.t("The Mojang servers limit requests rate at one per second, this may take some time..."));
|
||||
|
||||
try {
|
||||
UUIDFetcher.fetchRemaining(userNamesToFetch, usersUUIDs);
|
||||
} catch (IOException ex) {
|
||||
PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang"));
|
||||
throw ex;
|
||||
} catch (InterruptedException ex) {
|
||||
PluginLogger.error(I.t("The migration worker has been interrupted"));
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (usersUUIDs.size() != userNamesToFetch.size()) {
|
||||
PluginLogger.warning(I.tn("Mojang did not find player data for {0} player",
|
||||
"Mojang did not find player data for {0} players",
|
||||
userNamesToFetch.size() - usersUUIDs.size()));
|
||||
PluginLogger.warning(I.t("The following players do not exist or do not have paid accounts :"));
|
||||
|
||||
String missingUsersList = "";
|
||||
|
||||
for (String user : userNamesToFetch) {
|
||||
if (!usersUUIDs.containsKey(user)) {
|
||||
missingUsersList += user + ", ";
|
||||
}
|
||||
}
|
||||
missingUsersList = missingUsersList.substring(0, missingUsersList.length());
|
||||
|
||||
PluginLogger.info(missingUsersList);
|
||||
}
|
||||
|
||||
if (usersUUIDs.size() <= 0) {
|
||||
PluginLogger.info(I.t("Mojang could not find any of the registered players."));
|
||||
PluginLogger.info(I.t("There is nothing to migrate. Stopping."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void mergeMapData() {
|
||||
PluginLogger.info(I.t("Merging map data..."));
|
||||
|
||||
ArrayDeque<OldSavedMap> remainingMaps = new ArrayDeque<>();
|
||||
ArrayDeque<OldSavedPoster> remainingPosters = new ArrayDeque<>();
|
||||
|
||||
ArrayDeque<Integer> missingMapIds = new ArrayDeque<>();
|
||||
|
||||
UUID playerUUID;
|
||||
OldSavedMap map;
|
||||
while (!mapsToMigrate.isEmpty()) {
|
||||
map = mapsToMigrate.pop();
|
||||
playerUUID = usersUUIDs.get(map.getUserName());
|
||||
if (playerUUID == null) {
|
||||
remainingMaps.add(map);
|
||||
} else if (!map.isMapValid()) {
|
||||
missingMapIds.add((int) map.getMapId());
|
||||
} else {
|
||||
MapManager.insertMap(map.toImageMap(playerUUID));
|
||||
}
|
||||
}
|
||||
mapsToMigrate.addAll(remainingMaps);
|
||||
|
||||
OldSavedPoster poster;
|
||||
while (!postersToMigrate.isEmpty()) {
|
||||
poster = postersToMigrate.pop();
|
||||
playerUUID = usersUUIDs.get(poster.getUserName());
|
||||
if (playerUUID == null) {
|
||||
remainingPosters.add(poster);
|
||||
} else if (!poster.isMapValid()) {
|
||||
missingMapIds.addAll(Arrays.stream(ArrayUtils.toObject(poster.getMapsIds())).map(id -> (int) id)
|
||||
.collect(Collectors.toList()));
|
||||
} else {
|
||||
MapManager.insertMap(poster.toImageMap(playerUUID));
|
||||
}
|
||||
}
|
||||
postersToMigrate.addAll(remainingPosters);
|
||||
|
||||
if (!missingMapIds.isEmpty()) {
|
||||
PluginLogger.warning(I.tn("{0} registered minecraft map is missing from the save.",
|
||||
"{0} registered minecraft maps are missing from the save.", missingMapIds.size()));
|
||||
PluginLogger.warning(
|
||||
I.t("These maps will not be migrated,"
|
||||
+ " but this could mean the save has been altered or corrupted."));
|
||||
PluginLogger.warning(I.t("The following maps are missing : {0} ",
|
||||
StringUtils.join(missingMapIds, ',')));
|
||||
}
|
||||
}
|
||||
|
||||
/* ****** Utils ***** */
|
||||
|
||||
private void saveChanges() {
|
||||
PluginLogger.info(I.t("Saving changes..."));
|
||||
MapManager.save();
|
||||
}
|
||||
|
||||
private void cleanup() throws IOException {
|
||||
PluginLogger.info(I.t("Cleaning up old data files..."));
|
||||
|
||||
//Cleaning maps file
|
||||
if (oldMapsFile != null) {
|
||||
if (mapsToMigrate.isEmpty()) {
|
||||
PluginLogger.info(I.t("Deleting old map data file..."));
|
||||
oldMapsFile.delete();
|
||||
} else {
|
||||
PluginLogger.info(I.tn("{0} map could not be migrated.", "{0} maps could not be migrated.",
|
||||
mapsToMigrate.size()));
|
||||
YamlConfiguration mapConfig = new YamlConfiguration();
|
||||
mapConfig.set("IdCount", mapsToMigrate.size());
|
||||
|
||||
for (OldSavedMap map : mapsToMigrate) {
|
||||
map.serialize(mapConfig);
|
||||
}
|
||||
|
||||
mapConfig.save(oldMapsFile);
|
||||
}
|
||||
}
|
||||
|
||||
//Cleaning posters file
|
||||
if (oldPostersFile != null) {
|
||||
if (postersToMigrate.isEmpty()) {
|
||||
PluginLogger.info(I.t("Deleting old poster data file..."));
|
||||
oldPostersFile.delete();
|
||||
} else {
|
||||
PluginLogger.info(I.tn("{0} poster could not be migrated.", "{0} posters could not be migrated.",
|
||||
postersToMigrate.size()));
|
||||
YamlConfiguration posterConfig = new YamlConfiguration();
|
||||
posterConfig.set("IdCount", postersToMigrate.size());
|
||||
|
||||
for (OldSavedPoster poster : postersToMigrate) {
|
||||
poster.serialize(posterConfig);
|
||||
}
|
||||
|
||||
posterConfig.save(oldPostersFile);
|
||||
}
|
||||
}
|
||||
|
||||
PluginLogger.info(I.t("Data that has not been migrated will be kept in the old data files."));
|
||||
}
|
||||
|
||||
public synchronized boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
private synchronized void setRunning(boolean running) {
|
||||
this.isRunning = running;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the full migration, and defines the running status of the migration
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
setRunning(true);
|
||||
migrate();
|
||||
setRunning(false);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -40,10 +40,8 @@ import fr.moribus.imageonmap.Permissions;
|
|||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.map.SingleMap;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.core.QuartzLib;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemUtils;
|
||||
import fr.zcraft.quartzlib.tools.runners.RunTask;
|
||||
|
@ -89,15 +87,10 @@ public class MapItemManager implements Listener {
|
|||
public static boolean give(Player player, ImageMap map) {
|
||||
if (map instanceof PosterMap) {
|
||||
return give(player, (PosterMap) map);
|
||||
} else if (map instanceof SingleMap) {
|
||||
return give(player, (SingleMap) map);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean give(Player player, SingleMap map) {
|
||||
return give(player, createMapItem(map, true));
|
||||
}
|
||||
|
||||
public static boolean give(Player player, PosterMap map) {
|
||||
if (!map.hasColumnData()) {
|
||||
|
@ -142,14 +135,6 @@ public class MapItemManager implements Listener {
|
|||
return givenItemsCount;
|
||||
}
|
||||
|
||||
public static ItemStack createMapItem(SingleMap map) {
|
||||
return createMapItem(map.getMapsIDs()[0], map.getName(), false);
|
||||
}
|
||||
|
||||
public static ItemStack createMapItem(SingleMap map, boolean goldTitle) {
|
||||
return createMapItem(map.getMapsIDs()[0], map.getName(), false, goldTitle);
|
||||
}
|
||||
|
||||
public static ItemStack createMapItem(PosterMap map, int index) {
|
||||
return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true);
|
||||
}
|
||||
|
@ -164,17 +149,24 @@ public class MapItemManager implements Listener {
|
|||
|
||||
public static ItemStack createMapItem(int mapID, String text, boolean isMapPart, boolean goldTitle) {
|
||||
ItemStack mapItem;
|
||||
if (goldTitle) {
|
||||
if (text == "") {
|
||||
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
|
||||
.title(ChatColor.GOLD, text)
|
||||
.hideAllAttributes()
|
||||
.item();
|
||||
} else {
|
||||
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
|
||||
.title(text)
|
||||
.hideAllAttributes()
|
||||
.item();
|
||||
if (goldTitle) {
|
||||
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
|
||||
.title(ChatColor.GOLD, text)
|
||||
.hideAllAttributes()
|
||||
.item();
|
||||
} else {
|
||||
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
|
||||
.title(text)
|
||||
.hideAllAttributes()
|
||||
.item();
|
||||
}
|
||||
}
|
||||
|
||||
final MapMeta meta = (MapMeta) mapItem.getItemMeta();
|
||||
meta.setMapId(mapID);
|
||||
meta.setColor(isMapPart ? Color.LIME : Color.GREEN);
|
||||
|
@ -194,17 +186,14 @@ public class MapItemManager implements Listener {
|
|||
|
||||
private static String getMapTitle(ItemStack item) {
|
||||
ImageMap map = MapManager.getMap(item);
|
||||
if (map instanceof SingleMap) {
|
||||
return map.getName();
|
||||
} else {
|
||||
PosterMap poster = (PosterMap) map;
|
||||
int index = poster.getIndex(MapManager.getMapIdFromItemStack(item));
|
||||
if (poster.hasColumnData()) {
|
||||
return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index));
|
||||
}
|
||||
|
||||
return getMapTitle(poster, index);
|
||||
PosterMap poster = (PosterMap) map;
|
||||
int index = poster.getIndex(MapManager.getMapIdFromItemStack(item));
|
||||
if (poster.hasColumnData()) {
|
||||
return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index));
|
||||
}
|
||||
|
||||
return getMapTitle(poster, index);
|
||||
//}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -297,19 +286,19 @@ public class MapItemManager implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player)) {
|
||||
if (player.isSneaking()) {
|
||||
PosterMap poster = SplatterMapManager.removeSplatterMap(frame, player);
|
||||
if (poster != null) {
|
||||
event.setCancelled(true);
|
||||
if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player) && player.isSneaking()) {
|
||||
|
||||
if (player.getGameMode() != GameMode.CREATIVE
|
||||
|| !SplatterMapManager.hasSplatterMap(player, poster)) {
|
||||
poster.give(player);
|
||||
}
|
||||
return;
|
||||
PosterMap poster = SplatterMapManager.removeSplatterMap(frame, player);
|
||||
if (poster != null) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (player.getGameMode() != GameMode.CREATIVE
|
||||
|| !SplatterMapManager.hasSplatterMap(player, poster)) {
|
||||
poster.give(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!MapManager.managesMap(frame.getItem())) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,9 +36,13 @@
|
|||
|
||||
package fr.moribus.imageonmap.ui;
|
||||
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.world.FlatLocation;
|
||||
import fr.zcraft.quartzlib.tools.world.WorldUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
@ -48,121 +52,22 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class PosterOnASurface {
|
||||
|
||||
public FlatLocation loc1;
|
||||
public FlatLocation loc2;
|
||||
|
||||
public ItemFrame[] frames;
|
||||
|
||||
/**
|
||||
* Return the list of map Frames associated with a specific map
|
||||
*/
|
||||
public static ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId, BlockFace bf) {
|
||||
int mapIndex = map.getIndex(mapId);
|
||||
//int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex);
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
switch (bf) {
|
||||
case EAST:
|
||||
case WEST:
|
||||
y = map.getColumnCount() - 1;
|
||||
break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
y = map.getRowCount() - 1;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
return getMatchingMapFrames(map, location.clone().addH(x, y, bf), bf).clone();
|
||||
}
|
||||
|
||||
public static ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, BlockFace bf) {
|
||||
ItemFrame[] frames = new ItemFrame[map.getMapCount()];
|
||||
FlatLocation loc = location.clone();
|
||||
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
switch (bf) {
|
||||
case EAST:
|
||||
case WEST:
|
||||
//X=map.getRowCount();
|
||||
//Y=map.getColumnCount();
|
||||
//break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
|
||||
y = map.getRowCount();
|
||||
x = map.getColumnCount();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
|
||||
for (int j = 0; j < y; ++j) {
|
||||
for (int i = 0; i < x; ++i) {
|
||||
int mapIndex = map.getIndexAt(i, j);
|
||||
|
||||
ItemFrame frame = getMapFrameAt(loc, map);
|
||||
if (frame != null) {
|
||||
frames[mapIndex] = frame;
|
||||
}
|
||||
switch (bf) {
|
||||
case EAST:
|
||||
case WEST:
|
||||
loc.addH(0, -1, bf);
|
||||
break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
loc.addH(1, 0, bf);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
switch (bf) {
|
||||
case EAST:
|
||||
case WEST:
|
||||
loc.addH(1, map.getColumnCount(), bf);//test
|
||||
|
||||
break;
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
loc.addH(-map.getColumnCount(), -1, bf);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
public static ItemFrame getMapFrameAt(FlatLocation location, PosterMap map) {
|
||||
public static ItemFrame getEmptyFrameAt(Location location, BlockFace facing) {
|
||||
Entity[] entities = location.getChunk().getEntities();
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
continue;
|
||||
}
|
||||
if (!WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
boolean notItemFrame = !(entity instanceof ItemFrame);
|
||||
if (notItemFrame || !WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
continue;
|
||||
}
|
||||
ItemFrame frame = (ItemFrame) entity;
|
||||
if (frame.getFacing() != location.getFacing()) {
|
||||
continue;
|
||||
}
|
||||
ItemStack item = frame.getItem();
|
||||
if (item.getType() != Material.FILLED_MAP) {
|
||||
continue;
|
||||
}
|
||||
if (!map.managesMap(item)) {
|
||||
if (frame.getFacing() != facing || item.getType() != Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
return frame;
|
||||
|
@ -171,22 +76,17 @@ public class PosterOnASurface {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static ItemFrame getEmptyFrameAt(Location location, BlockFace facing) {
|
||||
public static ItemFrame getFrameAt(Location location, BlockFace facing) {
|
||||
Entity[] entities = location.getChunk().getEntities();
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
continue;
|
||||
}
|
||||
if (!WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
boolean notItemFrame = !(entity instanceof ItemFrame);
|
||||
if (notItemFrame || !WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
continue;
|
||||
}
|
||||
ItemFrame frame = (ItemFrame) entity;
|
||||
if (frame.getFacing() != facing) {
|
||||
continue;
|
||||
}
|
||||
ItemStack item = frame.getItem();
|
||||
if (item.getType() != Material.AIR) {
|
||||
if (frame.getFacing() != facing) {
|
||||
continue;
|
||||
}
|
||||
return frame;
|
||||
|
@ -253,6 +153,116 @@ public class PosterOnASurface {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static Map<Location, ItemFrame> getItemFramesLocation(Player p, Location startingLocation,
|
||||
Location selectedLocation, BlockFace facing,
|
||||
int rows,
|
||||
int columns) {
|
||||
Map<Location, ItemFrame> itemFramesLocationMap = new HashMap();
|
||||
BlockFace bf = WorldUtils.get4thOrientation(p.getLocation());
|
||||
boolean isWall =
|
||||
facing.equals(BlockFace.WEST) || facing.equals(BlockFace.EAST) || facing.equals(BlockFace.NORTH)
|
||||
|| facing.equals(BlockFace.SOUTH);
|
||||
boolean isFloor = facing.equals(BlockFace.DOWN);
|
||||
boolean isCeiling = facing.equals(BlockFace.UP);
|
||||
Location loc = startingLocation;
|
||||
|
||||
ItemFrame selectedFrame = getFrameAt(selectedLocation, facing);
|
||||
|
||||
int x = 0;
|
||||
int z = 0;
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < columns; c++) {
|
||||
PluginLogger.info("column " + c);
|
||||
PluginLogger.info("row " + r);
|
||||
|
||||
if (test(selectedFrame, loc, facing)) {
|
||||
itemFramesLocationMap.put(loc.clone(), getFrameAt(loc, facing));
|
||||
}
|
||||
//do a row
|
||||
if (isWall || isFloor) {
|
||||
switch (bf) {
|
||||
case NORTH:
|
||||
x++;
|
||||
loc = loc.add(1, 0, 0);
|
||||
break;
|
||||
case SOUTH:
|
||||
x--;
|
||||
loc = loc.add(-1, 0, 0);
|
||||
break;
|
||||
case EAST:
|
||||
z++;
|
||||
loc = loc.add(0, 0, 1);
|
||||
break;
|
||||
case WEST:
|
||||
z--;
|
||||
loc = loc.add(0, 0, -1);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
|
||||
}
|
||||
} else if (isCeiling) {
|
||||
switch (bf) {
|
||||
case NORTH:
|
||||
x--;
|
||||
loc = loc.add(-1, 0, 0);
|
||||
break;
|
||||
case SOUTH:
|
||||
x++;
|
||||
loc = loc.add(1, 0, 0);
|
||||
break;
|
||||
case EAST:
|
||||
z--;
|
||||
loc = loc.add(0, 0, -1);
|
||||
break;
|
||||
case WEST:
|
||||
z++;
|
||||
loc = loc.add(0, 0, 1);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (isWall) {
|
||||
loc = loc.add(-x, -1, -z);
|
||||
} else if (isFloor || isCeiling) {
|
||||
switch (bf) {
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
loc = loc.add(-x, 0, 1);
|
||||
break;
|
||||
case EAST:
|
||||
case WEST:
|
||||
loc = loc.add(1, 0, -z);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
x = 0;
|
||||
z = 0;
|
||||
}
|
||||
}
|
||||
return itemFramesLocationMap;
|
||||
}
|
||||
|
||||
//TODO add descr and move to correct class and rename
|
||||
private static boolean test(ItemFrame selectedFrame, Location loc, BlockFace facing) {
|
||||
ImageMap firstMap = MapManager.getMap(selectedFrame.getItem());
|
||||
MapManager.getMap(getFrameAt(loc, facing).getItem());
|
||||
|
||||
for (int id : firstMap.getMapsIDs()) {
|
||||
if (id == MapManager.getMapIdFromItemStack(getFrameAt(loc, facing).getItem())) {
|
||||
return true;
|
||||
}
|
||||
//TODO refactor with lambda
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void expand() {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,15 +36,10 @@
|
|||
|
||||
package fr.moribus.imageonmap.ui;
|
||||
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.zcraft.quartzlib.tools.world.FlatLocation;
|
||||
import fr.zcraft.quartzlib.tools.world.WorldUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class PosterWall {
|
||||
|
||||
|
@ -53,84 +48,8 @@ public class PosterWall {
|
|||
|
||||
public ItemFrame[] frames;
|
||||
|
||||
public static ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId) {
|
||||
int mapIndex = map.getIndex(mapId);
|
||||
int x = map.getColumnAt(mapIndex);
|
||||
int y = map.getRowAt(mapIndex);
|
||||
|
||||
return getMatchingMapFrames(map, location.clone().add(-x, y));
|
||||
}
|
||||
|
||||
public static ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location) {
|
||||
ItemFrame[] frames = new ItemFrame[map.getMapCount()];
|
||||
FlatLocation loc = location.clone();
|
||||
|
||||
for (int y = 0; y < map.getRowCount(); ++y) {
|
||||
for (int x = 0; x < map.getColumnCount(); ++x) {
|
||||
int mapIndex = map.getIndexAt(x, y);
|
||||
ItemFrame frame = getMapFrameAt(loc, map);
|
||||
if (frame != null) {
|
||||
frames[mapIndex] = frame;
|
||||
}
|
||||
loc.add(1, 0);
|
||||
}
|
||||
loc.setX(location.getX());
|
||||
loc.setZ(location.getZ());
|
||||
loc.add(0, -1);
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
public static ItemFrame getMapFrameAt(FlatLocation location, PosterMap map) {
|
||||
Entity[] entities = location.getChunk().getEntities();
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
continue;
|
||||
}
|
||||
if (!WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
continue;
|
||||
}
|
||||
ItemFrame frame = (ItemFrame) entity;
|
||||
if (frame.getFacing() != location.getFacing()) {
|
||||
continue;
|
||||
}
|
||||
ItemStack item = frame.getItem();
|
||||
if (item.getType() != Material.FILLED_MAP) {
|
||||
continue;
|
||||
}
|
||||
if (!map.managesMap(item)) {
|
||||
continue;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemFrame getEmptyFrameAt(Location location, BlockFace facing) {
|
||||
Entity[] entities = location.getChunk().getEntities();
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
continue;
|
||||
}
|
||||
if (!WorldUtils.blockEquals(location, entity.getLocation())) {
|
||||
continue;
|
||||
}
|
||||
ItemFrame frame = (ItemFrame) entity;
|
||||
if (frame.getFacing() != facing) {
|
||||
continue;
|
||||
}
|
||||
ItemStack item = frame.getItem();
|
||||
if (item.getType() != Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
return null;
|
||||
return PosterOnASurface.getEmptyFrameAt(location, facing);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
|
@ -159,7 +78,4 @@ public class PosterWall {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void expand() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* 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 – 2021)
|
||||
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (2019 – 2021)
|
||||
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 – 2022)
|
||||
* Copyright or © or Copr. Vlammar <anais.jabre@gmail.com> (2019 – 2023)
|
||||
*
|
||||
* This software is a computer program whose purpose is to allow insertion of
|
||||
* custom images in a Minecraft world.
|
||||
|
@ -36,39 +36,37 @@
|
|||
|
||||
package fr.moribus.imageonmap.ui;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.image.MapInitEvent;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.components.nbt.NBT;
|
||||
import fr.zcraft.quartzlib.components.nbt.NBTCompound;
|
||||
import fr.zcraft.quartzlib.components.nbt.NBTList;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.items.GlowEffect;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
|
||||
import fr.zcraft.quartzlib.tools.reflection.NMSException;
|
||||
import fr.zcraft.quartzlib.tools.runners.RunTask;
|
||||
import fr.zcraft.quartzlib.tools.text.MessageSender;
|
||||
import fr.zcraft.quartzlib.tools.world.FlatLocation;
|
||||
import fr.zcraft.quartzlib.tools.world.WorldUtils;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Rotation;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
|
||||
//TODO rework splatter effect, using ID is far more stable than nbt tags.
|
||||
// To update when adding small picture previsualization.
|
||||
// To update when adding small picture snapshot.
|
||||
public abstract class SplatterMapManager {
|
||||
private SplatterMapManager() {
|
||||
}
|
||||
|
@ -128,7 +126,8 @@ public abstract class SplatterMapManager {
|
|||
* @return The modified item stack. The instance may be different if the passed item stack is not a craft itemstack.
|
||||
*/
|
||||
public static ItemStack addSplatterAttribute(final ItemStack itemStack) {
|
||||
GlowEffect.addGlow(itemStack);
|
||||
itemStack.addUnsafeEnchantment(Enchantment.LURE, 1);
|
||||
//TODO check if safe guard for duplication XP still works
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
|
@ -140,21 +139,7 @@ public abstract class SplatterMapManager {
|
|||
* @return True if the attribute was detected.
|
||||
*/
|
||||
public static boolean hasSplatterAttributes(ItemStack itemStack) {
|
||||
|
||||
try {
|
||||
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
||||
if (!nbt.containsKey("Enchantments")) {
|
||||
return false;
|
||||
}
|
||||
final Object enchantments = nbt.get("Enchantments");
|
||||
if (!(enchantments instanceof NBTList)) {
|
||||
return false;
|
||||
}
|
||||
return !((NBTList) enchantments).isEmpty();
|
||||
} catch (NMSException e) {
|
||||
PluginLogger.error("Unable to get Splatter Map attribute on item", e);
|
||||
return false;
|
||||
}
|
||||
return MapManager.managesMap(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,6 +183,7 @@ public abstract class SplatterMapManager {
|
|||
* @param player Player placing map
|
||||
* @return true if the map was correctly placed
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")
|
||||
public static boolean placeSplatterMap(ItemFrame startFrame, Player player, PlayerInteractEntityEvent event) {
|
||||
ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand());
|
||||
|
||||
|
@ -229,8 +215,6 @@ public abstract class SplatterMapManager {
|
|||
|
||||
int i = 0;
|
||||
for (ItemFrame frame : surface.frames) {
|
||||
BlockFace bf = WorldUtils.get4thOrientation(player.getLocation());
|
||||
int id = poster.getMapIdAtReverseZ(i, bf, startFrame.getFacing());
|
||||
Rotation rot = Rotation.NONE;
|
||||
switch (frame.getFacing()) {
|
||||
case UP:
|
||||
|
@ -241,13 +225,12 @@ public abstract class SplatterMapManager {
|
|||
default:
|
||||
//throw new IllegalStateException("Unexpected value: " + frame.getFacing());
|
||||
}
|
||||
BlockFace bf = WorldUtils.get4thOrientation(player.getLocation());
|
||||
int id = poster.getMapIdAtReverseZ(i, bf, startFrame.getFacing());
|
||||
//Rotation management relative to player rotation the default position is North,
|
||||
// when on ceiling we flipped the rotation
|
||||
RunTask.later(() -> {
|
||||
addPropertiesToFrames(player, frame);
|
||||
frame.setItem(
|
||||
new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||
}, 5L);
|
||||
|
||||
setupMap(player, frame, id);
|
||||
|
||||
if (i == 0) {
|
||||
//First map need to be rotate one time CounterClockwise
|
||||
|
@ -281,7 +264,6 @@ public abstract class SplatterMapManager {
|
|||
throw new IllegalStateException("Unexpected value: " + bf);
|
||||
}
|
||||
|
||||
|
||||
MapInitEvent.initMap(id);
|
||||
i++;
|
||||
}
|
||||
|
@ -305,11 +287,8 @@ public abstract class SplatterMapManager {
|
|||
|
||||
int id = poster.getMapIdAtReverseY(i);
|
||||
|
||||
RunTask.later(() -> {
|
||||
addPropertiesToFrames(player, frame);
|
||||
frame.setItem(
|
||||
new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||
}, 5L);
|
||||
|
||||
setupMap(player, frame, id);
|
||||
|
||||
|
||||
//Force reset of rotation
|
||||
|
@ -321,6 +300,14 @@ public abstract class SplatterMapManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
private static void setupMap(Player player, ItemFrame frame, int id) {
|
||||
RunTask.later(() -> {
|
||||
addPropertiesToFrames(player, frame);
|
||||
ItemStack item = MapItemManager.createMapItem(id, "", true, false);
|
||||
frame.setItem(item);
|
||||
}, 5L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove splattermap
|
||||
*
|
||||
|
@ -337,33 +324,18 @@ public abstract class SplatterMapManager {
|
|||
if (!poster.hasColumnData()) {
|
||||
return null;
|
||||
}
|
||||
FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
|
||||
ItemFrame[] matchingFrames = null;
|
||||
//We search for the map on the top left corner
|
||||
Location startingLocation = poster.findLocationFirstFrame(startFrame, player);
|
||||
|
||||
switch (startFrame.getFacing()) {
|
||||
case UP:
|
||||
case DOWN:
|
||||
matchingFrames = PosterOnASurface.getMatchingMapFrames(poster, loc,
|
||||
MapManager.getMapIdFromItemStack(startFrame.getItem()),
|
||||
WorldUtils.get4thOrientation(player.getLocation()));//startFrame.getFacing());
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
case EAST:
|
||||
case WEST:
|
||||
matchingFrames = PosterWall.getMatchingMapFrames(poster, loc,
|
||||
MapManager.getMapIdFromItemStack(startFrame.getItem()));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + startFrame.getFacing());
|
||||
}
|
||||
|
||||
if (matchingFrames == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (ItemFrame frame : matchingFrames) {
|
||||
Map<Location, ItemFrame>
|
||||
itemFrameLocations =
|
||||
PosterOnASurface.getItemFramesLocation(player, startingLocation, startFrame.getLocation(),
|
||||
startFrame.getFacing(),
|
||||
poster.getRowCount(), poster.getColumnCount());
|
||||
//TODO check if it is the correct map id and check the why it delete more than it should and out of place
|
||||
for (Map.Entry<Location, ItemFrame> entry : itemFrameLocations.entrySet()) {
|
||||
ItemFrame frame = itemFrameLocations.get(entry.getKey());
|
||||
PluginLogger.info("Frame to delete " + frame);
|
||||
if (frame != null) {
|
||||
removePropertiesFromFrames(player, frame);
|
||||
frame.setItem(null);
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
name: ImageOnMap
|
||||
main: fr.moribus.imageonmap.ImageOnMap
|
||||
version: "4.2.2"
|
||||
version: "5.0.0"
|
||||
api-version: "1.13"
|
||||
|
||||
|
||||
commands:
|
||||
tomap:
|
||||
description: render an image in a map
|
||||
description: Render an image in a map
|
||||
usage: /<command> [URL]
|
||||
maptool:
|
||||
description: Manage maps
|
||||
maps:
|
||||
description: Manage maps through a GUI
|
||||
givemap:
|
||||
description: give a map to a player from a player map store, by default take from the player that make the command
|
||||
description: Give a map to a player from a playerMapStore, by default take from the player that make the command
|
||||
usage: /<command> [player_from] player_to map_name
|
||||
placemap:
|
||||
description: Place a map remotely and deploy it
|
||||
usage: /<command> [player_from]:<map_name> <N/S/E/W> <UP/DOWN/WALL> x y z
|
||||
|
||||
permissions:
|
||||
imageonmap.*:
|
||||
|
@ -42,6 +45,7 @@ permissions:
|
|||
imageonmap.bypassimagelimit: false
|
||||
imageonmap.bypasswhitelist: true
|
||||
imageonmap.placeinvisiblesplattermap: true
|
||||
imageonmap.remoteplacing: false
|
||||
|
||||
imageonmap.userender:
|
||||
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
|
||||
|
@ -130,3 +134,7 @@ permissions:
|
|||
imageonmap.placeinvisiblesplattermap:
|
||||
description: "Allows you to make the item frame on which you placed your splatter map invisible."
|
||||
default: true
|
||||
|
||||
imageonmap.remoteplacing:
|
||||
description: "Allows you to remotly place a map from a playerMapStore to a specific position."
|
||||
default: op
|
Loading…
Reference in New Issue