This commit is contained in:
Iaccidentally 2013-01-14 17:25:32 -05:00
commit 32ea86bfd3
42 changed files with 918 additions and 317 deletions

18
Essentials/src/book.txt Normal file
View file

@ -0,0 +1,18 @@
This is the book file.
This file format works similar to the info.txt, motd.txt and rules.txt
Place content in here that you would like to be used by books ingame.
You can use this content by using the book:<section> meta option in kits or item spawning.
#Colors
Minecraft colors:
&0 &&0 &1 &&1 &2 &&2 &3 &&3
&4 &&4 &5 &&5 &6 &&6 &7 &&7
&8 &&8 &9 &&9 &a &&a &b &&b
&c &&c &d &&d &e &&e &f &&f
&0
&&k &kMagic&r &&l &lBold
&&m &mStrike&r &&n &nUline
&&o &oItalic&r &&r &rReset

View file

@ -221,6 +221,69 @@ public class EssentialsConf extends YamlConfiguration
this.resourceClass = resClass; this.resourceClass = resClass;
} }
public void save()
{
try
{
save(configFile);
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
}
}
public void saveWithError() throws IOException
{
save(configFile);
}
@Override
public synchronized void save(final File file) throws IOException
{
if (file == null)
{
throw new IllegalArgumentException("File cannot be null");
}
Files.createParentDirs(file);
final String data = saveToString();
if (data.length() == 0)
{
return;
}
if (!configFile.exists())
{
try
{
LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
if (!configFile.createNewFile())
{
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
}
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
}
}
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF8);
try
{
writer.write(data);
}
finally
{
writer.close();
}
}
public boolean hasProperty(final String path) public boolean hasProperty(final String path)
{ {
return isSet(path); return isSet(path);
@ -305,94 +368,14 @@ public class EssentialsConf extends YamlConfiguration
set(path, map); set(path, map);
} }
public long getLong(final String path, final long def) public void setProperty(String path, List object)
{ {
try set(path, new ArrayList(object));
{
final Number num = (Number)get(path);
return num == null ? def : num.longValue();
}
catch (ClassCastException ex)
{
return def;
}
} }
@Override public void setProperty(String path, Map object)
public double getDouble(final String path, final double def)
{ {
try set(path, new LinkedHashMap(object));
{
Number num = (Number)get(path);
return num == null ? def : num.doubleValue();
}
catch (ClassCastException ex)
{
return def;
}
}
public void save()
{
try
{
save(configFile);
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
}
}
public void saveWithError() throws IOException
{
save(configFile);
}
@Override
public synchronized void save(final File file) throws IOException
{
if (file == null)
{
throw new IllegalArgumentException("File cannot be null");
}
Files.createParentDirs(file);
final String data = saveToString();
if (data.length() == 0)
{
return;
}
if (!configFile.exists())
{
try
{
LOGGER.log(Level.INFO, _("creatingEmptyConfig", configFile.toString()));
if (!configFile.createNewFile())
{
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()));
}
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, _("failedToCreateConfig", configFile.toString()), ex);
}
}
final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), UTF8);
try
{
writer.write(data);
}
finally
{
writer.close();
}
} }
public Object getProperty(String path) public Object getProperty(String path)
@ -464,6 +447,12 @@ public class EssentialsConf extends YamlConfiguration
return super.getDouble(path); return super.getDouble(path);
} }
@Override
public synchronized double getDouble(final String path, final double def)
{
return super.getDouble(path, def);
}
@Override @Override
public synchronized List<Double> getDoubleList(String path) public synchronized List<Double> getDoubleList(String path)
{ {
@ -524,6 +513,12 @@ public class EssentialsConf extends YamlConfiguration
return super.getLong(path); return super.getLong(path);
} }
@Override
public synchronized long getLong(final String path, final long def)
{
return super.getLong(path, def);
}
@Override @Override
public synchronized List<Long> getLongList(String path) public synchronized List<Long> getLongList(String path)
{ {

View file

@ -5,9 +5,7 @@ import com.earth2me.essentials.api.IItemDb;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
public class ItemDb implements IConf, IItemDb public class ItemDb implements IConf, IItemDb
@ -139,95 +137,7 @@ public class ItemDb implements IConf, IItemDb
retval.setDurability(metaData); retval.setDurability(metaData);
return retval; return retval;
} }
public void addStringEnchantment(final User user, final boolean allowUnsafe, final ItemStack stack, final String string) throws Exception
{
final String[] split = splitPattern.split(string, 2);
if (split.length < 1)
{
return;
}
Enchantment enchantment = getEnchantment(user, split[0]);
int level = -1;
if (split.length > 1)
{
try
{
level = Integer.parseInt(split[1]);
}
catch (NumberFormatException ex)
{
level = -1;
}
}
if (level < 0 || (!allowUnsafe && level > enchantment.getMaxLevel()))
{
level = enchantment.getMaxLevel();
}
addEnchantment(user, allowUnsafe, stack, enchantment, level);
}
public void addEnchantment(final User user, final boolean allowUnsafe, final ItemStack stack, final Enchantment enchantment, final int level) throws Exception
{
try
{
if (stack.getType().equals(Material.ENCHANTED_BOOK))
{
EnchantmentStorageMeta meta = (EnchantmentStorageMeta)stack.getItemMeta();
if (level == 0)
{
meta.removeStoredEnchant(enchantment);
}
else
{
meta.addStoredEnchant(enchantment, level, allowUnsafe);
}
stack.setItemMeta(meta);
}
else // all other material types besides ENCHANTED_BOOK
{
if (level == 0)
{
stack.removeEnchantment(enchantment);
}
else
{
if (allowUnsafe)
{
stack.addUnsafeEnchantment(enchantment, level);
}
else
{
stack.addEnchantment(enchantment, level);
}
}
}
}
catch (Exception ex)
{
throw new Exception("Enchantment " + enchantment.getName() + ": " + ex.getMessage(), ex);
}
}
//TODO: Properly TL this
public Enchantment getEnchantment(final User user, final String name) throws Exception
{
final Enchantment enchantment = Enchantments.getByName(name);
if (enchantment == null)
{
throw new Exception(_("enchantmentNotFound") + ": " + name);
}
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH);
if (user != null && !user.isAuthorized("essentials.enchant." + enchantmentName))
{
throw new Exception(_("enchantmentPerm", enchantmentName));
}
return enchantment;
}
public String names(ItemStack item) public String names(ItemStack item)
{ {
ItemData itemData = new ItemData(item.getTypeId(), item.getDurability()); ItemData itemData = new ItemData(item.getTypeId(), item.getDurability());

View file

@ -115,24 +115,25 @@ public class Kit
} }
final String[] parts = d.split(" "); final String[] parts = d.split(" ");
final ItemStack stack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1); final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
final MetaItemStack metaStack = new MetaItemStack(parseStack);
if (parts.length > 2) if (parts.length > 2)
{ {
for (int i = 2; i < parts.length; i++) for (int i = 2; i < parts.length; i++)
{ {
ess.getItemDb().addStringEnchantment(null, allowUnsafe, stack, parts[i]); metaStack.addStringMeta(null, allowUnsafe, parts[i], ess);
} }
} }
final Map<Integer, ItemStack> overfilled; final Map<Integer, ItemStack> overfilled;
if (user.isAuthorized("essentials.oversizedstacks")) if (user.isAuthorized("essentials.oversizedstacks"))
{ {
overfilled = InventoryWorkaround.addOversizedItems(user.getInventory(), ess.getSettings().getOversizedStackSize(), stack); overfilled = InventoryWorkaround.addOversizedItems(user.getInventory(), ess.getSettings().getOversizedStackSize(), metaStack.getItemStack());
} }
else else
{ {
overfilled = InventoryWorkaround.addItems(user.getInventory(), stack); overfilled = InventoryWorkaround.addItems(user.getInventory(), metaStack.getItemStack());
} }
for (ItemStack itemStack : overfilled.values()) for (ItemStack itemStack : overfilled.values())
{ {

View file

@ -0,0 +1,216 @@
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.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.*;
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, 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 = Util.replaceFormat(split[1].replace('_', ' '));
final ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(displayName);
stack.setItemMeta(meta);
}
else if (split.length > 1 && (split[0].equalsIgnoreCase("lore") || split[0].equalsIgnoreCase("desc")))
{
final List<String> lore = new ArrayList<String>();
for (String line : split[1].split("\\|"))
{
lore.add(Util.replaceFormat(line.replace('_', ' ')));
}
final ItemMeta meta = stack.getItemMeta();
meta.setLore(lore);
stack.setItemMeta(meta);
}
else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && stack.getType() == Material.SKULL_ITEM)
{
if (stack.getDurability() == 3)
{
final String owner = split[1];
final SkullMeta meta = (SkullMeta)stack.getItemMeta();
boolean result = meta.setOwner(owner);
stack.setItemMeta(meta);
}
else
{
throw new Exception("You can only set the owner of player skulls (397:3)");
}
}
else if (split.length > 1 && split[0].equalsIgnoreCase("book") && stack.getType() == Material.WRITTEN_BOOK)
{
final BookMeta meta = (BookMeta)stack.getItemMeta();
final IText input = new BookInput("book", 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 = Util.replaceFormat(split[1].replace('_', ' '));
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
|| stack.getType() == Material.LEATHER_HELMET
|| stack.getType() == Material.LEATHER_LEGGINGS))
{
final String[] color = split[1].split("\\|");
if (color.length == 3)
{
final int red = Util.isInt(color[0]) ? Integer.parseInt(color[0]) : 0;
final int green = Util.isInt(color[1]) ? Integer.parseInt(color[1]) : 0;
final int blue = Util.isInt(color[2]) ? Integer.parseInt(color[2]) : 0;
final LeatherArmorMeta meta = (LeatherArmorMeta)stack.getItemMeta();
meta.setColor(Color.fromRGB(red, green, blue));
stack.setItemMeta(meta);
}
else
{
throw new Exception("Leather Color Syntax: color:<red>|<green>|<blue> eg: color:255|0|0");
}
}
else
{
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);
if (split.length < 1)
{
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)
{
try
{
level = Integer.parseInt(split[1]);
}
catch (NumberFormatException ex)
{
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
{
if (stack.getType().equals(Material.ENCHANTED_BOOK))
{
EnchantmentStorageMeta meta = (EnchantmentStorageMeta)stack.getItemMeta();
if (level == 0)
{
meta.removeStoredEnchant(enchantment);
}
else
{
meta.addStoredEnchant(enchantment, level, allowUnsafe);
}
stack.setItemMeta(meta);
}
else // all other material types besides ENCHANTED_BOOK
{
if (level == 0)
{
stack.removeEnchantment(enchantment);
}
else
{
if (allowUnsafe)
{
stack.addUnsafeEnchantment(enchantment, level);
}
else
{
stack.addEnchantment(enchantment, level);
}
}
}
}
catch (Exception ex)
{
throw new Exception("Enchantment " + enchantment.getName() + ": " + ex.getMessage(), ex);
}
}
//TODO: Properly TL this
public Enchantment getEnchantment(final User user, final String name) throws Exception
{
final Enchantment enchantment = Enchantments.getByName(name);
if (enchantment == null)
{
throw new Exception(_("enchantmentNotFound") + ": " + name);
}
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH);
if (user != null && !user.isAuthorized("essentials.enchant." + enchantmentName))
{
throw new Exception(_("enchantmentPerm", enchantmentName));
}
return enchantment;
}
}

