diff --git a/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java b/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java index 40292ba23..19441f0c5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java +++ b/Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java @@ -220,7 +220,7 @@ public class MetaItemStack { } else { throw new Exception(tl("onlyPlayerSkulls")); } - } else if (split.length > 1 && split[0].equalsIgnoreCase("book") && stack.getType() == WRITTEN_BOOK && (hasMetaPermission(sender, "book", true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) { + } else if (split.length > 1 && split[0].equalsIgnoreCase("book") && MaterialUtil.isEditableBook(stack.getType()) && (hasMetaPermission(sender, "book",true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) { final BookMeta meta = (BookMeta) stack.getItemMeta(); final IText input = new BookInput("book", true, ess); final BookPager pager = new BookPager(input); @@ -238,6 +238,23 @@ public class MetaItemStack { final BookMeta meta = (BookMeta) stack.getItemMeta(); meta.setTitle(title); stack.setItemMeta(meta); + } else if (split.length > 1 && split[0].startsWith("page") && split[0].length() > 4 && MaterialUtil.isEditableBook(stack.getType()) && hasMetaPermission(sender, "page", false, true, ess)) { + final int page = NumberUtil.isInt(split[0].substring(4)) ? (Integer.parseInt(split[0].substring(4)) - 1) : 0; + final BookMeta meta = (BookMeta) stack.getItemMeta(); + final List pages = meta.hasPages() ? new ArrayList<>(meta.getPages()) : new ArrayList<>(); + final List lines = new ArrayList<>(); + for (final String line : split[1].split("(?= pages.size()) { + for (int i = 0; i <= page - pages.size(); i++) { + pages.add(""); + } + } + pages.set(page, content); + meta.setPages(pages); + stack.setItemMeta(meta); } else if (split.length > 1 && split[0].equalsIgnoreCase("power") && MaterialUtil.isFirework(stack.getType()) && hasMetaPermission(sender, "firework-power", false, true, ess)) { final int power = NumberUtil.isInt(split[1]) ? Integer.parseInt(split[1]) : 0; final FireworkMeta meta = (FireworkMeta) stack.getItemMeta(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/items/AbstractItemDb.java b/Essentials/src/main/java/com/earth2me/essentials/items/AbstractItemDb.java index e35f13313..579d64f01 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/items/AbstractItemDb.java +++ b/Essentials/src/main/java/com/earth2me/essentials/items/AbstractItemDb.java @@ -29,6 +29,7 @@ import org.bukkit.potion.Potion; import org.bukkit.potion.PotionEffect; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -208,18 +209,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb { } if (meta.hasLore()) { - sb.append("lore:"); - boolean first = true; - for (final String s : meta.getLore()) { - // Add | before the line if it's not the first one. Easy but weird way - // to do this since we need each line separated by | - if (!first) { - sb.append("|"); - } - first = false; - sb.append(FormatUtil.unformatString(s).replace(" ", "_")); - } - sb.append(" "); + sb.append("lore:").append(serializeLines(meta.getLore())).append(" "); } if (meta.hasEnchants()) { @@ -246,14 +236,23 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb { switch (material) { case WRITTEN_BOOK: + case WRITABLE_BOOK: // Everything from http://wiki.ess3.net/wiki/Item_Meta#Books in that order. // Interesting as I didn't see a way to do pages or chapters. final BookMeta bookMeta = (BookMeta) is.getItemMeta(); if (bookMeta.hasTitle()) { - sb.append("title:").append(bookMeta.getTitle()).append(" "); + sb.append("title:").append(FormatUtil.unformatString(bookMeta.getTitle()).replace(' ', '_')).append(" "); } if (bookMeta.hasAuthor()) { - sb.append("author:").append(bookMeta.getAuthor()).append(" "); + sb.append("author:").append(FormatUtil.unformatString(bookMeta.getAuthor()).replace(' ', '_')).append(" "); + } + if (bookMeta.hasPages()) { + final List pages = bookMeta.getPages(); + for (int i = 0; i < pages.size(); i++) { + sb.append("page").append(i + 1).append(":"); + sb.append(serializeLines(Arrays.asList(pages.get(i).split("\n")))); + sb.append(" "); + } } // Only other thing it could have is lore but that's done up there ^^^ break; @@ -364,6 +363,21 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb { } } + private String serializeLines(Iterable lines) { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + for (final String line : lines) { + // Add | before the line if it's not the first one. Easy but weird way + // to do this since we need each line separated by | + if (!first) { + sb.append("|"); + } + first = false; + sb.append(FormatUtil.unformatString(line).replace(" ", "_").replace("|", "\\|")); + } + return sb.toString(); + } + @Override public boolean isReady() { return ready; diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/MaterialUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/MaterialUtil.java index 2a4e4c3e2..7f1e37aec 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/MaterialUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/MaterialUtil.java @@ -15,6 +15,7 @@ public final class MaterialUtil { public static final Material SPAWNER = EnumUtil.getMaterial("MOB_SPAWNER", "SPAWNER"); private static final Set BEDS; private static final Set BANNERS; + private static final Set EDITABLE_BOOKS; private static final Set FIREWORKS; private static final Set FIREWORK_CHARGE; private static final Set LEGACY_SKULLS; @@ -55,6 +56,8 @@ public final class MaterialUtil { "PINK_BANNER", "GRAY_BANNER", "LIGHT_GRAY_BANNER", "CYAN_BANNER", "PURPLE_BANNER", "BLUE_BANNER", "BROWN_BANNER", "GREEN_BANNER", "RED_BANNER", "BLACK_BANNER", "SHIELD"); + EDITABLE_BOOKS = EnumUtil.getAllMatching(Material.class, "WRITTEN_BOOK", "WRITABLE_BOOK", "BOOK_AND_QUILL"); + FIREWORKS = EnumUtil.getAllMatching(Material.class, "FIREWORK", "FIREWORK_ROCKET"); FIREWORK_CHARGE = EnumUtil.getAllMatching(Material.class, "FIREWORK_CHARGE", "FIREWORK_STAR"); @@ -154,6 +157,10 @@ public final class MaterialUtil { return WALL_SIGNS.contains(material); } + public static boolean isEditableBook(final Material material) { + return EDITABLE_BOOKS.contains(material); + } + public static boolean isSign(final Material material) { return isSignPost(material) || isWallSign(material); }