Adding support for books made from /einfo

This commit is contained in:
KHobbits 2013-01-13 21:08:24 +00:00
parent 3f783bb43b
commit bd22aec38a
12 changed files with 305 additions and 26 deletions

View File

@ -122,7 +122,7 @@ public class Kit
{ {
for (int i = 2; i < parts.length; i++) for (int i = 2; i < parts.length; i++)
{ {
metaStack.addStringMeta(null, allowUnsafe, parts[i]); metaStack.addStringMeta(null, allowUnsafe, parts[i], ess);
} }
} }

View File

@ -1,45 +1,42 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._; import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.textreader.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.*;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.SkullMeta;
public class MetaItemStack public class MetaItemStack
{ {
private final transient Pattern splitPattern = Pattern.compile("[:+',;.]"); private final transient Pattern splitPattern = Pattern.compile("[:+',;.]");
private final ItemStack stack; private final ItemStack stack;
public MetaItemStack(final ItemStack stack) public MetaItemStack(final ItemStack stack)
{ {
this.stack = stack.clone(); this.stack = stack.clone();
} }
public ItemStack getItemStack() public ItemStack getItemStack()
{ {
return stack; return stack;
} }
//TODO: TL this //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); final String[] split = splitPattern.split(string, 2);
if (split.length < 1) if (split.length < 1)
{ {
return; return;
} }
if (split.length > 1 && split[0].equalsIgnoreCase("name")) if (split.length > 1 && split[0].equalsIgnoreCase("name"))
{ {
final String displayName = split[1].replace('_', ' '); 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)"); 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<String> 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")) else if (split.length > 1 && (split[0].equalsIgnoreCase("color") || split[0].equalsIgnoreCase("colour"))
&& (stack.getType() == Material.LEATHER_BOOTS && (stack.getType() == Material.LEATHER_BOOTS
|| stack.getType() == Material.LEATHER_CHESTPLATE || stack.getType() == Material.LEATHER_CHESTPLATE
@ -98,7 +120,7 @@ public class MetaItemStack
parseEnchantmentStrings(user, allowUnsafe, split); parseEnchantmentStrings(user, allowUnsafe, split);
} }
} }
public void addStringEnchantment(final User user, final boolean allowUnsafe, final String string) throws Exception public void addStringEnchantment(final User user, final boolean allowUnsafe, final String string) throws Exception
{ {
final String[] split = splitPattern.split(string, 2); final String[] split = splitPattern.split(string, 2);
@ -106,14 +128,14 @@ public class MetaItemStack
{ {
return; return;
} }
parseEnchantmentStrings(user, allowUnsafe, split); parseEnchantmentStrings(user, allowUnsafe, split);
} }
private void parseEnchantmentStrings(final User user, final boolean allowUnsafe, final String[] split) throws Exception private void parseEnchantmentStrings(final User user, final boolean allowUnsafe, final String[] split) throws Exception
{ {
Enchantment enchantment = getEnchantment(user, split[0]); Enchantment enchantment = getEnchantment(user, split[0]);
int level = -1; int level = -1;
if (split.length > 1) if (split.length > 1)
{ {
@ -126,14 +148,14 @@ public class MetaItemStack
level = -1; level = -1;
} }
} }
if (level < 0 || (!allowUnsafe && level > enchantment.getMaxLevel())) if (level < 0 || (!allowUnsafe && level > enchantment.getMaxLevel()))
{ {
level = enchantment.getMaxLevel(); level = enchantment.getMaxLevel();
} }
addEnchantment(user, allowUnsafe, enchantment, level); addEnchantment(user, allowUnsafe, enchantment, level);
} }
public void addEnchantment(final User user, final boolean allowUnsafe, final Enchantment enchantment, final int level) throws Exception public void addEnchantment(final User user, final boolean allowUnsafe, final Enchantment enchantment, final int level) throws Exception
{ {
try try

View File

@ -604,7 +604,7 @@ public class Util
return input.substring(pos, pos + 2); 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 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 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 REPLACE_PATTERN = Pattern.compile("&([0-9a-fk-or])");
private static transient final Pattern VANILLA_COLOR_PATTERN = Pattern.compile("\u00A7+[0-9A-Fa-f]"); private static transient final Pattern VANILLA_COLOR_PATTERN = Pattern.compile("\u00A7+[0-9A-Fa-f]");

View File

@ -12,7 +12,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
//TODO: Remove op and replace with perm
public class Commandbalancetop extends EssentialsCommand public class Commandbalancetop extends EssentialsCommand
{ {
public Commandbalancetop() public Commandbalancetop()

View File

@ -39,7 +39,7 @@ public class Commandbook extends EssentialsCommand
} }
else else
{ {
throw new Exception("You are not holding a book."); throw new Exception("You are not holding a writable book.");
} }
} }
} }