View file

@ -5,7 +5,6 @@ import java.io.File;
import java.util.*; import java.util.*;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -794,44 +793,44 @@ public abstract class UserData extends PlayerExtension implements IConf
{ {
return config.getBoolean("powertoolsenabled", true); return config.getBoolean("powertoolsenabled", true);
} }
private ConfigurationSection kitTimestamps; private Map<String, Long> kitTimestamps;
private ConfigurationSection _getKitTimestamps() private Map<String, Long> _getKitTimestamps()
{ {
if (config.isConfigurationSection("timestamps.kits")) if (config.isConfigurationSection("timestamps.kits"))
{ {
final ConfigurationSection section = config.getConfigurationSection("timestamps.kits"); final ConfigurationSection section = config.getConfigurationSection("timestamps.kits");
final ConfigurationSection newSection = new MemoryConfiguration(); final Map<String, Long> timestamps = new HashMap<String, Long>();
for (String command : section.getKeys(false)) for (String command : section.getKeys(false))
{ {
if (section.isLong(command)) if (section.isLong(command))
{ {
newSection.set(command.toLowerCase(Locale.ENGLISH), section.getLong(command)); timestamps.put(command.toLowerCase(Locale.ENGLISH), section.getLong(command));
} }
else if (section.isInt(command)) else if (section.isInt(command))
{ {
newSection.set(command.toLowerCase(Locale.ENGLISH), (long)section.getInt(command)); timestamps.put(command.toLowerCase(Locale.ENGLISH), (long)section.getInt(command));
} }
} }
return newSection; return timestamps;
} }
return new MemoryConfiguration(); return new HashMap<String, Long>();
} }
public long getKitTimestamp(String name) public long getKitTimestamp(String name)
{ {
name = name.replace('.', '_').replace('/', '_'); name = name.replace('.', '_').replace('/', '_');
if (kitTimestamps != null) if (kitTimestamps != null && kitTimestamps.containsKey(name))
{ {
return kitTimestamps.getLong(name, 0l); return kitTimestamps.get(name);
} }
return 0l; return 0l;
} }
public void setKitTimestamp(final String name, final long time) public void setKitTimestamp(final String name, final long time)
{ {
kitTimestamps.set(name.toLowerCase(Locale.ENGLISH), time); kitTimestamps.put(name.toLowerCase(Locale.ENGLISH), time);
config.setProperty("timestamps.kits", kitTimestamps); config.setProperty("timestamps.kits", kitTimestamps);
config.save(); config.save();
} }

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()
@ -82,7 +82,7 @@ public class Commandbalancetop extends EssentialsCommand
cal.setTimeInMillis(cacheage); cal.setTimeInMillis(cacheage);
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
sender.sendMessage(_("balanceTop", format.format(cal.getTime()))); sender.sendMessage(_("balanceTop", format.format(cal.getTime())));
new TextPager(cache).showPage(Integer.toString(page), "", "balancetop", sender); new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
} }

