Add book page serialization (#4048)

Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>

Allows serialization of books in `/createkit`. Closes #31.
This commit is contained in:
Josh Roy 2021-05-28 13:52:18 -04:00 committed by GitHub
parent b2d7d1b4cb
commit 7852aedabd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 15 deletions

View File

@ -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<String> pages = meta.hasPages() ? new ArrayList<>(meta.getPages()) : new ArrayList<>();
final List<String> lines = new ArrayList<>();
for (final String line : split[1].split("(?<!\\\\)\\|")) {
lines.add(FormatUtil.replaceFormat(line.replace('_', ' ').replace("\\|", "|")));
}
final String content = String.join("\n", lines);
if (page >= 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();

View File

@ -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<String> 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<String> 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;

View File

@ -15,6 +15,7 @@ public final class MaterialUtil {
public static final Material SPAWNER = EnumUtil.getMaterial("MOB_SPAWNER", "SPAWNER");
private static final Set<Material> BEDS;
private static final Set<Material> BANNERS;
private static final Set<Material> EDITABLE_BOOKS;
private static final Set<Material> FIREWORKS;
private static final Set<Material> FIREWORK_CHARGE;
private static final Set<Material> 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);
}