View File

@ -80,7 +80,7 @@ public class Commandgive extends EssentialsCommand
for (int i = Util.isInt(args[3]) ? 4 : 3; i < args.length; i++) 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(); stack = metaStack.getItemStack();
} }

View File

@ -62,7 +62,7 @@ public class Commanditem extends EssentialsCommand
for (int i = 2; i < args.length; i++) for (int i = 2; i < args.length; i++)
{ {
metaStack.addStringMeta(null, allowUnsafe, args[i]); metaStack.addStringMeta(null, allowUnsafe, args[i], ess);
} }
stack = metaStack.getItemStack(); stack = metaStack.getItemStack();
} }

View File

@ -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<String> lines;
private final transient List<String> chapters;
private final transient Map<String, Integer> bookmarks;
private final transient long lastChange;
private final static HashMap<String, SoftReference<BookInput>> cache = new HashMap<String, SoftReference<BookInput>>();
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<BookInput> inputRef = cache.get(file.getName());
BookInput input;
if (inputRef == null || (input = inputRef.get()) == null || input.lastChange < lastChange)
{
lines = new ArrayList<String>();
chapters = new ArrayList<String>();
bookmarks = new HashMap<String, Integer>();
cache.put(file.getName(), new SoftReference<BookInput>(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<String> getLines()
{
return lines;
}
@Override
public List<String> getChapters()
{
return chapters;
}
@Override
public Map<String, Integer> getBookmarks()
{
return bookmarks;
}
}

View File

@ -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<String> getPages(final String pageStr) throws Exception
{
List<String> lines = text.getLines();
List<String> chapters = text.getChapters();
Map<String, Integer> 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<String> pageLines = new ArrayList<String>();
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<String> pages = new ArrayList<String>();
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;
}
}

View File

@ -30,6 +30,8 @@ public class TextPager
List<String> chapters = text.getChapters(); List<String> chapters = text.getChapters();
Map<String, Integer> bookmarks = text.getBookmarks(); Map<String, Integer> 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 (pageStr == null || pageStr.isEmpty() || pageStr.matches("[0-9]+"))
{ {
//If an info file starts with a chapter title, list the chapters //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; int chapterpage = 0;
if (chapterPageStr != null) 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))) if (!bookmarks.containsKey(pageStr.toLowerCase(Locale.ENGLISH)))
{ {
sender.sendMessage(_("infoUnknownChapter")); sender.sendMessage(_("infoUnknownChapter"));
return; 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; final int chapterstart = bookmarks.get(pageStr.toLowerCase(Locale.ENGLISH)) + 1;
int chapterend; int chapterend;
for (chapterend = chapterstart; chapterend < lines.size(); chapterend++) for (chapterend = chapterstart; chapterend < lines.size(); chapterend++)
@ -148,8 +154,9 @@ public class TextPager
break; break;
} }
} }
//Display the chapter from the starting position
final int start = chapterstart + (onePage ? 0 : chapterpage * 9); final int start = chapterstart + (onePage ? 0 : chapterpage * 9);
final int page = chapterpage + 1; final int page = chapterpage + 1;
final int pages = (chapterend - chapterstart) / 9 + ((chapterend - chapterstart) % 9 > 0 ? 1 : 0); final int pages = (chapterend - chapterstart) / 9 + ((chapterend - chapterstart) % 9 > 0 ? 1 : 0);
if (!onePage && commandName != null) if (!onePage && commandName != null)

View File

@ -227,6 +227,10 @@ kits:
delay: 1000 delay: 1000
items: items:
- 397:3 1 player:Notch - 397:3 1 player:Notch
color:
delay: 1000
items:
- 387 1 title:Colors author:KHobbits lore:Ingame_color_codes info:Colors
# Essentials Sign Control # Essentials Sign Control
# See http://wiki.ess3.net/wiki/Sign_Tutorial for instructions on how to use these. # See http://wiki.ess3.net/wiki/Sign_Tutorial for instructions on how to use these.

View File

@ -29,10 +29,10 @@ Minecraft colors:
&4 &&4 &5 &&5 &6 &&6 &7 &&7 &4 &&4 &5 &&5 &6 &&6 &7 &&7
&8 &&8 &9 &&9 &a &&a &b &&b &8 &&8 &9 &&9 &a &&a &b &&b
&c &&c &d &&d &e &&e &f &&f &c &&c &d &&d &e &&e &f &&f
&0
&&k &k Magic!&r &&l &l Bold! &&k &kMagic&r &&l &lBold
&&m &m Strike!&r &&n &n Underline! &&m &mStrike&r &&n &nUline
&&o &o Italic!&r &&r &r reset format codes! &&o &oItalic&r &&r &rReset
#Tags #Tags
&6Player name:&r {PLAYER} &6Player name:&r {PLAYER}