View file

@ -58,17 +58,17 @@ public class Commandban extends EssentialsCommand
String banReason; String banReason;
if (args.length > 1) if (args.length > 1)
{ {
banReason = _("banFormat", Util.replaceFormat(getFinalArg(args, 1).replace("\\n", "\n")), senderName); banReason = Util.replaceFormat(getFinalArg(args, 1).replace("\\n", "\n").replace("|", "\n"));
} }
else else
{ {
banReason = _("banFormat", _("defaultBanReason"), senderName); banReason = _("defaultBanReason");
} }
user.setBanReason(banReason); user.setBanReason(_("banFormat", banReason, senderName));
user.setBanned(true); user.setBanned(true);
user.setBanTimeout(0); user.setBanTimeout(0);
user.kickPlayer(banReason); user.kickPlayer(_("banFormat", banReason, senderName));
server.getLogger().log(Level.INFO, _("playerBanned", senderName, user.getName(), banReason)); server.getLogger().log(Level.INFO, _("playerBanned", senderName, user.getName(), banReason));

View file

@ -0,0 +1,88 @@
package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.User;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
public class Commandbook extends EssentialsCommand
{
public Commandbook()
{
super("book");
}
//TODO: Translate this
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception
{
final ItemStack item = user.getItemInHand();
final String player = user.getName();
if (item.getType() == Material.WRITTEN_BOOK)
{
BookMeta bmeta = (BookMeta)item.getItemMeta();
if (args[0].equalsIgnoreCase("author"))
{
if (user.isAuthorized("essentals.book.author"))
{
bmeta.setAuthor(args[1]);
item.setItemMeta(bmeta);
user.sendMessage(_("bookAuthorSet", args[1]));
}
else
{
throw new Exception(_("denyChangeAuthor"));
}
}
else if (args[0].equalsIgnoreCase("title"))
{
if (user.isAuthorized("essentials.book.title") && (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others")))
{
bmeta.setTitle(args[1]);
item.setItemMeta(bmeta);
user.sendMessage(_("bookTitleSet", args[1]));
}
else
{
throw new Exception(_("denyChangeTitle"));
}
}
else
{
if (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others"))
{
ItemStack newItem = new ItemStack(Material.BOOK_AND_QUILL, item.getAmount());
newItem.setItemMeta(bmeta);
user.setItemInHand(newItem);
user.sendMessage(_("editBookContents"));
}
else
{
throw new Exception(_("denyBookEdit"));
}
}
}
else if (item.getType() == Material.BOOK_AND_QUILL)
{
BookMeta bmeta = (BookMeta)item.getItemMeta();
bmeta.setAuthor(player);
ItemStack newItem = new ItemStack(Material.WRITTEN_BOOK, item.getAmount());
newItem.setItemMeta(bmeta);
user.setItemInHand(newItem);
user.sendMessage(_("bookLocked"));
}
else
{
throw new Exception(_("holdBook"));
}
}
private boolean isAuthor(BookMeta bmeta, String player)
{
return bmeta.getAuthor().equalsIgnoreCase(player);
}
}

View file

@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Enchantments; import com.earth2me.essentials.Enchantments;
import static com.earth2me.essentials.I18n._; import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.Util; import com.earth2me.essentials.Util;
import java.util.Locale; import java.util.Locale;
@ -58,11 +59,13 @@ public class Commandenchant extends EssentialsCommand
} }
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchant.allowunsafe"); final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchant.allowunsafe");
final Enchantment enchantment = ess.getItemDb().getEnchantment(user, args[0]);
ess.getItemDb().addEnchantment(user, allowUnsafe, stack, enchantment, level); final MetaItemStack metaStack = new MetaItemStack(stack);
final Enchantment enchantment = metaStack.getEnchantment(user, args[0]);
metaStack.addEnchantment(user, allowUnsafe, enchantment, level);
user.getInventory().setItemInHand(stack); user.getInventory().setItemInHand(metaStack.getItemStack());
user.updateInventory(); user.updateInventory();
final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH); final String enchantmentName = enchantment.getName().toLowerCase(Locale.ENGLISH);
if (level == 0) if (level == 0)

View file

