diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/CommandValidator.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/CommandValidator.java index 23b73fb5..db4069c0 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/CommandValidator.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/CommandValidator.java @@ -16,12 +16,24 @@ package com.gmail.filoghost.holographicdisplays.commands; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; + +import com.gmail.filoghost.holographicdisplays.disk.HologramLineParser; import com.gmail.filoghost.holographicdisplays.exception.CommandException; +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; public class CommandValidator { + public static CraftHologramLine parseHologramLine(NamedHologram hologram, String serializedLine, boolean validateMaterial) throws CommandException { + try { + return HologramLineParser.parseLine(hologram, serializedLine, validateMaterial); + } catch (HologramLineParseException e) { + throw new CommandException(e.getMessage()); + } + } + public static NamedHologram getNamedHologram(String hologramName) throws CommandException { NamedHologram hologram = NamedHologramManager.getHologram(hologramName); notNull(hologram, Strings.noSuchHologram(hologramName)); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/AddlineCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/AddlineCommand.java index 004f3428..2f3abb84 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/AddlineCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/AddlineCommand.java @@ -18,7 +18,6 @@ import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.command.CommandSender; import com.gmail.filoghost.holographicdisplays.commands.Colors; @@ -29,7 +28,7 @@ import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; import com.gmail.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import com.gmail.filoghost.holographicdisplays.exception.CommandException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; -import com.gmail.filoghost.holographicdisplays.util.ItemUtils; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; import com.gmail.filoghost.holographicdisplays.util.Utils; public class AddlineCommand extends HologramSubCommand { @@ -52,21 +51,10 @@ public class AddlineCommand extends HologramSubCommand { @Override public void execute(CommandSender sender, String label, String[] args) throws CommandException { NamedHologram hologram = CommandValidator.getNamedHologram(args[0]); - String line = Utils.join(args, " ", 1, args.length); + String serializedLine = Utils.join(args, " ", 1, args.length); - // Check material validity - if (line.toLowerCase().startsWith("icon:")) { - String iconMaterial = ItemUtils.stripSpacingChars(line.substring("icon:".length(), line.length())); - - if (iconMaterial.contains(":")) { - iconMaterial = iconMaterial.split(":")[0]; - } - - Material mat = ItemUtils.matchMaterial(iconMaterial); - CommandValidator.notNull(mat, "Invalid icon material."); - } - - hologram.getLinesUnsafe().add(HologramDatabase.deserializeHologramLine(line, hologram)); + CraftHologramLine line = CommandValidator.parseHologramLine(hologram, serializedLine, true); + hologram.getLinesUnsafe().add(line); hologram.refreshAll(); HologramDatabase.saveHologram(hologram); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CopyCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CopyCommand.java index 17c5aa6b..3185bea6 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CopyCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CopyCommand.java @@ -52,8 +52,8 @@ public class CopyCommand extends HologramSubCommand { toHologram.clearLines(); for (CraftHologramLine line : fromHologram.getLinesUnsafe()) { - String lineString = HologramDatabase.serializeHologramLine(line); - toHologram.getLinesUnsafe().add(HologramDatabase.deserializeHologramLine(lineString, toHologram)); + CraftHologramLine clonedLine = CommandValidator.parseHologramLine(toHologram, HologramDatabase.serializeHologramLine(line), false); + toHologram.getLinesUnsafe().add(clonedLine); } toHologram.refreshAll(); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CreateCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CreateCommand.java index 8e40c8bb..82634a18 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CreateCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/CreateCommand.java @@ -30,6 +30,7 @@ import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; import com.gmail.filoghost.holographicdisplays.exception.CommandException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; import com.gmail.filoghost.holographicdisplays.util.Utils; public class CreateCommand extends HologramSubCommand { @@ -69,19 +70,19 @@ public class CreateCommand extends HologramSubCommand { } NamedHologram hologram = new NamedHologram(spawnLoc, hologramName); - NamedHologramManager.addHologram(hologram); if (args.length > 1) { - String text = Utils.join(args, " ", 1, args.length); CommandValidator.isTrue(!text.equalsIgnoreCase("{empty}"), "The first line should not be empty."); - hologram.getLinesUnsafe().add(HologramDatabase.deserializeHologramLine(text, hologram)); + CraftHologramLine line = CommandValidator.parseHologramLine(hologram, text, true); + hologram.getLinesUnsafe().add(line); player.sendMessage(Colors.SECONDARY_SHADOW + "(Change the lines with /" + label + " edit " + hologram.getName() + ")"); } else { hologram.appendTextLine("Default hologram. Change it with " + Colors.PRIMARY + "/" + label + " edit " + hologram.getName()); } + NamedHologramManager.addHologram(hologram); hologram.refreshAll(); HologramDatabase.saveHologram(hologram); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/InsertlineCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/InsertlineCommand.java index a23ef07e..1e8960cb 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/InsertlineCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/InsertlineCommand.java @@ -28,6 +28,7 @@ import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; import com.gmail.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import com.gmail.filoghost.holographicdisplays.exception.CommandException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; import com.gmail.filoghost.holographicdisplays.util.Utils; public class InsertlineCommand extends HologramSubCommand { @@ -52,13 +53,15 @@ public class InsertlineCommand extends HologramSubCommand { @Override public void execute(CommandSender sender, String label, String[] args) throws CommandException { NamedHologram hologram = CommandValidator.getNamedHologram(args[0]); - int insertAfter = CommandValidator.getInteger(args[1]); + String serializedLine = Utils.join(args, " ", 2, args.length); + int oldLinesAmount = hologram.size(); CommandValidator.isTrue(insertAfter >= 0 && insertAfter <= oldLinesAmount, "The number must be between 0 and " + hologram.size() + "(amount of lines of the hologram)."); - hologram.getLinesUnsafe().add(insertAfter, HologramDatabase.deserializeHologramLine(Utils.join(args, " ", 2, args.length), hologram)); + CraftHologramLine line = CommandValidator.parseHologramLine(hologram, serializedLine, true); + hologram.getLinesUnsafe().add(insertAfter, line); hologram.refreshAll(); HologramDatabase.saveHologram(hologram); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReadtextCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReadtextCommand.java index 74b12e88..3131f73a 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReadtextCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReadtextCommand.java @@ -17,6 +17,7 @@ package com.gmail.filoghost.holographicdisplays.commands.main.subs; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -30,10 +31,14 @@ import com.gmail.filoghost.holographicdisplays.commands.CommandValidator; import com.gmail.filoghost.holographicdisplays.commands.Strings; import com.gmail.filoghost.holographicdisplays.commands.main.HologramSubCommand; import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; +import com.gmail.filoghost.holographicdisplays.disk.HologramLineParser; import com.gmail.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import com.gmail.filoghost.holographicdisplays.exception.CommandException; +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; import com.gmail.filoghost.holographicdisplays.util.FileUtils; +import com.gmail.filoghost.holographicdisplays.util.Utils; public class ReadtextCommand extends HologramSubCommand { @@ -55,25 +60,33 @@ public class ReadtextCommand extends HologramSubCommand { @Override public void execute(CommandSender sender, String label, String[] args) throws CommandException { NamedHologram hologram = CommandValidator.getNamedHologram(args[0]); + String fileName = args[1]; try { - String fileName = args[1]; File targetFile = new File(HolographicDisplays.getInstance().getDataFolder(), fileName); CommandValidator.isTrue(FileUtils.isParentFolder(HolographicDisplays.getInstance().getDataFolder(), targetFile), "The file must be inside HolographicDisplays' folder."); CommandValidator.isTrue(!HolographicDisplays.isConfigFile(targetFile), "Cannot read default configuration files."); - List lines = FileUtils.readLines(targetFile); + List serializedLines = FileUtils.readLines(targetFile); - int linesAmount = lines.size(); + int linesAmount = serializedLines.size(); if (linesAmount > 40) { Strings.sendWarning(sender, "The file contained more than 40 lines, that have been limited."); linesAmount = 40; } - hologram.clearLines(); + List linesToAdd = new ArrayList<>(); for (int i = 0; i < linesAmount; i++) { - hologram.getLinesUnsafe().add(HologramDatabase.deserializeHologramLine(lines.get(i), hologram)); + try { + CraftHologramLine line = HologramLineParser.parseLine(hologram, serializedLines.get(i), true); + linesToAdd.add(line); + } catch (HologramLineParseException e) { + throw new CommandException("Error at line " + (i + 1) + ": " + Utils.uncapitalize(e.getMessage())); + } } + + hologram.clearLines(); + hologram.getLinesUnsafe().addAll(linesToAdd); hologram.refreshAll(); HologramDatabase.saveHologram(hologram); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReloadCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReloadCommand.java index 9685ae26..e6b30099 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReloadCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/ReloadCommand.java @@ -17,7 +17,6 @@ package com.gmail.filoghost.holographicdisplays.commands.main.subs; import java.util.Arrays; import java.util.List; import java.util.Set; - import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -33,12 +32,14 @@ import com.gmail.filoghost.holographicdisplays.event.HolographicDisplaysReloadEv import com.gmail.filoghost.holographicdisplays.exception.CommandException; import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException; import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException; +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException; import com.gmail.filoghost.holographicdisplays.object.CraftHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager; import com.gmail.filoghost.holographicdisplays.placeholder.AnimationsRegister; import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager; +import com.gmail.filoghost.holographicdisplays.util.Utils; public class ReloadCommand extends HologramSubCommand { @@ -85,6 +86,8 @@ public class ReloadCommand extends HologramSubCommand { Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' not found, skipping it."); } catch (InvalidFormatException e) { Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' has an invalid location format."); + } catch (HologramLineParseException e) { + Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' has an invalid line: " + Utils.uncapitalize(e.getMessage())); } catch (WorldNotFoundException e) { Strings.sendWarning(sender, "Hologram '" + singleSavedHologram + "' was in the world '" + e.getMessage() + "' but it wasn't loaded."); } diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/SetlineCommand.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/SetlineCommand.java index 16a9cb87..054d97ff 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/SetlineCommand.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/commands/main/subs/SetlineCommand.java @@ -18,7 +18,6 @@ import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.command.CommandSender; import com.gmail.filoghost.holographicdisplays.commands.Colors; @@ -29,7 +28,7 @@ import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; import com.gmail.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import com.gmail.filoghost.holographicdisplays.exception.CommandException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; -import com.gmail.filoghost.holographicdisplays.util.ItemUtils; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; import com.gmail.filoghost.holographicdisplays.util.Utils; public class SetlineCommand extends HologramSubCommand { @@ -53,26 +52,16 @@ public class SetlineCommand extends HologramSubCommand { @Override public void execute(CommandSender sender, String label, String[] args) throws CommandException { NamedHologram hologram = CommandValidator.getNamedHologram(args[0]); - String line = Utils.join(args, " ", 2, args.length); - - // Check material validity - if (line.toLowerCase().startsWith("icon:")) { - String iconMaterial = ItemUtils.stripSpacingChars(line.substring("icon:".length(), line.length())); - - if (iconMaterial.contains(":")) { - iconMaterial = iconMaterial.split(":")[0]; - } - - Material mat = ItemUtils.matchMaterial(iconMaterial); - CommandValidator.notNull(mat, "Invalid icon material."); - } + String serializedLine = Utils.join(args, " ", 2, args.length); int lineNumber = CommandValidator.getInteger(args[1]); CommandValidator.isTrue(lineNumber >= 1 && lineNumber <= hologram.size(), "The line number must be between 1 and " + hologram.size() + "."); int index = lineNumber - 1; + CraftHologramLine line = CommandValidator.parseHologramLine(hologram, serializedLine, true); + hologram.getLinesUnsafe().get(index).despawn(); - hologram.getLinesUnsafe().set(index, HologramDatabase.deserializeHologramLine(line, hologram)); + hologram.getLinesUnsafe().set(index, line); hologram.refreshAll(); HologramDatabase.saveHologram(hologram); diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramDatabase.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramDatabase.java index 6b2c09dd..439680da 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramDatabase.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramDatabase.java @@ -21,28 +21,19 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; -import com.gmail.filoghost.holographicdisplays.HolographicDisplays; import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException; import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException; +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException; -import com.gmail.filoghost.holographicdisplays.object.CraftHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; -import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; -import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine; import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger; -import com.gmail.filoghost.holographicdisplays.util.ItemUtils; -import com.gmail.filoghost.holographicdisplays.util.nbt.parser.MojangsonParseException; -import com.gmail.filoghost.holographicdisplays.util.nbt.parser.MojangsonParser; public class HologramDatabase { @@ -60,7 +51,7 @@ public class HologramDatabase { config = YamlConfiguration.loadConfiguration(file); } - public static NamedHologram loadHologram(String name) throws HologramNotFoundException, InvalidFormatException, WorldNotFoundException { + public static NamedHologram loadHologram(String name) throws HologramNotFoundException, InvalidFormatException, WorldNotFoundException, HologramLineParseException { ConfigurationSection configSection = config.getConfigurationSection(name); if (configSection == null) { @@ -77,90 +68,14 @@ public class HologramDatabase { Location loc = LocationSerializer.locationFromString(locationString); NamedHologram hologram = new NamedHologram(loc, name); - for (int i = 0; i < lines.size(); i++) { - hologram.getLinesUnsafe().add(deserializeHologramLine(lines.get(i), hologram)); + + for (String line : lines) { + hologram.getLinesUnsafe().add(HologramLineParser.parseLine(hologram, line, false)); } return hologram; } - public static CraftHologramLine deserializeHologramLine(String rawText, CraftHologram hologram) { - CraftHologramLine hologramLine; - - if (rawText.toLowerCase().startsWith("icon:")) { - String serializedIcon = rawText.substring("icon:".length(), rawText.length()); - ItemStack icon = parseItemStack(serializedIcon); - hologramLine = new CraftItemLine(hologram, icon); - - } else { - if (rawText.trim().equalsIgnoreCase("{empty}")) { - hologramLine = new CraftTextLine(hologram, ""); - } else { - hologramLine = new CraftTextLine(hologram, StringConverter.toReadableFormat(rawText)); - } - } - - hologramLine.setSerializedConfigValue(rawText); - return hologramLine; - } - - @SuppressWarnings("deprecation") - private static ItemStack parseItemStack(String serializedItem) { - serializedItem = serializedItem.trim(); - - // Parse json - int nbtStart = serializedItem.indexOf('{'); - int nbtEnd = serializedItem.lastIndexOf('}'); - String nbtString = null; - - String basicItemData; - - if (nbtStart > 0 && nbtEnd > 0 && nbtEnd > nbtStart) { - nbtString = serializedItem.substring(nbtStart, nbtEnd + 1); - basicItemData = serializedItem.substring(0, nbtStart) + serializedItem.substring(nbtEnd + 1, serializedItem.length()); - } else { - basicItemData = serializedItem; - } - - basicItemData = ItemUtils.stripSpacingChars(basicItemData); - - String materialName; - short dataValue = 0; - - if (basicItemData.contains(":")) { - String[] materialAndDataValue = basicItemData.split(":", -1); - try { - dataValue = (short) Integer.parseInt(materialAndDataValue[1]); - } catch (NumberFormatException e) { - HolographicDisplays.getInstance().getLogger().log(Level.WARNING, "Could not set data value for the item \"" + basicItemData + "\": invalid number."); - } - materialName = materialAndDataValue[0]; - } else { - materialName = basicItemData; - } - - Material material = ItemUtils.matchMaterial(materialName); - if (material == null) { - material = Material.BEDROCK; - } - - ItemStack itemStack = new ItemStack(material, 1, dataValue); - - if (nbtString != null) { - try { - // Check NBT syntax validity before applying it. - MojangsonParser.parse(nbtString); - Bukkit.getUnsafe().modifyItemStack(itemStack, nbtString); - } catch (MojangsonParseException e) { - HolographicDisplays.getInstance().getLogger().log(Level.WARNING, "Invalid NBT data \"" + nbtString + "\" for the item \"" + basicItemData + "\": " + e.getMessage()); - } catch (Throwable t) { - HolographicDisplays.getInstance().getLogger().log(Level.WARNING, "Could not apply NBT data \"" + nbtString + "\" to the item \"" + basicItemData + "\".", t); - } - } - - return itemStack; - } - public static String serializeHologramLine(CraftHologramLine line) { return line.getSerializedConfigValue(); } @@ -169,16 +84,15 @@ public class HologramDatabase { config.set(name, null); } - public static void saveHologram(NamedHologram hologram) { - ConfigurationSection hologramSection = getOrCreateSection(hologram.getName()); - hologramSection.set("location", LocationSerializer.locationToString(hologram.getLocation())); - - List lines = new ArrayList<>(); + public static void saveHologram(NamedHologram hologram) { + List serializedLines = new ArrayList<>(); for (CraftHologramLine line : hologram.getLinesUnsafe()) { - lines.add(serializeHologramLine(line)); + serializedLines.add(serializeHologramLine(line)); } - hologramSection.set("lines", lines); + ConfigurationSection hologramSection = getOrCreateSection(hologram.getName()); + hologramSection.set("location", LocationSerializer.locationToString(hologram.getLocation())); + hologramSection.set("lines", serializedLines); } public static Set getHolograms() { @@ -207,8 +121,7 @@ public class HologramDatabase { try { saveToDisk(); } catch (IOException ex) { - ex.printStackTrace(); - ConsoleLogger.log(Level.SEVERE, "Unable to save database.yml to disk!"); + ConsoleLogger.log(Level.SEVERE, "Unable to save database.yml to disk!", ex); } } } diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramLineParser.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramLineParser.java new file mode 100644 index 00000000..979c59c1 --- /dev/null +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/disk/HologramLineParser.java @@ -0,0 +1,116 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.gmail.filoghost.holographicdisplays.disk; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; +import com.gmail.filoghost.holographicdisplays.object.NamedHologram; +import com.gmail.filoghost.holographicdisplays.object.line.CraftHologramLine; +import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine; +import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine; +import com.gmail.filoghost.holographicdisplays.util.ItemUtils; +import com.gmail.filoghost.holographicdisplays.util.Utils; +import com.gmail.filoghost.holographicdisplays.util.nbt.parser.MojangsonParseException; +import com.gmail.filoghost.holographicdisplays.util.nbt.parser.MojangsonParser; + +public class HologramLineParser { + + + public static CraftHologramLine parseLine(NamedHologram hologram, String serializedLine, boolean checkMaterialValidity) throws HologramLineParseException { + CraftHologramLine hologramLine; + + if (serializedLine.toLowerCase().startsWith("icon:")) { + String serializedIcon = serializedLine.substring("icon:".length(), serializedLine.length()); + ItemStack icon = parseItemStack(serializedIcon, checkMaterialValidity); + hologramLine = new CraftItemLine(hologram, icon); + + } else { + if (serializedLine.trim().equalsIgnoreCase("{empty}")) { + hologramLine = new CraftTextLine(hologram, ""); + } else { + hologramLine = new CraftTextLine(hologram, StringConverter.toReadableFormat(serializedLine)); + } + } + + hologramLine.setSerializedConfigValue(serializedLine); + return hologramLine; + } + + + @SuppressWarnings("deprecation") + private static ItemStack parseItemStack(String serializedItem, boolean checkMaterialValidity) throws HologramLineParseException { + serializedItem = serializedItem.trim(); + + // Parse json + int nbtStart = serializedItem.indexOf('{'); + int nbtEnd = serializedItem.lastIndexOf('}'); + String nbtString = null; + + String basicItemData; + + if (nbtStart > 0 && nbtEnd > 0 && nbtEnd > nbtStart) { + nbtString = serializedItem.substring(nbtStart, nbtEnd + 1); + basicItemData = serializedItem.substring(0, nbtStart) + serializedItem.substring(nbtEnd + 1, serializedItem.length()); + } else { + basicItemData = serializedItem; + } + + basicItemData = ItemUtils.stripSpacingChars(basicItemData); + + String materialName; + short dataValue = 0; + + if (basicItemData.contains(":")) { + String[] materialAndDataValue = basicItemData.split(":", -1); + try { + dataValue = (short) Integer.parseInt(materialAndDataValue[1]); + } catch (NumberFormatException e) { + throw new HologramLineParseException("Data value \"" + materialAndDataValue[1] + "\" is not a valid number."); + } + materialName = materialAndDataValue[0]; + } else { + materialName = basicItemData; + } + + Material material = ItemUtils.matchMaterial(materialName); + if (material == null) { + if (checkMaterialValidity) { + throw new HologramLineParseException("\"" + materialName + "\" is not a valid material."); + } + material = Material.BEDROCK; + } + + ItemStack itemStack = new ItemStack(material, 1, dataValue); + + if (nbtString != null) { + try { + // Check NBT syntax validity before applying it. + MojangsonParser.parse(nbtString); + Bukkit.getUnsafe().modifyItemStack(itemStack, nbtString); + } catch (MojangsonParseException e) { + throw new HologramLineParseException("Invalid NBT data, " + Utils.uncapitalize(ChatColor.stripColor(e.getMessage()))); + } catch (Throwable t) { + throw new HologramLineParseException("Unexpected exception while parsing NBT data.", t); + } + } + + return itemStack; + } + +} diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/exception/HologramLineParseException.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/exception/HologramLineParseException.java new file mode 100644 index 00000000..139517fb --- /dev/null +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/exception/HologramLineParseException.java @@ -0,0 +1,29 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.gmail.filoghost.holographicdisplays.exception; + +public class HologramLineParseException extends Exception { + + private static final long serialVersionUID = 1L; + + public HologramLineParseException(String message) { + super(message); + } + + public HologramLineParseException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java index ec2c20f6..11731d7b 100644 --- a/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java +++ b/Plugin/src/main/java/com/gmail/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java @@ -20,6 +20,7 @@ import java.util.logging.Level; import com.gmail.filoghost.holographicdisplays.disk.HologramDatabase; import com.gmail.filoghost.holographicdisplays.exception.HologramNotFoundException; import com.gmail.filoghost.holographicdisplays.exception.InvalidFormatException; +import com.gmail.filoghost.holographicdisplays.exception.HologramLineParseException; import com.gmail.filoghost.holographicdisplays.exception.WorldNotFoundException; import com.gmail.filoghost.holographicdisplays.object.NamedHologram; import com.gmail.filoghost.holographicdisplays.object.NamedHologramManager; @@ -42,6 +43,8 @@ public class StartupLoadHologramsTask implements Runnable { ConsoleLogger.log(Level.WARNING, "Hologram '" + hologramName + "' has an invalid location format."); } catch (WorldNotFoundException e) { ConsoleLogger.log(Level.WARNING, "Hologram '" + hologramName + "' was in the world '" + e.getMessage() + "' but it wasn't loaded."); + } catch (HologramLineParseException e) { + ConsoleLogger.log(Level.WARNING, "Hologram '" + hologramName + "' has an invalid line: " + e.getMessage()); } catch (Exception e) { ConsoleLogger.log(Level.WARNING, "Unhandled exception while loading the hologram '" + hologramName + "'. Please contact the developer.", e); } diff --git a/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/Utils.java b/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/Utils.java index c955aa50..362bc78b 100644 --- a/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/Utils.java +++ b/Utils/src/main/java/com/gmail/filoghost/holographicdisplays/util/Utils.java @@ -14,7 +14,7 @@ */ package com.gmail.filoghost.holographicdisplays.util; -public class Utils extends Object { +public class Utils { /** * Converts a generic array to an array of Strings using the method toString(). @@ -99,4 +99,16 @@ public class Utils extends Object { return false; } } + + public static String uncapitalize(String str) { + if (str == null || str.isEmpty()) { + return str; + } + + return new StringBuilder(str.length()) + .append(Character.toLowerCase(str.charAt(0))) + .append(str.substring(1)) + .toString(); + } + }