diff --git a/Essentials/src/com/earth2me/essentials/Kit.java b/Essentials/src/com/earth2me/essentials/Kit.java index 4ff59a948..13652701a 100644 --- a/Essentials/src/com/earth2me/essentials/Kit.java +++ b/Essentials/src/com/earth2me/essentials/Kit.java @@ -122,7 +122,7 @@ public class Kit { for (int i = 2; i < parts.length; i++) { - metaStack.addStringMeta(null, allowUnsafe, parts[i]); + metaStack.addStringMeta(null, allowUnsafe, parts[i], ess); } } diff --git a/Essentials/src/com/earth2me/essentials/MetaItemStack.java b/Essentials/src/com/earth2me/essentials/MetaItemStack.java index 0dea8c63d..f7b78b5c8 100644 --- a/Essentials/src/com/earth2me/essentials/MetaItemStack.java +++ b/Essentials/src/com/earth2me/essentials/MetaItemStack.java @@ -1,45 +1,42 @@ package com.earth2me.essentials; import static com.earth2me.essentials.I18n._; +import com.earth2me.essentials.textreader.*; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.logging.Logger; import java.util.regex.Pattern; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.EnchantmentStorageMeta; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.LeatherArmorMeta; -import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.inventory.meta.*; public class MetaItemStack { private final transient Pattern splitPattern = Pattern.compile("[:+',;.]"); private final ItemStack stack; - + public MetaItemStack(final ItemStack stack) { this.stack = stack.clone(); } - + public ItemStack getItemStack() { return stack; } //TODO: TL this - public void addStringMeta(final User user, final boolean allowUnsafe, final String string) throws Exception + public void addStringMeta(final User user, final boolean allowUnsafe, final String string, final IEssentials ess) throws Exception { final String[] split = splitPattern.split(string, 2); if (split.length < 1) { return; } - + if (split.length > 1 && split[0].equalsIgnoreCase("name")) { final String displayName = split[1].replace('_', ' '); @@ -72,6 +69,31 @@ public class MetaItemStack throw new Exception("You can only set the owner of player skulls (397:3)"); } } + else if (split.length > 1 && split[0].equalsIgnoreCase("info") && stack.getType() == Material.WRITTEN_BOOK) + { + final BookMeta meta = (BookMeta)stack.getItemMeta(); + final IText input = new BookInput("info", true, ess); + final BookPager pager = new BookPager(input); + + List pages = pager.getPages(split[1]); + meta.setPages(pages); + + stack.setItemMeta(meta); + } + else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == Material.WRITTEN_BOOK) + { + final String author = split[1]; + final BookMeta meta = (BookMeta)stack.getItemMeta(); + meta.setAuthor(author); + stack.setItemMeta(meta); + } + else if (split.length > 1 && split[0].equalsIgnoreCase("title") && stack.getType() == Material.WRITTEN_BOOK) + { + final String title = split[1]; + final BookMeta meta = (BookMeta)stack.getItemMeta(); + meta.setTitle(title); + stack.setItemMeta(meta); + } else if (split.length > 1 && (split[0].equalsIgnoreCase("color") || split[0].equalsIgnoreCase("colour")) && (stack.getType() == Material.LEATHER_BOOTS || stack.getType() == Material.LEATHER_CHESTPLATE @@ -98,7 +120,7 @@ public class MetaItemStack parseEnchantmentStrings(user, allowUnsafe, split); } } - + public void addStringEnchantment(final User user, final boolean allowUnsafe, final String string) throws Exception { final String[] split = splitPattern.split(string, 2); @@ -106,14 +128,14 @@ public class MetaItemStack { return; } - + parseEnchantmentStrings(user, allowUnsafe, split); } - + private void parseEnchantmentStrings(final User user, final boolean allowUnsafe, final String[] split) throws Exception { Enchantment enchantment = getEnchantment(user, split[0]); - + int level = -1; if (split.length > 1) { @@ -126,14 +148,14 @@ public class MetaItemStack level = -1; } } - + if (level < 0 || (!allowUnsafe && level > enchantment.getMaxLevel())) { level = enchantment.getMaxLevel(); } addEnchantment(user, allowUnsafe, enchantment, level); } - + public void addEnchantment(final User user, final boolean allowUnsafe, final Enchantment enchantment, final int level) throws Exception { try diff --git a/Essentials/src/com/earth2me/essentials/Util.java b/Essentials/src/com/earth2me/essentials/Util.java index a31d18f0e..ad24a80d8 100644 --- a/Essentials/src/com/earth2me/essentials/Util.java +++ b/Essentials/src/com/earth2me/essentials/Util.java @@ -604,7 +604,7 @@ public class Util return input.substring(pos, pos + 2); } private static transient final Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-z]{2,3}(?:/\\S+)?)"); - private static transient final Pattern VANILLA_PATTERN = Pattern.compile("\u00A7+[0-9A-FK-ORa-fk-or]"); + private static transient final Pattern VANILLA_PATTERN = Pattern.compile("\u00A7+[0-9A-FK-ORa-fk-or]?"); private static transient final Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]"); private static transient final Pattern REPLACE_PATTERN = Pattern.compile("&([0-9a-fk-or])"); private static transient final Pattern VANILLA_COLOR_PATTERN = Pattern.compile("\u00A7+[0-9A-Fa-f]"); diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbalancetop.java b/Essentials/src/com/earth2me/essentials/commands/Commandbalancetop.java index 4711ffe40..d9007587f 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandbalancetop.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbalancetop.java @@ -12,7 +12,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.bukkit.Server; import org.bukkit.command.CommandSender; - +//TODO: Remove op and replace with perm public class Commandbalancetop extends EssentialsCommand { public Commandbalancetop() diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandbook.java b/Essentials/src/com/earth2me/essentials/commands/Commandbook.java index da46dbe7a..19d316032 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandbook.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandbook.java @@ -39,7 +39,7 @@ public class Commandbook extends EssentialsCommand } else { - throw new Exception("You are not holding a book."); + throw new Exception("You are not holding a writable book."); } } } \ No newline at end of file diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgive.java b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java index 49b60a8e7..dfaf1b189 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandgive.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java @@ -80,7 +80,7 @@ public class Commandgive extends EssentialsCommand for (int i = Util.isInt(args[3]) ? 4 : 3; i < args.length; i++) { - metaStack.addStringMeta(null, allowUnsafe, args[i]); + metaStack.addStringMeta(null, allowUnsafe, args[i], ess); } stack = metaStack.getItemStack(); } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanditem.java b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java index b69c73f2c..223162e2d 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commanditem.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java @@ -62,7 +62,7 @@ public class Commanditem extends EssentialsCommand for (int i = 2; i < args.length; i++) { - metaStack.addStringMeta(null, allowUnsafe, args[i]); + metaStack.addStringMeta(null, allowUnsafe, args[i], ess); } stack = metaStack.getItemStack(); } diff --git a/Essentials/src/com/earth2me/essentials/textreader/BookInput.java b/Essentials/src/com/earth2me/essentials/textreader/BookInput.java new file mode 100644 index 000000000..26ee1dad5 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/textreader/BookInput.java @@ -0,0 +1,124 @@ +package com.earth2me.essentials.textreader; + +import com.earth2me.essentials.IEssentials; +import java.io.*; +import java.lang.ref.SoftReference; +import java.util.*; + + +public class BookInput implements IText +{ + private final transient List lines; + private final transient List chapters; + private final transient Map bookmarks; + private final transient long lastChange; + private final static HashMap> cache = new HashMap>(); + + public BookInput(final String filename, final boolean createFile, final IEssentials ess) throws IOException + { + + File file = null; + if (file == null || !file.exists()) + { + file = new File(ess.getDataFolder(), filename + ".txt"); + } + if (file.exists()) + { + lastChange = file.lastModified(); + boolean readFromfile; + synchronized (cache) + { + final SoftReference inputRef = cache.get(file.getName()); + BookInput input; + if (inputRef == null || (input = inputRef.get()) == null || input.lastChange < lastChange) + { + lines = new ArrayList(); + chapters = new ArrayList(); + bookmarks = new HashMap(); + cache.put(file.getName(), new SoftReference(this)); + readFromfile = true; + } + else + { + lines = Collections.unmodifiableList(input.getLines()); + chapters = Collections.unmodifiableList(input.getChapters()); + bookmarks = Collections.unmodifiableMap(input.getBookmarks()); + readFromfile = false; + } + } + if (readFromfile) + { + final BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); + try + { + int lineNumber = 0; + while (bufferedReader.ready()) + { + final String line = bufferedReader.readLine(); + if (line == null) + { + break; + } + if (line.length() > 0 && line.charAt(0) == '#') + { + bookmarks.put(line.substring(1).toLowerCase(Locale.ENGLISH).replaceAll("&[0-9a-fk]", ""), lineNumber); + chapters.add(line.substring(1).replace('&', '§').replace("§§", "&")); + } + lines.add(line.replace('&', '§').replace("§§", "&")); + lineNumber++; + } + } + finally + { + bufferedReader.close(); + } + } + } + else + { + lastChange = 0; + lines = Collections.emptyList(); + chapters = Collections.emptyList(); + bookmarks = Collections.emptyMap(); + if (createFile) + { + final InputStream input = ess.getResource(filename + ".txt"); + final OutputStream output = new FileOutputStream(file); + try + { + final byte[] buffer = new byte[1024]; + int length = input.read(buffer); + while (length > 0) + { + output.write(buffer, 0, length); + length = input.read(buffer); + } + } + finally + { + output.close(); + input.close(); + } + throw new FileNotFoundException("File " + filename + ".txt does not exist. Creating one for you."); + } + } + } + + @Override + public List getLines() + { + return lines; + } + + @Override + public List getChapters() + { + return chapters; + } + + @Override + public Map getBookmarks() + { + return bookmarks; + } +} diff --git a/Essentials/src/com/earth2me/essentials/textreader/BookPager.java b/Essentials/src/com/earth2me/essentials/textreader/BookPager.java new file mode 100644 index 000000000..0cd2c630e --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/textreader/BookPager.java @@ -0,0 +1,122 @@ +package com.earth2me.essentials.textreader; + +import static com.earth2me.essentials.I18n._; +import com.earth2me.essentials.Util; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.logging.Logger; + + +public class BookPager +{ + private final transient IText text; + + public BookPager(final IText text) + { + this.text = text; + } + + public List getPages(final String pageStr) throws Exception + { + List lines = text.getLines(); + List chapters = text.getChapters(); + Map bookmarks = text.getBookmarks(); + + int chapterpage = 0; + + //This checks to see if we have the chapter in the index + if (!bookmarks.containsKey(pageStr.toLowerCase(Locale.ENGLISH))) + { + throw new Exception("No such /einfo chapter!"); + } + + //Since we have a valid chapter, count the number of lines in the chapter + final int chapterstart = bookmarks.get(pageStr.toLowerCase(Locale.ENGLISH)) + 1; + int chapterend; + for (chapterend = chapterstart; chapterend < lines.size(); chapterend++) + { + final String line = lines.get(chapterend); + if (line.length() > 0 && line.charAt(0) == '#') + { + break; + } + } + + List pageLines = new ArrayList(); + + for (int lineNo = chapterstart; lineNo < chapterend; lineNo += 1) + { + String pageLine = "\u00a70" + lines.get(lineNo); + String tempLine; + final double max = 18; + final int lineLength = pageLine.length(); + double length = 0; + int pointer = 0; + int start = 0; + double weight = 1; + + while (pointer < lineLength) + { + if (length >= max) + { + tempLine = pageLine.substring(start, pointer); + pageLines.add(tempLine); + start = pointer; + length = 0; + } + + Character letter = pageLine.charAt(pointer); + + if (letter == '\u00a7') + { + Character nextLetter = pageLine.charAt(pointer + 1); + if (nextLetter == 'l') + { + weight = 1.25; + } + else + { + weight = 1; + } + pointer++; + } + else if (letter == ' ') + { + length += (0.7 * weight); + } + else + { + length += weight; + } + pointer++; + } + if (length > 0) + { + tempLine = pageLine.substring(start, lineLength); + pageLines.add(tempLine); + } + } + + List pages = new ArrayList(); + + for (int count = 0; count < pageLines.size(); count += 12) + { + + StringBuilder newPage = new StringBuilder(); + + for (int i = count; i < count + 12 && i < pageLines.size(); i++) + { + newPage.append("\n").append(pageLines.get(i)); + //Logger.getLogger("Minecraft").info("adding line " + pageLines.get(i) + " to book"); + } + + //Logger.getLogger("Minecraft").info("adding page to book"); + pages.add(newPage.toString()); + } + + return pages; + + } +} diff --git a/Essentials/src/com/earth2me/essentials/textreader/TextPager.java b/Essentials/src/com/earth2me/essentials/textreader/TextPager.java index 503606527..c9353f89e 100644 --- a/Essentials/src/com/earth2me/essentials/textreader/TextPager.java +++ b/Essentials/src/com/earth2me/essentials/textreader/TextPager.java @@ -30,6 +30,8 @@ public class TextPager List chapters = text.getChapters(); Map bookmarks = text.getBookmarks(); + //This code deals with the initial chapter. We use this to display the initial output or contents. + //We also use this code to display some extra information if we don't intend to use chapters if (pageStr == null || pageStr.isEmpty() || pageStr.matches("[0-9]+")) { //If an info file starts with a chapter title, list the chapters @@ -116,6 +118,7 @@ public class TextPager } } + //If we have a chapter, check to see if we have a page number int chapterpage = 0; if (chapterPageStr != null) { @@ -133,11 +136,14 @@ public class TextPager } } + //This checks to see if we have the chapter in the index if (!bookmarks.containsKey(pageStr.toLowerCase(Locale.ENGLISH))) { sender.sendMessage(_("infoUnknownChapter")); return; } + + //Since we have a valid chapter, count the number of lines in the chapter final int chapterstart = bookmarks.get(pageStr.toLowerCase(Locale.ENGLISH)) + 1; int chapterend; for (chapterend = chapterstart; chapterend < lines.size(); chapterend++) @@ -148,8 +154,9 @@ public class TextPager break; } } + + //Display the chapter from the starting position final int start = chapterstart + (onePage ? 0 : chapterpage * 9); - final int page = chapterpage + 1; final int pages = (chapterend - chapterstart) / 9 + ((chapterend - chapterstart) % 9 > 0 ? 1 : 0); if (!onePage && commandName != null) diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml index 724a1b82f..b1ebf6ca0 100644 --- a/Essentials/src/config.yml +++ b/Essentials/src/config.yml @@ -227,6 +227,10 @@ kits: delay: 1000 items: - 397:3 1 player:Notch + color: + delay: 1000 + items: + - 387 1 title:Colors author:KHobbits lore:Ingame_color_codes info:Colors # Essentials Sign Control # See http://wiki.ess3.net/wiki/Sign_Tutorial for instructions on how to use these. diff --git a/Essentials/src/info.txt b/Essentials/src/info.txt index 965780a15..fbd433843 100644 --- a/Essentials/src/info.txt +++ b/Essentials/src/info.txt @@ -29,10 +29,10 @@ Minecraft colors: &4 &&4 &5 &&5 &6 &&6 &7 &&7 &8 &&8 &9 &&9 &a &&a &b &&b &c &&c &d &&d &e &&e &f &&f - -&&k &k Magic!&r &&l &l Bold! -&&m &m Strike!&r &&n &n Underline! -&&o &o Italic!&r &&r &r reset format codes! +&0 +&&k &kMagic&r &&l &lBold +&&m &mStrike&r &&n &nUline +&&o &oItalic&r &&r &rReset #Tags &6Player name:&r {PLAYER}