@ -1,6 +1,7 @@
package com.earth2me.essentials.commands; package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._; import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.Util; import com.earth2me.essentials.Util;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround; import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
@ -27,7 +28,7 @@ public class Commandgive extends EssentialsCommand
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
final ItemStack stack = ess.getItemDb().get(args[1]); ItemStack stack = ess.getItemDb().get(args[1]);
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""); final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (sender instanceof Player if (sender instanceof Player
@ -70,7 +71,8 @@ public class Commandgive extends EssentialsCommand
if (args.length > 3) if (args.length > 3)
{ {
boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments(); MetaItemStack metaStack = new MetaItemStack(stack);
boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
if (allowUnsafe && sender instanceof Player && !ess.getUser(sender).isAuthorized("essentials.enchant.allowunsafe")) if (allowUnsafe && sender instanceof Player && !ess.getUser(sender).isAuthorized("essentials.enchant.allowunsafe"))
{ {
allowUnsafe = false; allowUnsafe = false;
@ -78,8 +80,9 @@ 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++)
{ {
ess.getItemDb().addStringEnchantment(null, allowUnsafe, stack, args[i]); metaStack.addStringMeta(null, allowUnsafe, args[i], ess);
} }
stack = metaStack.getItemStack();
} }
if (stack.getType() == Material.AIR) if (stack.getType() == Material.AIR)

View file

@ -1,6 +1,7 @@
package com.earth2me.essentials.commands; package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._; import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround; import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import java.util.Locale; import java.util.Locale;
@ -23,7 +24,7 @@ public class Commanditem extends EssentialsCommand
{ {
throw new NotEnoughArgumentsException(); throw new NotEnoughArgumentsException();
} }
final ItemStack stack = ess.getItemDb().get(args[0]); ItemStack stack = ess.getItemDb().get(args[0]);
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""); final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (ess.getSettings().permissionBasedItemSpawn() if (ess.getSettings().permissionBasedItemSpawn()
@ -56,12 +57,14 @@ public class Commanditem extends EssentialsCommand
} }
if (args.length > 2) if (args.length > 2)
{ {
MetaItemStack metaStack = new MetaItemStack(stack);
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchant.allowunsafe"); final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments() && user.isAuthorized("essentials.enchant.allowunsafe");
for (int i = 2; i < args.length; i++) for (int i = 2; i < args.length; i++)
{ {
ess.getItemDb().addStringEnchantment(null, allowUnsafe, stack, args[i]); metaStack.addStringMeta(null, allowUnsafe, args[i], ess);
} }
stack = metaStack.getItemStack();
} }

View file

@ -40,7 +40,7 @@ public class Commandkick extends EssentialsCommand
} }
String kickReason = args.length > 1 ? getFinalArg(args, 1) : _("kickDefault"); String kickReason = args.length > 1 ? getFinalArg(args, 1) : _("kickDefault");
kickReason = Util.replaceFormat(kickReason.replace("\\n", "\n")); kickReason = Util.replaceFormat(kickReason.replace("\\n", "\n").replace("|", "\n"));
target.kickPlayer(kickReason); target.kickPlayer(kickReason);
final String senderName = sender instanceof Player ? ((Player)sender).getDisplayName() : Console.NAME; final String senderName = sender instanceof Player ? ((Player)sender).getDisplayName() : Console.NAME;

View file

@ -18,7 +18,7 @@ public class Commandkickall extends EssentialsCommand
public void run(final Server server, final CommandSender sender, final String commandLabel, final String[] args) throws Exception public void run(final Server server, final CommandSender sender, final String commandLabel, final String[] args) throws Exception
{ {
String kickReason = args.length > 0 ? getFinalArg(args, 0) : _("kickDefault"); String kickReason = args.length > 0 ? getFinalArg(args, 0) : _("kickDefault");
kickReason = Util.replaceFormat(kickReason.replace("\\n", "\n")); kickReason = Util.replaceFormat(kickReason.replace("\\n", "\n").replace("|", "\n"));
for (Player onlinePlayer : server.getOnlinePlayers()) for (Player onlinePlayer : server.getOnlinePlayers())
{ {

View file

@ -20,7 +20,9 @@ public class Commandtop extends EssentialsCommand
{ {
final int topX = user.getLocation().getBlockX(); final int topX = user.getLocation().getBlockX();
final int topZ = user.getLocation().getBlockZ(); final int topZ = user.getLocation().getBlockZ();
final Location location = new Location(user.getWorld(), topX, user.getWorld().getMaxHeight(), topZ); final float pitch = user.getLocation().getPitch();
final float yaw = user.getLocation().getYaw();
final Location location = new Location(user.getWorld(), topX, user.getWorld().getMaxHeight(), topZ, yaw, pitch);
user.getTeleport().teleport(location, new Trade(this.getName(), ess), TeleportCause.COMMAND); user.getTeleport().teleport(location, new Trade(this.getName(), ess), TeleportCause.COMMAND);
user.sendMessage(_("teleportTop")); user.sendMessage(_("teleportTop"));
} }

View file

@ -0,0 +1,128 @@
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())
{
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();
}
ess.getLogger().info("File " + filename + ".txt does not exist. Creating one for you.");
}
}
if (!file.exists())
{
lastChange = 0;
lines = Collections.emptyList();
chapters = Collections.emptyList();
bookmarks = Collections.emptyMap();
throw new FileNotFoundException("Could not create " + filename + ".txt");
}
else
{
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();
}
}
}
}
@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,110 @@
package com.earth2me.essentials.textreader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
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();
List<String> pageLines = new ArrayList<String>();
Map<String, Integer> bookmarks = text.getBookmarks();
//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;
}
}
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' || 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));
}
pages.add(newPage.toString());
}
return pages;
}
}

View file

