Checkstyle added and refactor

This commit is contained in:
Vlammar 2020-12-10 22:13:05 +01:00
parent 509e379386
commit cc58b1d320
45 changed files with 2799 additions and 2616 deletions

303
checkstyle.xml Normal file
View File

@ -0,0 +1,303 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.org (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
To suppress certain violations please review suppression filters.
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-->
<module name = "Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="error"/>
<module name="SuppressWarningsFilter"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
default="checkstyle-suppressions.xml" />
<property name="optional" value="true"/>
</module>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.org/config_whitespace.html -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="LineLength">
<property name="fileExtensions" value="java"/>
<property name="max" value="120"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="TreeWalker">
<module name="SuppressWarningsHolder"/>
<module name="SuppressWarnings">
<property name="id" value="checkstyle:suppresswarnings"/>
</module>
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="AvoidStarImport"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap">
<property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
</module>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="NeedBraces">
<property name="tokens"
value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
</module>
<module name="LeftCurly">
<property name="tokens"
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
OBJBLOCK, STATIC_INIT"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
LITERAL_DO"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlyAlone"/>
<property name="option" value="alone"/>
<property name="tokens"
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF"/>
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyLambdas" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
<property name="tokens"
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
<message key="ws.notFollowed"
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
<message key="ws.notPreceded"
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>
<module name="OneStatementPerLine"/>
<module name="MultipleVariableDeclarations"/>
<module name="ArrayTypeStyle"/>
<module name="MissingSwitchDefault"/>
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
<module name="EmptyLineSeparator">
<property name="tokens"
value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
<property name="allowNoEmptyLineBetweenFields" value="true"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapDot"/>
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapComma"/>
<property name="tokens" value="COMMA"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/258 -->
<property name="id" value="SeparatorWrapEllipsis"/>
<property name="tokens" value="ELLIPSIS"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/259 -->
<property name="id" value="SeparatorWrapArrayDeclarator"/>
<property name="tokens" value="ARRAY_DECLARATOR"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapMethodRef"/>
<property name="tokens" value="METHOD_REF"/>
<property name="option" value="nl"/>
</module>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF"/>
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LambdaParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="InterfaceTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="NoFinalizer"/>
<module name="GenericWhitespace">
<message key="ws.followed"
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
<message key="ws.preceded"
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
<message key="ws.illegalFollow"
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
<message key="ws.notPreceded"
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>
<module name="Indentation">
<property name="basicOffset" value="4"/>
<property name="braceAdjustment" value="0"/>
<property name="caseIndent" value="4"/>
<property name="throwsIndent" value="8"/>
<property name="lineWrappingIndentation" value="8"/>
<property name="arrayInitIndent" value="4"/>
</module>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="CustomImportOrder">
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="true"/>
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
<property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
</module>
<module name="MethodParamPad">
<property name="tokens"
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
SUPER_CTOR_CALL, ENUM_CONSTANT_DEF"/>
</module>
<module name="NoWhitespaceBefore">
<property name="tokens"
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
<property name="allowLineBreaks" value="true"/>
</module>
<module name="ParenPad">
<property name="tokens"
value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA"/>
</module>
<module name="OperatorWrap">
<property name="option" value="NL"/>
<property name="tokens"
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF "/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationMostCases"/>
<property name="tokens"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationVariables"/>
<property name="tokens" value="VARIABLE_DEF"/>
<property name="allowSamelineMultipleAnnotations" value="true"/>
</module>
<module name="NonEmptyAtclauseDescription"/>
<module name="InvalidJavadocPosition"/>
<module name="JavadocTagContinuationIndentation"/>
<module name="JavadocParagraph"/>
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
<property name="target"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
</module>
<module name="MethodName">
<property name="format" value="^(t|[a-z][a-z0-9][a-zA-Z0-9_]*)$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="SingleLineJavadoc">
<property name="ignoreInlineTags" value="false"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="ignored"/>
</module>
<module name="CommentsIndentation">
<property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
<module name="SuppressionXpathFilter">
<property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
default="checkstyle-xpath-suppressions.xml" />
<property name="optional" value="true"/>
</module>
</module>
</module>

22
pom.xml
View File

@ -42,6 +42,28 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<logViolationsToConsole>true</logViolationsToConsole>
<failOnViolation>true</failOnViolation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -37,7 +37,20 @@
package fr.moribus.imageonmap;
import fr.moribus.imageonmap.commands.maptool.*;
import fr.moribus.imageonmap.commands.maptool.DeleteCommand;
import fr.moribus.imageonmap.commands.maptool.DeleteOtherCommand;
import fr.moribus.imageonmap.commands.maptool.ExploreCommand;
import fr.moribus.imageonmap.commands.maptool.ExploreOtherCommand;
import fr.moribus.imageonmap.commands.maptool.GetCommand;
import fr.moribus.imageonmap.commands.maptool.GetOtherCommand;
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.ListOtherCommand;
import fr.moribus.imageonmap.commands.maptool.MigrateCommand;
import fr.moribus.imageonmap.commands.maptool.NewCommand;
import fr.moribus.imageonmap.commands.maptool.RenameCommand;
import fr.moribus.imageonmap.commands.maptool.UpdateCommand;
import fr.moribus.imageonmap.image.ImageIOExecutor;
import fr.moribus.imageonmap.image.ImageRendererExecutor;
import fr.moribus.imageonmap.image.MapInitEvent;
@ -52,60 +65,58 @@ import fr.zcraft.quartzlib.components.i18n.I18n;
import fr.zcraft.quartzlib.core.QuartzPlugin;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.UpdateChecker;
import java.io.File;
import java.io.IOException;
public final class ImageOnMap extends QuartzPlugin
{
static private final String IMAGES_DIRECTORY_NAME = "images";
static private final String MAPS_DIRECTORY_NAME = "maps";
static private ImageOnMap plugin;
private File imagesDirectory;
public final class ImageOnMap extends QuartzPlugin {
private static final String IMAGES_DIRECTORY_NAME = "images";
private static final String MAPS_DIRECTORY_NAME = "maps";
private static ImageOnMap plugin;
private final File mapsDirectory;
private File imagesDirectory;
public ImageOnMap()
{
public ImageOnMap() {
imagesDirectory = new File(this.getDataFolder(), IMAGES_DIRECTORY_NAME);
mapsDirectory = new File(this.getDataFolder(), MAPS_DIRECTORY_NAME);
plugin = this;
}
static public ImageOnMap getPlugin()
{
public static ImageOnMap getPlugin() {
return plugin;
}
public File getImagesDirectory() {return imagesDirectory;}
public File getMapsDirectory() {return mapsDirectory;}
public File getImageFile(int mapID)
{
return new File(imagesDirectory, "map"+mapID+".png");
public File getImagesDirectory() {
return imagesDirectory;
}
@SuppressWarnings ("unchecked")
public File getMapsDirectory() {
return mapsDirectory;
}
public File getImageFile(int mapID) {
return new File(imagesDirectory, "map" + mapID + ".png");
}
@SuppressWarnings("unchecked")
@Override
public void onEnable()
{
public void onEnable() {
// Creating the images and maps directories if necessary
try
{
try {
imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this));
checkPluginDirectory(mapsDirectory);
}
catch(final IOException ex)
{
} catch (final IOException ex) {
PluginLogger.error("FATAL: " + ex.getMessage());
this.setEnabled(false);
return;
}
saveDefaultConfig();
loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class, ImageRendererExecutor.class, CommandWorkers.class);
loadComponents(I18n.class, Gui.class, Commands.class, PluginConfiguration.class, ImageIOExecutor.class,
ImageRendererExecutor.class, CommandWorkers.class);
//Init all the things !
I18n.setPrimaryLocale(PluginConfiguration.LANG.get());
@ -136,39 +147,40 @@ public final class ImageOnMap extends QuartzPlugin
Commands.registerShortcut("maptool", ExploreCommand.class, "maps");
Commands.registerShortcut("maptool", GiveCommand.class, "mapgive");
if (PluginConfiguration.CHECK_FOR_UPDATES.get())
{
if (PluginConfiguration.CHECK_FOR_UPDATES.get()) {
UpdateChecker.boot("imageonmap.26585");
}
if (PluginConfiguration.COLLECT_DATA.get())
{
/* final Metrics metrics = new Metrics(this);
if (PluginConfiguration.COLLECT_DATA.get()) {
metrics.addCustomChart(new Metrics.SingleLineChart("rendered-images", MapManager::getImagesCount));
metrics.addCustomChart(new Metrics.SingleLineChart("used-minecraft-maps", MapManager::getMapCount));*/
PluginLogger.warning("Collect data disabled");
//final Metrics metrics = new Metrics(this);
//metrics.addCustomChart(new Metrics.SingleLineChart("rendered-images", MapManager::getImagesCount));
//metrics.addCustomChart(new Metrics.SingleLineChart("used-minecraft-maps", MapManager::getMapCount));
}
}
@Override
public void onDisable()
{
public void onDisable() {
MapManager.exit();
MapItemManager.exit();
MigratorExecutor.waitForMigration();
super.onDisable();
}
private File checkPluginDirectory(File primaryFile, File... alternateFiles) throws IOException
{
if(primaryFile.exists()) return primaryFile;
for(File file : alternateFiles)
{
if(file.exists()) return file;
private File checkPluginDirectory(File primaryFile, File... alternateFiles) throws IOException {
if (primaryFile.exists()) {
return primaryFile;
}
if(!primaryFile.mkdirs())
for (File file : alternateFiles) {
if (file.exists()) {
return file;
}
}
if (!primaryFile.mkdirs()) {
throw new IOException("Could not create '" + primaryFile.getName() + "' plugin directory.");
}
return primaryFile;
}
}

View File

@ -34,13 +34,13 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap;
import org.bukkit.permissions.Permissible;
public enum Permissions
{
public enum Permissions {
NEW("imageonmap.new", "imageonmap.userender"),
LIST("imageonmap.list"),
LISTOTHER("imageonmap.listother"),
@ -54,14 +54,12 @@ public enum Permissions
UPDATEOTHER("imageonmap.updateother"),
ADMINISTRATIVE("imageonmap.administrative"),
BYPASS_SIZE("imageonmap.bypasssize"),
GIVE("imageonmap.give")
;
GIVE("imageonmap.give");
private final String permission;
private final String[] aliases;
Permissions(String permission, String... aliases)
{
Permissions(String permission, String... aliases) {
this.permission = permission;
this.aliases = aliases;
}
@ -72,14 +70,16 @@ public enum Permissions
* @param permissible The permissible to check.
* @return {@code true} if this permission is granted to the permissible.
*/
public boolean grantedTo(Permissible permissible)
{
if (permissible.hasPermission(permission))
public boolean grantedTo(Permissible permissible) {
if (permissible.hasPermission(permission)) {
return true;
}
for (String alias : aliases)
if (permissible.hasPermission(alias))
for (String alias : aliases) {
if (permissible.hasPermission(alias)) {
return true;
}
}
return false;
}

View File

@ -36,29 +36,27 @@
package fr.moribus.imageonmap;
import fr.zcraft.quartzlib.components.configuration.Configuration;
import fr.zcraft.quartzlib.components.configuration.ConfigurationItem;
import java.util.Locale;
import static fr.zcraft.quartzlib.components.configuration.ConfigurationItem.item;
public final class PluginConfiguration extends Configuration
{
static public ConfigurationItem<Locale> LANG = item("lang", Locale.class);
static public ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
static public ConfigurationItem<Boolean> CHECK_FOR_UPDATES = item("check-for-updates", true);
static public ConfigurationItem<Integer> MAP_GLOBAL_LIMIT = item("map-global-limit", 0, "Limit-map-by-server");
static public ConfigurationItem<Integer> MAP_PLAYER_LIMIT = item("map-player-limit", 0, "Limit-map-by-player");
static public ConfigurationItem<Boolean> SAVE_FULL_IMAGE = item("save-full-image", true);
import fr.zcraft.quartzlib.components.configuration.Configuration;
import fr.zcraft.quartzlib.components.configuration.ConfigurationItem;
import java.util.Locale;
static public ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
static public ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
public final class PluginConfiguration extends Configuration {
public static ConfigurationItem<Locale> LANG = item("lang", Locale.class);
public static ConfigurationItem<Boolean> COLLECT_DATA = item("collect-data", true);
public static 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 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);
}

View File

@ -33,6 +33,7 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.commands;
import fr.moribus.imageonmap.map.ImageMap;
@ -40,97 +41,100 @@ import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.quartzlib.components.commands.Command;
import fr.zcraft.quartzlib.components.commands.CommandException;
import fr.zcraft.quartzlib.components.i18n.I;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.entity.Player;
public abstract class IoMCommand extends Command
{
protected ImageMap getMapFromArgs() throws CommandException
{
return getMapFromArgs(playerSender(), 0, true);
}
//TODO:Add the quote system to zlib and refactor this
protected ImageMap getMapFromArgs(Player player, int index) throws CommandException
{
if(args.length <= index) throwInvalidArgument(I.t("You need to give a map name."));
public abstract class IoMCommand extends Command {
protected ImageMap getMapFromArgs() throws CommandException {
return getMapFromArgs(playerSender(), 0, true);
}
ImageMap map;
String mapName = args[index];
for (int i = index + 1, c = args.length; i < c; i++) {
mapName += " " + args[i];
}
String regex="((\"([^\\\"]*(\\\\\\\")*)*([^\\\\\\\"]\"))|([^\\\"\\s\\\\]*(\\\\\\s)*[\\\\]*)*\"?)";
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(mapName);
StringBuilder result = new StringBuilder();
matcher.find();
result.append(matcher.group(0));
if(result!=null)
if(result.charAt(0)=='\"')
if(result.length()==1){
result.deleteCharAt(0);
}
else
if(result.charAt(result.length()-1)=='\"') {
result=result.deleteCharAt(result.length() - 1);
if(result!=null&&!result.equals("")&&result.charAt(0)=='\"')
mapName=result.deleteCharAt(0).toString();
}
//TODO:Add the quote system to zlib and refactor this
protected ImageMap getMapFromArgs(Player player, int index) throws CommandException {
if (args.length <= index) {
throwInvalidArgument(I.t("You need to give a map name."));
}
mapName = mapName.trim();
StringBuilder mapName = new StringBuilder(args[index]);
for (int i = index + 1, c = args.length; i < c; i++) {
mapName.append(" ").append(args[i]);
}
String regex = "((\"([^\\\"]*(\\\\\\\")*)*([^\\\\\\\"]\"))|([^\\\"\\s\\\\]*(\\\\\\s)*[\\\\]*)*\"?)";
map = MapManager.getMap(player.getUniqueId(), mapName);
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(mapName.toString());
if(map == null) error(I.t("This map does not exist."));
return map;
}
protected ImageMap getMapFromArgs(Player player, int index, boolean expand) throws CommandException
{
if(args.length <= index) throwInvalidArgument(I.t("You need to give a map name."));
StringBuilder result = new StringBuilder();
ImageMap map;
String mapName = args[index];
//matcher.find();
result.append(matcher.group(0));
if (result != null) {
if (result.charAt(0) == '\"') {
if (result.length() == 1) {
result.deleteCharAt(0);
} else if (result.charAt(result.length() - 1) == '\"') {
result = result.deleteCharAt(result.length() - 1);
if (result != null && !result.equals("") && result.charAt(0) == '\"') {
mapName = new StringBuilder(result.deleteCharAt(0).toString());
}
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."));
mapName = new StringBuilder(mapName.toString().trim());
ImageMap map;
map = MapManager.getMap(player.getUniqueId(), mapName.toString());
return map;
}
if (map == null) {
error(I.t("This map does not exist."));
}
return map;
}
protected List<String> getMatchingMapNames(Player player, String prefix)
{
return getMatchingMapNames(MapManager.getMapList(player.getUniqueId()), prefix);
}
protected ImageMap getMapFromArgs(Player player, int index, boolean expand) throws CommandException {
if (args.length <= index) {
throwInvalidArgument(I.t("You need to give a map name."));
}
protected List<String> getMatchingMapNames(Iterable<? extends ImageMap> maps, String prefix)
{
List<String> matches = new ArrayList<>();
ImageMap map;
String mapName = args[index];
for(ImageMap map : maps)
{
if(map.getId().startsWith(prefix)) matches.add(map.getId());
}
if (expand) {
for (int i = index + 1, c = args.length; i < c; i++) {
mapName += " " + args[i];
}
}
return matches;
}
mapName = mapName.trim();
map = MapManager.getMap(player.getUniqueId(), mapName);
if (map == null) {
error(I.t("This map does not exist."));
}
return map;
}
protected List<String> getMatchingMapNames(Player player, String prefix) {
return getMatchingMapNames(MapManager.getMapList(player.getUniqueId()), prefix);
}
protected List<String> getMatchingMapNames(Iterable<? extends ImageMap> maps, String prefix) {
List<String> matches = new ArrayList<>();
for (ImageMap map : maps) {
if (map.getId().startsWith(prefix)) {
matches.add(map.getId());
}
}
return matches;
}
}

View File

@ -47,19 +47,17 @@ import fr.zcraft.quartzlib.components.commands.WithFlags;
import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.components.rawtext.RawText;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
@CommandInfo(name = "delete", usageParameters = "<map name> [--confirm]")
@WithFlags({"confirm"})
public class DeleteCommand extends IoMCommand {
@CommandInfo (name = "delete", usageParameters = "<map name> [--confirm]")
@WithFlags ({"confirm"})
public class DeleteCommand extends IoMCommand
{
private static RawText deleteMsg(Class klass,ImageMap map){
return new RawText(I.t("You are going to delete") + " ")
private static RawText deleteMsg(Class klass, ImageMap map) {
return new RawText(I.t("You are going to delete") + " ")
.then(map.getId())
.color(ChatColor.GOLD)
.then(". " + I.t("Are you sure ? "))
@ -72,45 +70,37 @@ public class DeleteCommand extends IoMCommand
}
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
ImageMap map = getMapFromArgs();
if (!hasFlag("confirm"))
{
RawText msg = deleteMsg(getClass(),map);
if (!hasFlag("confirm")) {
RawText msg = deleteMsg(getClass(), map);
send(msg);
}
else
{
} else {
Player player = playerSender();
MapManager.clear(player.getInventory(), map);
try
{
try {
MapManager.deleteMap(map);
info(I.t("Map successfully deleted."));
}
catch (MapManagerException ex)
{
} catch (MapManagerException ex) {
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
warning(I.t("This map does not exist."));
}
}
}
@Override
protected List<String> complete() throws CommandException
{
if(args.length == 1)
protected List<String> complete() throws CommandException {
if (args.length == 1) {
return getMatchingMapNames(playerSender(), args[0]);
}
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.DELETE.grantedTo(sender);
}
}

View File

@ -46,23 +46,20 @@ import fr.zcraft.quartzlib.components.commands.CommandInfo;
import fr.zcraft.quartzlib.components.commands.WithFlags;
import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
@CommandInfo (name = "deleteother", usageParameters = "<player name> <map name>")
@WithFlags ({"confirm"})
public class DeleteOtherCommand extends IoMCommand
{
@CommandInfo(name = "deleteother", usageParameters = "<player name> <map name>")
@WithFlags({"confirm"})
public class DeleteOtherCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(args.length < 2) {
protected void run() throws CommandException {
if (args.length < 2) {
warning(I.t("Not enough parameters! Usage: /maptool deleteother <playername> <mapname>"));
return;
}
@ -71,44 +68,46 @@ public class DeleteOtherCommand extends IoMCommand
UUID uuid = null;
OfflinePlayer op = null;
player = Bukkit.getPlayer(args[0]);
if(player == null){
if (player == null) {
op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) uuid = op.getUniqueId();
else warning(I.t("We've never seen that player before!"));
if (op.hasPlayedBefore()) {
uuid = op.getUniqueId();
} else {
warning(I.t("We've never seen that player before!"));
}
} else {
uuid = player.getUniqueId();
}
else uuid = player.getUniqueId();
if(player==null){
if (player == null) {
warning(I.t("Player not found"));
return;
}
ImageMap map = getMapFromArgs(player, 1, true);
if(player != null) MapManager.clear(player.getInventory(), map);
//if (player != null) {
MapManager.clear(player.getInventory(), map);
//}
try
{
try {
MapManager.deleteMap(map);
info(I.t("{gray}Map successfully deleted."));
}
catch (MapManagerException ex)
{
} catch (MapManagerException ex) {
PluginLogger.warning(I.t("A non-existent map was requested to be deleted", ex));
warning(ChatColor.RED+(I.t("This map does not exist.")));
warning(ChatColor.RED + (I.t("This map does not exist.")));
}
}
@Override
protected List<String> complete() throws CommandException
{
if(args.length == 1)
protected List<String> complete() throws CommandException {
if (args.length == 1) {
return getMatchingMapNames(playerSender(), args[0]);
}
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.DELETEOTHER.grantedTo(sender);
}
}

View File

@ -43,21 +43,47 @@ 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 org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandInfo (name = "explore")
public class ExploreCommand extends IoMCommand
{
@Override
protected void run() throws CommandException
{
Gui.open(playerSender(), new MapListGui(playerSender()));
}
@CommandInfo(name = "explore")
public class ExploreCommand extends IoMCommand {
@Override
protected void run() throws CommandException {
if (args.length < 1) {
Gui.open(playerSender(), new MapListGui(playerSender()));
} else {
if (Permissions.LISTOTHER.grantedTo(sender)) {
String name = args[0];
Player sender = playerSender();
offlinePlayerParameter(0, uuid -> {
if (uuid == null) {
try {
throwInvalidArgument(I.t("Player not found."));
} catch (CommandException e) {
PluginLogger.error("CommandException " + e);
return;
}
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.LIST.grantedTo(sender);
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if (offlinePlayer != null) {
Gui.open(sender, new MapListGui(offlinePlayer, name));
} else {
PluginLogger.warning(I.t("Can't find player"));
}
});
}
}
}
@Override
public boolean canExecute(CommandSender sender) {
return Permissions.LIST.grantedTo(sender);
}
}

View File

@ -50,32 +50,29 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandInfo (name = "exploreother")
public class ExploreOtherCommand extends IoMCommand
{
@CommandInfo(name = "exploreother")
public class ExploreOtherCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(args.length < 1) {
protected void run() throws CommandException {
if (args.length < 1) {
warning(I.t("Not enough parameters! Usage: /maptool exploreother <playername>"));
return;
}
String name=args[0];
Player sender=playerSender();
String name = args[0];
Player sender = playerSender();
offlinePlayerParameter(0, uuid -> {
if(uuid==null){
if (uuid == null) {
try {
throwInvalidArgument(I.t("Player not found."));
} catch (CommandException e) {
PluginLogger.error("CommandException "+e);
PluginLogger.error("CommandException " + e);
return;
}
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if (offlinePlayer != null) {
Gui.open(sender, new MapListGui(offlinePlayer, name));
}
else{
} else {
PluginLogger.warning(I.t("Can't find player"));
return;
}
@ -83,8 +80,7 @@ public class ExploreOtherCommand extends IoMCommand
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.LISTOTHER.grantedTo(sender);
}
}

View File

@ -36,42 +36,36 @@
package fr.moribus.imageonmap.commands.maptool;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
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 fr.zcraft.quartzlib.components.i18n.I;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandInfo (name = "get")
public class GetCommand extends IoMCommand
{
@CommandInfo(name = "get")
public class GetCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
Player player = playerSender();
if(getMapFromArgs().give(player))
{
if (getMapFromArgs().give(player)) {
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
protected List<String> complete() throws CommandException
{
if(args.length == 1)
protected List<String> complete() throws CommandException {
if (args.length == 1) {
return getMatchingMapNames(playerSender(), args[0]);
}
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.GET.grantedTo(sender);
}
}

View File

@ -44,58 +44,56 @@ 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 java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.UUID;
@CommandInfo(name = "getother", usageParameters = "<PlayerName> <MapName>")
public class GetOtherCommand extends IoMCommand {
@CommandInfo (name = "getother", usageParameters = "<PlayerName> <MapName>")
public class GetOtherCommand extends IoMCommand
{
@Override
protected void run() throws CommandException {
if (args.length < 2) {
warning(I.t("Not enough parameters! Usage: /maptool getother <playername> <mapname>"));
return;
}
@Override
protected void run() throws CommandException
{
if(args.length < 2) {
warning(I.t("Not enough parameters! Usage: /maptool getother <playername> <mapname>"));
return;
}
Player player = null;
UUID uuid = null;
player = Bukkit.getPlayer(args[0]);
Player player = null;
UUID uuid = null;
player = Bukkit.getPlayer(args[0]);
if (player == null) {
OfflinePlayer op = Bukkit.getOfflinePlayer(args[0]);
if (op.hasPlayedBefore()) {
uuid = op.getUniqueId();
} else {
warning(I.t("We've never seen that player before!"));
}
return;
} else {
uuid = player.getUniqueId();
}
ImageMap map = null;
String mapName = "";
mapName = args[1];
if (args.length > 2) {
for (int i = 2; i < args.length; i++) {
mapName += (" " + args[i - 1]);
}
}
map = MapManager.getMap(uuid, mapName);
if (map != null) {
map.give(playerSender());
} else {
warning(I.t("Unknown map {0}", mapName));
}
}
if(player == null){
OfflinePlayer op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) uuid = op.getUniqueId();
else warning(I.t("We've never seen that player before!"));
return;
}
else {
uuid = player.getUniqueId();
}
ImageMap map = null;
String mapName = "";
mapName = args[1];
if(args.length > 2) {
for(int i = 2; i < args.length; i++) {
mapName += (" " + args[i - 1]);
}
}
map = MapManager.getMap(uuid, mapName);
if(map!=null)
map.give(playerSender());
else{
warning(I.t("Unknown map {0}",mapName));
}
return;
}
@Override
public boolean canExecute(CommandSender sender)
{
return Permissions.GETOTHER.grantedTo(sender);
}
@Override
public boolean canExecute(CommandSender sender) {
return Permissions.GETOTHER.grantedTo(sender);
}
}

View File

@ -45,35 +45,29 @@ import fr.zcraft.quartzlib.components.i18n.I;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandInfo (name = "getremaining", aliases = {"getrest"})
public class GetRemainingCommand extends IoMCommand
{
@CommandInfo(name = "getremaining", aliases = {"getrest"})
public class GetRemainingCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
Player player = playerSender();
if(MapItemManager.getCacheSize(player) <= 0)
{
if (MapItemManager.getCacheSize(player) <= 0) {
info(I.t("You have no remaining map."));
return;
}
int givenMaps = MapItemManager.giveCache(player);
if(givenMaps == 0)
{
if (givenMaps == 0) {
error(I.t("Your inventory is full! Make some space before requesting the remaining maps."));
}
else
{
info(I.tn("There is {0} map remaining.", "There are {0} maps remaining.", MapItemManager.getCacheSize(player)));
} else {
info(I.tn("There is {0} map remaining.", "There are {0} maps remaining.",
MapItemManager.getCacheSize(player)));
}
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.NEW.grantedTo(sender) || Permissions.GET.grantedTo(sender);
}
}

View File

@ -40,83 +40,90 @@ import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.zlib.components.commands.CommandException;
import fr.zcraft.zlib.components.commands.CommandInfo;
import fr.zcraft.zlib.components.i18n.I;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.quartzlib.components.commands.CommandException;
import fr.zcraft.quartzlib.components.commands.CommandInfo;
import fr.zcraft.quartzlib.components.i18n.I;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@CommandInfo(name = "give", usageParameters = "<Player> <MapName> or <Player> <MapName> <Player where to find the map>")
public class GiveCommand extends IoMCommand {
//TODO passer avec une reconnaissance player/UUID, par défaut
/**
* Parse an argument given at a specific index, it will return a player depending on the given prefixe. Can be player:<username> or uuid:<uuid>
* Parse an argument given at a specific index, it will return a player depending on the given prefixe.
* Can be player:< username > or uuid:< uuid >
*
* @param index The index.
* @return The retrieved player.
* @throws CommandException If the value is invalid.
* @throws InterruptedException .
* @throws IOException
*
*/
private OfflinePlayer parse(int index) throws CommandException {
String s = args[index].trim();
String[] subs = s.split(":");
try {
//
if (subs.length == 1) {
return getOfflinePlayerParameter(index);
}
switch (subs[0]) {
case "player":
return getOfflinePlayerParameter(subs[1]);
case "uuid":
StringBuffer string = new StringBuffer(subs[1].toLowerCase());
//if there are no '-'
if (string.length() == 32) {
//we try to fix it by adding - at pos 8,12,16,20
Integer[] pos={20,16,12,8};
for(int i:pos)
string = string.insert(i, "-");
}
//if the given uuid is well formed with 8-4-4-4-12 = 36 chars in length (including '-')
if (string.length() == 36)
return Bukkit.getOfflinePlayer(UUID.fromString(string.toString()));
throwInvalidArgument(I.t("Invalid uuid, please provide an uuid of this form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
case "bank":
throwInvalidArgument(I.t("Not supported yet"));
break;
default:
throwInvalidArgument(I.t("Invalid prefix, valid one are: player | uuid"));
}
} catch (InterruptedException | ExecutionException e) {
PluginLogger.warning(I.t("Can't access to mojang API to check the player UUID"));
//try {
//
if (subs.length == 1) {
return null;//temp
//return offlinePlayerParameter(index);
}
switch (subs[0]) {
case "player":
return null;//temp
// return offlinePlayerParameter(subs[1]);
case "uuid":
StringBuffer string = new StringBuffer(subs[1].toLowerCase());
//if there are no '-'
if (string.length() == 32) {
//we try to fix it by adding - at pos 8,12,16,20
Integer[] pos = {20, 16, 12, 8};
for (int i : pos) {
string = string.insert(i, "-");
}
}
//if the given uuid is well formed with 8-4-4-4-12 = 36 chars in length (including '-')
if (string.length() == 36) {
return Bukkit.getOfflinePlayer(UUID.fromString(string.toString()));
}
throwInvalidArgument(
I.t("Invalid uuid, please provide an uuid of this form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ " or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
break;
case "bank":
throwInvalidArgument(I.t("Not supported yet"));
break;
default:
throwInvalidArgument(I.t("Invalid prefix, valid one are: player | uuid"));
}
/*} catch (InterruptedException | ExecutionException e) {
PluginLogger.warning(I.t("Can't access to mojang API to check the player UUID"));
}*/
return null;
}
@Override
protected void run() throws CommandException {
if (args.length < 2) throwInvalidArgument(I.t("You must give a valid player name and a map name."));
if (args.length < 2) {
throwInvalidArgument(I.t("You must give a valid player name and a map name."));
}
final Player p = getPlayerParameter(0);
ImageMap map;
//TODO add support for map name with spaces "cool name" or name or "name" "cool name with a \" and some stuff" should work
//TODO add support for map name with spaces "cool name" or name or "name" "cool name with a \" and some stuff"
// should work
OfflinePlayer player = null;
if (args.length < 4) {

View File

@ -47,34 +47,29 @@ 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.text.RawMessage;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
@CommandInfo (name = "list")
public class ListCommand extends IoMCommand
{
@CommandInfo(name = "list")
public class ListCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
Player player = playerSender();
List<ImageMap> mapList = MapManager.getMapList(player.getUniqueId());
if(mapList.isEmpty())
{
if (mapList.isEmpty()) {
info(I.t("No map found."));
return;
}
info(I.tn("{white}{bold}{0} map found.", "{white}{bold}{0} maps found.", mapList.size()));
RawTextPart rawText = new RawText("");
rawText = addMap(rawText, mapList.get(0));
for(int i = 1, c = mapList.size(); i < c; i++)
{
for (int i = 1, c = mapList.size(); i < c; i++) {
rawText = rawText.then(", ").color(ChatColor.GRAY);
rawText = addMap(rawText, mapList.get(i));
}
@ -82,9 +77,9 @@ public class ListCommand extends IoMCommand
RawMessage.send(player, rawText.build());
}
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map)
{
final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" : ((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount();
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map) {
final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" :
((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount();
return rawText
.then(map.getId())
@ -98,8 +93,7 @@ public class ListCommand extends IoMCommand
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.LIST.grantedTo(sender);
}
}

View File

@ -48,23 +48,20 @@ 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.text.RawMessage;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
@CommandInfo (name = "listother", usageParameters = "<PlayerName>")
public class ListOtherCommand extends IoMCommand
{
@CommandInfo(name = "listother", usageParameters = "<PlayerName>")
public class ListOtherCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(args.length < 1){
protected void run() throws CommandException {
if (args.length < 1) {
warning(I.t("Not enough parameters! Usage: /maptool listother <playername>"));
return;
}
@ -73,29 +70,25 @@ public class ListOtherCommand extends IoMCommand
Player player = null;
UUID uuid = null;
player = Bukkit.getPlayer(args[0]);
if(player == null){
if (player == null) {
OfflinePlayer op = Bukkit.getOfflinePlayer(args[0]);
if(op.hasPlayedBefore()) {
if (op.hasPlayedBefore()) {
uuid = op.getUniqueId();
}
else {
} else {
warning(I.t("We've never seen that player before!"));
}
}
else{
} else {
uuid = player.getUniqueId();
}
List<ImageMap> mapList = null;
try{
try {
mapList = MapManager.getMapList(uuid);
}
catch(Exception e){
} catch (Exception e) {
return;
}
if(mapList.isEmpty())
{
if (mapList.isEmpty()) {
info(I.t("No map found."));
return;
}
@ -105,8 +98,7 @@ public class ListOtherCommand extends IoMCommand
RawTextPart rawText = new RawText("");
rawText = addMap(rawText, mapList.get(0));
for(int i = 1, c = mapList.size(); i < c; i++)
{
for (int i = 1, c = mapList.size(); i < c; i++) {
rawText = rawText.then(", ").color(ChatColor.GRAY);
rawText = addMap(rawText, mapList.get(i));
}
@ -114,9 +106,9 @@ public class ListOtherCommand extends IoMCommand
RawMessage.send(playerSender(), rawText.build());
}
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map)
{
final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" : ((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount();
private RawTextPart<?> addMap(RawTextPart<?> rawText, ImageMap map) {
final String size = map.getType() == ImageMap.Type.SINGLE ? "1 × 1" :
((PosterMap) map).getColumnCount() + " × " + ((PosterMap) map).getRowCount();
return rawText
.then(map.getId())
@ -128,9 +120,9 @@ public class ListOtherCommand extends IoMCommand
.then(I.t("{white}Click{gray} to get this map"))
);
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.LISTOTHER.grantedTo(sender);
}
}

View File

@ -44,26 +44,20 @@ import fr.zcraft.quartzlib.components.commands.CommandInfo;
import fr.zcraft.quartzlib.components.i18n.I;
import org.bukkit.command.CommandSender;
@CommandInfo (name = "migrate")
public class MigrateCommand extends IoMCommand
{
@CommandInfo(name = "migrate")
public class MigrateCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(MigratorExecutor.isRunning())
{
protected void run() throws CommandException {
if (MigratorExecutor.isRunning()) {
error(I.t("A migration process is already running. Check console for details."));
}
else
{
} else {
info(I.t("Migration started. See console for details."));
MigratorExecutor.migrate();
}
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return sender.isOp() || Permissions.ADMINISTRATIVE.grantedTo(sender);
}
}

View File

@ -49,86 +49,88 @@ import fr.zcraft.quartzlib.components.worker.WorkerCallback;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.text.ActionBar;
import fr.zcraft.quartzlib.tools.text.MessageSender;
import java.net.MalformedURLException;
import java.net.URL;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.net.MalformedURLException;
import java.net.URL;
@CommandInfo (name = "new", usageParameters = "<URL> [resize]")
public class NewCommand extends IoMCommand
{
@CommandInfo(name = "new", usageParameters = "<URL> [resize]")
public class NewCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
final Player player = playerSender();
ImageUtils.ScalingType scaling = ImageUtils.ScalingType.NONE;
URL url;
int width = 0, height = 0;
if(args.length < 1) throwInvalidArgument(I.t("You must give an URL to take the image from."));
try
{
url = new URL(args[0]);
int width = 0;
int height = 0;
if (args.length < 1) {
throwInvalidArgument(I.t("You must give an URL to take the image from."));
}
catch(MalformedURLException ex)
{
try {
url = new URL(args[0]);
} catch (MalformedURLException ex) {
throwInvalidArgument(I.t("Invalid URL."));
return;
}
if(args.length >= 2)
{
if(args.length >= 4) {
if (args.length >= 2) {
if (args.length >= 4) {
width = Integer.parseInt(args[2]);
height = Integer.parseInt(args[3]);
}
switch(args[1]) {
case "resize": scaling = ImageUtils.ScalingType.CONTAINED; break;
case "resize-stretched": scaling = ImageUtils.ScalingType.STRETCHED; break;
case "resize-covered": scaling = ImageUtils.ScalingType.COVERED; break;
default: throwInvalidArgument(I.t("Invalid Stretching mode.")); break;
switch (args[1]) {
case "resize":
scaling = ImageUtils.ScalingType.CONTAINED;
break;
case "resize-stretched":
scaling = ImageUtils.ScalingType.STRETCHED;
break;
case "resize-covered":
scaling = ImageUtils.ScalingType.COVERED;
break;
default:
throwInvalidArgument(I.t("Invalid Stretching mode."));
break;
}
}
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!"));
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."));
}
}
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."));
}
}
@Override
public void errored(Throwable exception) {
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
@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());
}
});
}
//Added to fix bug with rendering displaying after error
finally {
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
player.getName(),
exception.getClass().getCanonicalName(),
exception.getMessage());
}
});
} finally {
ActionBar.removeMessage(player);
}
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.NEW.grantedTo(sender);
}
}

View File

@ -24,38 +24,37 @@ import fr.moribus.imageonmap.map.ImageMap;
import fr.zcraft.quartzlib.components.commands.CommandException;
import fr.zcraft.quartzlib.components.commands.CommandInfo;
import fr.zcraft.quartzlib.components.i18n.I;
import java.util.List;
import org.bukkit.command.CommandSender;
import java.util.List;
@CommandInfo(name = "rename",usageParameters = "<original map name> <new map name>")
@CommandInfo(name = "rename", usageParameters = "<original map name> <new map name>")
public class RenameCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
if(args.length != 4) {
protected void run() throws CommandException {
if (args.length != 4) {
warning(I.t("Not enough or too many arguments! Usage: /maptool rename <map name> <new map name>"));
return;
}
//if(args.length == 2)
//{
ImageMap map = getMapFromArgs();
map.rename(args[2]);
// } else {
ImageMap map = getMapFromArgs();
map.rename(args[2]);
// } else {
// info(I.t("Not enough or too many arguments"));
// }
// }
}
@Override
protected List<String> complete() throws CommandException
{
if(args.length == 1)
@Override
protected List<String> complete() throws CommandException {
if (args.length == 1) {
return getMatchingMapNames(playerSender(), args[0]);
}
return null;
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.RENAME.grantedTo(sender);
}
}

View File

@ -49,29 +49,30 @@ import fr.zcraft.quartzlib.components.worker.WorkerCallback;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.text.ActionBar;
import fr.zcraft.quartzlib.tools.text.MessageSender;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
@CommandInfo (name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateCommand extends IoMCommand
{
@CommandInfo(name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
final Player player = playerSender();
ImageUtils.ScalingType scaling;
URL url;
if(args.length < 1) throwInvalidArgument(I.t("You must give an URL and a map name to update."));
if(args.length < 2) throwInvalidArgument(I.t("You must give a map name to update."));
if (args.length < 1) {
throwInvalidArgument(I.t("You must give an URL and a map name to update."));
}
if (args.length < 2) {
throwInvalidArgument(I.t("You must give a map name to update."));
}
switch(args[1]) {
switch (args[1]) {
case "stretched":
scaling = ImageUtils.ScalingType.STRETCHED;
@ -83,51 +84,53 @@ public class UpdateCommand extends IoMCommand
scaling = ImageUtils.ScalingType.CONTAINED;
}
ImageMap map;
if(scaling.equals(ImageUtils.ScalingType.CONTAINED))
map=getMapFromArgs(player,1);
else
map=getMapFromArgs(player,2);
try
{
if (scaling.equals(ImageUtils.ScalingType.CONTAINED)) {
map = getMapFromArgs(player, 1);
} else {
map = getMapFromArgs(player, 2);
}
try {
url = new URL(args[0]);
MapManager.load();
Integer[] size={1,1};
if(map.getType()== ImageMap.Type.POSTER)
size=map.getSize( new HashMap<String, Object>(),map.getUserUUID(),map.getId());
int width=size[0],height=size[1];
Integer[] size = {1, 1};
if (map.getType() == ImageMap.Type.POSTER) {
size = map.getSize(new HashMap<String, Object>(), map.getUserUUID(), map.getId());
}
//assert size != null;
int width = size[0];
int height = size[1];
try {
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Updating..."));
ImageRendererExecutor.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
@Override
public void errored(Throwable exception) {
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
ImageRendererExecutor
.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player,
ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
player.getName(),
exception.getClass().getCanonicalName(),
exception.getMessage());
}
});
}
finally {
@Override
public void errored(Throwable exception) {
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
player.getName(),
exception.getClass().getCanonicalName(),
exception.getMessage());
}
});
} finally {
ActionBar.removeMessage(player);
}
}
catch(MalformedURLException ex)
{
} catch (MalformedURLException ex) {
throwInvalidArgument(I.t("Invalid URL."));
}
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.UPDATE.grantedTo(sender);
}
}

View File

@ -49,30 +49,31 @@ import fr.zcraft.quartzlib.components.worker.WorkerCallback;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.text.ActionBar;
import fr.zcraft.quartzlib.tools.text.MessageSender;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
@CommandInfo (name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateOtherCommand extends IoMCommand
{
@CommandInfo(name = "update", usageParameters = "<new url> [stretched|covered] \"<map name to update>\"")
public class UpdateOtherCommand extends IoMCommand {
@Override
protected void run() throws CommandException
{
protected void run() throws CommandException {
//TODO separer les deux update(update et update other)
final Player player = playerSender();
ImageUtils.ScalingType scaling;
URL url;
if(args.length < 1) throwInvalidArgument(I.t("You must give an URL and a map name to update."));
if(args.length < 2) throwInvalidArgument(I.t("You must give a map name to update."));
if (args.length < 1) {
throwInvalidArgument(I.t("You must give an URL and a map name to update."));
}
if (args.length < 2) {
throwInvalidArgument(I.t("You must give a map name to update."));
}
switch(args[1]) {
switch (args[1]) {
case "stretched":
scaling = ImageUtils.ScalingType.STRETCHED;
@ -84,51 +85,52 @@ public class UpdateOtherCommand extends IoMCommand
scaling = ImageUtils.ScalingType.CONTAINED;
}
ImageMap map;
if(scaling.equals(ImageUtils.ScalingType.CONTAINED))
map=getMapFromArgs(player,1);
else
map=getMapFromArgs(player,2);
try
{
if (scaling.equals(ImageUtils.ScalingType.CONTAINED)) {
map = getMapFromArgs(player, 1);
} else {
map = getMapFromArgs(player, 2);
}
try {
url = new URL(args[0]);
MapManager.load();
Integer[] size={1,1};
if(map.getType()== ImageMap.Type.POSTER)
size=map.getSize( new HashMap<String, Object>(),map.getUserUUID(),map.getId());
int width=size[0],height=size[1];
Integer[] size = {1, 1};
if (map.getType() == ImageMap.Type.POSTER) {
size = map.getSize(new HashMap<String, Object>(), map.getUserUUID(), map.getId());
}
int width = size[0];
int height = size[1];
try {
ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Updating..."));
ImageRendererExecutor.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
@Override
public void errored(Throwable exception) {
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
ImageRendererExecutor
.update(url, scaling, player.getUniqueId(), map, width, height, new WorkerCallback<ImageMap>() {
@Override
public void finished(ImageMap result) {
ActionBar.removeMessage(player);
MessageSender.sendActionBarMessage(player,
ChatColor.DARK_GREEN + I.t("The map was updated using the new image!"));
}
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
player.getName(),
exception.getClass().getCanonicalName(),
exception.getMessage());
}
});
}
finally {
@Override
public void errored(Throwable exception) {
player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage()));
PluginLogger.warning("Rendering from {0} failed: {1}: {2}",
player.getName(),
exception.getClass().getCanonicalName(),
exception.getMessage());
}
});
} finally {
ActionBar.removeMessage(player);
}
}
catch(MalformedURLException ex)
{
} catch (MalformedURLException ex) {
throwInvalidArgument(I.t("Invalid URL."));
}
}
@Override
public boolean canExecute(CommandSender sender)
{
public boolean canExecute(CommandSender sender) {
return Permissions.UPDATEOTHER.grantedTo(sender);
}
}

View File

@ -46,48 +46,46 @@ import fr.zcraft.quartzlib.components.gui.GuiAction;
import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
import java.util.Random;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.Random;
public class ConfirmDeleteMapGui extends ActionGui {
private static final int BUTTONS_WIDTH = 4;
public class ConfirmDeleteMapGui extends ActionGui
{
static private final int BUTTONS_WIDTH = 4;
static private final int FIRST_SLOT_DELETE_BUTTON = 27;
static private final int SHIFT_CANCEL_BUTTON = 5;
private static final int FIRST_SLOT_DELETE_BUTTON = 27;
private static final int SHIFT_CANCEL_BUTTON = 5;
/**
* The messages randomly displayed in the lore of the delete buttons.
*/
static private final String[] DELETE_MESSAGES = new String[]{
"Please", "I'm still alive", "Don't do that", "I'm still loving you", "I want to live",
"Please please", "Please please please", "What are you doing?!", "Nooooo!",
"Click and I'll be dead", "Why?", "Please don't do that", "Think about my family",
"Click, I don't like you anymore.", "I don't hate you.", "Click, I'm ready.",
"I'm a green button.", "I'm different.", "Thanks anyway.", "Excuse me.", "Get mad.",
"Sorry!", "My fault!", "I don't blame you.", "No hard feelings.",
"But I need to protect the humans!", "Noooo!", "I'm scared!", "What are you doing?",
"It burns.", "This is not good.", "Can't breathe.", "Thanks anyway.", "These things happen.",
"That was nobody's fault.", "I probably deserved it.", "I blame myself."
private static final String[] DELETE_MESSAGES = new String[] {
"Please", "I'm still alive", "Don't do that", "I'm still loving you", "I want to live",
"Please please", "Please please please", "What are you doing?!", "Nooooo!",
"Click and I'll be dead", "Why?", "Please don't do that", "Think about my family",
"Click, I don't like you anymore.", "I don't hate you.", "Click, I'm ready.",
"I'm a green button.", "I'm different.", "Thanks anyway.", "Excuse me.", "Get mad.",
"Sorry!", "My fault!", "I don't blame you.", "No hard feelings.",
"But I need to protect the humans!", "Noooo!", "I'm scared!", "What are you doing?",
"It burns.", "This is not good.", "Can't breathe.", "Thanks anyway.", "These things happen.",
"That was nobody's fault.", "I probably deserved it.", "I blame myself."
};
/**
* The messages randomly displayed in the lore of the cancel buttons.
*/
static private final String[] CANCEL_MESSAGES = new String[] {
"Yay!", "Still aliiiive!", "Click click click", "Yes do that", "I'm a red button.",
"Please click here", "The other button is ugly", "Save me", "This is the good choice",
"Click, I want to live!", "I'll be dead another day anyway", "Are you sure?",
"So you're still loving me?", "Please save me", "Take me with you.",
"Excuse me.", "Don't make lemonade.", "Sleep mode activated.", "Hybernating.",
"Your business is appreciated.", "Hey! It's me! Don't shoot!", "Wheee!", "Hurray!",
"You have excellent aim!", "Please please please"
private static final String[] CANCEL_MESSAGES = new String[] {
"Yay!", "Still aliiiive!", "Click click click", "Yes do that", "I'm a red button.",
"Please click here", "The other button is ugly", "Save me", "This is the good choice",
"Click, I want to live!", "I'll be dead another day anyway", "Are you sure?",
"So you're still loving me?", "Please save me", "Take me with you.",
"Excuse me.", "Don't make lemonade.", "Sleep mode activated.", "Hybernating.",
"Your business is appreciated.", "Hey! It's me! Don't shoot!", "Wheee!", "Hurray!",
"You have excellent aim!", "Please please please"
};
/**
* The map being deleted.
*/
@ -95,24 +93,20 @@ public class ConfirmDeleteMapGui extends ActionGui
/**
* A source of randomness.
*
* Yes, this javadoc comment is REALLY useful. Trust me.
*/
private final Random random = new Random();
/**
*
* @param mapToDelete The map being deleted.
*/
public ConfirmDeleteMapGui(ImageMap mapToDelete)
{
public ConfirmDeleteMapGui(ImageMap mapToDelete) {
this.mapToDelete = mapToDelete;
}
@Override
protected void onUpdate()
{
protected void onUpdate() {
/// The title of the map deletion GUI. {0}: map name.
setTitle(I.t(getPlayerLocale(), "{0} » {black}Confirm deletion", mapToDelete.getName()));
setSize(6 * 9);
@ -121,43 +115,40 @@ public class ConfirmDeleteMapGui extends ActionGui
/* ** Item representation of the image being deleted ** */
action("", 13, new ItemStackBuilder(Material.FILLED_MAP)
/// The title of the map deletion item
/// The title of the map deletion item
.title(I.t(getPlayerLocale(), "{red}You're about to destroy this map..."))
/// The end, in the lore, of a title starting with You're about to destroy this map....
/// The end, in the lore, of a title starting with You're about to destroy this map....
.lore(I.t(getPlayerLocale(), "{red}...{italic}forever{red}."))
.loreLine()
.lore(I.t(getPlayerLocale(), "{gray}Name: {white}{0}",mapToDelete.getName()))
.lore(I.t(getPlayerLocale(), "{gray}Name: {white}{0}", mapToDelete.getName()))
.lore(I.t(getPlayerLocale(), "{gray}Map ID: {white}{0}", mapToDelete.getId()))
.lore(I.t(getPlayerLocale(), "{gray}Maps inside: {white}{0}", mapToDelete.getMapsIDs().length))
//.hideAllAttributes()
);
);
//.hideAllAttributes()
/* ** Buttons ** */
int slot = FIRST_SLOT_DELETE_BUTTON;
for(; slot < getSize() - (9 - BUTTONS_WIDTH); slot++)
{
for (; slot < getSize() - (9 - BUTTONS_WIDTH); slot++) {
action("delete", slot, createDeleteSubButton());
action("cancel", slot + SHIFT_CANCEL_BUTTON, createCancelSubButton());
if((slot + 1) % 9 == (9 - BUTTONS_WIDTH - 1))
if ((slot + 1) % 9 == (9 - BUTTONS_WIDTH - 1)) {
slot += 5;
}
}
}
private ItemStack createDeleteSubButton()
{
private ItemStack createDeleteSubButton() {
return createSubButton(Material.RED_STAINED_GLASS_PANE, ChatColor.RED + "Delete the map", DELETE_MESSAGES);
}
private ItemStack createCancelSubButton()
{
private ItemStack createCancelSubButton() {
return createSubButton(Material.LIME_STAINED_GLASS_PANE, ChatColor.GREEN + "Cancel", CANCEL_MESSAGES);
}
private ItemStack createSubButton(Material color, String title, String[] messages)
{
private ItemStack createSubButton(Material color, String title, String[] messages) {
return new ItemStackBuilder(color)
.title(title)
.loreSeparator()
@ -165,19 +156,16 @@ public class ConfirmDeleteMapGui extends ActionGui
.item();
}
@GuiAction ("cancel")
protected void cancel()
{
close();
@GuiAction("cancel")
protected void cancel() {
close();
}
@GuiAction ("delete")
protected void delete()
{
@GuiAction("delete")
protected void delete() {
// Does the player still have the permission to delete a map?
if (!Permissions.DELETE.grantedTo(getPlayer()))
{
if (!Permissions.DELETE.grantedTo(getPlayer())) {
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
close();
return;
@ -185,13 +173,10 @@ public class ConfirmDeleteMapGui extends ActionGui
MapManager.clear(getPlayer().getInventory(), mapToDelete);
try
{
try {
MapManager.deleteMap(mapToDelete);
getPlayer().sendMessage(I.t("{gray}Map successfully deleted."));
}
catch (MapManagerException ex)
{
} catch (MapManagerException ex) {
PluginLogger.warning("Error while deleting map", ex);
getPlayer().sendMessage(ChatColor.RED + ex.getMessage());
}
@ -199,9 +184,10 @@ public class ConfirmDeleteMapGui extends ActionGui
// We try to open the map list GUI, if the map was deleted, before the details GUI
// (so the grandparent GUI).
if (getParent() != null && getParent().getParent() != null)
if (getParent() != null && getParent().getParent() != null) {
Gui.open(getPlayer(), getParent().getParent());
else
} else {
close();
}
}
}

View File

@ -54,20 +54,19 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
public class MapDetailGui extends ExplorerGui<Integer>
{
public class MapDetailGui extends ExplorerGui<Integer> {
private final ImageMap map;
private OfflinePlayer p;
private OfflinePlayer offplayer;
private String name;
public MapDetailGui(ImageMap map, OfflinePlayer p, String name){
this.map=map;
this.p=p;
this.name=name;
public MapDetailGui(ImageMap map, OfflinePlayer p, String name) {
this.map = map;
this.offplayer = p;
this.name = name;
}
@Override
protected ItemStack getViewItem(int x, int y)
{
protected ItemStack getViewItem(int x, int y) {
final Material partMaterial = y % 2 == x % 2 ? Material.MAP : Material.PAPER;
final ItemStackBuilder builder = new ItemStackBuilder(partMaterial)
@ -75,15 +74,15 @@ public class MapDetailGui extends ExplorerGui<Integer>
.lore(I.t(getPlayerLocale(), "{gray}Row: {white}{0}", y + 1))
.lore(I.t(getPlayerLocale(), "{gray}Column: {white}{0}", x + 1));
if (Permissions.GET.grantedTo(getPlayer()))
if (Permissions.GET.grantedTo(getPlayer())) {
builder.loreLine().lore(I.t(getPlayerLocale(), "{gray}» {white}Click{gray} to get only this part"));
}
return builder.item();
}
@Override
protected ItemStack getViewItem(Integer mapId)
{
protected ItemStack getViewItem(Integer mapId) {
final int index = ((PosterMap) map).getIndex(mapId);
final Material partMaterial = index % 2 == 0 ? Material.MAP : Material.PAPER;
@ -91,77 +90,66 @@ public class MapDetailGui extends ExplorerGui<Integer>
.title(I.t(getPlayerLocale(), "{green}Map part"))
.lore(I.t(getPlayerLocale(), "{gray}Part: {white}{0}", index + 1));
if (Permissions.GET.grantedTo(getPlayer()))
if (Permissions.GET.grantedTo(getPlayer())) {
builder.loreLine().lore(I.t(getPlayerLocale(), "{gray}» {white}Click{gray} to get only this part"));
}
return builder.item();
}
@Override
protected ItemStack getPickedUpItem(int x, int y)
{
if (!Permissions.GET.grantedTo(getPlayer()))
return null;
if (map instanceof SingleMap)
{
return MapItemManager.createMapItem((SingleMap)map,true);
@Override
protected ItemStack getPickedUpItem(int x, int y) {
if (!Permissions.GET.grantedTo(getPlayer())) {
return null;
}
else if (map instanceof PosterMap)
{
return MapItemManager.createMapItem((PosterMap)map, x, y);
if (map instanceof SingleMap) {
return MapItemManager.createMapItem((SingleMap) map, true);
} else if (map instanceof PosterMap) {
return MapItemManager.createMapItem((PosterMap) map, x, y);
}
throw new IllegalStateException("Unsupported map type: " + map.getType());
}
@Override
protected ItemStack getPickedUpItem(Integer mapId)
{
if (!Permissions.GET.grantedTo(getPlayer()))
protected ItemStack getPickedUpItem(Integer mapId) {
if (!Permissions.GET.grantedTo(getPlayer())) {
return null;
}
final PosterMap poster = (PosterMap) map;
return MapItemManager.createMapItem(poster, poster.getIndex(mapId));
}
@Override
protected ItemStack getEmptyViewItem()
{
if (map instanceof SingleMap)
{
protected ItemStack getEmptyViewItem() {
if (map instanceof SingleMap) {
return getViewItem(0, 0);
} else {
return super.getEmptyViewItem();
}
else return super.getEmptyViewItem();
}
@Override
protected void onUpdate()
{
protected void onUpdate() {
/// Title of the map details GUI
if(p.getUniqueId().equals(getPlayer().getUniqueId())) {
if (offplayer.getUniqueId().equals(getPlayer().getUniqueId())) {
setTitle(I.t(getPlayerLocale(), "Your maps » {black}{0}", map.getName()));
}
else{
setTitle(I.t(getPlayerLocale(), "{1}'s maps » {black}{0}", map.getName(),name));
} else {
setTitle(I.t(getPlayerLocale(), "{1}'s maps » {black}{0}", map.getName(), name));
}
setKeepHorizontalScrollingSpace(true);
if (map instanceof PosterMap)
{
if (map instanceof PosterMap) {
PosterMap poster = (PosterMap) map;
if(poster.hasColumnData())
{
if (poster.hasColumnData()) {
setDataShape(poster.getColumnCount(), poster.getRowCount());
}
else
{
} else {
setData(ArrayUtils.toObject(poster.getMapsIDs()));
}
}
else
{
setDataShape(1,1);
} else {
setDataShape(1, 1);
}
final boolean canRename = Permissions.RENAME.grantedTo(getPlayer());
@ -170,24 +158,26 @@ public class MapDetailGui extends ExplorerGui<Integer>
int renameSlot = getSize() - 7;
int deleteSlot = getSize() - 6;
if (!canRename)
if (!canRename) {
deleteSlot--;
}
if (canRename)
{
if (canRename) {
action("rename", renameSlot, new ItemStackBuilder(Material.WRITABLE_BOOK)
.title(I.t(getPlayerLocale(), "{blue}Rename this image"))
.longLore(I.t(getPlayerLocale(), "{gray}Click here to rename this image; this is used for your own organization."))
.longLore(I.t(getPlayerLocale(),
"{gray}Click here to rename this image; this is used for your own organization."))
);
}
if (canDelete)
{
if (canDelete) {
action("delete", deleteSlot, new ItemStackBuilder(Material.BARRIER)
.title(I.t(getPlayerLocale(), "{red}Delete this image"))
.longLore(I.t(getPlayerLocale(), "{gray}Deletes this map {white}forever{gray}. This action cannot be undone!"))
.longLore(I.t(getPlayerLocale(),
"{gray}Deletes this map {white}forever{gray}. This action cannot be undone!"))
.loreLine()
.longLore(I.t(getPlayerLocale(), "{gray}You will be asked to confirm your choice if you click here."))
.longLore(
I.t(getPlayerLocale(), "{gray}You will be asked to confirm your choice if you click here."))
);
}
@ -196,10 +186,11 @@ public class MapDetailGui extends ExplorerGui<Integer>
// arrow isn't displayed, so when the map fit on the grid without sliders.
int backSlot = getSize() - 4;
if (!canRename && !canDelete)
if (!canRename && !canDelete) {
backSlot = getSize() - 5;
else if (map instanceof PosterMap && ((PosterMap) map).getColumnCount() <= INVENTORY_ROW_SIZE)
} else if (map instanceof PosterMap && ((PosterMap) map).getColumnCount() <= INVENTORY_ROW_SIZE) {
backSlot++;
}
action("back", backSlot, new ItemStackBuilder(Material.EMERALD)
.title(I.t(getPlayerLocale(), "{green}« Back"))
@ -208,29 +199,23 @@ public class MapDetailGui extends ExplorerGui<Integer>
}
@GuiAction ("rename")
public void rename()
{
if (!Permissions.RENAME.grantedTo(getPlayer()))
{
@GuiAction("rename")
public void rename() {
if (!Permissions.RENAME.grantedTo(getPlayer())) {
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
update();
return;
}
PromptGui.prompt(getPlayer(), new Callback<String>()
{
PromptGui.prompt(getPlayer(), new Callback<String>() {
@Override
public void call(String newName)
{
if (!Permissions.RENAME.grantedTo(getPlayer()))
{
public void call(String newName) {
if (!Permissions.RENAME.grantedTo(getPlayer())) {
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
return;
}
if (newName == null || newName.isEmpty())
{
if (newName == null || newName.isEmpty()) {
I.sendT(getPlayer(), "{ce}Map names can't be empty.");
return;
}
@ -241,11 +226,9 @@ public class MapDetailGui extends ExplorerGui<Integer>
}, map.getName(), this);
}
@GuiAction ("delete")
public void delete()
{
if (!Permissions.DELETE.grantedTo(getPlayer()))
{
@GuiAction("delete")
public void delete() {
if (!Permissions.DELETE.grantedTo(getPlayer())) {
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
update();
return;
@ -253,9 +236,8 @@ public class MapDetailGui extends ExplorerGui<Integer>
Gui.open(getPlayer(), new ConfirmDeleteMapGui(map), this);
}
@GuiAction ("back")
public void back()
{
@GuiAction("back")
public void back() {
close();
}
}

View File

@ -33,6 +33,7 @@
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-B license and that you accept its terms.
*/
package fr.moribus.imageonmap.gui;
import fr.moribus.imageonmap.Permissions;
@ -55,38 +56,33 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
public class MapListGui extends ExplorerGui<ImageMap>
{
private OfflinePlayer p;
public class MapListGui extends ExplorerGui<ImageMap> {
private OfflinePlayer offplayer;
private String name;
public MapListGui(Player sender){
this.p=sender;
this.name=sender.getName();
public MapListGui(Player sender) {
this.offplayer = sender;
this.name = sender.getName();
}
public MapListGui(OfflinePlayer p,String name){
this.p=p;
this.name=name;
public MapListGui(OfflinePlayer p, String name) {
this.offplayer = p;
this.name = name;
}
@Override
protected ItemStack getViewItem(ImageMap map)
{
protected ItemStack getViewItem(ImageMap map) {
String mapDescription;
if (map instanceof SingleMap)
{
if (map instanceof SingleMap) {
/// Displayed subtitle description of a single map on the list GUI
mapDescription = I.t(getPlayerLocale(), "{white}Single map");
}
else
{
} else {
PosterMap poster = (PosterMap) map;
if(poster.hasColumnData())
{
if (poster.hasColumnData()) {
/// Displayed subtitle description of a poster map on the list GUI (columns × rows in english)
mapDescription = I.t(getPlayerLocale(), "{white}Poster map ({0} × {1})", poster.getColumnCount(), poster.getRowCount());
}
else
{
mapDescription = I.t(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.t(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount());
}
@ -102,8 +98,9 @@ public class MapListGui extends ExplorerGui<ImageMap>
.lore(I.tl(getPlayerLocale(), "{gray}Map ID: {0}", map.getId()))
.loreLine();
if (Permissions.GET.grantedTo(getPlayer()))
if (Permissions.GET.grantedTo(getPlayer())) {
builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Left-click{gray} to get this map"));
}
builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Right-click{gray} for details and options"));
@ -117,48 +114,45 @@ public class MapListGui extends ExplorerGui<ImageMap>
}
@Override
protected ItemStack getEmptyViewItem()
{
protected ItemStack getEmptyViewItem() {
ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER);
if(p.getUniqueId().equals(getPlayer().getUniqueId())) {
if (offplayer.getUniqueId().equals(getPlayer().getUniqueId())) {
builder.title(I.tl(getPlayerLocale(), "{red}You don't have any map."));
if (Permissions.NEW.grantedTo(getPlayer()))
builder.longLore(I.tl(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!"));
else
if (Permissions.NEW.grantedTo(getPlayer())) {
builder.longLore(I.tl(getPlayerLocale(),
"{gray}Get started by creating a new one using {white}/tomap <URL> [resize]{gray}!"));
} else {
builder.longLore(I.tl(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one."));
}
else{
builder.title(I.tl(getPlayerLocale(), "{red}{0} doesn't have any map.",name));
}
} else {
builder.title(I.tl(getPlayerLocale(), "{red}{0} doesn't have any map.", name));
}
return builder.item();
}
@Override
protected void onRightClick(ImageMap data)
{
Gui.open(getPlayer(), new MapDetailGui(data,getPlayer(),name), this);
protected void onRightClick(ImageMap data) {
Gui.open(getPlayer(), new MapDetailGui(data, getPlayer(), name), this);
}
@Override
protected ItemStack getPickedUpItem(ImageMap map)
{
if (!Permissions.GET.grantedTo(getPlayer()))
protected ItemStack getPickedUpItem(ImageMap map) {
if (!Permissions.GET.grantedTo(getPlayer())) {
return null;
if (map instanceof SingleMap)
{
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false,true);
}
else if (map instanceof PosterMap)
{
if (map instanceof SingleMap) {
return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false, true);
} else if (map instanceof PosterMap) {
PosterMap poster = (PosterMap) map;
if(poster.hasColumnData())
if (poster.hasColumnData()) {
return SplatterMapManager.makeSplatterMap((PosterMap) map);
}
MapItemManager.giveParts(getPlayer(), poster);
return null;
}
@ -168,24 +162,24 @@ public class MapListGui extends ExplorerGui<ImageMap>
}
@Override
protected void onUpdate()
{
ImageMap[] maps = MapManager.getMaps(p.getUniqueId());
protected void onUpdate() {
ImageMap[] maps = MapManager.getMaps(offplayer.getUniqueId());
setData(maps);
/// The maps list GUI title
//Equal if the person who send the command is the owner of the mapList
if(p.getUniqueId().equals(getPlayer().getUniqueId()))
if (offplayer.getUniqueId().equals(getPlayer().getUniqueId())) {
setTitle(I.tl(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length));
else
setTitle(I.tl(getPlayerLocale(), "{black}{1}'s maps {reset}({0})", maps.length, name ));
} else {
setTitle(I.tl(getPlayerLocale(), "{black}{1}'s maps {reset}({0})", maps.length, name));
}
setKeepHorizontalScrollingSpace(true);
/* ** Statistics ** */
int imagesCount = MapManager.getMapList(p.getUniqueId()).size();
int mapPartCount = MapManager.getMapPartCount(p.getUniqueId());
int imagesCount = MapManager.getMapList(offplayer.getUniqueId()).size();
int mapPartCount = MapManager.getMapPartCount(offplayer.getUniqueId());
int mapGlobalLimit = PluginConfiguration.MAP_GLOBAL_LIMIT.get();
int mapPersonalLimit = PluginConfiguration.MAP_PLAYER_LIMIT.get();
@ -194,25 +188,28 @@ public class MapListGui extends ExplorerGui<ImageMap>
int mapPartPersonallyLeft = mapPersonalLimit - mapPartCount;
int mapPartLeft;
if (mapGlobalLimit <= 0 && mapPersonalLimit <= 0)
if (mapGlobalLimit <= 0 && mapPersonalLimit <= 0) {
mapPartLeft = -1;
else if (mapGlobalLimit <= 0)
} else if (mapGlobalLimit <= 0) {
mapPartLeft = mapPartPersonallyLeft;
else if (mapPersonalLimit <= 0)
} else if (mapPersonalLimit <= 0) {
mapPartLeft = mapPartGloballyLeft;
else
} else {
mapPartLeft = Math.min(mapPartGloballyLeft, mapPartPersonallyLeft);
}
double percentageUsed = mapPartLeft < 0 ? 0 : ((double) mapPartCount) / ((double) (mapPartCount + mapPartLeft)) * 100;
double percentageUsed =
mapPartLeft < 0 ? 0 : ((double) mapPartCount) / ((double) (mapPartCount + mapPartLeft)) * 100;
ItemStackBuilder statistics = new ItemStackBuilder(Material.ENCHANTED_BOOK)
.title(I.t(getPlayerLocale(), "{blue}Usage statistics"))
.loreLine()
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} image rendered", "{white}{0}{gray} images rendered", imagesCount))
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} Minecraft map used", "{white}{0}{gray} Minecraft maps used", mapPartCount));
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} image rendered", "{white}{0}{gray} images rendered",
imagesCount))
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} Minecraft map used",
"{white}{0}{gray} Minecraft maps used", mapPartCount));
if(mapPartLeft >= 0)
{
if (mapPartLeft >= 0) {
statistics
.lore("", I.t(getPlayerLocale(), "{blue}Minecraft maps limits"), "")
.lore(mapGlobalLimit == 0
@ -222,8 +219,10 @@ public class MapListGui extends ExplorerGui<ImageMap>
? I.t(getPlayerLocale(), "{gray}Per-player limit: {white}unlimited")
: I.t(getPlayerLocale(), "{gray}Per-player limit: {white}{0}", mapPersonalLimit))
.loreLine()
.lore(I.t(getPlayerLocale(), "{white}{0} %{gray} of your quota used", (int) Math.rint(percentageUsed)))
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} map left", "{white}{0}{gray} maps left", mapPartLeft));
.lore(I.t(getPlayerLocale(), "{white}{0} %{gray} of your quota used",
(int) Math.rint(percentageUsed)))
.lore(I.tn(getPlayerLocale(), "{white}{0}{gray} map left", "{white}{0}{gray} maps left",
mapPartLeft));
}
//statistics.hideAllAttributes();

View File

@ -41,24 +41,19 @@ import fr.moribus.imageonmap.map.ImageMap;
import fr.zcraft.quartzlib.components.worker.Worker;
import fr.zcraft.quartzlib.components.worker.WorkerAttributes;
import fr.zcraft.quartzlib.components.worker.WorkerRunnable;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Files;
import javax.imageio.ImageIO;
@WorkerAttributes (name = "Image IO")
public class ImageIOExecutor extends Worker
{
static public void loadImage(final File file, final Renderer mapRenderer)
{
@WorkerAttributes(name = "Image IO")
public class ImageIOExecutor extends Worker {
public static void loadImage(final File file, final Renderer mapRenderer) {
submitQuery(new WorkerRunnable<Void>()
{
submitQuery(new WorkerRunnable<Void>() {
@Override
public Void run() throws Exception
{
public Void run() throws Exception {
BufferedImage image = ImageIO.read(file);
mapRenderer.setImage(image);
image.flush();//Safe to free
@ -66,51 +61,40 @@ public class ImageIOExecutor extends Worker
}
});
}
static public void saveImage(final File file, final BufferedImage image)
{
submitQuery(new WorkerRunnable<Void>()
{
public static void saveImage(final File file, final BufferedImage image) {
submitQuery(new WorkerRunnable<Void>() {
@Override
public Void run() throws Throwable
{
public Void run() throws Throwable {
ImageIO.write(image, "png", file);
return null;
}
});
}
static public void saveImage(int mapID, BufferedImage image)
{
public static void saveImage(int mapID, BufferedImage image) {
saveImage(ImageOnMap.getPlugin().getImageFile(mapID), image);
}
static public void saveImage(int[] mapsIDs, PosterImage image)
{
for(int i = 0, c = mapsIDs.length; i < c; i++)
{
BufferedImage img=image.getImageAt(i);
public static void saveImage(int[] mapsIDs, PosterImage image) {
for (int i = 0, c = mapsIDs.length; i < c; i++) {
BufferedImage img = image.getImageAt(i);
ImageIOExecutor.saveImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i]), img);
img.flush();//Safe to free
}
}
static public void deleteImage(ImageMap map)
{
public static void deleteImage(ImageMap map) {
int[] mapsIDs = map.getMapsIDs();
for(int i = 0, c = mapsIDs.length; i < c; i++)
{
for (int i = 0, c = mapsIDs.length; i < c; i++) {
deleteImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i]));
}
}
static public void deleteImage(final File file)
{
submitQuery(new WorkerRunnable<Void>()
{
public static void deleteImage(final File file) {
submitQuery(new WorkerRunnable<Void>() {
@Override
public Void run() throws Throwable
{
public Void run() throws Throwable {
Files.delete(file.toPath());
return null;
}

View File

@ -45,9 +45,6 @@ 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 org.bukkit.Bukkit;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
@ -57,12 +54,15 @@ import java.net.URLConnection;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import javax.imageio.ImageIO;
import org.bukkit.Bukkit;
@WorkerAttributes(name = "Image Renderer", queriesMainThread = true)
public class ImageRendererExecutor extends Worker {
private static URLConnection connecting(URL url) throws IOException {
final URLConnection connection = url.openConnection();
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
connection.addRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
connection.connect();
if (connection instanceof HttpURLConnection) {
@ -75,30 +75,25 @@ public class ImageRendererExecutor extends Worker {
return connection;
}
static private void checkSizeLimit(final UUID playerUUID, final BufferedImage image) throws IOException {
if ((PluginConfiguration.LIMIT_SIZE_X.get() > 0 || PluginConfiguration.LIMIT_SIZE_Y.get() > 0) && !Permissions.BYPASS_SIZE.grantedTo(Bukkit.getPlayer(playerUUID)))
{
if (PluginConfiguration.LIMIT_SIZE_X.get() > 0)
{
if (image.getWidth() > PluginConfiguration.LIMIT_SIZE_X.get())
private static void checkSizeLimit(final UUID playerUUID, final BufferedImage image) throws IOException {
if ((PluginConfiguration.LIMIT_SIZE_X.get() > 0 || PluginConfiguration.LIMIT_SIZE_Y.get() > 0)
&& !Permissions.BYPASS_SIZE.grantedTo(Bukkit.getPlayer(playerUUID))) {
if (PluginConfiguration.LIMIT_SIZE_X.get() > 0) {
if (image.getWidth() > PluginConfiguration.LIMIT_SIZE_X.get()) {
throw new IOException(I.t("The image is too wide!"));
}
}
if (PluginConfiguration.LIMIT_SIZE_Y.get() > 0)
{
if (image.getHeight() > PluginConfiguration.LIMIT_SIZE_Y.get())
if (PluginConfiguration.LIMIT_SIZE_Y.get() > 0) {
if (image.getHeight() > PluginConfiguration.LIMIT_SIZE_Y.get()) {
throw new IOException(I.t("The image is too tall!"));
}
}
}
}
private enum extension{
png, jpg, jpeg, gif
}
static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback<ImageMap> callback)
{
submitQuery(new WorkerRunnable<ImageMap>()
{
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 {
@ -109,11 +104,16 @@ public class ImageRendererExecutor extends Worker {
//Not handled, can't with the hash only access the image in i.imgur.com/<hash>.<extension>
if (url.toString().contains("gallery/")) {
throw new IOException("We do not support imgur gallery yet, please use direct link to image instead. Right click on the picture you want to use then select copy picture link:) ");
throw new IOException(
"We do not support imgur gallery yet, please use direct link to image instead."
+ " Right click on the picture you want "
+ "to use then select copy picture link:) ");
}
for (extension ext : extension.values()) {
String newLink = "https://i.imgur.com/" + url.toString().split("https://imgur.com/")[1] + "." + ext.toString();
for (Extension ext : Extension.values()) {
String newLink = "https://i.imgur.com/" + url.toString().split("https://imgur.com/")[1]
+ "."
+ ext.toString();
URL url2 = new URL(newLink);
//Try connecting
@ -124,13 +124,13 @@ public class ImageRendererExecutor extends Worker {
image = ImageIO.read(stream);
//valid image
if (image != null) break;
if (image != null) {
break;
}
}
}
//If not an Imgur link
else {
} else {
//Try connecting
URLConnection connection = connecting(url);
@ -138,7 +138,9 @@ public class ImageRendererExecutor extends Worker {
image = ImageIO.read(stream);
}
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
if (image == null) {
throw new IOException(I.t("The given URL is not a valid image"));
}
// Limits are in place and the player does NOT have rights to avoid them.
checkSizeLimit(playerUUID, image);
if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) {
@ -146,19 +148,20 @@ public class ImageRendererExecutor extends Worker {
image.flush();//Safe to free
return ret;
}
final BufferedImage resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
final BufferedImage resizedImage =
scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
image.flush();//Safe to free
return renderPoster(resizedImage, playerUUID);
}
}, callback);
}
public static void update(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final ImageMap map, final int width, final int height, WorkerCallback<ImageMap> callback) {
submitQuery(new WorkerRunnable<ImageMap>()
{
public static void update(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID,
final ImageMap map, final int width, final int height,
WorkerCallback<ImageMap> callback) {
submitQuery(new WorkerRunnable<ImageMap>() {
@Override
public ImageMap run() throws Throwable
{
public ImageMap run() throws Throwable {
final URLConnection connection = connecting(url);
@ -166,44 +169,42 @@ public class ImageRendererExecutor extends Worker {
final BufferedImage image = ImageIO.read(stream);
stream.close();
if (image == null) throw new IOException(I.t("The given URL is not a valid image"));
if (image == null) {
throw new IOException(I.t("The given URL is not a valid image"));
}
// Limits are in place and the player does NOT have rights to avoid them.
checkSizeLimit(playerUUID, image);
updateMap(scaling.resize(image, width*128, height*128),playerUUID,map.getMapsIDs());
updateMap(scaling.resize(image, width * 128, height * 128), playerUUID, map.getMapsIDs());
return map;
}
}, callback);
}
static private void updateMap(final BufferedImage image, final UUID playerUUID,int[] mapsIDs) throws Throwable
{
private static void updateMap(final BufferedImage image, final UUID playerUUID, int[] mapsIDs) throws Throwable {
final PosterImage poster = new PosterImage(image);
poster.splitImages();
ImageIOExecutor.saveImage(mapsIDs, poster);
if (PluginConfiguration.SAVE_FULL_IMAGE.get())
{
if (PluginConfiguration.SAVE_FULL_IMAGE.get()) {
ImageIOExecutor.saveImage(ImageMap.getFullImageFile(mapsIDs[0], mapsIDs[mapsIDs.length - 1]), image);
}
submitToMainThread(new Callable<Void>()
{
submitToMainThread(new Callable<Void>() {
@Override
public Void call() throws Exception
{
public Void call() throws Exception {
Renderer.installRenderer(poster, mapsIDs);
return null;
}
});
}
static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable
{
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
@ -224,7 +225,7 @@ public class ImageRendererExecutor extends Worker {
return MapManager.createMap(playerUUID, mapID);
}
static private ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable {
private static ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable {
final PosterImage poster = new PosterImage(image);
final int mapCount = poster.getImagesCount();
MapManager.checkMapLimit(mapCount, playerUUID);
@ -238,7 +239,6 @@ public class ImageRendererExecutor extends Worker {
final int[] mapsIDs = futureMapsIds.get();
ImageIOExecutor.saveImage(mapsIDs, poster);
final int[] mapsIDs = futureMapsIds.get();
ImageIOExecutor.saveImage(mapsIDs, poster);
if (PluginConfiguration.SAVE_FULL_IMAGE.get()) {
@ -257,7 +257,8 @@ public class ImageRendererExecutor extends Worker {
return MapManager.createMap(poster, playerUUID, mapsIDs);
}
private enum extension {
private enum Extension {
png, jpg, jpeg, gif
}
}

View File

@ -36,9 +36,8 @@
package fr.moribus.imageonmap.image;
import fr.zcraft.zlib.tools.PluginLogger;
import java.awt.*;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
/**
@ -49,16 +48,18 @@ public class ImageUtils {
/**
* Generates a resized buffer of the given source
*
* @param source
* @param destinationW
* @param destinationH
* @return
* @param source The source buffer to draw
* @param destinationW resize width
* @param destinationH resize height
* @return The new buffer, with the source buffer drawn on it
*/
static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) {
private static BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) {
float ratioW = (float) destinationW / (float) source.getWidth();
float ratioH = (float) destinationH / (float) source.getHeight();
int finalW, finalH;
int x, y;
int finalW;
int finalH;
int x;
int y;
if (covered ? ratioW > ratioH : ratioW < ratioH) {
finalW = destinationW;
@ -77,12 +78,12 @@ public class ImageUtils {
}
/**
* @param source
* @param destinationW
* @param destinationH
* @return
* @param source The source buffer to draw
* @param destinationW resize width
* @param destinationH resize height
* @return The new buffer, with the source buffer drawn on it
*/
static private BufferedImage resizeStretched(BufferedImage source, int destinationW, int destinationH) {
private static BufferedImage resizeStretched(BufferedImage source, int destinationW, int destinationH) {
return drawImage(source,
destinationW, destinationH,
0, 0, destinationW, destinationH);
@ -101,11 +102,11 @@ public class ImageUtils {
* @param sourceH The height of the source buffer
* @return The new buffer, with the source buffer drawn on it
*/
static private BufferedImage drawImage(BufferedImage source,
private static BufferedImage drawImage(BufferedImage source,
int bufferW, int bufferH,
int posX, int posY,
int sourceW, int sourceH) {
Graphics graphics = null;
Graphics graphics;
BufferedImage newImage = null;
try {
newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB);
@ -116,8 +117,9 @@ public class ImageUtils {
return newImage;
} catch (final Throwable e) {
PluginLogger.warning("Exception/error at drawImage");
if (newImage != null)
if (newImage != null) {
newImage.flush();//Safe to free
}
throw e;
}

View File

@ -55,89 +55,80 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapView;
public class MapInitEvent implements Listener
{
static public void init()
{
public class MapInitEvent implements Listener {
public static void init() {
QuartzLib.registerEvents(new MapInitEvent());
for(World world : Bukkit.getWorlds())
{
for(ItemFrame frame : world.getEntitiesByClass(ItemFrame.class))
{
for (World world : Bukkit.getWorlds()) {
for (ItemFrame frame : world.getEntitiesByClass(ItemFrame.class)) {
initMap(frame.getItem());
}
}
for(Player player : Bukkit.getOnlinePlayers())
{
for (Player player : Bukkit.getOnlinePlayers()) {
initMap(player.getInventory().getItemInMainHand());
}
}
public static void initMap(ItemStack item) {
if (item != null && item.getType() == Material.FILLED_MAP) {
initMap(MapManager.getMapIdFromItemStack(item));
}
}
public static void initMap(int id) {
initMap(Bukkit.getServer().getMap(id));
}
public static void initMap(MapView map) {
if (map == null) {
return;
}
if (Renderer.isHandled(map)) {
return;
}
File imageFile = ImageOnMap.getPlugin().getImageFile(map.getId());
if (imageFile.isFile()) {
ImageIOExecutor.loadImage(imageFile, Renderer.installRenderer(map));
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event)
{
for (Entity entity : event.getChunk().getEntities())
{
if (entity instanceof ItemFrame)
{
initMap(((ItemFrame)entity).getItem());
public void onChunkLoad(ChunkLoadEvent event) {
for (Entity entity : event.getChunk().getEntities()) {
if (entity instanceof ItemFrame) {
initMap(((ItemFrame) entity).getItem());
}
}
}
@EventHandler
public void onPlayerInv(PlayerItemHeldEvent event)
{
public void onPlayerInv(PlayerItemHeldEvent event) {
ItemStack item = event.getPlayer().getInventory().getItem(event.getNewSlot());
initMap(item);
}
@EventHandler
public void onPlayerPickup(EntityPickupItemEvent event)
{
if (!(event.getEntity() instanceof HumanEntity)) return;
public void onPlayerPickup(EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof HumanEntity)) {
return;
}
initMap(event.getItem().getItemStack());
}
@EventHandler
public void onPlayerInventoryPlace(InventoryClickEvent event)
{
switch(event.getAction())
{
public void onPlayerInventoryPlace(InventoryClickEvent event) {
switch (event.getAction()) {
case PLACE_ALL:
case PLACE_ONE:
case PLACE_SOME:
case SWAP_WITH_CURSOR:
initMap(event.getCursor());
}
}
static public void initMap(ItemStack item)
{
if (item != null && item.getType() == Material.FILLED_MAP)
{
initMap(MapManager.getMapIdFromItemStack(item));
}
}
static public void initMap(int id)
{
initMap(Bukkit.getServer().getMap(id));
}
static public void initMap(MapView map)
{
if(map == null) {
return;}
if(Renderer.isHandled(map)) {
return;}
File imageFile = ImageOnMap.getPlugin().getImageFile(map.getId());
if(imageFile.isFile())
{
ImageIOExecutor.loadImage(imageFile, Renderer.installRenderer(map));
break;
default:
}
}
}

View File

@ -44,15 +44,16 @@ import java.awt.image.BufferedImage;
* This class represents an image split into pieces
*/
public class PosterImage {
static private final int WIDTH = 128;
static private final int HEIGHT = 128;
private static final int WIDTH = 128;
private static final int HEIGHT = 128;
private BufferedImage originalImage;
private BufferedImage[] cutImages;
private int lines;
private int columns;
private int cutImagesCount;
private int remainderX, remainderY;
private int remainderX;
private int remainderY;
/**
* Creates a new Poster from an entire image
@ -74,8 +75,12 @@ public class PosterImage {
remainderX = originalWidth % WIDTH;
remainderY = originalHeight % HEIGHT;
if (remainderX > 0) columns++;
if (remainderY > 0) lines++;
if (remainderX > 0) {
columns++;
}
if (remainderY > 0) {
lines++;
}
cutImagesCount = columns * lines;
}
@ -95,12 +100,13 @@ public class PosterImage {
imageY += HEIGHT;
}
} catch (final Throwable e) {
if (cutImages != null)
if (cutImages != null) {
for (BufferedImage bi : cutImages) {
if (bi != null) {
bi.flush();//Safe to free
}
}
}
throw e;
}

View File

@ -37,91 +37,79 @@
package fr.moribus.imageonmap.image;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.awt.image.BufferedImage;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import java.awt.image.BufferedImage;
public class Renderer extends MapRenderer {
private BufferedImage image;
public class Renderer extends MapRenderer
{
static public boolean isHandled(MapView map)
{
if(map == null) return false;
for(MapRenderer renderer : map.getRenderers())
{
if(renderer instanceof Renderer) return true;
protected Renderer() {
this(null);
}
protected Renderer(BufferedImage image) {
this.image = image;
}
public static boolean isHandled(MapView map) {
if (map == null) {
return false;
}
for (MapRenderer renderer : map.getRenderers()) {
if (renderer instanceof Renderer) {
return true;
}
}
return false;
}
static public void installRenderer(PosterImage image, int[] mapsIds)
{
for(int i = 0; i < mapsIds.length; i++)
{
public static void installRenderer(PosterImage image, int[] mapsIds) {
for (int i = 0; i < mapsIds.length; i++) {
installRenderer(image.getImageAt(i), mapsIds[i]);
}
}
static public void installRenderer(BufferedImage image, int mapID)
{
public static void installRenderer(BufferedImage image, int mapID) {
MapView map = Bukkit.getMap(mapID);
if(map == null)
{
if (map == null) {
PluginLogger.warning("Could not install renderer for map {0}: the Minecraft map does not exist", mapID);
}
else
{
} else {
installRenderer(map).setImage(image);
}
}
static public Renderer installRenderer(MapView map)
{
public static Renderer installRenderer(MapView map) {
Renderer renderer = new Renderer();
removeRenderers(map);
map.addRenderer(renderer);
return renderer;
}
static public void removeRenderers(MapView map)
{
for(MapRenderer renderer : map.getRenderers())
{
public static void removeRenderers(MapView map) {
for (MapRenderer renderer : map.getRenderers()) {
map.removeRenderer(renderer);
}
}
private BufferedImage image;
protected Renderer()
{
this(null);
}
protected Renderer(BufferedImage image)
{
this.image = image;
}
@Override
public void render(MapView v, final MapCanvas canvas, Player p)
{
public void render(MapView v, final MapCanvas canvas, Player p) {
//Render only once to avoid overloading the server
if (image == null) return;
if (image == null) {
return;
}
canvas.drawImage(0, 0, image);
image = null;
}
public BufferedImage getImage()
{
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image)
{
public void setImage(BufferedImage image) {
this.image = image;
}
}

View File

@ -39,6 +39,11 @@ package fr.moribus.imageonmap.map;
import fr.moribus.imageonmap.ImageOnMap;
import fr.moribus.imageonmap.ui.MapItemManager;
import fr.zcraft.quartzlib.components.i18n.I;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
@ -46,105 +51,131 @@ import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public abstract class ImageMap implements ConfigurationSerializable
{
public enum Type
{
SINGLE, POSTER
}
static public final int WIDTH = 128;
static public final int HEIGHT = 128;
public abstract class ImageMap implements ConfigurationSerializable {
public static final int WIDTH = 128;
public static final int HEIGHT = 128;
/// The default display name of a map
static public final String DEFAULT_NAME = I.t("Map");
private String id;
public static final String DEFAULT_NAME = I.t("Map");
private final UUID userUUID;
private final Type mapType;
private String id;
private String name;
protected ImageMap(UUID userUUID, Type mapType)
{
protected ImageMap(UUID userUUID, Type mapType) {
this(userUUID, mapType, null, null);
}
protected ImageMap(UUID userUUID, Type mapType, String id, String name)
{
protected ImageMap(UUID userUUID, Type mapType, String id, String name) {
this.userUUID = userUUID;
this.mapType = mapType;
this.id = id;
this.name = name;
if(this.id == null)
{
if(this.name == null) this.name = DEFAULT_NAME;
if (this.id == null) {
if (this.name == null) {
this.name = DEFAULT_NAME;
}
this.id = MapManager.getNextAvailableMapID(this.name, userUUID);
}
}
public abstract int[] getMapsIDs();
public abstract boolean managesMap(int mapID);
public abstract int getMapCount();
public boolean managesMap(ItemStack item)
{
if(item == null) return false;
if(item.getType() != Material.FILLED_MAP) return false;
return managesMap(MapManager.getMapIdFromItemStack(item));
}
public boolean give(Player player)
{
return MapItemManager.give(player, this);
}
public static File getFullImageFile(int mapIDstart, int mapIDend)
{
return new File(ImageOnMap.getPlugin().getImagesDirectory(), "_"+mapIDstart+"-"+mapIDend+".png");
}
/* ====== Serialization methods ====== */
static public ImageMap fromConfig(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException
{
Type mapType;
try
{
mapType = Type.valueOf((String) map.get("type"));
}
catch(ClassCastException ex)
{
throw new InvalidConfigurationException(ex);
}
switch(mapType)
{
case SINGLE: return new SingleMap(map, userUUID);
case POSTER: return new PosterMap(map, userUUID);
default: throw new IllegalArgumentException("Unhandled map type given");
}
}
protected ImageMap(Map<String, Object> map, UUID userUUID, Type mapType) throws InvalidConfigurationException
{
protected ImageMap(Map<String, Object> map, UUID userUUID, Type mapType) throws InvalidConfigurationException {
this(userUUID, mapType,
(String) getNullableFieldValue(map, "id"),
(String) getNullableFieldValue(map, "name"));
}
public static File getFullImageFile(int mapIDstart, int mapIDend) {
return new File(ImageOnMap.getPlugin().getImagesDirectory(), "_" + mapIDstart + "-" + mapIDend + ".png");
}
public static ImageMap fromConfig(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
Type mapType;
try {
mapType = Type.valueOf((String) map.get("type"));
} catch (ClassCastException ex) {
throw new InvalidConfigurationException(ex);
}
switch (mapType) {
case SINGLE:
return new SingleMap(map, userUUID);
case POSTER:
return new PosterMap(map, userUUID);
default:
throw new IllegalArgumentException("Unhandled map type given");
}
}
public static Integer[] getSize(Map<String, Object> map, UUID playerUUID, String id) {
ConfigurationSection section =
MapManager.getPlayerMapStore(playerUUID).getToolConfig().getConfigurationSection("PlayerMapStore");
if (section == null) {
return null;
}
List<Map<String, Object>> list = (List<Map<String, Object>>) section.getList("mapList");
if (list == null) {
return null;
}
for (Map<String, Object> tmpMap : list) {
if (tmpMap.get("id").equals(id)) {
return new Integer[] {(Integer) tmpMap.get("columns"), (Integer) tmpMap.get("rows")};
}
}
return null;
}
protected static <T> T getFieldValue(Map<String, Object> map, String fieldName)
throws InvalidConfigurationException {
T value = getNullableFieldValue(map, fieldName);
if (value == null) {
throw new InvalidConfigurationException("Field value not found for \"" + fieldName + "\"");
}
return value;
}
protected static <T> T getNullableFieldValue(Map<String, Object> map, String fieldName)
throws InvalidConfigurationException {
try {
return (T) map.get(fieldName);
} catch (ClassCastException ex) {
throw new InvalidConfigurationException("Invalid field \"" + fieldName + "\"", ex);
}
}
public abstract int[] getMapsIDs();
/* ====== Serialization methods ====== */
public abstract boolean managesMap(int mapID);
public boolean managesMap(ItemStack item) {
if (item == null) {
return false;
}
if (item.getType() != Material.FILLED_MAP) {
return false;
}
return managesMap(MapManager.getMapIdFromItemStack(item));
}
//
public abstract int getMapCount();
//
public boolean give(Player player) {
return MapItemManager.give(player, this);
}
protected abstract void postSerialize(Map<String, Object> map);
@Override
public Map<String, Object> serialize()
{
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", getId());
map.put("type", mapType.toString());
@ -153,73 +184,38 @@ public abstract class ImageMap implements ConfigurationSerializable
return map;
}
static public Integer[] getSize(Map<String, Object> map, UUID playerUUID, String id){
ConfigurationSection section=MapManager.getPlayerMapStore(playerUUID).getToolConfig().getConfigurationSection("PlayerMapStore");
if(section == null) return null;
List<Map<String, Object>> list = (List<Map<String, Object>>) section.getList("mapList");
if(list == null) return null;
for(Map<String, Object> tMap : list)
{
if(tMap.get("id").equals(id)) {
return new Integer[]{(Integer)tMap.get("columns"), (Integer)tMap.get("rows")};
}
}
return null;
}
static protected <T> T getFieldValue(Map<String, Object> map, String fieldName) throws InvalidConfigurationException
{
T value = getNullableFieldValue(map, fieldName);
if(value == null) throw new InvalidConfigurationException("Field value not found for \"" + fieldName + "\"");
return value;
}
static protected <T> T getNullableFieldValue(Map<String, Object> map, String fieldName) throws InvalidConfigurationException
{
try
{
return (T)map.get(fieldName);
}
catch(ClassCastException ex)
{
throw new InvalidConfigurationException("Invalid field \"" + fieldName + "\"", ex);
}
}
/* ====== Getters & Setters ====== */
public UUID getUserUUID()
{
public UUID getUserUUID() {
return userUUID;
}
public synchronized String getName()
{
/* ====== Getters & Setters ====== */
public synchronized String getName() {
return name;
}
public synchronized String getId()
{
public synchronized String getId() {
return id;
}
public synchronized Type getType()
{
public synchronized Type getType() {
return mapType;
}
public synchronized void rename(String id, String name)
{
public synchronized void rename(String id, String name) {
this.id = id;
this.name = name;
}
public void rename(String name)
{
if(getName().equals(name)) return;
public void rename(String name) {
if (getName().equals(name)) {
return;
}
rename(MapManager.getNextAvailableMapID(name, getUserUUID()), name);
}
public enum Type {
SINGLE, POSTER
}
}

View File

@ -42,6 +42,10 @@ import fr.moribus.imageonmap.image.ImageIOExecutor;
import fr.moribus.imageonmap.image.PosterImage;
import fr.moribus.imageonmap.map.MapManagerException.Reason;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
@ -50,84 +54,73 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public abstract class MapManager {
private static final long SAVE_DELAY = 200;
private static final ArrayList<PlayerMapStore> playerMaps = new ArrayList<PlayerMapStore>();
private static BukkitTask autosaveTask;
abstract public class MapManager
{
static private final long SAVE_DELAY = 200;
static private final ArrayList<PlayerMapStore> playerMaps = new ArrayList<PlayerMapStore>();
static private BukkitTask autosaveTask;
static public void init()
{
public static void init() {
load();
}
static public void exit()
{
public static void exit() {
save();
playerMaps.clear();
if(autosaveTask != null) autosaveTask.cancel();
if (autosaveTask != null) {
autosaveTask.cancel();
}
}
static public boolean managesMap(int mapID)
{
synchronized(playerMaps)
{
for(PlayerMapStore mapStore : playerMaps)
{
if(mapStore.managesMap(mapID)) return true;
public static boolean managesMap(int mapID) {
synchronized (playerMaps) {
for (PlayerMapStore mapStore : playerMaps) {
if (mapStore.managesMap(mapID)) {
return true;
}
}
}
return false;
}
static public boolean managesMap(ItemStack item)
{
if(item == null) return false;
if(item.getType() != Material.FILLED_MAP) return false;
synchronized(playerMaps)
{
for(PlayerMapStore mapStore : playerMaps)
{
if(mapStore.managesMap(item)) return true;
public static boolean managesMap(ItemStack item) {
if (item == null) {
return false;
}
if (item.getType() != Material.FILLED_MAP) {
return false;
}
synchronized (playerMaps) {
for (PlayerMapStore mapStore : playerMaps) {
if (mapStore.managesMap(item)) {
return true;
}
}
}
return false;
}
static public ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException
{
public static ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException {
ImageMap newMap = new SingleMap(playerUUID, mapID);
addMap(newMap);
return newMap;
}
static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException
{
public static ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException {
ImageMap newMap;
if(image.getImagesCount() == 1)
{
if (image.getImagesCount() == 1) {
newMap = new SingleMap(playerUUID, mapsIDs[0]);
}
else
{
} else {
newMap = new PosterMap(playerUUID, mapsIDs, image.getColumns(), image.getLines());
}
addMap(newMap);
return newMap;
}
static public int[] getNewMapsIds(int amount)
{
public static int[] getNewMapsIds(int amount) {
int[] mapsIds = new int[amount];
for(int i = 0; i < amount; i++)
{
for (int i = 0; i < amount; i++) {
mapsIds[i] = Bukkit.createMap(Bukkit.getWorlds().get(0)).getId();
}
return mapsIds;
@ -135,52 +128,48 @@ abstract public class MapManager
/**
* Returns the map ID from an ItemStack
*
* @param item The item stack
* @return The map ID, or 0 if invalid.
*/
static public int getMapIdFromItemStack(final ItemStack item)
{
public static int getMapIdFromItemStack(final ItemStack item) {
final ItemMeta meta = item.getItemMeta();
if (!(meta instanceof MapMeta)) return 0;
if (!(meta instanceof MapMeta)) {
return 0;
}
return ((MapMeta) meta).hasMapId() ? ((MapMeta) meta).getMapId() : 0;
}
static public void addMap(ImageMap map) throws MapManagerException
{
public static void addMap(ImageMap map) throws MapManagerException {
getPlayerMapStore(map.getUserUUID()).addMap(map);
}
static public void insertMap(ImageMap map)
{
public static void insertMap(ImageMap map) {
getPlayerMapStore(map.getUserUUID()).insertMap(map);
}
static public void deleteMap(ImageMap map) throws MapManagerException
{
public static void deleteMap(ImageMap map) throws MapManagerException {
getPlayerMapStore(map.getUserUUID()).deleteMap(map);
ImageIOExecutor.deleteImage(map);
}
static public void notifyModification(UUID playerUUID)
{
public static void notifyModification(UUID playerUUID) {
getPlayerMapStore(playerUUID).notifyModification();
if(autosaveTask == null)
if (autosaveTask == null) {
Bukkit.getScheduler().runTaskLater(ImageOnMap.getPlugin(), new AutosaveRunnable(), SAVE_DELAY);
}
}
static public String getNextAvailableMapID(String mapId, UUID playerUUID)
{
public static String getNextAvailableMapID(String mapId, UUID playerUUID) {
return getPlayerMapStore(playerUUID).getNextAvailableMapID(mapId);
}
static public List<ImageMap> getMapList(UUID playerUUID)
{
public static List<ImageMap> getMapList(UUID playerUUID) {
return getPlayerMapStore(playerUUID).getMapList();
}
static public ImageMap[] getMaps(UUID playerUUID)
{
public static ImageMap[] getMaps(UUID playerUUID) {
return getPlayerMapStore(playerUUID).getMaps();
}
@ -188,16 +177,13 @@ abstract public class MapManager
* Returns the number of minecraft maps used by the images rendered by the given player.
*
* @param playerUUID The player's UUID.
*
* @return The count.
*/
static public int getMapPartCount(UUID playerUUID)
{
public static int getMapPartCount(UUID playerUUID) {
return getPlayerMapStore(playerUUID).getMapCount();
}
static public ImageMap getMap(UUID playerUUID, String mapId)
{
public static ImageMap getMap(UUID playerUUID, String mapId) {
return getPlayerMapStore(playerUUID).getMap(mapId);
}
@ -207,18 +193,12 @@ abstract public class MapManager
* @param mapId The ID of the Minecraft map.
* @return The {@link ImageMap}.
*/
static public ImageMap getMap(int mapId)
{
synchronized(playerMaps)
{
for(PlayerMapStore mapStore : playerMaps)
{
if(mapStore.managesMap(mapId))
{
for(ImageMap map : mapStore.getMapList())
{
if(map.managesMap(mapId))
{
public static ImageMap getMap(int mapId) {
synchronized (playerMaps) {
for (PlayerMapStore mapStore : playerMaps) {
if (mapStore.managesMap(mapId)) {
for (ImageMap map : mapStore.getMapList()) {
if (map.managesMap(mapId)) {
return map;
}
}
@ -235,90 +215,83 @@ abstract public class MapManager
* @param item The map, as an {@link ItemStack}.
* @return The {@link ImageMap}.
*/
static public ImageMap getMap(ItemStack item)
{
if(item == null) return null;
if(item.getType() != Material.FILLED_MAP) return null;
public static ImageMap getMap(ItemStack item) {
if (item == null) {
return null;
}
if (item.getType() != Material.FILLED_MAP) {
return null;
}
return getMap(getMapIdFromItemStack(item));
}
static public void clear(Inventory inventory)
{
for(int i = 0, c = inventory.getSize(); i < c; i++)
{
if(managesMap(inventory.getItem(i)))
{
public static void clear(Inventory inventory) {
for (int i = 0, c = inventory.getSize(); i < c; i++) {
if (managesMap(inventory.getItem(i))) {
inventory.setItem(i, new ItemStack(Material.AIR));
}
}
}
static public void clear(Inventory inventory, ImageMap map)
{
for(int i = 0, c = inventory.getSize(); i < c; i++)
{
if(map.managesMap(inventory.getItem(i)))
{
public static void clear(Inventory inventory, ImageMap map) {
for (int i = 0, c = inventory.getSize(); i < c; i++) {
if (map.managesMap(inventory.getItem(i))) {
inventory.setItem(i, new ItemStack(Material.AIR));
}
}
}
static private UUID getUUIDFromFile(File file)
{
private static UUID getUUIDFromFile(File file) {
String fileName = file.getName();
int fileExtPos = fileName.lastIndexOf('.');
if(fileExtPos <= 0) return null;
String fileExt = fileName.substring(fileExtPos + 1);
if(!fileExt.equals("yml")) return null;
try
{
return UUID.fromString(fileName.substring(0, fileExtPos));
if (fileExtPos <= 0) {
return null;
}
catch(IllegalArgumentException ex)
{
String fileExt = fileName.substring(fileExtPos + 1);
if (!fileExt.equals("yml")) {
return null;
}
try {
return UUID.fromString(fileName.substring(0, fileExtPos));
} catch (IllegalArgumentException ex) {
return null;
}
}
static public void load()
{
public static void load() {
int loadedFilesCount = 0;
for(File file : ImageOnMap.getPlugin().getMapsDirectory().listFiles())
{
for (File file : ImageOnMap.getPlugin().getMapsDirectory().listFiles()) {
UUID uuid = getUUIDFromFile(file);
if(uuid == null) continue;
if (uuid == null) {
continue;
}
getPlayerMapStore(uuid);
++loadedFilesCount;
}
PluginLogger.info("Loaded {0} player map files.", loadedFilesCount);
}
static public void save()
{
synchronized(playerMaps)
{
for(PlayerMapStore tStore : playerMaps)
{
tStore.save();
public static void save() {
synchronized (playerMaps) {
for (PlayerMapStore tmpStore : playerMaps) {
tmpStore.save();
}
}
}
static public void checkMapLimit(ImageMap map) throws MapManagerException
{
public static void checkMapLimit(ImageMap map) throws MapManagerException {
checkMapLimit(map.getMapCount(), map.getUserUUID());
}
static public void checkMapLimit(int newMapsCount, UUID userUUID) throws MapManagerException
{
public static void checkMapLimit(int newMapsCount, UUID userUUID) throws MapManagerException {
int limit = PluginConfiguration.MAP_GLOBAL_LIMIT.get();
if (limit > 0 && getMapCount() + newMapsCount > limit)
if (limit > 0 && getMapCount() + newMapsCount > limit) {
throw new MapManagerException(Reason.MAXIMUM_SERVER_MAPS_EXCEEDED);
}
getPlayerMapStore(userUUID).checkMapLimit(newMapsCount);
}
@ -328,14 +301,11 @@ abstract public class MapManager
*
* @return The count.
*/
static public int getMapCount()
{
public static int getMapCount() {
int mapCount = 0;
synchronized(playerMaps)
{
for(PlayerMapStore tStore : playerMaps)
{
mapCount += tStore.getMapCount();
synchronized (playerMaps) {
for (PlayerMapStore tmpStore : playerMaps) {
mapCount += tmpStore.getMapCount();
}
}
return mapCount;
@ -346,44 +316,35 @@ abstract public class MapManager
*
* @return The count.
*/
static public int getImagesCount()
{
public static int getImagesCount() {
int imagesCount = 0;
synchronized(playerMaps)
{
for(PlayerMapStore tStore : playerMaps)
{
imagesCount += tStore.getImagesCount();
synchronized (playerMaps) {
for (PlayerMapStore tmpStore : playerMaps) {
imagesCount += tmpStore.getImagesCount();
}
}
return imagesCount;
}
/**
* Returns if the given map ID is valid and exists in the current save.
*
* @param mapId the map ID.
* @return true if the given map ID is valid and exists in the current save, false otherwise.
*/
static public boolean mapIdExists(int mapId)
{
try
{
public static boolean mapIdExists(int mapId) {
try {
return Bukkit.getMap(mapId) != null;
}
catch(Throwable ex)
{
} catch (Throwable ex) {
return false;
}
}
static public PlayerMapStore getPlayerMapStore(UUID playerUUID)
{
public static PlayerMapStore getPlayerMapStore(UUID playerUUID) {
PlayerMapStore store;
synchronized(playerMaps)
{
synchronized (playerMaps) {
store = getExistingPlayerMapStore(playerUUID);
if(store == null)
{
if (store == null) {
store = new PlayerMapStore(playerUUID);
playerMaps.add(store);
@ -392,33 +353,30 @@ abstract public class MapManager
}
return store;
}
static private PlayerMapStore getExistingPlayerMapStore(UUID playerUUID)
{
synchronized(playerMaps)
{
for(PlayerMapStore mapStore : playerMaps)
{
if(mapStore.getUUID().equals(playerUUID)) return mapStore;
private static PlayerMapStore getExistingPlayerMapStore(UUID playerUUID) {
synchronized (playerMaps) {
for (PlayerMapStore mapStore : playerMaps) {
if (mapStore.getUUID().equals(playerUUID)) {
return mapStore;
}
}
}
return null;
}
static private class AutosaveRunnable implements Runnable
{
private static class AutosaveRunnable implements Runnable {
@Override
public void run()
{
synchronized(playerMaps)
{
for(PlayerMapStore toolStore : playerMaps)
{
if(toolStore.isModified()) toolStore.save();
public void run() {
synchronized (playerMaps) {
for (PlayerMapStore toolStore : playerMaps) {
if (toolStore.isModified()) {
toolStore.save();
}
}
autosaveTask = null;
}
}
}
}

View File

@ -37,38 +37,34 @@
package fr.moribus.imageonmap.map;
import fr.zcraft.quartzlib.components.i18n.I;
import java.text.MessageFormat;
public class MapManagerException extends Exception
{
public enum Reason
{
MAXIMUM_PLAYER_MAPS_EXCEEDED(I.t("You have too many maps (maximum : {0}).")),
MAXIMUM_SERVER_MAPS_EXCEEDED(I.t("The server ImageOnMap limit has been reached.")),
IMAGEMAP_DOES_NOT_EXIST(I.t("The given map does not exist."));
private final String reasonString;
Reason(String reasonString)
{
this.reasonString = reasonString;
}
public String getReasonString(Object ...arguments)
{
return MessageFormat.format(reasonString, arguments);
}
}
public class MapManagerException extends Exception {
private final Reason reason;
public MapManagerException(Reason reason, Object ...arguments)
{
public MapManagerException(Reason reason, Object... arguments) {
super(reason.getReasonString(arguments));
this.reason = reason;
}
public Reason getReason() {
return reason;
}
public Reason getReason() { return reason; }
public enum Reason {
MAXIMUM_PLAYER_MAPS_EXCEEDED(I.t("You have too many maps (maximum : {0}).")),
MAXIMUM_SERVER_MAPS_EXCEEDED(I.t("The server ImageOnMap limit has been reached.")),
IMAGEMAP_DOES_NOT_EXIST(I.t("The given map does not exist."));
private final String reasonString;
Reason(String reasonString) {
this.reasonString = reasonString;
}
public String getReasonString(Object... arguments) {
return MessageFormat.format(reasonString, arguments);
}
}
}

View File

@ -40,6 +40,13 @@ import fr.moribus.imageonmap.ImageOnMap;
import fr.moribus.imageonmap.PluginConfiguration;
import fr.moribus.imageonmap.map.MapManagerException.Reason;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
@ -48,245 +55,225 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class PlayerMapStore implements ConfigurationSerializable
{
public class PlayerMapStore implements ConfigurationSerializable {
private final UUID playerUUID;
private final ArrayList<ImageMap> mapList = new ArrayList<ImageMap>();
private boolean modified = false;
private int mapCount = 0;
public PlayerMapStore(UUID playerUUID)
{
private FileConfiguration mapConfig = null;
private File mapsFile = null;
public PlayerMapStore(UUID playerUUID) {
this.playerUUID = playerUUID;
}
public synchronized boolean managesMap(int mapID)
{
for(ImageMap map : mapList)
{
if(map.managesMap(mapID)) return true;
public synchronized boolean managesMap(int mapID) {
for (ImageMap map : mapList) {
if (map.managesMap(mapID)) {
return true;
}
}
return false;
}
public synchronized boolean managesMap(ItemStack item)
{
if(item == null) return false;
if(item.getType() != Material.FILLED_MAP) return false;
for(ImageMap map : mapList)
{
if(map.managesMap(item)) return true;
public synchronized boolean managesMap(ItemStack item) {
if (item == null) {
return false;
}
if (item.getType() != Material.FILLED_MAP) {
return false;
}
for (ImageMap map : mapList) {
if (map.managesMap(item)) {
return true;
}
}
return false;
}
public synchronized void addMap(ImageMap map) throws MapManagerException
{
public synchronized void addMap(ImageMap map) throws MapManagerException {
checkMapLimit(map);
insertMap(map);
}
public synchronized void insertMap(ImageMap map)
{
_addMap(map);
public synchronized void insertMap(ImageMap map) {
add_Map(map);
notifyModification();
}
private void _addMap(ImageMap map)
{
private void add_Map(ImageMap map) {
mapList.add(map);
mapCount += map.getMapCount();
}
public synchronized void deleteMap(ImageMap map) throws MapManagerException
{
_removeMap(map);
public synchronized void deleteMap(ImageMap map) throws MapManagerException {
remove_Map(map);
notifyModification();
}
private void _removeMap(ImageMap map) throws MapManagerException
{
if(!mapList.remove(map))
{
private void remove_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;
public synchronized boolean mapExists(String id) {
for (ImageMap map : mapList) {
if (map.getId().equals(id)) {
return true;
}
}
return false;
}
public String getNextAvailableMapID(String mapId)
{
if(!mapExists(mapId)) return mapId;
public String getNextAvailableMapID(String mapId) {
if (!mapExists(mapId)) {
return mapId;
}
int id = 0;
do
{
do {
id++;
}while(mapExists(mapId + "-" + id));
} while (mapExists(mapId + "-" + id));
return mapId + "-" + id;
}
public synchronized List<ImageMap> getMapList()
{
public synchronized List<ImageMap> getMapList() {
return new ArrayList(mapList);
}
public synchronized ImageMap[] getMaps()
{
public synchronized ImageMap[] getMaps() {
return mapList.toArray(new ImageMap[mapList.size()]);
}
public synchronized ImageMap getMap(String mapId)
{
for(ImageMap map : mapList)
{
if(map.getId().equals(mapId)) return map;
public synchronized ImageMap getMap(String mapId) {
for (ImageMap map : mapList) {
if (map.getId().equals(mapId)) {
return map;
}
}
return null;
}
public void checkMapLimit(ImageMap map) throws MapManagerException
{
/* ===== Getters & Setters ===== */
public void checkMapLimit(ImageMap map) throws MapManagerException {
checkMapLimit(map.getMapCount());
}
public void checkMapLimit(int newMapsCount) throws MapManagerException
{
public void checkMapLimit(int newMapsCount) throws MapManagerException {
int limit = PluginConfiguration.MAP_PLAYER_LIMIT.get();
if(limit <= 0) return;
if(getMapCount() + newMapsCount > limit)
if (limit <= 0) {
return;
}
if (getMapCount() + newMapsCount > limit) {
throw new MapManagerException(Reason.MAXIMUM_PLAYER_MAPS_EXCEEDED, limit);
}
}
/* ===== Getters & Setters ===== */
public UUID getUUID()
{
public UUID getUUID() {
return playerUUID;
}
public synchronized boolean isModified()
{
public synchronized boolean isModified() {
return modified;
}
public synchronized void notifyModification()
{
public synchronized void notifyModification() {
this.modified = true;
}
public synchronized int getMapCount()
{
/* ****** Serializing ***** */
public synchronized int getMapCount() {
return this.mapCount;
}
public synchronized int getImagesCount()
{
public synchronized int getImagesCount() {
return this.mapList.size();
}
/* ****** Serializing ***** */
/* ****** Configuration Files management ***** */
@Override
public Map<String, Object> serialize()
{
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<String, Object>();
ArrayList<Map> list = new ArrayList<Map>();
synchronized(this)
{
for(ImageMap tMap : mapList)
{
list.add(tMap.serialize());
synchronized (this) {
for (ImageMap tmpMap : mapList) {
list.add(tmpMap.serialize());
}
}
map.put("mapList", list);
return map;
}
private void loadFromConfig(ConfigurationSection section)
{
if(section == null) return;
private void loadFromConfig(ConfigurationSection section) {
if (section == null) {
return;
}
List<Map<String, Object>> list = (List<Map<String, Object>>) section.getList("mapList");
if(list == null) return;
for(Map<String, Object> tMap : list)
{
try
{
ImageMap newMap = ImageMap.fromConfig(tMap, playerUUID);
synchronized(this) {_addMap(newMap);}
}
catch(InvalidConfigurationException ex)
{
if (list == null) {
return;
}
for (Map<String, Object> tmpMap : list) {
try {
ImageMap newMap = ImageMap.fromConfig(tmpMap, playerUUID);
synchronized (this) {
add_Map(newMap);
}
} catch (InvalidConfigurationException ex) {
PluginLogger.warning("Could not load map data : ", ex);
}
}
try { checkMapLimit(0); }
catch(MapManagerException ex)
{
try {
checkMapLimit(0);
} catch (MapManagerException ex) {
PluginLogger.warning("Map limit exceeded for player {0} ({1} maps loaded)",
playerUUID.toString(),mapList.size());
playerUUID.toString(), mapList.size());
}
}
/* ****** Configuration Files management ***** */
private FileConfiguration mapConfig = null;
private File mapsFile = null;
public FileConfiguration getToolConfig()
{
if(mapConfig == null) load();
public FileConfiguration getToolConfig() {
if (mapConfig == null) {
load();
}
return mapConfig;
}
public void load()
{
if(mapsFile == null)
{
public void load() {
if (mapsFile == null) {
mapsFile = new File(ImageOnMap.getPlugin().getMapsDirectory(), playerUUID.toString() + ".yml");
if(!mapsFile.exists()) save();
if (!mapsFile.exists()) {
save();
}
}
mapConfig = YamlConfiguration.loadConfiguration(mapsFile);
loadFromConfig(getToolConfig().getConfigurationSection("PlayerMapStore"));
}
public void save()
{
if(mapsFile == null || mapConfig == null) return;
public void save() {
if (mapsFile == null || mapConfig == null) {
return;
}
getToolConfig().set("PlayerMapStore", this.serialize());
try
{
try {
getToolConfig().save(mapsFile);
}
catch (IOException ex)
{
} catch (IOException ex) {
PluginLogger.error("Could not save maps file for player '{0}'", ex, playerUUID.toString());
}
synchronized(this) {modified = false;}
synchronized (this) {
modified = false;
}
}
}

View File

@ -36,163 +36,165 @@
package fr.moribus.imageonmap.map;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.InvalidConfigurationException;
public class PosterMap extends ImageMap {
protected final int[] mapsIDs;
protected final int columnCount;
protected final int rowCount;
protected final int[] mapsIDs;
protected final int columnCount;
protected final int rowCount;
public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount) {
super(userUUID, Type.POSTER, id, name);
this.mapsIDs = mapsIDs;
this.columnCount = Math.max(columnCount, 0);
this.rowCount = Math.max(rowCount, 0);
}
public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount) {
super(userUUID, Type.POSTER, id, name);
this.mapsIDs = mapsIDs;
this.columnCount = Math.max(columnCount, 0);
this.rowCount = Math.max(rowCount, 0);
}
public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount) {
this(userUUID, mapsIDs, null, null, columnCount, rowCount);
}
public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount) {
this(userUUID, mapsIDs, null, null, columnCount, rowCount);
}
@Override
public int[] getMapsIDs() {
return mapsIDs;
}
public PosterMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
super(map, userUUID, Type.POSTER);
@Override
public boolean managesMap(int mapID) {
for (int i = 0; i < mapsIDs.length; i++) {
if (mapsIDs[i] == mapID)
return true;
}
columnCount = getFieldValue(map, "columns");
rowCount = getFieldValue(map, "rows");
return false;
}
List<Integer> idList = getFieldValue(map, "mapsIDs");
mapsIDs = new int[idList.size()];
for (int i = 0, c = idList.size(); i < c; i++) {
mapsIDs[i] = idList.get(i);
}
}
/* ====== Serialization methods ====== */
@Override
public int[] getMapsIDs() {
return mapsIDs;
}
public PosterMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
super(map, userUUID, Type.POSTER);
/* ====== Serialization methods ====== */
columnCount = getFieldValue(map, "columns");
rowCount = getFieldValue(map, "rows");
@Override
public boolean managesMap(int mapID) {
for (int mapsID : mapsIDs) {
if (mapsID == mapID) {
return true;
}
}
List<Integer> idList = getFieldValue(map, "mapsIDs");
mapsIDs = new int[idList.size()];
for (int i = 0, c = idList.size(); i < c; i++) {
mapsIDs[i] = idList.get(i);
}
}
return false;
}
@Override
protected void postSerialize(Map<String, Object> map) {
map.put("columns", columnCount);
map.put("rows", rowCount);
map.put("mapsIDs", mapsIDs);
}
@Override
protected void postSerialize(Map<String, Object> map) {
map.put("columns", columnCount);
map.put("rows", rowCount);
map.put("mapsIDs", mapsIDs);
}
/* ====== Getters & Setters ====== */
/* ====== Getters & Setters ====== */
/**
* Returns the amount of columns in the poster map
*
* @return The number of columns, or 0 if this data is missing
*/
public int getColumnCount() {
return columnCount;
}
/**
* Returns the amount of columns in the poster map
*
* @return The number of columns, or 0 if this data is missing
*/
public int getColumnCount() {
return columnCount;
}
/**
* Returns the amount of rows in the poster map
*
* @return The number of rows, or 0 if this data is missing
*/
public int getRowCount() {
return rowCount;
}
/**
* Returns the amount of rows in the poster map
*
* @return The number of rows, or 0 if this data is missing
*/
public int getRowCount() {
return rowCount;
}
public int getColumnAt(int i) {
if (columnCount == 0)
return 0;
return (i % columnCount);
}
public int getColumnAt(int i) {
if (columnCount == 0) {
return 0;
}
return (i % columnCount);
}
public int getRowAt(int i) {
if (columnCount == 0)
return 0;
return (i / columnCount);
}
public int getRowAt(int i) {
if (columnCount == 0) {
return 0;
}
return (i / columnCount);
}
public int getIndexAt(int col, int row) {
return columnCount * row + col;
}
public int getIndexAt(int col, int row) {
return columnCount * row + col;
}
/**
* Returns the map id at the given column and line.
*
* @param x
* The x coordinate. Starts at 0.
* @param y
* The y coordinate. Starts at 0.
* @return The Minecraft map ID.
*
* @throws ArrayIndexOutOfBoundsException
* if the given coordinates are too big (out of the poster).
*/
public int getMapIdAt(int x, int y) {
return mapsIDs[y * columnCount + x];
}
/**
* Returns the map id at the given column and line.
*
* @param x The x coordinate. Starts at 0.
* @param y The y coordinate. Starts at 0.
* @return The Minecraft map ID.
* @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster).
*/
public int getMapIdAt(int x, int y) {
return mapsIDs[y * columnCount + x];
}
public int getMapIdAt(int index) {
return mapsIDs[index];
}
public int getMapIdAtReverseY(int index) {
int x = index % (columnCount);
int y = index / (columnCount);
return getMapIdAt(x, rowCount - y - 1);
}
public int getMapIdAtReverseY(int index) {
int x = index % (columnCount);
int y = index / (columnCount);
return getMapIdAt(x, rowCount - y - 1);
}
public int getMapIdAtReverseZ(int index, BlockFace orientation, BlockFace bf) {
int x = 0;
int y = 0;
switch (bf) {
case UP:
x = index % (columnCount);
y = index / (columnCount);
break;
case DOWN:
x = (columnCount - 1) - index % (columnCount);
y = index / (columnCount);
break;
default:
}
return getMapIdAt(x, rowCount - y - 1);
}
public int getMapIdAtReverseZ(int index, BlockFace orientation, BlockFace bf) {
int x = 0, y = 0;
switch (bf) {
case UP:
x = index % (columnCount);
y = index / (columnCount);
break;
case DOWN:
x = (columnCount - 1) - index % (columnCount);
y = index / (columnCount);
break;
}
return getMapIdAt(x, rowCount - y - 1);
public boolean hasColumnData() {
return rowCount != 0 && columnCount != 0;
}
}
@Override
public int getMapCount() {
return mapsIDs.length;
}
public int getMapIdAt(int index) {
return mapsIDs[index];
}
public int getIndex(int mapID) {
for (int i = 0; i < mapsIDs.length; i++) {
if (mapsIDs[i] == mapID) {
return i;
}
}
public boolean hasColumnData() {
return rowCount != 0 && columnCount != 0;
}
@Override
public int getMapCount() {
return mapsIDs.length;
}
public int getIndex(int mapID) {
for (int i = 0; i < mapsIDs.length; i++) {
if (mapsIDs[i] == mapID)
return i;
}
throw new IllegalArgumentException("Invalid map ID");
}
throw new IllegalArgumentException("Invalid map ID");
}
}

View File

@ -36,55 +36,46 @@
package fr.moribus.imageonmap.map;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.Map;
import java.util.UUID;
import org.bukkit.configuration.InvalidConfigurationException;
public class SingleMap extends ImageMap
{
public class SingleMap extends ImageMap {
protected final int mapID;
public SingleMap(UUID ownerUUID, int mapID, String id, String name)
{
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)
{
public SingleMap(UUID ownerUUID, int mapID) {
this(ownerUUID, mapID, null, null);
}
@Override
public int[] getMapsIDs()
{
return new int[]{mapID};
}
@Override
public boolean managesMap(int mapID)
{
return this.mapID == mapID;
}
@Override
public int getMapCount()
{
return 1;
}
/* ====== Serialization methods ====== */
public SingleMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException
{
public SingleMap(Map<String, Object> map, UUID userUUID) throws InvalidConfigurationException {
super(map, userUUID, Type.SINGLE);
mapID = getFieldValue(map, "mapID");
}
@Override
protected void postSerialize(Map<String, Object> map)
{
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);
}

View File

@ -41,39 +41,32 @@ import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.tools.PluginLogger;
public class MigratorExecutor
{
static private Thread migratorThread;
static public void migrate()
{
if(isRunning())
{
public class MigratorExecutor {
private static Thread migratorThread;
public static void migrate() {
if (isRunning()) {
PluginLogger.error(I.t("Migration is already running."));
return;
}
migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration");
migratorThread.start();
}
static public boolean isRunning()
{
public static boolean isRunning() {
return migratorThread != null && migratorThread.isAlive();
}
static public void waitForMigration()
{
if(isRunning())
{
public static void waitForMigration() {
if (isRunning()) {
PluginLogger.info(I.t("Waiting for migration to finish..."));
try
{
try {
migratorThread.join();
}
catch(InterruptedException ex)
{
PluginLogger.error(I.t("Migration thread has been interrupted while waiting to finish. It may not have ended correctly."));
} catch (InterruptedException ex) {
PluginLogger.error(I.t(
"Migration thread has been interrupted while waiting to finish."
+ " It may not have ended correctly."));
}
}
}

View File

@ -45,58 +45,53 @@ import java.util.UUID;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.InvalidConfigurationException;
class OldSavedMap
{
class OldSavedMap {
private final short mapId;
private final String mapName;
private final String userName;
public OldSavedMap(Object rawData) throws InvalidConfigurationException
{
public OldSavedMap(Object rawData) throws InvalidConfigurationException {
List<String> data;
try
{
try {
data = (List<String>) rawData;
}
catch(ClassCastException ex)
{
} catch (ClassCastException ex) {
throw new InvalidConfigurationException("Invalid map data : " + ex.getMessage());
}
if(data.size() < 3)
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)
{
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)
{
public ImageMap toImageMap(UUID userUUID) {
return new SingleMap(userUUID, mapId, null, mapName);
}
public void serialize(Configuration configuration)
{
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()
{
public boolean isMapValid() {
return MapManager.mapIdExists(mapId);
}
public short getMapId() {return mapId;}
public String getUserName() {return userName;}
public short getMapId() {
return mapId;
}
public String getUserName() {
return userName;
}
}

View File

@ -39,96 +39,89 @@ package fr.moribus.imageonmap.migration;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.moribus.imageonmap.map.PosterMap;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.InvalidConfigurationException;
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
{
class OldSavedPoster {
private final String userName;
private final String posterName;
private final short[] mapsIds;
public OldSavedPoster(Object rawData, String key) throws InvalidConfigurationException
{
public OldSavedPoster(Object rawData, String key) throws InvalidConfigurationException {
posterName = key;
List<String> data;
try
{
try {
data = (List<String>) rawData;
}
catch(ClassCastException ex)
{
} 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)");
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
{
for (int i = 1, c = data.size(); i < c; i++) {
try {
mapsIds[i - 1] = Short.parseShort(data.get(i));
}
catch(NumberFormatException ex)
{
} catch (NumberFormatException ex) {
throw new InvalidConfigurationException("Invalid map ID : " + ex.getMessage());
}
}
}
public boolean contains(OldSavedMap map)
{
public boolean contains(OldSavedMap map) {
short mapId = map.getMapId();
for(int i = 0, c = mapsIds.length; i < c; i++)
{
if(mapsIds[i] == mapId) return true;
for (short mapsId : mapsIds) {
if (mapsId == mapId) {
return true;
}
}
return false;
}
public ImageMap toImageMap(UUID userUUID)
{
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)
{
public void serialize(Configuration configuration) {
ArrayList<String> data = new ArrayList<String>();
data.add(userName);
for(short mapId : mapsIds)
{
for (short mapId : mapsIds) {
data.add(Short.toString(mapId));
}
configuration.set(posterName, data);
}
public boolean isMapValid()
{
for(short mapId : mapsIds)
{
if(!MapManager.mapIdExists(mapId))
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;}
public String getUserName() {
return userName;
}
public short[] getMapsIds() {
return mapsIds;
}
}

View File

@ -41,13 +41,6 @@ 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 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;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -57,593 +50,570 @@ import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
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
{
public class V3Migrator implements Runnable {
/**
* The name of the former images directory
*/
static private final String OLD_IMAGES_DIRECTORY_NAME = "Image";
private static final String OLD_IMAGES_DIRECTORY_NAME = "Image";
/**
* The name of the former file that contained all the maps definitions (including posters)
*/
static private final String OLD_MAPS_FILE_NAME = "map.yml";
private static final String OLD_MAPS_FILE_NAME = "map.yml";
/**
* The name of the former file that contained all the posters definitions
*/
static private final String OLD_POSTERS_FILE_NAME = "poster.yml";
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
*/
static private final String BACKUPS_PREV3_DIRECTORY_NAME = "backups_pre-v3";
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
*/
static private final String BACKUPS_POSTV3_DIRECTORY_NAME = "backups_post-v3";
/**
* Returns the former images directory of a given plugin
* @param plugin The plugin.
* @return the corresponding 'Image' directory
*/
static public File getOldImagesDirectory(Plugin plugin)
{
return new File(plugin.getDataFolder(), OLD_IMAGES_DIRECTORY_NAME);
}
private static final String BACKUPS_POSTV3_DIRECTORY_NAME = "backups_post-v3";
/**
* The plugin that is running the migration
*/
private final ImageOnMap plugin;
/**
* 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 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)
{
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;
private void migrate() {
try {
if (!spotFilesToMigrate()) {
return;
}
if (checkForExistingBackups()) {
return;
}
if (!loadOldFiles()) {
return;
}
backupMapData();
fetchUUIDs();
if(!fetchMissingUUIDs()) return;
}
catch(Exception ex)
{
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
{
try {
mergeMapData();
saveChanges();
cleanup();
}
catch(Exception ex)
{
} 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."));
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."));
}
}
/* ****** Actions ***** */
/**
* 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()
{
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)
{
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
{
} 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))
{
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."));
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
{
*
* @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())
{
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())
{
if (oldPostersFile != null && oldPostersFile.exists()) {
File oldPostersFileBackup = new File(backupsPrev3Directory, oldPostersFile.getName());
verifiedBackupCopy(oldPostersFile, oldPostersFileBackup);
}
File backupFile;
for(File mapFile : plugin.getMapsDirectory().listFiles())
{
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;
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)
{
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
{
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()))
if (!userNamesToFetch.contains(oldPoster.getUserName())) {
userNamesToFetch.add(oldPoster.getUserName());
}
catch(InvalidConfigurationException ex)
{
}
} catch (InvalidConfigurationException ex) {
PluginLogger.warning("Could not read poster data for key {0}", ex, key);
}
}
}
if(oldMapsFile != null)
{
if (oldMapsFile != null) {
FileConfiguration oldMaps = YamlConfiguration.loadConfiguration(oldMapsFile);
OldSavedMap oldMap;
for(String key : oldMaps.getKeys(false))
{
try
{
if("IdCount".equals(key)) continue;
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()))
if (!posterContains(oldMap)) {
mapsToMigrate.add(oldMap);
}
if (!userNamesToFetch.contains(oldMap.getUserName())) {
userNamesToFetch.add(oldMap.getUserName());
}
catch(InvalidConfigurationException ex)
{
}
} 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 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
{
private void fetchUUIDs() throws IOException, InterruptedException {
PluginLogger.info(I.t("Fetching UUIDs from Mojang..."));
try
{
try {
usersUUIDs = UUIDFetcher.fetch(new ArrayList<String>(userNamesToFetch));
}
catch(IOException ex)
{
} catch (IOException ex) {
PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang"), ex);
throw ex;
}
catch(InterruptedException 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()));
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);
private boolean fetchMissingUUIDs() throws IOException, InterruptedException {
if (usersUUIDs.size() == userNamesToFetch.size()) {
return true;
}
catch(IOException ex)
{
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)
{
} 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",
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 + ", ";
for (String user : userNamesToFetch) {
if (!usersUUIDs.containsKey(user)) {
missingUsersList += user + ", ";
}
}
missingUsersList = missingUsersList.substring(0, missingUsersList.length());
PluginLogger.info(missingUsersList);
}
if(usersUUIDs.size() <= 0)
{
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()
{
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())
{
while (!mapsToMigrate.isEmpty()) {
map = mapsToMigrate.pop();
playerUUID = usersUUIDs.get(map.getUserName());
if(playerUUID == null)
{
if (playerUUID == null) {
remainingMaps.add(map);
}
else if(!map.isMapValid())
{
} else if (!map.isMapValid()) {
missingMapIds.add((int) map.getMapId());
}
else
{
} else {
MapManager.insertMap(map.toImageMap(playerUUID));
}
}
mapsToMigrate.addAll(remainingMaps);
OldSavedPoster poster;
while(!postersToMigrate.isEmpty())
{
while (!postersToMigrate.isEmpty()) {
poster = postersToMigrate.pop();
playerUUID = usersUUIDs.get(poster.getUserName());
if(playerUUID == null)
{
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
{
} 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, ',')));
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, ',')));
}
}
private void saveChanges()
{
/* ****** Utils ***** */
private void saveChanges() {
PluginLogger.info(I.t("Saving changes..."));
MapManager.save();
}
private void cleanup() throws IOException
{
private void cleanup() throws IOException {
PluginLogger.info(I.t("Cleaning up old data files..."));
//Cleaning maps file
if(oldMapsFile != null)
{
if(mapsToMigrate.isEmpty())
{
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()));
} 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)
{
for (OldSavedMap map : mapsToMigrate) {
map.serialize(mapConfig);
}
mapConfig.save(oldMapsFile);
}
}
//Cleaning posters file
if(oldPostersFile != null)
{
if(postersToMigrate.isEmpty())
{
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()));
} 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)
{
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."));
}
/* ****** Utils ***** */
public synchronized boolean isRunning()
{
public synchronized boolean isRunning() {
return isRunning;
}
private synchronized void setRunning(boolean running)
{
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()
{
public void run() {
setRunning(true);
migrate();
setRunning(false);
}
/**
* 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
*/
static private 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.");
}
}
/**
* 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
*/
static private 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();
}
}

View File

@ -45,7 +45,17 @@ import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.core.QuartzLib;
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
import fr.zcraft.quartzlib.tools.items.ItemUtils;
import org.bukkit.*;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Queue;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Rotation;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
@ -59,68 +69,70 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.MapMeta;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Queue;
import java.util.UUID;
public class MapItemManager implements Listener {
private static HashMap<UUID, Queue<ItemStack>> mapItemCache;
public class MapItemManager implements Listener
{
static private HashMap<UUID, Queue<ItemStack>> mapItemCache;
static public void init()
{
public static void init() {
mapItemCache = new HashMap<>();
QuartzLib.registerEvents(new MapItemManager());
}
static public void exit()
{
if (mapItemCache != null) mapItemCache.clear();
public static void exit() {
if (mapItemCache != null) {
mapItemCache.clear();
}
mapItemCache = null;
}
static public 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);
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;
}
static public boolean give(Player player, SingleMap map)
{
return give(player, createMapItem(map,true));
public static boolean give(Player player, SingleMap map) {
return give(player, createMapItem(map, true));
}
static public boolean give(Player player, PosterMap map)
{
if (!map.hasColumnData())
public static boolean give(Player player, PosterMap map) {
if (!map.hasColumnData()) {
return giveParts(player, map);
}
return give(player, SplatterMapManager.makeSplatterMap(map));
}
static public boolean giveParts(Player player, PosterMap map)
{
private static boolean give(final Player player, final ItemStack item) {
boolean given = ItemUtils.give(player, item);
if (given) {
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
}
return !given;
}
public static boolean giveParts(Player player, PosterMap map) {
boolean inventoryFull = false;
ItemStack mapPartItem;
for (int i = 0, c = map.getMapCount(); i < c; i++)
{
mapPartItem = map.hasColumnData() ? createMapItem(map, map.getColumnAt(i), map.getRowAt(i)) : createMapItem(map, i);
for (int i = 0, c = map.getMapCount(); i < c; i++) {
mapPartItem = map.hasColumnData() ? createMapItem(map, map.getColumnAt(i), map.getRowAt(i)) :
createMapItem(map, i);
inventoryFull = give(player, mapPartItem) || inventoryFull;
}
return inventoryFull;
}
static public int giveCache(Player player)
{
public static int giveCache(Player player) {
Queue<ItemStack> cache = getCache(player);
Inventory inventory = player.getInventory();
int givenItemsCount = 0;
while (inventory.firstEmpty() >= 0 && !cache.isEmpty())
{
while (inventory.firstEmpty() >= 0 && !cache.isEmpty()) {
give(player, cache.poll());
givenItemsCount++;
}
@ -128,60 +140,35 @@ public class MapItemManager implements Listener
return givenItemsCount;
}
static private boolean give(final Player player, final ItemStack item)
{
boolean given = ItemUtils.give(player, item);
if (given)
{
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
}
return !given;
}
static public ItemStack createMapItem(SingleMap map)
{
public static ItemStack createMapItem(SingleMap map) {
return createMapItem(map.getMapsIDs()[0], map.getName(), false);
}
static public ItemStack createMapItem(SingleMap map, boolean goldTitle)
{
public static ItemStack createMapItem(SingleMap map, boolean goldTitle) {
return createMapItem(map.getMapsIDs()[0], map.getName(), false, goldTitle);
}
static public ItemStack createMapItem(PosterMap map, int index)
{
public static ItemStack createMapItem(PosterMap map, int index) {
return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true);
}
static public ItemStack createMapItem(PosterMap map, int x, int y)
{
public static ItemStack createMapItem(PosterMap map, int x, int y) {
return createMapItem(map.getMapIdAt(x, y), getMapTitle(map, y, x), true);
}
static public String getMapTitle(PosterMap map, int row, int column)
{
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column.
return I.t("{0} (row {1}, column {2})", map.getName(), row + 1, column + 1);
public static ItemStack createMapItem(int mapID, String text, boolean isMapPart) {
return createMapItem(mapID, text, isMapPart, false);
}
static public String getMapTitle(PosterMap map, int index)
{
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
return I.t("{0} (part {1})", map.getName(), index + 1);
}
static public ItemStack createMapItem(int mapID, String text, boolean isMapPart, boolean goldTitle)
{
public static ItemStack createMapItem(int mapID, String text, boolean isMapPart, boolean goldTitle) {
ItemStack mapItem;
if(goldTitle) {
if (goldTitle) {
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
.title( ChatColor.GOLD, text)
.title(ChatColor.GOLD, text)
//.hideAllAttributes()
.item();
}
else{
mapItem= new ItemStackBuilder(Material.FILLED_MAP)
} else {
mapItem = new ItemStackBuilder(Material.FILLED_MAP)
.title(text)
//.hideAllAttributes()
.item();
@ -192,11 +179,33 @@ public class MapItemManager implements Listener
mapItem.setItemMeta(meta);
return mapItem;
}
static public ItemStack createMapItem(int mapID, String text, boolean isMapPart)
{
return createMapItem( mapID, text, isMapPart,false);
public static String getMapTitle(PosterMap map, int row, int column) {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column.
return I.t("{0} (row {1}, column {2})", map.getName(), row + 1, column + 1);
}
public static String getMapTitle(PosterMap map, int index) {
/// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index.
return I.t("{0} (part {1})", map.getName(), index + 1);
}
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);
}
}
//
/**
* Returns the item to place to display the (col;row) part of the given poster.
*
@ -206,16 +215,11 @@ public class MapItemManager implements Listener
* @return The map.
* @throws ArrayIndexOutOfBoundsException If x;y is not inside the map.
*/
static public ItemStack createSubMapItem(ImageMap map, int x, int y)
{
if (map instanceof PosterMap && ((PosterMap) map).hasColumnData())
{
public static ItemStack createSubMapItem(ImageMap map, int x, int y) {
if (map instanceof PosterMap && ((PosterMap) map).hasColumnData()) {
return MapItemManager.createMapItem((PosterMap) map, x, y);
}
else
{
if (x != 0 || y != 0)
{
} else {
if (x != 0 || y != 0) {
throw new ArrayIndexOutOfBoundsException(); // Coherence
}
@ -223,64 +227,45 @@ public class MapItemManager implements Listener
}
}
static public int getCacheSize(Player player)
{
public static int getCacheSize(Player player) {
return getCache(player).size();
}
static private Queue<ItemStack> getCache(Player player)
{
private static Queue<ItemStack> getCache(Player player) {
Queue<ItemStack> cache = mapItemCache.get(player.getUniqueId());
if (cache == null)
{
if (cache == null) {
cache = new ArrayDeque<>();
mapItemCache.put(player.getUniqueId(), cache);
}
return cache;
}
static private 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);
}
}
static private void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event)
{
private static void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event) {
final ItemStack mapItem = player.getInventory().getItemInMainHand();
if (frame.getItem().getType() != Material.AIR) return;
if (!MapManager.managesMap(mapItem)) return;
if (frame.getItem().getType() != Material.AIR) {
return;
}
if (!MapManager.managesMap(mapItem)) {
return;
}
if (SplatterMapManager.hasSplatterAttributes(mapItem))
{
if (!SplatterMapManager.placeSplatterMap(frame, player,event)){
if (SplatterMapManager.hasSplatterAttributes(mapItem)) {
if (!SplatterMapManager.placeSplatterMap(frame, player, event)) {
event.setCancelled(true); //In case of an error allow to cancel map placement
return;
}
if(frame.getFacing()!= BlockFace.UP&&frame.getFacing()!= BlockFace.DOWN)
if (frame.getFacing() != BlockFace.UP && frame.getFacing() != BlockFace.DOWN) {
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
}
else
{
if(frame.getFacing()!= BlockFace.UP&&frame.getFacing()!= BlockFace.DOWN)
}
} else {
if (frame.getFacing() != BlockFace.UP && frame.getFacing() != BlockFace.DOWN) {
frame.setRotation(Rotation.NONE.rotateCounterClockwise());
}
// If the item has a display name, bot not one from an anvil by the player, we remove it
// If it is not displayed on hover on the wall.
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName() && mapItem.getItemMeta().getDisplayName().startsWith("§6"))
{
if (mapItem.hasItemMeta() && mapItem.getItemMeta().hasDisplayName()
&& mapItem.getItemMeta().getDisplayName().startsWith("§6")) {
final ItemStack frameItem = mapItem.clone();
final ItemMeta meta = frameItem.getItemMeta();
@ -289,9 +274,7 @@ public class MapItemManager implements Listener
frameItem.setItemMeta(meta);
frame.setItem(frameItem);
}
else{
} else {
frame.setItem(mapItem);
}
@ -301,29 +284,31 @@ public class MapItemManager implements Listener
ItemUtils.consumeItem(player);
}
static private void onItemFrameRemove(ItemFrame frame, Player player, EntityDamageByEntityEvent event)
{
private static void onItemFrameRemove(ItemFrame frame, Player player, EntityDamageByEntityEvent event) {
ItemStack item = frame.getItem();
if (frame.getItem().getType() != Material.FILLED_MAP) return;
if (item.getType() != Material.FILLED_MAP) {
return;
}
if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player))
{
if (player.isSneaking())
{
PosterMap poster = SplatterMapManager.removeSplatterMap(frame,player);
if (poster != null)
{
if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player)) {
if (player.isSneaking()) {
PosterMap poster = SplatterMapManager.removeSplatterMap(frame, player);
if (poster != null) {
event.setCancelled(true);
if (player.getGameMode() != GameMode.CREATIVE || !SplatterMapManager.hasSplatterMap(player, poster))
if (player.getGameMode() != GameMode.CREATIVE
|| !SplatterMapManager.hasSplatterMap(player, poster)) {
poster.give(player);
}
return;
}
}
}
if (!MapManager.managesMap(frame.getItem())) return;
if (!MapManager.managesMap(frame.getItem())) {
return;
}
frame.setItem(new ItemStackBuilder(item)
.title(getMapTitle(item))
@ -333,18 +318,22 @@ public class MapItemManager implements Listener
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
static public void onEntityDamage(EntityDamageByEntityEvent event)
{
if (!(event.getEntity() instanceof ItemFrame)) return;
if (!(event.getDamager() instanceof Player)) return;
public static void onEntityDamage(EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof ItemFrame)) {
return;
}
if (!(event.getDamager() instanceof Player)) {
return;
}
onItemFrameRemove((ItemFrame) event.getEntity(), (Player) event.getDamager(), event);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
static public void onEntityInteract(PlayerInteractEntityEvent event)
{
if (!(event.getRightClicked() instanceof ItemFrame)) return;
public static void onEntityInteract(PlayerInteractEntityEvent event) {
if (!(event.getRightClicked() instanceof ItemFrame)) {
return;
}
onItemFramePlace((ItemFrame) event.getRightClicked(), event.getPlayer(), event);
}
}

View File

@ -49,188 +49,211 @@ import org.bukkit.inventory.ItemStack;
public class PosterOnASurface {
public FlatLocation loc1;
public FlatLocation loc2;
public FlatLocation loc1;
public FlatLocation loc2;
public ItemFrame[] frames;
public ItemFrame[] frames;
public boolean isValid(Player p) {
ItemFrame curFrame;
/**
* 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();
FlatLocation l = loc1.clone();
int x = 0;
int y = 0;
switch (bf) {
case EAST:
case WEST:
//X=map.getRowCount();
//Y=map.getColumnCount();
//break;
case NORTH:
case SOUTH:
BlockFace bf = WorldUtils.get4thOrientation(p.getLocation());
y = map.getRowCount();
x = map.getColumnCount();
break;
l.subtract(loc2);
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);
}
int distX = Math.abs(l.getBlockX());
int distZ = Math.abs(l.getBlockZ());
}
frames = new ItemFrame[distX * distZ];
l = loc1.clone();
for (int x = 0; x < distX; x++) {
for (int z = 0; z < distZ; z++) {
switch (bf) {
case EAST:
case WEST:
loc.addH(1, map.getColumnCount(), bf);//test
curFrame = getEmptyFrameAt(l, l.getFacing());
break;
case NORTH:
case SOUTH:
loc.addH(-map.getColumnCount(), -1, bf);
break;
default:
throw new IllegalStateException("Unexpected value: " + bf);
}
if (curFrame == null)
return false;
}
frames[z * distX + x] = curFrame;
return frames;
}
switch (bf) {
case NORTH:
case SOUTH:
l.addH(0, 1, bf);
break;
case EAST:
case WEST:
l.addH(1, 0, bf);
break;
}
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;
}
switch (bf) {
case NORTH:
case SOUTH:
l.addH(1, -distZ, bf);
break;
case EAST:
case WEST:
l.addH(-distZ, 1, bf);
break;
}
}
return true;
}
return null;
}
public void expand() {
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 the list of map Frames associated with a specific map
* */
static public 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,y=0;
switch(bf){
case EAST:
case WEST:
y=map.getColumnCount()-1;
break;
case NORTH:
case SOUTH:
y=map.getRowCount()-1;
break;
}
return getMatchingMapFrames(map, location.clone().addH(x, y,bf),bf).clone();
}
return null;
}
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, BlockFace bf) {
ItemFrame[] frames = new ItemFrame[map.getMapCount()];
FlatLocation loc = location.clone();
public boolean isValid(Player p) {
ItemFrame curFrame;
FlatLocation l = loc1.clone();
int X=0;
int Y=0;
switch (bf){
case EAST:
case WEST:
/*X=map.getRowCount();
Y=map.getColumnCount();
break;*/
case NORTH:
case SOUTH:
BlockFace bf = WorldUtils.get4thOrientation(p.getLocation());
Y=map.getRowCount();
X=map.getColumnCount();
break;
}
for (int y = 0; y < Y; ++y) {
for (int x = 0; x < X; ++x) {
int mapIndex = map.getIndexAt(x, y);
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;
}
l.subtract(loc2);
}
int distX = Math.abs(l.getBlockX());
int distZ = Math.abs(l.getBlockZ());
switch (bf){
case EAST:
case WEST:
loc.addH( 1,map.getColumnCount(),bf);//test
frames = new ItemFrame[distX * distZ];
l = loc1.clone();
for (int x = 0; x < distX; x++) {
for (int z = 0; z < distZ; z++) {
break;
case NORTH:
case SOUTH:
loc.addH(-map.getColumnCount(), -1,bf);
break;
}
curFrame = getEmptyFrameAt(l, l.getFacing());
}
if (curFrame == null) {
return false;
}
return frames;
}
frames[z * distX + x] = curFrame;
static public ItemFrame getMapFrameAt(FlatLocation location, PosterMap map) {
Entity entities[] = location.getChunk().getEntities();
switch (bf) {
case NORTH:
case SOUTH:
l.addH(0, 1, bf);
break;
case EAST:
case WEST:
l.addH(1, 0, bf);
break;
default:
throw new IllegalStateException("Unexpected value: " + bf);
}
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;
}
switch (bf) {
case NORTH:
case SOUTH:
l.addH(1, -distZ, bf);
break;
case EAST:
case WEST:
l.addH(-distZ, 1, bf);
break;
default:
throw new IllegalStateException("Unexpected value: " + bf);
}
}
return true;
}
static public ItemFrame getEmptyFrameAt(Location location, BlockFace facing) {
Entity entities[] = location.getChunk().getEntities();
public void expand() {
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;
}
}
}

View File

@ -46,110 +46,120 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.inventory.ItemStack;
public class PosterWall
{
public class PosterWall {
public FlatLocation loc1;
public FlatLocation loc2;
public ItemFrame[] frames;
public boolean isValid()
{
ItemFrame curFrame;
FlatLocation bottomLeft = FlatLocation.minMerged(loc1, loc2);
FlatLocation loc = bottomLeft.clone();
int distX = FlatLocation.flatBlockDistanceX(loc1, loc2);
int distY = FlatLocation.flatBlockDistanceY(loc1, loc2);
frames = new ItemFrame[distX * distY];
for(int x = 0; x < distX; x++)
{
for(int y = 0; y < distY; y++)
{
curFrame = getEmptyFrameAt(loc, loc.getFacing());
if(curFrame == null) return false;
frames[y * distX + x] = curFrame;
loc.add(0, 1);
}
loc.add(1, 0);
loc.setY(bottomLeft.getY());
}
return true;
}
public void expand()
{
}
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId)
{
public static ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId) {
int mapIndex = map.getIndex(mapId);
int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex);
int x = map.getColumnAt(mapIndex);
int y = map.getRowAt(mapIndex);
return getMatchingMapFrames(map, location.clone().add(-x, y));
}
static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location)
{
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)
{
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;
if (frame != null) {
frames[mapIndex] = frame;
}
loc.add(1, 0);
}
loc.setX(location.getX());
loc.setZ(location.getZ());
loc.add(0, -1);
}
return frames;
}
static public 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;
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;
if (frame.getFacing() != location.getFacing()) {
continue;
}
ItemStack item = frame.getItem();
if(item.getType() != Material.FILLED_MAP) continue;
if(!map.managesMap(item)) continue;
if (item.getType() != Material.FILLED_MAP) {
continue;
}
if (!map.managesMap(item)) {
continue;
}
return frame;
}
return null;
}
static public 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;
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;
if (frame.getFacing() != facing) {
continue;
}
ItemStack item = frame.getItem();
if(item.getType() != Material.AIR) continue;
if (item.getType() != Material.AIR) {
continue;
}
return frame;
}
return null;
}
public boolean isValid() {
ItemFrame curFrame;
FlatLocation bottomLeft = FlatLocation.minMerged(loc1, loc2);
FlatLocation loc = bottomLeft.clone();
int distX = FlatLocation.flatBlockDistanceX(loc1, loc2);
int distY = FlatLocation.flatBlockDistanceY(loc1, loc2);
frames = new ItemFrame[distX * distY];
for (int x = 0; x < distX; x++) {
for (int y = 0; y < distY; y++) {
curFrame = getEmptyFrameAt(loc, loc.getFacing());
if (curFrame == null) {
return false;
}
frames[y * distX + x] = curFrame;
loc.add(0, 1);
}
loc.add(1, 0);
loc.setY(bottomLeft.getY());
}
return true;
}
public void expand() {
}
}

View File

@ -65,11 +65,11 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
abstract public class SplatterMapManager {
public abstract class SplatterMapManager {
private SplatterMapManager() {
}
static public ItemStack makeSplatterMap(PosterMap map) {
public static ItemStack makeSplatterMap(PosterMap map) {
final ItemStack splatter = new ItemStackBuilder(Material.FILLED_MAP).title(ChatColor.GOLD, map.getName())
@ -89,7 +89,8 @@ abstract public class SplatterMapManager {
.longLore(
ChatColor.GRAY
+
I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."),
I.t("Place empty item frames on a wall, enough to host the whole map."
+ " Then, right-click on the bottom-left frame with this map."),
40)
.loreLine()
.longLore(ChatColor.GRAY
@ -108,22 +109,23 @@ abstract public class SplatterMapManager {
/**
* To identify image on maps for the auto-splattering to work, we mark the
* items using an enchantment maps are not supposed to have (Mending).
*
* <p>
* Then we check if the map is enchanted at all to know if it's a splatter
* map. This ensure compatibility with old splatter maps from 3.x, where
* zLib's glow effect was used.
* <p>
* </p>
* An AttributeModifier (using zLib's attributes system) is not used,
* because Minecraft (or Spigot) removes them from maps in 1.14+, so that
* wasn't stable enough (and the glowing effect of enchantments is
* prettier).
*
* @param itemStack The item stack to mark as a splatter map.
* @return The modified item stack. The instance may be different if the
* passed item stack is not a craft item stack; that's why the
* instance is returned.
* @return The modified item stack. The instance may be different if the passed item stack is not
a craft item stack; that's why the instance is returned.
*
*/
static public ItemStack addSplatterAttribute(final ItemStack itemStack) {
public static ItemStack addSplatterAttribute(final ItemStack itemStack) {
try {
final NBTCompound nbt = NBT.fromItemStack(itemStack);
final NBTList enchantments = new NBTList();
@ -149,16 +151,16 @@ abstract public class SplatterMapManager {
* @param itemStack The item to check.
* @return True if the attribute was detected.
*/
static public boolean hasSplatterAttributes(ItemStack itemStack) {
public static boolean hasSplatterAttributes(ItemStack itemStack) {
try {
final NBTCompound nbt = NBT.fromItemStack(itemStack);
if (!nbt.containsKey("Enchantments")) {
return false;
}
if (!nbt.containsKey("Enchantments")) {
return false;
}
final Object enchantments = nbt.get("Enchantments");
if (!(enchantments instanceof NBTList)) {
return false;
}
if (!(enchantments instanceof NBTList)) {
return false;
}
return !((NBTList) enchantments).isEmpty();
} catch (NMSException e) {
PluginLogger.error("Unable to get Splatter Map attribute on item", e);
@ -172,23 +174,23 @@ abstract public class SplatterMapManager {
* @param itemStack The item to check.
* @return True if is a splatter map
*/
static public boolean isSplatterMap(ItemStack itemStack) {
if (itemStack == null) {
return false;
}
public static boolean isSplatterMap(ItemStack itemStack) {
if (itemStack == null) {
return false;
}
return hasSplatterAttributes(itemStack) && MapManager.managesMap(itemStack);
}
//TODO doc a faire
static public boolean hasSplatterMap(Player player, PosterMap map) {
public static boolean hasSplatterMap(Player player, PosterMap map) {
Inventory playerInventory = player.getInventory();
for (int i = 0; i < playerInventory.getSize(); ++i) {
ItemStack item = playerInventory.getItem(i);
if (isSplatterMap(item) && map.managesMap(item)) {
return true;
}
if (isSplatterMap(item) && map.managesMap(item)) {
return true;
}
}
return false;
@ -201,12 +203,12 @@ abstract public class SplatterMapManager {
* @param player Player placing map
* @return true if the map was correctly placed
*/
static public boolean placeSplatterMap(ItemFrame startFrame, Player player, PlayerInteractEntityEvent event) {
public static boolean placeSplatterMap(ItemFrame startFrame, Player player, PlayerInteractEntityEvent event) {
ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand());
if (!(map instanceof PosterMap)) {
return false;
}
if (!(map instanceof PosterMap)) {
return false;
}
PosterMap poster = (PosterMap) map;
PosterWall wall = new PosterWall();
@ -222,7 +224,8 @@ abstract public class SplatterMapManager {
if (!surface.isValid(player)) {
MessageSender.sendActionBarMessage(player,
I.t("{ce}There is not enough space to place this map ({0} × {1}).", poster.getColumnCount(),
I.t("{ce}There is not enough space to place this map ({0} × {1}).",
poster.getColumnCount(),
poster.getRowCount()));
@ -240,10 +243,14 @@ abstract public class SplatterMapManager {
case DOWN:
rot = Rotation.FLIPPED;
break;
default:
//throw new IllegalStateException("Unexpected value: " + frame.getFacing());
}
//Rotation management relative to player rotation the default position is North, when on ceiling we flipped the rotation
//Rotation management relative to player rotation the default position is North,
// when on ceiling we flipped the rotation
frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
if (i == 0) {//First map need to be rotate one time CounterClockwise
if (i == 0) {
//First map need to be rotate one time CounterClockwise
rot = rot.rotateCounterClockwise();
}
@ -270,6 +277,8 @@ abstract public class SplatterMapManager {
rot = rot.rotateCounterClockwise();
frame.setRotation(rot);
break;
default:
throw new IllegalStateException("Unexpected value: " + bf);
}
@ -312,16 +321,16 @@ abstract public class SplatterMapManager {
* @param startFrame Frame clicked by the player
* @param player The player removing the map
* @return
*/
static public PosterMap removeSplatterMap(ItemFrame startFrame, Player player) {
**/
public static PosterMap removeSplatterMap(ItemFrame startFrame, Player player) {
final ImageMap map = MapManager.getMap(startFrame.getItem());
if (!(map instanceof PosterMap)) {
return null;
}
if (!(map instanceof PosterMap)) {
return null;
}
PosterMap poster = (PosterMap) map;
if (!poster.hasColumnData()) {
return null;
}
if (!poster.hasColumnData()) {
return null;
}
FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing());
ItemFrame[] matchingFrames = null;
@ -339,16 +348,19 @@ abstract public class SplatterMapManager {
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;
}
if (matchingFrames == null) {
return null;
}
for (ItemFrame frame : matchingFrames) {
if (frame != null) {
frame.setItem(null);
}
if (frame != null) {
frame.setItem(null);
}
}
return poster;

View File

@ -5,103 +5,103 @@ api-version: "1.13"
commands:
tomap:
description: render an image in a map
usage: /<command> [URL]
maptool:
description: Manage maps
maps:
description: Manage maps through a GUI
mapgive:
description: give a map to a player from a player map store, by default take from the player that make the command
usage: /<command> player_to map_name [player_from]
tomap:
description: render an image in a map
usage: /<command> [URL]
maptool:
description: Manage maps
maps:
description: Manage maps through a GUI
mapgive:
description: give a map to a player from a player map store, by default take from the player that make the command
usage: /<command> player_to map_name [player_from]
permissions:
imageonmap.*:
description: "Grants all the user permissions (excluding administrative ones)."
default: true
children:
imageonmap.userender: true
imageonmap.new: true
imageonmap.list: true
imageonmap.listother: true
imageonmap.get: true
imageonmap.getother: true
imageonmap.explore: true
imageonmap.exploreother: true
imageonmap.rename: true
imageonmap.removesplattermap: true
imageonmap.delete: true
imageonmap.deleteother: false
imageonmap.bypasssize: false
imageonmap.give: false
imageonmap.update: true
imageonmap.updateother: false
imageonmap.*:
description: "Grants all the user permissions (excluding administrative ones)."
default: true
children:
imageonmap.userender: true
imageonmap.new: true
imageonmap.list: true
imageonmap.listother: true
imageonmap.get: true
imageonmap.getother: true
imageonmap.explore: true
imageonmap.exploreother: true
imageonmap.rename: true
imageonmap.removesplattermap: true
imageonmap.delete: true
imageonmap.deleteother: false
imageonmap.bypasssize: false
imageonmap.give: false
imageonmap.update: true
imageonmap.updateother: false
imageonmap.userender:
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
default: true
imageonmap.userender:
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
default: true
imageonmap.new:
description: "Allows you to use /tomap and related commands (/maptool getremaining)."
default: true
imageonmap.new:
description: "Allows you to use /tomap and related commands (/maptool getremaining)."
default: true
imageonmap.list:
description: "Allows you to list the images you rendered."
default: true
imageonmap.list:
description: "Allows you to list the images you rendered."
default: true
imageonmap.listother:
description: "Allows you to list the images a player have rendered."
default: false
imageonmap.listother:
description: "Allows you to list the images a player have rendered."
default: false
imageonmap.get:
description: "Allows you to get a new map among the ones you already rendered, and related commands (/maptool getremaining)."
default: true
imageonmap.get:
description: "Allows you to get a new map among the ones you already rendered, and related commands (/maptool getremaining)."
default: true
imageonmap.getother:
description: "Allows you to get a new map among the ones a player have already rendered."
default: false
imageonmap.getother:
description: "Allows you to get a new map among the ones a player have already rendered."
default: false
imageonmap.explore:
description: "Allows you to open a GUI with all your maps."
default: true
imageonmap.explore:
description: "Allows you to open a GUI with all your maps."
default: true
imageonmap.exploreother:
description: "Allows you to open a GUI with all of the player maps."
default: false
imageonmap.exploreother:
description: "Allows you to open a GUI with all of the player maps."
default: false
imageonmap.rename:
description: "Allows you to rename a map you rendered in the past."
default: true
imageonmap.rename:
description: "Allows you to rename a map you rendered in the past."
default: true
imageonmap.delete:
description: "Allows you to delete a map you rendered in the past."
default: true
imageonmap.delete:
description: "Allows you to delete a map you rendered in the past."
default: true
imageonmap.give:
description: "Allows you to give a map to a specified player."
default: op
imageonmap.deleteother:
description: "Allows you to delete a map a player rendered in the past."
default: false
imageonmap.give:
description: "Allows you to give a map to a specified player."
default: op
imageonmap.removesplattermap:
description: "Allows you to remove a splatter map from a wall by sneaking and breaking a map."
default: true
imageonmap.deleteother:
description: "Allows you to delete a map a player rendered in the past."
default: false
imageonmap.administrative:
description: "Allows you to perform administrative tasks (like /maptool migrate)."
default: op
imageonmap.removesplattermap:
description: "Allows you to remove a splatter map from a wall by sneaking and breaking a map."
default: true
imageonmap.bypasssize:
description: "Allows you to create maps larger than the configured limit."
default: op
imageonmap.administrative:
description: "Allows you to perform administrative tasks (like /maptool migrate)."
default: op
imageonmap.update:
description: "Allows you to update an existing map with a new image."
default: true
imageonmap.bypasssize:
description: "Allows you to create maps larger than the configured limit."
default: op
imageonmap.updateother:
description: "Allows you to update an existing map of an other player with a new image."
default: op
imageonmap.update:
description: "Allows you to update an existing map with a new image."
default: true
imageonmap.updateother:
description: "Allows you to update an existing map of an other player with a new image."
default: op