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++)
{
metaStack.addStringMeta(null, allowUnsafe, parts[i]);
metaStack.addStringMeta(null, allowUnsafe, parts[i], ess);
}
}

View File

@ -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<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"))
&& (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

View File

@ -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]");

View File

@ -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()

View File

@ -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.");
}
}
}

View File

@ -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();
}

View File

@ -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();
}

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();
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 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)

View File

@ -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.

View File

@ -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}