@ -30,57 +30,12 @@ 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();
if (bookmarks.isEmpty()) //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
int page = 1;
try
{
page = Integer.parseInt(pageStr);
}
catch (Exception ex)
{
page = 1;
}
if (page < 1)
{
page = 1;
}
final int start = onePage ? 0 : (page - 1) * 9;
final int pages = lines.size() / 9 + (lines.size() % 9 > 0 ? 1 : 0);
if (!onePage && commandName != null)
{
StringBuilder content = new StringBuilder();
final String[] title = commandName.split(" ", 2);
if (title.length > 1)
{
content.append(I18n.capitalCase(title[0])).append(": ");
content.append(title[1]);
}
else if (chapterPageStr != null)
{
content.append(I18n.capitalCase(commandName)).append(": ");
content.append(chapterPageStr);
}
else
{
content.append(I18n.capitalCase(commandName));
}
sender.sendMessage(_("infoPages", page, pages, content));
}
for (int i = start; i < lines.size() && i < start + (onePage ? 20 : 9); i++)
{
sender.sendMessage("§r" + lines.get(i));
}
if (!onePage && page < pages && commandName != null)
{
sender.sendMessage(_("readNextPage", commandName, page + 1));
}
return;
}
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 not display the text up until the first chapter.
if (lines.get(0).startsWith("#")) if (lines.get(0).startsWith("#"))
{ {
if (onePage) if (onePage)
@ -133,7 +88,23 @@ public class TextPager
if (!onePage && commandName != null) if (!onePage && commandName != null)
{ {
sender.sendMessage(_("infoPages", page, pages, I18n.capitalCase(commandName))); StringBuilder content = new StringBuilder();
final String[] title = commandName.split(" ", 2);
if (title.length > 1)
{
content.append(I18n.capitalCase(title[0])).append(": ");
content.append(title[1]);
}
else if (chapterPageStr != null)
{
content.append(I18n.capitalCase(commandName)).append(": ");
content.append(chapterPageStr);
}
else
{
content.append(I18n.capitalCase(commandName));
}
sender.sendMessage(_("infoPages", page, pages, content));
} }
for (int i = start; i < end && i < start + (onePage ? 20 : 9); i++) for (int i = start; i < end && i < start + (onePage ? 20 : 9); i++)
{ {
@ -147,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)
{ {
@ -164,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++)
@ -179,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

@ -205,16 +205,11 @@ player-commands:
# Note: All items MUST be followed by a quantity! # Note: All items MUST be followed by a quantity!
# All kit names should be lower case, and will be treated as lower in permissions/costs. # All kit names should be lower case, and will be treated as lower in permissions/costs.
# Syntax: - itemID[:DataValue] Amount [Enchantment:Level].. # Syntax: - itemID[:DataValue/Durability] Amount [Enchantment:Level].. [meta:value]...
# Supported meta includes: name, lore, color, player, title, author, book
# 'delay' refers to the cooldown between how often you can use each kit, measured in seconds. # 'delay' refers to the cooldown between how often you can use each kit, measured in seconds.
# For more information, visit http://wiki.ess3.net/wiki/Command_Reference/ICheat#kits # For more information, visit http://wiki.ess3.net/wiki/Command_Reference/ICheat#kits
kits: kits:
dtools:
delay: 10
items:
- 277 1 efficiency:1 durability:1
- 278 1
- 279:780 1
tools: tools:
delay: 10 delay: 10
items: items:
@ -222,6 +217,21 @@ kits:
- 273 1 - 273 1
- 274 1 - 274 1
- 275 1 - 275 1
dtools:
delay: 600
items:
- 278 1 efficiency:1 durability:1 fortune:1 name:&4Gigadrill lore:The_drill_that_&npierces|the_heavens
- 277 1 digspeed:3 name:Dwarf lore:Diggy|Diggy|Hole
- 298 1 color:255|255|255 name:Top_Hat lore:Good_day,_Good_day
- 279:780 1
notch:
delay: 6000
items:
- 397:3 1 player:Notch
color:
delay: 6000
items:
- 387 1 title:&4Book_&9o_&6Colors author:KHobbits lore:Ingame_color_codes book: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}

View file

@ -5763,8 +5763,10 @@ headwitherskeleton,397,1
headwskeletion,397,1 headwskeletion,397,1
zombiehead,397,2 zombiehead,397,2
headzombie,397,2 headzombie,397,2
playerhead,397,3
humanhead,397,3 humanhead,397,3
stevehead,397,3 stevehead,397,3
headplayer,397,3
headhuman,397,3 headhuman,397,3
headsteve,397,3 headsteve,397,3
creeperhead,397,4 creeperhead,397,4

1 #version: TeamCity
5763 headwskeletion,397,1
5764 zombiehead,397,2
5765 headzombie,397,2
5766 playerhead,397,3
5767 humanhead,397,3
5768 stevehead,397,3
5769 headplayer,397,3
5770 headhuman,397,3
5771 headsteve,397,3
5772 creeperhead,397,4

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -481,3 +481,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -5,15 +5,15 @@
action=* {0} {1} action=* {0} {1}
addedToAccount=\u00a7a{0} har blivit tillagt p\u00e5 ditt konto. addedToAccount=\u00a7a{0} har blivit tillagt p\u00e5 ditt konto.
addedToOthersAccount=\u00a7a{0} har blivit tillagt p\u00e5 {1}\u00a7a konto. Ny balans: {2} addedToOthersAccount=\u00a7a{0} har blivit tillagt p\u00e5 {1}\u00a7a konto. Ny balans: {2}
adventure = \u00E4ventyr adventure = \u00e4ventyr
alertBroke=gjorde s\u00f6nder: alertBroke=gjorde s\u00f6nder:
alertFormat=\u00a73[{0}] \u00a7f {1} \u00a76 {2} at: {3} alertFormat=\u00a73[{0}] \u00a7f {1} \u00a76 {2} at: {3}
alertPlaced=placerade: alertPlaced=placerade:
alertUsed=anv\u00e4nde: alertUsed=anv\u00e4nde:
antiBuildBreak=\u00a74Du har inte till\u00E5telse att ta s\u00F6nder {0} blocks h\u00E4r. antiBuildBreak=\u00a74Du har inte till\u00e5telse att ta s\u00f6nder {0} blocks h\u00e4r.
antiBuildInteract=\u00a74Du har inte till\u00E5telse att p\u00E5verka {0}. antiBuildInteract=\u00a74Du har inte till\u00e5telse att p\u00e5verka {0}.
antiBuildPlace=\u00a74Du har inte till\u00E5telse att placera {0} h\u00E4r. antiBuildPlace=\u00a74Du har inte till\u00e5telse att placera {0} h\u00e4r.
antiBuildUse=\u00a74Du har inte till\u00E5telse att anv\u00E4nda {0}. antiBuildUse=\u00a74Du har inte till\u00e5telse att anv\u00e4nda {0}.
autoAfkKickReason=Du har blivit utsparkad f\u00f6r att ha varit inaktiv i mer \u00e4n {0} minuter. autoAfkKickReason=Du har blivit utsparkad f\u00f6r att ha varit inaktiv i mer \u00e4n {0} minuter.
backAfterDeath=\u00a77Anv\u00e4nd /back kommandot f\u00f6r att komma tillbaka till din d\u00f6dsplats. backAfterDeath=\u00a77Anv\u00e4nd /back kommandot f\u00f6r att komma tillbaka till din d\u00f6dsplats.
backUsageMsg=\u00a77Tar dig tillbaka till din f\u00f6reg\u00e5ende position. backUsageMsg=\u00a77Tar dig tillbaka till din f\u00f6reg\u00e5ende position.
@ -115,7 +115,7 @@ godDisabledFor=inaktiverat f\u00f6r {0}
godEnabledFor=aktiverat f\u00f6r {0} godEnabledFor=aktiverat f\u00f6r {0}
godMode=\u00a77Od\u00f6dlighet {0}. godMode=\u00a77Od\u00f6dlighet {0}.
hatArmor=\u00a7cFel, du kan inte anv\u00e4nda den h\u00e4r saken som en hatt! hatArmor=\u00a7cFel, du kan inte anv\u00e4nda den h\u00e4r saken som en hatt!
hatEmpty=\u00a7cDu har inte p\u00E5 dig en hatt. hatEmpty=\u00a7cDu har inte p\u00e5 dig en hatt.
hatFail=\u00a7cDu m\u00e5ste ha n\u00e5gonting att b\u00e4ra i din hand. hatFail=\u00a7cDu m\u00e5ste ha n\u00e5gonting att b\u00e4ra i din hand.
hatPlaced=\u00a7eNjut av din nya hatt! hatPlaced=\u00a7eNjut av din nya hatt!
hatRemoved=\u00a7eDin hatt har tagits bort. hatRemoved=\u00a7eDin hatt har tagits bort.
@ -157,7 +157,7 @@ inventoryClearedOthers=\u00a77F\u00f6rr\u00e5det av \u00a7c{0}\u00a77 \u00e4r re
is=\u00e4r is=\u00e4r
itemCannotBeSold=Det objektet kan inte s\u00e4ljas till servern. itemCannotBeSold=Det objektet kan inte s\u00e4ljas till servern.
itemMustBeStacked=Objektet m\u00e5ste k\u00f6pas i staplar. En m\u00e4ngd av 2s kommer bli 2 staplar, etc. itemMustBeStacked=Objektet m\u00e5ste k\u00f6pas i staplar. En m\u00e4ngd av 2s kommer bli 2 staplar, etc.
itemNames=F\u00F6rkortning p\u00E5 objekt: {0} itemNames=F\u00f6rkortning p\u00e5 objekt: {0}
itemNotEnough1=\u00a7cDu har inte tillr\u00e4ckligt av den saken f\u00f6r att s\u00e4lja. itemNotEnough1=\u00a7cDu har inte tillr\u00e4ckligt av den saken f\u00f6r att s\u00e4lja.
itemNotEnough2=\u00a77Om du ville s\u00e4lja alla block av den typen, anv\u00e4nd /sell blocknamn itemNotEnough2=\u00a77Om du ville s\u00e4lja alla block av den typen, anv\u00e4nd /sell blocknamn
itemNotEnough3=\u00a77/sell blocknamn -1 kommer att s\u00e4lja allt av den blocktypen f\u00f6rutom 1 o.s.v. itemNotEnough3=\u00a77/sell blocknamn -1 kommer att s\u00e4lja allt av den blocktypen f\u00f6rutom 1 o.s.v.
@ -218,7 +218,7 @@ moneyTaken={0} \u00e4r taget fr\u00e5n ditt bankkonto.
month=m\u00e5nad month=m\u00e5nad
months=m\u00e5nader months=m\u00e5nader
moreThanZero=M\u00e5ngden m\u00e5ste vara st\u00f6rre \u00e4n 0. moreThanZero=M\u00e5ngden m\u00e5ste vara st\u00f6rre \u00e4n 0.
moveSpeed=\u00a77Satte {0}fart till {1} f\u00F6r {2}. moveSpeed=\u00a77Satte {0}fart till {1} f\u00f6r {2}.
msgFormat=\u00a77[{0}\u00a77 -> {1}\u00a77] \u00a7f{2} msgFormat=\u00a77[{0}\u00a77 -> {1}\u00a77] \u00a7f{2}
muteExempt=\u00a7cDu kan inte tysta den spelaren. muteExempt=\u00a7cDu kan inte tysta den spelaren.
mutedPlayer=Spelaren {0} \u00e4r tystad. mutedPlayer=Spelaren {0} \u00e4r tystad.
@ -373,8 +373,8 @@ timeSet=Tid inst\u00e4lld i alla v\u00e4rldar.
timeSetPermission=\u00a7cDu har inte tillst\u00e5nd att st\u00e4lla in tiden. timeSetPermission=\u00a7cDu har inte tillst\u00e5nd att st\u00e4lla in tiden.
timeWorldCurrent=Den nuvarande tiden i {0} \u00e4r \u00a73{1} timeWorldCurrent=Den nuvarande tiden i {0} \u00e4r \u00a73{1}
timeWorldSet=Tiden \u00e4r nu {0} i: \u00a7c{1} timeWorldSet=Tiden \u00e4r nu {0} i: \u00a7c{1}
totalWorthAll=\u00a7aS\u00E5lde alla objekt f\u00F6r ett totalt v\u00E4rde av {1}. totalWorthAll=\u00a7aS\u00e5lde alla objekt f\u00f6r ett totalt v\u00e4rde av {1}.
totalWorthBlocks=\u00a7aS\u00E5lde alla blocks f\u00F6r ett totalt v\u00E4rde av {1}. totalWorthBlocks=\u00a7aS\u00e5lde alla blocks f\u00f6r ett totalt v\u00e4rde av {1}.
tps=Nuvarande TPS = {0} tps=Nuvarande TPS = {0}
tradeCompleted=\u00a77K\u00f6p avslutat. tradeCompleted=\u00a77K\u00f6p avslutat.
tradeSignEmpty=K\u00f6pskylten har inget tillg\u00e4ngligt f\u00f6r dig. tradeSignEmpty=K\u00f6pskylten har inget tillg\u00e4ngligt f\u00f6r dig.
@ -447,24 +447,24 @@ year=\u00e5r
years=\u00e5r years=\u00e5r
youAreHealed=\u00a77Du har blivit l\u00e4kt. youAreHealed=\u00a77Du har blivit l\u00e4kt.
youHaveNewMail=\u00a7cDu har {0} meddelanden!\u00a7f Skriv \u00a77/mail read\u00a7f f\u00f6r att l\u00e4sa dina meddelanden. youHaveNewMail=\u00a7cDu har {0} meddelanden!\u00a7f Skriv \u00a77/mail read\u00a7f f\u00f6r att l\u00e4sa dina meddelanden.
posX=\u00a76X: {0} (+\u00D6ster <-> -V\u00e4st) posX=\u00a76X: {0} (+\u00d6ster <-> -V\u00e4st)
posY=\u00a76Y: {0} (+Upp <-> -Ner) posY=\u00a76Y: {0} (+Upp <-> -Ner)
posZ=\u00a76Z: {0} (+Syd <-> -Nort) posZ=\u00a76Z: {0} (+Syd <-> -Nort)
posYaw=\u00a76Girning: {0} (Rotation) posYaw=\u00a76Girning: {0} (Rotation)
posPitch=\u00a76Pitch: {0} (Huvudvinkel) posPitch=\u00a76Pitch: {0} (Huvudvinkel)
distance=\u00a76Avst\u00E5nd: {0} distance=\u00a76Avst\u00e5nd: {0}
giveSpawn=\u00a76Ger\u00a7c {0} \u00a76av\u00a7c {1} till\u00a7c {2}\u00a76. giveSpawn=\u00a76Ger\u00a7c {0} \u00a76av\u00a7c {1} till\u00a7c {2}\u00a76.
warpList={0} warpList={0}
uptime=\u00a76Upptid:\u00a7c {0} uptime=\u00a76Upptid:\u00a7c {0}
antiBuildCraft=\u00a74Du har inte till\u00E5telse att skapa\u00a7c {0}\u00a74. antiBuildCraft=\u00a74Du har inte till\u00e5telse att skapa\u00a7c {0}\u00a74.
antiBuildDrop=\u00a74Du har inte till\u00E5telse att kasta ut\u00a7c {0}\u00a74. antiBuildDrop=\u00a74Du har inte till\u00e5telse att kasta ut\u00a7c {0}\u00a74.
gcWorld=\u00a76{0} "\u00a7c{1}\u00a76": \u00a7c{2}\u00a76 bitar, \u00a7c{3}\u00a76 enheter gcWorld=\u00a76{0} "\u00a7c{1}\u00a76": \u00a7c{2}\u00a76 bitar, \u00a7c{3}\u00a76 enheter
invalidHomeName=\u00a74Ogiltigt hemnamn invalidHomeName=\u00a74Ogiltigt hemnamn
invalidWarpName=\u00a74Ogiltigt warpnamn invalidWarpName=\u00a74Ogiltigt warpnamn
userUnknown=\u00a74Varning: Anv\u00E4ndaren '\u00a7c{0}\u00a74' har aldrig varit inne p\u00E5 denna server tidigare. userUnknown=\u00a74Varning: Anv\u00e4ndaren '\u00a7c{0}\u00a74' har aldrig varit inne p\u00e5 denna server tidigare.
teleportationEnabledFor=\u00a76TTeleportering aktiverat f\u00F6r {0} teleportationEnabledFor=\u00a76TTeleportering aktiverat f\u00f6r {0}
teleportationDisabledFor=\u00a76Teleportering inaktiverat f\u00F6r {0} teleportationDisabledFor=\u00a76Teleportering inaktiverat f\u00f6r {0}
kitOnce=\u00a74Du kan inte av\u00E4nda det kitet igen. kitOnce=\u00a74Du kan inte av\u00e4nda det kitet igen.
fullStack=\u00a74Du har redan en full stapel fullStack=\u00a74Du har redan en full stapel
oversizedTempban=\u00a74Du kan inte banna en spelare just vid denna tidpunkt. oversizedTempban=\u00a74Du kan inte banna en spelare just vid denna tidpunkt.
recipeNone=No recipes exist for {0} recipeNone=No recipes exist for {0}
@ -478,3 +478,11 @@ recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2} recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}
recipeWhere=\u00a76Where: {0} recipeWhere=\u00a76Where: {0}
recipeShapeless=\u00a76Combine \u00a7c{0} recipeShapeless=\u00a76Combine \u00a7c{0}
editBookContents=\u00a7eYou may now edit the contents of this book
bookAuthorSet=\u00a76Author of the book set to {0}
bookTitleSet=\u00a76Title of the book set to {0}
denyChangeAuthor=\u00a74You cannot change the author of this book
denyChangeTitle=\u00a74You cannot change the title of this book
denyBookEdit=\u00a74You cannot unlock this book
bookLocked=\u00a7cThis book is now locked
holdBook=\u00a74You are not holding a writable book

View file

@ -39,6 +39,10 @@ commands:
description: Bans an IP address. description: Bans an IP address.
usage: /<command> <address> usage: /<command> <address>
aliases: [ebanip] aliases: [ebanip]
book:
description: Allows reopening written books.
usage: /<command>
aliases: [ebook]
break: break:
description: Breaks the block you are looking at. description: Breaks the block you are looking at.
usage: /<command> usage: /<command>
@ -148,9 +152,9 @@ commands:
usage: /<command> [search term] [page] usage: /<command> [search term] [page]
aliases: [ehelp] aliases: [ehelp]
helpop: helpop:
description: Request help from online operators. description: Message online admins.
usage: /<command> <message> usage: /<command> <message>
aliases: [ehelpop] aliases: [amsg,eamsg,ac,eac,ehelpop]
home: home:
description: Teleport to your home. description: Teleport to your home.
usage: /<command> [player:][name] usage: /<command> [player:][name]

View file

@ -205,4 +205,6 @@ v 2.0:
- Add support for Rcon. - Add support for Rcon.
- Prevent GM commands from being used on CommandBlocks. - Prevent GM commands from being used on CommandBlocks.
- Clear our attachment map upon a manload so we correctly reconfigure a players new permissions. - Clear our attachment map upon a manload so we correctly reconfigure a players new permissions.
- Synchronize the raising of GroupManager events to Bukkit.getServer() (should prevent deadlocks). - Synchronize the raising of GroupManager events to Bukkit.getServer() (should prevent deadlocks).
- Synchronize pushing to Bukkit perms to prevent any ConcurrentModificationException.
- Do not grant any permissions (nor update Bukkit) if the server is in offline mode and the player has the permission node 'groupmanager.noofflineperms'.

View file

@ -112,7 +112,7 @@ public class GMConfiguration {
Object level = ((Map<String, String>) getElement("settings", GMconfig).get("logging")).get("level"); Object level = ((Map<String, String>) getElement("settings", GMconfig).get("logging")).get("level");
if (level instanceof String) if (level instanceof String)
level = (String) level; loggerLevel = (String) level;
/* /*
* Store our mirrors map for parsing later. * Store our mirrors map for parsing later.

View file

@ -152,7 +152,7 @@ public class GroupManager extends JavaPlugin {
ch = new GMLoggerHandler(); ch = new GMLoggerHandler();
GroupManager.logger.addHandler(ch); GroupManager.logger.addHandler(ch);
} }
logger.setLevel(Level.ALL); GroupManager.logger.setLevel(Level.ALL);
// Create the backup folder, if it doesn't exist. // Create the backup folder, if it doesn't exist.
prepareFileFields(); prepareFileFields();

View file

@ -16,6 +16,7 @@ import org.anjocaido.groupmanager.data.Group;
import org.anjocaido.groupmanager.dataholder.WorldDataHolder; import org.anjocaido.groupmanager.dataholder.WorldDataHolder;
import org.anjocaido.groupmanager.data.User; import org.anjocaido.groupmanager.data.User;
import org.anjocaido.groupmanager.utils.PermissionCheckResult; import org.anjocaido.groupmanager.utils.PermissionCheckResult;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
@ -784,6 +785,15 @@ public class AnjoPermissionsHandler extends PermissionsReaderInterface {
if (user == null || targetPermission == null || targetPermission.isEmpty()) { if (user == null || targetPermission == null || targetPermission.isEmpty()) {
return result; return result;
} }
/*
* Do not push any perms to bukkit if...
* We are in offline mode
* and the player has the 'groupmanager.noofflineperms' permission.
*/
if (!Bukkit.getServer().getOnlineMode()
&& (checkFullGMPermission(user, "groupmanager.noofflineperms", true).resultType == PermissionCheckResult.Type.FOUND))
return result;
if (checkBukkit) { if (checkBukkit) {
// Check Bukkit perms to support plugins which add perms via code // Check Bukkit perms to support plugins which add perms via code

View file

@ -31,7 +31,6 @@ import java.util.WeakHashMap;
import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.data.User; import org.anjocaido.groupmanager.data.User;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -137,8 +136,7 @@ public class BukkitPermissions {
/** /**
* Push all permissions which are registered with GM for this player, on * Push all permissions which are registered with GM for this player, on
* this world to Bukkit * this world to Bukkit and make it update for the child nodes.
* and make it update for the child nodes.
* *
* @param player * @param player
* @param world * @param world
@ -148,9 +146,9 @@ public class BukkitPermissions {
if (player == null || !GroupManager.isLoaded()) { if (player == null || !GroupManager.isLoaded()) {
return; return;
} }
String name = player.getName(); String name = player.getName();
// Reset the User objects player reference. // Reset the User objects player reference.
User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(name); User user = plugin.getWorldsHolder().getWorldData(player.getWorld().getName()).getUser(name);
if (user != null) if (user != null)
@ -175,7 +173,8 @@ public class BukkitPermissions {
List<String> playerPermArray = new ArrayList<String>(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(name, false)); List<String> playerPermArray = new ArrayList<String>(plugin.getWorldsHolder().getWorldData(world).getPermissionsHandler().getAllPlayersPermissions(name, false));
LinkedHashMap<String, Boolean> newPerms = new LinkedHashMap<String, Boolean>(); LinkedHashMap<String, Boolean> newPerms = new LinkedHashMap<String, Boolean>();
// Sort the perm list by parent/child, so it will push to superperms correctly. // Sort the perm list by parent/child, so it will push to superperms
// correctly.
playerPermArray = sort(playerPermArray); playerPermArray = sort(playerPermArray);
Boolean value = false; Boolean value = false;
@ -183,28 +182,43 @@ public class BukkitPermissions {
value = (!permission.startsWith("-")); value = (!permission.startsWith("-"));
newPerms.put((value ? permission : permission.substring(1)), value); newPerms.put((value ? permission : permission.substring(1)), value);
} }
/*
* Do not push any perms to bukkit if...
* We are in offline mode
* and the player has the 'groupmanager.noofflineperms' permission.
*/
if (!Bukkit.getServer().getOnlineMode()
&& (newPerms.containsKey("groupmanager.noofflineperms") && (newPerms.get("groupmanager.noofflineperms") == true))) {
removeAttachment(name);
return;
}
/** /**
* This is put in place until such a time as Bukkit pull 466 is * This is put in place until such a time as Bukkit pull 466 is
* implemented * implemented https://github.com/Bukkit/Bukkit/pull/466
* https://github.com/Bukkit/Bukkit/pull/466
*/ */
try { // Codename_B source try { // Codename_B source
@SuppressWarnings("unchecked") synchronized (attachment.getPermissible()) {
Map<String, Boolean> orig = (Map<String, Boolean>) permissions.get(attachment);
// Clear the map (faster than removing the attachment and recalculating) @SuppressWarnings("unchecked")
orig.clear(); Map<String, Boolean> orig = (Map<String, Boolean>) permissions.get(attachment);
// Then whack our map into there // Clear the map (faster than removing the attachment and
orig.putAll(newPerms); // recalculating)
// That's all folks! orig.clear();
attachment.getPermissible().recalculatePermissions(); // Then whack our map into there
//player.recalculatePermissions(); orig.putAll(newPerms);
// That's all folks!
attachment.getPermissible().recalculatePermissions();
}
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
GroupManager.logger.finest("Attachment updated for: " + name); GroupManager.logger.finest("Attachment updated for: " + name);
} }

View file

@ -3,13 +3,16 @@ users:
snowleo: snowleo:
group: Builder group: Builder
subgroups: [] subgroups: []
permissions: [] permissions:
- groupmanager.noofflineperms
KHobbits: KHobbits:
group: Moderator group: Moderator
subgroups: [] subgroups: []
permissions: [] permissions:
- groupmanager.noofflineperms
ElgarL: ElgarL:
group: Moderator group: Moderator
subgroups: [] subgroups: []
permissions: [] permissions:
- groupmanager.noofflineperms