diff --git a/Essentials/nbproject/project.properties b/Essentials/nbproject/project.properties index a9cebbb92..40b0ae9b6 100644 --- a/Essentials/nbproject/project.properties +++ b/Essentials/nbproject/project.properties @@ -68,7 +68,6 @@ file.reference.BOSEconomy7.jar=../lib/BOSEconomy7.jar file.reference.bPermissions.jar=../lib/bPermissions.jar file.reference.bpermissions2.jar=../lib/bpermissions2.jar file.reference.bukkit.jar=../lib/bukkit.jar -file.reference.craftbukkit.jar=../lib/craftbukkit.jar file.reference.iCo4.jar=../lib/iCo4.jar file.reference.iCo5.jar=../lib/iCo5.jar file.reference.iCo6.jar=../lib/iCo6.jar @@ -96,12 +95,11 @@ javac.classpath=\ ${file.reference.lombok.jar}:\ ${reference.EssentialsGroupManager.jar}:\ ${file.reference.bukkit.jar}:\ - ${file.reference.craftbukkit.jar}:\ ${file.reference.Vault.jar}:\ ${file.reference.Privileges.jar}:\ ${file.reference.bpermissions2.jar} # Space-separated list of extra javac options -javac.compilerargs= +javac.compilerargs=-Xlint:unchecked javac.deprecation=false javac.processorpath=\ ${javac.classpath} diff --git a/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java b/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java index e75644ad5..e9cb6fe19 100644 --- a/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java +++ b/Essentials/src/com/earth2me/essentials/AlternativeCommandsHandler.java @@ -121,13 +121,14 @@ public class AlternativeCommandsHandler return commands.get(0); } - public void executed(final String label, final String otherLabel) + public void executed(final String label, final PluginCommand pc) { + final String altString = pc.getPlugin().getName() + ":" + pc.getLabel(); if (ess.getSettings().isDebug()) { - LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + otherLabel); + LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString); } - disabledList.put(label, otherLabel); + disabledList.put(label, altString); } public Map disabledCommands() diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index 9ba2c696a..49c09fe90 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -65,7 +65,7 @@ import org.yaml.snakeyaml.error.YAMLException; public class Essentials extends JavaPlugin implements IEssentials { - public static final int BUKKIT_VERSION = 2455; + public static final int BUKKIT_VERSION = 2543; private static final Logger LOGGER = Logger.getLogger("Minecraft"); private transient ISettings settings; private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this); @@ -308,7 +308,7 @@ public class Essentials extends JavaPlugin implements IEssentials final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel); if (pc != null) { - alternativeCommandsHandler.executed(commandLabel, pc.getLabel()); + alternativeCommandsHandler.executed(commandLabel, pc); try { return pc.execute(sender, commandLabel, args); @@ -368,6 +368,19 @@ public class Essentials extends JavaPlugin implements IEssentials return true; } + if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) + { + if (user.getJailTimeout() > 0) + { + user.sendMessage(_("playerJailedFor", user.getName(), Util.formatDateDiff(user.getJailTimeout()))); + } + else + { + user.sendMessage(_("jailMessage")); + } + return true; + } + // Run the command try { @@ -471,7 +484,7 @@ public class Essentials extends JavaPlugin implements IEssentials } return null; } - + @Override public User getOfflineUser(final String name) { diff --git a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java index d182c5656..f617ff85b 100644 --- a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java @@ -60,6 +60,12 @@ public class EssentialsPlayerListener implements Listener user.sendMessage(_("playerMuted")); LOGGER.info(_("mutedUserSpeaks", user.getName())); } + if(ess.getSettings().isChatPermEnabled() && !user.isAuthorized("essentials.chat.allowed")) + { + event.setCancelled(true); + user.sendMessage(_("playerChatDenied")); + LOGGER.info(_("mutedUserSpeaks", user.getName())); + } final Iterator it = event.getRecipients().iterator(); while (it.hasNext()) { @@ -335,14 +341,13 @@ public class EssentialsPlayerListener implements Listener }); } } - private final static List COMMANDS = Arrays.asList("msg", "r", "mail", "m", "t", "whisper", "emsg", "tell", "er", "reply", "ereply", "email", "action", "describe", "eme", "eaction", "edescribe", "etell", "ewhisper", "pm"); @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { final Player player = event.getPlayer(); final String cmd = event.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); - if (COMMANDS.contains(cmd)) + if (ess.getSettings().getSocialSpyCommands().contains(cmd)) { for (Player onlinePlayer : ess.getServer().getOnlinePlayers()) { @@ -417,6 +422,7 @@ public class EssentialsPlayerListener implements Listener if (event.getItem() != null && event.getItem().getTypeId() != AIR) { final User user = ess.getUser(event.getPlayer()); + user.updateActivity(true); if (user.hasPowerTools() && user.arePowerToolsEnabled() && usePowertools(user, event.getItem().getTypeId())) { event.setCancelled(true); @@ -537,6 +543,14 @@ public class EssentialsPlayerListener implements Listener event.setCancelled(true); } } + else if (event.getView().getTopInventory().getType() == InventoryType.WORKBENCH) + { + User user = ess.getUser(event.getWhoClicked()); + if (user.isRecipeSee()) + { + event.setCancelled(true); + } + } } @EventHandler(priority = EventPriority.MONITOR) @@ -552,12 +566,21 @@ public class EssentialsPlayerListener implements Listener final User user = ess.getUser(event.getPlayer()); user.setEnderSee(false); } + if (event.getView().getTopInventory().getType() == InventoryType.WORKBENCH) + { + final User user = ess.getUser(event.getPlayer()); + if(user.isRecipeSee()) + { + user.setRecipeSee(false); + event.getView().getTopInventory().clear(); + } + } } - + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onPlayerFishEvent(final PlayerFishEvent event) { final User user = ess.getUser(event.getPlayer()); user.updateActivity(true); } -} \ No newline at end of file +} diff --git a/Essentials/src/com/earth2me/essentials/ISettings.java b/Essentials/src/com/earth2me/essentials/ISettings.java index fb0073c8a..eb2af8554 100644 --- a/Essentials/src/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/com/earth2me/essentials/ISettings.java @@ -42,6 +42,8 @@ public interface ISettings extends IConf double getHealCooldown(); + Set getSocialSpyCommands(); + Map getKit(String name); ConfigurationSection getKits(); @@ -183,4 +185,8 @@ public interface ISettings extends IConf public int getMailsPerMinute(); public void setEssentialsChatActive(boolean b); + + long getMaxTempban(); + + boolean isChatPermEnabled(); } diff --git a/Essentials/src/com/earth2me/essentials/IUser.java b/Essentials/src/com/earth2me/essentials/IUser.java index 43f9d7210..1b5f314be 100644 --- a/Essentials/src/com/earth2me/essentials/IUser.java +++ b/Essentials/src/com/earth2me/essentials/IUser.java @@ -44,4 +44,8 @@ public interface IUser extends Player void setJail(String jail); boolean isIgnoreExempt(); + + boolean isAfk(); + + void setAfk(final boolean set); } diff --git a/Essentials/src/com/earth2me/essentials/Kit.java b/Essentials/src/com/earth2me/essentials/Kit.java index 89965e589..fcd1b4932 100644 --- a/Essentials/src/com/earth2me/essentials/Kit.java +++ b/Essentials/src/com/earth2me/essentials/Kit.java @@ -158,11 +158,11 @@ public class Kit final Map overfilled; if (user.isAuthorized("essentials.oversizedstacks")) { - overfilled = InventoryWorkaround.addItem(user.getInventory(), true, ess.getSettings().getOversizedStackSize(), stack); + overfilled = InventoryWorkaround.addOversizedItems(user.getInventory(), ess.getSettings().getOversizedStackSize(), stack); } else { - overfilled = InventoryWorkaround.addItem(user.getInventory(), true, 0, stack); + overfilled = InventoryWorkaround.addItems(user.getInventory(), stack); } for (ItemStack itemStack : overfilled.values()) { diff --git a/Essentials/src/com/earth2me/essentials/OfflinePlayer.java b/Essentials/src/com/earth2me/essentials/OfflinePlayer.java index 571873384..a47b32582 100644 --- a/Essentials/src/com/earth2me/essentials/OfflinePlayer.java +++ b/Essentials/src/com/earth2me/essentials/OfflinePlayer.java @@ -11,11 +11,8 @@ import org.bukkit.conversations.ConversationAbandonedEvent; import org.bukkit.entity.*; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.*; import org.bukkit.inventory.InventoryView.Property; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; import org.bukkit.map.MapView; import org.bukkit.metadata.MetadataValue; import org.bukkit.permissions.Permission; @@ -1117,4 +1114,40 @@ public class OfflinePlayer implements Player { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public boolean getRemoveWhenFarAway() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setRemoveWhenFarAway(boolean bln) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public EntityEquipment getEquipment() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setCanPickupItems(boolean bln) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getCanPickupItems() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Location getLocation(Location lctn) + { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java index b178f4c8e..4138ae835 100644 --- a/Essentials/src/com/earth2me/essentials/Settings.java +++ b/Essentials/src/com/earth2me/essentials/Settings.java @@ -12,6 +12,7 @@ import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import org.bukkit.ChatColor; +import org.bukkit.command.PluginCommand; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemoryConfiguration; import org.bukkit.event.EventPriority; @@ -189,6 +190,11 @@ public class Settings implements ISettings final ConfigurationSection newSection = new MemoryConfiguration(); for (String command : section.getKeys(false)) { + PluginCommand cmd = ess.getServer().getPluginCommand(command); + if (command.charAt(0) == '/') + { + ess.getLogger().warning("Invalid command cost. '" + command + "' should not start with '/'."); + } if (section.isDouble(command)) { newSection.set(command.toLowerCase(Locale.ENGLISH), section.getDouble(command)); @@ -197,6 +203,24 @@ public class Settings implements ISettings { newSection.set(command.toLowerCase(Locale.ENGLISH), (double)section.getInt(command)); } + else if (section.isString(command)) + { + String costString = section.getString(command); + try + { + double cost = Double.parseDouble(costString.trim().replace(getCurrencySymbol(), "").replaceAll("\\W", "")); + newSection.set(command.toLowerCase(Locale.ENGLISH), cost); + } + catch (NumberFormatException ex) + { + ess.getLogger().warning("Invalid command cost for: " + command + " (" + costString + ")"); + } + + } + else + { + ess.getLogger().warning("Invalid command cost for: " + command); + } } return newSection; } @@ -213,6 +237,31 @@ public class Settings implements ISettings } return 0.0; } + private Set socialSpyCommands = new HashSet(); + + public Set _getSocialSpyCommands() + { + Set socialspyCommands = new HashSet(); + + if (config.isConfigurationSection("socialspy-commands")) + { + for (String c : config.getStringList("socialspy-commands")) + { + socialspyCommands.add(c.toLowerCase(Locale.ENGLISH)); + } + } + else + { + socialspyCommands.addAll(Arrays.asList("msg", "r", "mail", "m", "whisper", "emsg", "t", "tell", "er", "reply", "ereply", "email", "action", "describe", "eme", "eaction", "edescribe", "etell", "ewhisper", "pm")); + } + + return socialspyCommands; + } + + public Set getSocialSpyCommands() + { + return socialSpyCommands; + } private String nicknamePrefix = "~"; private String _getNicknamePrefix() @@ -438,6 +487,7 @@ public class Settings implements ISettings disableSuffix = _disableSuffix(); chatRadius = _getChatRadius(); commandCosts = _getCommandCosts(); + socialSpyCommands = _getSocialSpyCommands(); warnOnBuildDisallow = _warnOnBuildDisallow(); mailsPerMinute = _getMailsPerMinute(); } @@ -946,15 +996,28 @@ public class Settings implements ISettings double maxSpeed = config.getDouble("max-walk-speed", 0.8); return maxSpeed > 1.0 ? 1.0 : Math.abs(maxSpeed); } - private int mailsPerMinute; - private int _getMailsPerMinute() { + private int _getMailsPerMinute() + { return config.getInt("mails-per-minute", 1000); } + @Override public int getMailsPerMinute() { return mailsPerMinute; } + + @Override + public long getMaxTempban() + { + return config.getLong("max-tempban-time", -1); + } + + @Override + public boolean isChatPermEnabled() + { + return config.getBoolean("enable-chat-perm", false); + } } diff --git a/Essentials/src/com/earth2me/essentials/SpawnMob.java b/Essentials/src/com/earth2me/essentials/SpawnMob.java index 8ea5c9492..7eb59974c 100644 --- a/Essentials/src/com/earth2me/essentials/SpawnMob.java +++ b/Essentials/src/com/earth2me/essentials/SpawnMob.java @@ -12,6 +12,7 @@ import org.bukkit.Server; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.*; +import org.bukkit.entity.Skeleton.SkeletonType; import org.bukkit.material.Colorable; @@ -34,20 +35,20 @@ public class SpawnMob } return Util.joinList(availableList); } - - public static String[] mobData(final String mobString) + + public static String[] mobData(final String mobString) { String[] returnString = new String[4]; - + final String[] parts = mobString.split(","); String[] mobParts = parts[0].split(":"); - + returnString[0] = mobParts[0]; if (mobParts.length == 2) { returnString[1] = mobParts[1]; } - + if (parts.length > 1) { String[] mountParts = parts[1].split(":"); @@ -57,8 +58,8 @@ public class SpawnMob returnString[3] = mountParts[1]; } } - - return returnString; + + return returnString; } // This method spawns a mob where the user is looking, owned by user @@ -71,7 +72,7 @@ public class SpawnMob } spawnmob(ess, server, user, user, block.getLocation(), Data, mobCount); } - + // This method spawns a mob at loc, owned by noone public static void spawnmob(final IEssentials ess, final Server server, final CommandSender sender, final Location loc, final String[] Data, int mobCount) throws Exception { @@ -83,7 +84,7 @@ public class SpawnMob { spawnmob(ess, server, sender, target, target.getLocation(), Data, mobCount); } - + // This method spawns a mob at loc, owned by target public static void spawnmob(final IEssentials ess, final Server server, final CommandSender sender, final User target, final Location loc, final String[] Data, int mobCount) throws Exception { @@ -91,7 +92,7 @@ public class SpawnMob final String mobType = Data[0]; final String mobData = Data[1]; final String mountType = Data[2]; - final String mountData = Data[3]; + final String mountData = Data[3]; Mob mob = Mob.fromName(mobType); Mob mobMount = null; @@ -137,7 +138,7 @@ public class SpawnMob { Entity spawnedMob = mob.spawn(sloc.getWorld(), server, sloc); Entity spawnedMount = null; - + if (mobMount != null) { spawnedMount = mobMount.spawn(sloc.getWorld(), server, sloc); @@ -186,14 +187,16 @@ public class SpawnMob throw new Exception(_("slimeMalformedSize"), e); } } - if (spawned instanceof Ageable && data.contains("baby")) + + if ((spawned instanceof Ageable) && data.contains("baby")) { ((Ageable)spawned).setBaby(); - return; + data = data.replace("baby", ""); } + if (spawned instanceof Colorable) { - final String color = data.toUpperCase(Locale.ENGLISH).replace("BABY", ""); + final String color = data.toUpperCase(Locale.ENGLISH); try { if (color.equals("RANDOM")) @@ -201,7 +204,7 @@ public class SpawnMob final Random rand = new Random(); ((Colorable)spawned).setColor(DyeColor.values()[rand.nextInt(DyeColor.values().length)]); } - else + else if (color.length() > 1) { ((Colorable)spawned).setColor(DyeColor.valueOf(color)); } @@ -211,21 +214,28 @@ public class SpawnMob throw new Exception(_("sheepMalformedColor"), e); } } + if (spawned instanceof Tameable && data.contains("tamed") && target != null) { final Tameable tameable = ((Tameable)spawned); tameable.setTamed(true); tameable.setOwner(target.getBase()); + data = data.replace("tamed", ""); } - if (type == EntityType.WOLF - && data.contains("angry")) + + if (type == EntityType.WOLF) { - ((Wolf)spawned).setAngry(true); + if (data.contains("angry")) + { + ((Wolf)spawned).setAngry(true); + } } + if (type == EntityType.CREEPER && data.contains("powered")) { ((Creeper)spawned).setPowered(true); } + if (type == EntityType.OCELOT) { if (data.contains("siamese")) @@ -241,6 +251,7 @@ public class SpawnMob ((Ocelot)spawned).setCatType(Ocelot.Type.BLACK_CAT); } } + if (type == EntityType.VILLAGER) { for (Villager.Profession prof : Villager.Profession.values()) @@ -251,5 +262,26 @@ public class SpawnMob } } } + + if (spawned instanceof Zombie) + { + if (data.contains("villager")) + { + ((Zombie)spawned).setVillager(true); + } + if (data.contains("baby")) + { + ((Zombie)spawned).setBaby(true); + } + } + + if (type == EntityType.SKELETON) + { + if (data.contains("wither")) + { + ((Skeleton)spawned).setSkeletonType(SkeletonType.WITHER); + } + } + } } diff --git a/Essentials/src/com/earth2me/essentials/Teleport.java b/Essentials/src/com/earth2me/essentials/Teleport.java index 5eba636d5..241a8328d 100644 --- a/Essentials/src/com/earth2me/essentials/Teleport.java +++ b/Essentials/src/com/earth2me/essentials/Teleport.java @@ -2,10 +2,12 @@ package com.earth2me.essentials; import static com.earth2me.essentials.I18n._; import com.earth2me.essentials.api.ITeleport; +import com.earth2me.essentials.commands.NoChargeException; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.logging.Logger; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -56,6 +58,7 @@ public class Teleport implements Runnable, ITeleport private long initY; private long initZ; private Target teleportTarget; + private boolean respawn; private Trade chargeFor; private final IEssentials ess; private static final Logger logger = Logger.getLogger("Minecraft"); @@ -63,10 +66,10 @@ public class Teleport implements Runnable, ITeleport private void initTimer(long delay, Target target, Trade chargeFor, TeleportCause cause) { - initTimer(delay, user, target, chargeFor, cause); + initTimer(delay, user, target, chargeFor, cause, false); } - private void initTimer(long delay, IUser teleportUser, Target target, Trade chargeFor, TeleportCause cause) + private void initTimer(long delay, IUser teleportUser, Target target, Trade chargeFor, TeleportCause cause, boolean respawn) { this.started = System.currentTimeMillis(); this.tpdelay = delay; @@ -78,6 +81,7 @@ public class Teleport implements Runnable, ITeleport this.teleportTarget = target; this.chargeFor = chargeFor; this.cause = cause; + this.respawn = respawn; } @Override @@ -115,8 +119,12 @@ public class Teleport implements Runnable, ITeleport teleportUser.sendMessage(_("teleportationCommencing")); try { - - teleportUser.getTeleport().now(teleportTarget, cause); + if (respawn) { + teleportUser.getTeleport().respawn(cause); + } + else { + teleportUser.getTeleport().now(teleportTarget, cause); + } cancel(false); if (chargeFor != null) { @@ -241,7 +249,7 @@ public class Teleport implements Runnable, ITeleport { teleport(loc, chargeFor, TeleportCause.PLUGIN); } - + public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception { teleport(new Target(loc), chargeFor, cause); @@ -283,7 +291,6 @@ public class Teleport implements Runnable, ITeleport public void teleportToMe(User otherUser, Trade chargeFor, TeleportCause cause) throws Exception { Target target = new Target(user); - double delay = ess.getSettings().getTeleportDelay(); if (chargeFor != null) @@ -304,8 +311,7 @@ public class Teleport implements Runnable, ITeleport cancel(false); warnUser(otherUser, delay); - initTimer((long)(delay * 1000.0), otherUser, target, chargeFor, cause); - + initTimer((long)(delay * 1000.0), otherUser, target, chargeFor, cause, false); teleTimer = ess.scheduleSyncRepeatingTask(this, 10, 10); } @@ -319,12 +325,43 @@ public class Teleport implements Runnable, ITeleport //The respawn function is a wrapper used to handle tp fallback, on /jail and /home public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception + { + double delay = ess.getSettings().getTeleportDelay(); + if (chargeFor != null) + { + chargeFor.isAffordableFor(user); + } + cooldown(true); + if (delay <= 0 || user.isAuthorized("essentials.teleport.timer.bypass")) + { + cooldown(false); + respawn(cause); + if (chargeFor != null) + { + chargeFor.charge(user); + } + return; + } + + cancel(false); + initTimer((long)(delay * 1000.0), user, null, chargeFor, cause, true); + teleTimer = ess.scheduleSyncRepeatingTask(this, 10, 10); + } + + public void respawn(TeleportCause cause) throws Exception { final Player player = user.getBase(); - final Location bed = player.getBedSpawnLocation(); - final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, bed == null ? player.getWorld().getSpawnLocation() : bed, bed != null); - ess.getServer().getPluginManager().callEvent(pre); - teleport(new Target(pre.getRespawnLocation()), chargeFor, cause); + Location bed = player.getBedSpawnLocation(); + if (bed != null && bed.getBlock().getType() != Material.BED_BLOCK) + { + now(new Target(bed), cause); + } + else + { + final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false); + ess.getServer().getPluginManager().callEvent(pre); + now(new Target(pre.getRespawnLocation()), cause); + } } //The warp function is a wrapper used to teleport a player to a /warp @@ -332,7 +369,7 @@ public class Teleport implements Runnable, ITeleport { Location loc = ess.getWarps().getWarp(warp); user.sendMessage(_("warpingTo", warp)); - teleport(new Target(loc), chargeFor, cause); + teleport(new Target(loc), chargeFor, cause); } //The back function is a wrapper used to teleport a player /back to their previous location. diff --git a/Essentials/src/com/earth2me/essentials/Trade.java b/Essentials/src/com/earth2me/essentials/Trade.java index 420525e63..1a03a0145 100644 --- a/Essentials/src/com/earth2me/essentials/Trade.java +++ b/Essentials/src/com/earth2me/essentials/Trade.java @@ -77,7 +77,7 @@ public class Trade } if (getItemStack() != null - && !InventoryWorkaround.containsItem(user.getInventory(), true, true, itemStack)) + && !user.getInventory().containsAtLeast(itemStack, itemStack.getAmount())) { throw new ChargeException(_("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))); } @@ -113,7 +113,7 @@ public class Trade { if (dropItems) { - final Map leftOver = InventoryWorkaround.addItem(user.getInventory(), true, getItemStack()); + final Map leftOver = InventoryWorkaround.addItems(user.getInventory(), getItemStack()); final Location loc = user.getLocation(); for (ItemStack itemStack : leftOver.values()) { @@ -137,7 +137,7 @@ public class Trade } else { - success = InventoryWorkaround.addAllItems(user.getInventory(), true, getItemStack()); + success = InventoryWorkaround.addAllItems(user.getInventory(), getItemStack()); } user.updateInventory(); } @@ -165,11 +165,11 @@ public class Trade } if (getItemStack() != null) { - if (!InventoryWorkaround.containsItem(user.getInventory(), true, true, itemStack)) + if (!user.getInventory().containsAtLeast(itemStack, itemStack.getAmount())) { throw new ChargeException(_("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))); } - InventoryWorkaround.removeItem(user.getInventory(), true, true, getItemStack()); + user.getInventory().removeItem(getItemStack()); user.updateInventory(); } if (command != null) diff --git a/Essentials/src/com/earth2me/essentials/User.java b/Essentials/src/com/earth2me/essentials/User.java index 5de4b7609..bb1e290f4 100644 --- a/Essentials/src/com/earth2me/essentials/User.java +++ b/Essentials/src/com/earth2me/essentials/User.java @@ -29,6 +29,7 @@ public class User extends UserData implements Comparable, IReplyTo, IUser private boolean rightClickJump = false; private transient Location afkPosition = null; private boolean invSee = false; + private boolean recipeSee = false; private boolean enderSee = false; private static final Logger logger = Logger.getLogger("Minecraft"); @@ -79,11 +80,6 @@ public class User extends UserData implements Comparable, IReplyTo, IUser return false; } - if (isJailed()) - { - return false; - } - try { return ess.getPermissionsHandler().hasPermission(base, node); @@ -743,4 +739,14 @@ public class User extends UserData implements Comparable, IReplyTo, IUser { return this.isAuthorized("essentials.chat.ignoreexempt"); } + + public boolean isRecipeSee() + { + return recipeSee; + } + + public void setRecipeSee(boolean recipeSee) + { + this.recipeSee = recipeSee; + } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandgive.java b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java index c5c1a0b6b..c4e26d9a8 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandgive.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandgive.java @@ -94,11 +94,11 @@ public class Commandgive extends EssentialsCommand sender.sendMessage(_("giveSpawn", stack.getAmount(), itemName, giveTo.getDisplayName())); if (giveTo.isAuthorized("essentials.oversizedstacks")) { - InventoryWorkaround.addItem(giveTo.getInventory(), true, ess.getSettings().getOversizedStackSize(), stack); + InventoryWorkaround.addOversizedItems(giveTo.getInventory(), ess.getSettings().getOversizedStackSize(), stack); } else { - InventoryWorkaround.addItem(giveTo.getInventory(), true, stack); + InventoryWorkaround.addItems(giveTo.getInventory(), stack); } giveTo.updateInventory(); } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhat.java b/Essentials/src/com/earth2me/essentials/commands/Commandhat.java index 5dd0fbb74..7ab9a446c 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandhat.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhat.java @@ -31,7 +31,7 @@ public class Commandhat extends EssentialsCommand { final ItemStack air = new ItemStack(Material.AIR); inv.setHelmet(air); - InventoryWorkaround.addItem(user.getInventory(), true, head); + InventoryWorkaround.addItems(user.getInventory(), head); user.sendMessage(_("hatRemoved")); } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhome.java b/Essentials/src/com/earth2me/essentials/commands/Commandhome.java index de6e1ea9b..293dbfb6d 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandhome.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhome.java @@ -65,13 +65,7 @@ public class Commandhome extends EssentialsCommand final List homes = player.getHomes(); if (homes.isEmpty() && player.equals(user)) { - if (bed != null) - { - user.getTeleport().teleport(bed, charge, TeleportCause.COMMAND); - throw new NoChargeException(); - } user.getTeleport().respawn(charge, TeleportCause.COMMAND); - } else if (homes.isEmpty()) { diff --git a/Essentials/src/com/earth2me/essentials/commands/Commanditem.java b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java index 1a77d772d..d14b04d2a 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commanditem.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commanditem.java @@ -87,11 +87,11 @@ public class Commanditem extends EssentialsCommand user.sendMessage(_("itemSpawn", stack.getAmount(), displayName)); if (user.isAuthorized("essentials.oversizedstacks")) { - InventoryWorkaround.addItem(user.getInventory(), true, ess.getSettings().getOversizedStackSize(), stack); + InventoryWorkaround.addOversizedItems(user.getInventory(), ess.getSettings().getOversizedStackSize(), stack); } else { - InventoryWorkaround.addItem(user.getInventory(), true, stack); + InventoryWorkaround.addItems(user.getInventory(), stack); } user.updateInventory(); } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandmore.java b/Essentials/src/com/earth2me/essentials/commands/Commandmore.java index 3fce3110c..e50e21e45 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandmore.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandmore.java @@ -25,7 +25,7 @@ public class Commandmore extends EssentialsCommand if (stack.getAmount() >= ((user.isAuthorized("essentials.oversizedstacks")) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) { - throw new NoChargeException(); + throw new Exception(_("fullStack")); } final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""); if (ess.getSettings().permissionBasedItemSpawn() diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/com/earth2me/essentials/commands/Commandrecipe.java new file mode 100755 index 000000000..e5c69a88b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/commands/Commandrecipe.java @@ -0,0 +1,189 @@ +package com.earth2me.essentials.commands; + +import static com.earth2me.essentials.I18n._; +import com.earth2me.essentials.User; +import com.earth2me.essentials.Util; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.inventory.ShapelessRecipe; + + +public class Commandrecipe extends EssentialsCommand +{ + public Commandrecipe() + { + super("recipe"); + } + + @Override + public void run(final Server server, final CommandSender sender, final String commandLabel, final String[] args) throws Exception + { + if (args.length < 1) + { + throw new NotEnoughArgumentsException(); + } + + final ItemStack itemType = ess.getItemDb().get(args[0]); + int recipeNo = 0; + + if (args.length > 1) + { + if (Util.isInt(args[1])) + { + recipeNo = Integer.parseInt(args[1]) - 1; + } + else + { + throw new Exception(_("invalidNumber")); + } + } + + final List recipesOfType = ess.getServer().getRecipesFor(itemType); + if (recipesOfType.size() < 1) + { + throw new Exception(_("recipeNone", getMaterialName(itemType))); + } + + if (recipeNo < 0 || recipeNo >= recipesOfType.size()) + { + throw new Exception(_("recipeBadIndex")); + } + + final Recipe selectedRecipe = recipesOfType.get(recipeNo); + sender.sendMessage(_("recipe", getMaterialName(itemType), recipeNo + 1, recipesOfType.size())); + + if (selectedRecipe instanceof FurnaceRecipe) + { + furnaceRecipe(sender, (FurnaceRecipe)selectedRecipe); + } + else if (selectedRecipe instanceof ShapedRecipe) + { + shapedRecipe(sender, (ShapedRecipe)selectedRecipe); + } + else if (selectedRecipe instanceof ShapelessRecipe) + { + shapelessRecipe(sender, (ShapelessRecipe)selectedRecipe); + } + + if (recipesOfType.size() > 1 && args.length == 1) + { + sender.sendMessage(_("recipeMore", commandLabel, args[0], getMaterialName(itemType))); + } + } + + public void furnaceRecipe(final CommandSender sender, final FurnaceRecipe recipe) + { + sender.sendMessage(_("recipeFurnace", getMaterialName(recipe.getInput()))); + } + + public void shapedRecipe(final CommandSender sender, final ShapedRecipe recipe) + { + final Map recipeMap = recipe.getIngredientMap(); + + if (sender instanceof Player) + { + final User user = ess.getUser(sender); + user.setRecipeSee(true); + final InventoryView view = user.openWorkbench(null, true); + final String shapeMap = recipe.getShape().length == 2 ? " abecdfghi" : " abcdefghi"; + for (Entry e : ((ShapedRecipe)recipe).getIngredientMap().entrySet()) + { + e.getValue().setAmount(0); + view.setItem(shapeMap.indexOf(e.getKey()), e.getValue()); + } + + } + else + { + final HashMap colorMap = new HashMap(); + int i = 1; + for (Character c : "abcdefghi".toCharArray()) + { + ItemStack item = recipeMap.get(c); + if (!colorMap.containsKey(item == null ? null : item.getType())) + { + colorMap.put(item == null ? null : item.getType(), String.valueOf(i++)); + } + } + final Material[][] materials = new Material[3][3]; + for (int j = 0; j < recipe.getShape().length; j++) + { + for (int k = 0; k < recipe.getShape()[j].length(); k++) + { + ItemStack item = recipe.getIngredientMap().get(recipe.getShape()[j].toCharArray()[k]); + materials[j][k] = item == null ? null : item.getType(); + } + } + sender.sendMessage(_("recipeGrid", colorMap.get(materials[0][0]), colorMap.get(materials[0][1]), colorMap.get(materials[0][2]))); + sender.sendMessage(_("recipeGrid", colorMap.get(materials[1][0]), colorMap.get(materials[1][1]), colorMap.get(materials[1][2]))); + sender.sendMessage(_("recipeGrid", colorMap.get(materials[2][0]), colorMap.get(materials[2][1]), colorMap.get(materials[2][2]))); + + StringBuilder s = new StringBuilder(); + for (Material items : colorMap.keySet().toArray(new Material[colorMap.size()])) + { + s.append(_("recipeGridItem", colorMap.get(items), getMaterialName(items))); + } + sender.sendMessage(_("recipeWhere", s.toString())); + } + } + + public void shapelessRecipe(final CommandSender sender, final ShapelessRecipe recipe) + { + final List ingredients = recipe.getIngredientList(); + if (sender instanceof Player) + { + final User user = ess.getUser(sender); + user.setRecipeSee(true); + final InventoryView view = user.openWorkbench(null, true); + for (int i = 0; i < ingredients.size(); i++) + { + view.setItem(i + 1, ingredients.get(i)); + } + + } + else + { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < ingredients.size(); i++) + { + s.append(getMaterialName(ingredients.get(i))); + if (i != ingredients.size() - 1) + { + s.append(","); + } + s.append(" "); + } + sender.sendMessage(_("recipeShapeless", s.toString())); + } + } + + public String getMaterialName(final ItemStack stack) + { + if (stack == null) + { + return _("recipeNothing"); + } + return getMaterialName(stack.getType()); + } + + public String getMaterialName(final Material type) + { + if (type == null) + { + return _("recipeNothing"); + } + return type.toString().replace("_", " ").toLowerCase(Locale.ENGLISH); + } +} \ No newline at end of file diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandseen.java b/Essentials/src/com/earth2me/essentials/commands/Commandseen.java index 24f1f9c41..b415108e2 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandseen.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandseen.java @@ -35,12 +35,28 @@ public class Commandseen extends EssentialsCommand } try { - User player = getPlayer(server, args, 0); - player.setDisplayNick(); - sender.sendMessage(_("seenOnline", player.getDisplayName(), Util.formatDateDiff(player.getLastLogin()))); + User user = getPlayer(server, args, 0); + user.setDisplayNick(); + sender.sendMessage(_("seenOnline", user.getDisplayName(), Util.formatDateDiff(user.getLastLogin()))); + if (user.isAfk()) + { + sender.sendMessage(_("whoisAFK", _("true"))); + } + if (user.isJailed()) + { + sender.sendMessage(_("whoisJail", (user.getJailTimeout() > 0 + ? Util.formatDateDiff(user.getJailTimeout()) + : _("true")))); + } + if (user.isMuted()) + { + sender.sendMessage(_("whoisMuted", (user.getMuteTimeout() > 0 + ? Util.formatDateDiff(user.getMuteTimeout()) + : _("true")))); + } if (extra) { - sender.sendMessage(_("whoisIPAddress", player.getAddress().getAddress().toString())); + sender.sendMessage(_("whoisIPAddress", user.getAddress().getAddress().toString())); } } catch (NoSuchFieldException e) @@ -60,7 +76,8 @@ public class Commandseen extends EssentialsCommand { sender.sendMessage(_("whoisIPAddress", player.getLastLoginAddress())); final Location loc = player.getLastLocation(); - if (loc != null) { + if (loc != null) + { sender.sendMessage(_("whoisLocation", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandsell.java b/Essentials/src/com/earth2me/essentials/commands/Commandsell.java index 566d1b42e..ec3262958 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandsell.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandsell.java @@ -22,6 +22,8 @@ public class Commandsell extends EssentialsCommand @Override public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception { + double totalWorth = 0.0; + String type = ""; if (args.length < 1) { throw new NotEnoughArgumentsException(); @@ -41,12 +43,16 @@ public class Commandsell extends EssentialsCommand } try { - sellItem(user, stack, args, true); + totalWorth += sellItem(user, stack, args, true); } catch (Exception e) { } } + if (totalWorth > 0) + { + user.sendMessage(_("totalWorthAll", type, Util.displayCurrency(totalWorth, ess))); + } return; } else if (args[0].equalsIgnoreCase("blocks")) @@ -59,12 +65,16 @@ public class Commandsell extends EssentialsCommand } try { - sellItem(user, stack, args, true); + totalWorth += sellItem(user, stack, args, true); } catch (Exception e) { } } + if (totalWorth > 0) + { + user.sendMessage(_("totalWorthBlocks", type, Util.displayCurrency(totalWorth, ess))); + } return; } if (is == null) @@ -74,7 +84,7 @@ public class Commandsell extends EssentialsCommand sellItem(user, is, args, false); } - private void sellItem(User user, ItemStack is, String[] args, boolean isBulkSell) throws Exception + private double sellItem(User user, ItemStack is, String[] args, boolean isBulkSell) throws Exception { if (is == null || is.getType() == Material.AIR) { @@ -149,19 +159,19 @@ public class Commandsell extends EssentialsCommand } else { - return; + return worth * amount; } } //TODO: Prices for Enchantments final ItemStack ris = is.clone(); ris.setAmount(amount); - InventoryWorkaround.removeItem(user.getInventory(), true, true, ris); + user.getInventory().removeItem(ris); user.updateInventory(); Trade.log("Command", "Sell", "Item", user.getName(), new Trade(ris, ess), user.getName(), new Trade(worth * amount, ess), user.getLocation(), ess); user.giveMoney(worth * amount); user.sendMessage(_("itemSold", Util.displayCurrency(worth * amount, ess), amount, is.getType().toString().toLowerCase(Locale.ENGLISH), Util.displayCurrency(worth, ess))); logger.log(Level.INFO, _("itemSoldConsole", user.getDisplayName(), is.getType().toString().toLowerCase(Locale.ENGLISH), Util.displayCurrency(worth * amount, ess), amount, Util.displayCurrency(worth, ess))); - + return worth * amount; } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtempban.java b/Essentials/src/com/earth2me/essentials/commands/Commandtempban.java index 0549e9c0d..97aa2ea3b 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtempban.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtempban.java @@ -4,6 +4,8 @@ import com.earth2me.essentials.Console; import static com.earth2me.essentials.I18n._; import com.earth2me.essentials.User; import com.earth2me.essentials.Util; +import java.util.Calendar; +import java.util.GregorianCalendar; import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -35,7 +37,7 @@ public class Commandtempban extends EssentialsCommand } else { - if (user.isAuthorized("essentials.tempban.exempt")) + if (user.isAuthorized("essentials.tempban.exempt") && sender instanceof Player) { sender.sendMessage(_("tempbanExempt")); return; @@ -44,6 +46,13 @@ public class Commandtempban extends EssentialsCommand final String time = getFinalArg(args, 1); final long banTimestamp = Util.parseDateDiff(time, true); + final long maxBanLength = ess.getSettings().getMaxTempban() * 1000; + if(maxBanLength > 0 && ((banTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxBanLength) && ess.getUser(sender).isAuthorized("essentials.tempban.unlimited")) + { + sender.sendMessage(_("oversizedTempban")); + throw new NoChargeException(); + } + final String senderName = sender instanceof Player ? ((Player)sender).getDisplayName() : Console.NAME; final String banReason = _("tempBanned", Util.formatDateDiff(banTimestamp), senderName); user.setBanReason(banReason); diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtp.java b/Essentials/src/com/earth2me/essentials/commands/Commandtp.java index 7c6cbe82d..59dbc1a3e 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtp.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtp.java @@ -4,6 +4,7 @@ import com.earth2me.essentials.Console; import static com.earth2me.essentials.I18n._; import com.earth2me.essentials.Trade; import com.earth2me.essentials.User; +import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -40,13 +41,34 @@ public class Commandtp extends EssentialsCommand charge.isAffordableFor(user); user.getTeleport().teleport(player, charge, TeleportCause.COMMAND); throw new NoChargeException(); - + case 4: + if (!user.isAuthorized("essentials.tp.others")) + { + throw new Exception(_("noPerm", "essentials.tp.others")); + } + final User target2 = getPlayer(server, args, 0); + final double x = args[1].startsWith("~") ? target2.getLocation().getX() + Integer.parseInt(args[1].substring(1)) : Integer.parseInt(args[1]); + final double y = args[2].startsWith("~") ? target2.getLocation().getY() + Integer.parseInt(args[2].substring(1)) : Integer.parseInt(args[2]); + final double z = args[3].startsWith("~") ? target2.getLocation().getZ() + Integer.parseInt(args[3].substring(1)) : Integer.parseInt(args[3]); + if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) + { + throw new NotEnoughArgumentsException("Value of coordinates cannot be over 30000000"); //todo: I18n + } + final Location location = new Location(target2.getWorld(), x, y, z); + if (!target2.isTeleportEnabled()) + { + throw new Exception(_("teleportDisabled", target2.getDisplayName())); + } + target2.getTeleport().now(location, false, TeleportCause.COMMAND); + user.sendMessage(_("teleporting")); + target2.sendMessage(_("teleporting")); + break; + case 2: default: if (!user.isAuthorized("essentials.tp.others")) { throw new Exception(_("noPerm", "essentials.tp.others")); } - user.sendMessage(_("teleporting")); final User target = getPlayer(server, args, 0); final User toPlayer = getPlayer(server, args, 1); if (!target.isTeleportEnabled()) @@ -63,6 +85,7 @@ public class Commandtp extends EssentialsCommand throw new Exception(_("noPerm", "essentials.worlds." + toPlayer.getWorld().getName())); } target.getTeleport().now(toPlayer, false, TeleportCause.COMMAND); + user.sendMessage(_("teleporting")); target.sendMessage(_("teleportAtoB", user.getDisplayName(), toPlayer.getDisplayName())); break; } @@ -76,10 +99,28 @@ public class Commandtp extends EssentialsCommand throw new NotEnoughArgumentsException(); } - sender.sendMessage(_("teleporting")); final User target = getPlayer(server, args, 0); - final User toPlayer = getPlayer(server, args, 1); - target.getTeleport().now(toPlayer, false, TeleportCause.COMMAND); - target.sendMessage(_("teleportAtoB", Console.NAME, toPlayer.getDisplayName())); + if (args.length == 2) + { + final User toPlayer = getPlayer(server, args, 1); + target.getTeleport().now(toPlayer, false, TeleportCause.COMMAND); + target.sendMessage(_("teleportAtoB", Console.NAME, toPlayer.getDisplayName())); + } + else if (args.length > 3) + { + final double x = args[1].startsWith("~") ? target.getLocation().getX() + Integer.parseInt(args[1].substring(1)) : Integer.parseInt(args[1]); + final double y = args[2].startsWith("~") ? target.getLocation().getY() + Integer.parseInt(args[2].substring(1)) : Integer.parseInt(args[2]); + final double z = args[3].startsWith("~") ? target.getLocation().getZ() + Integer.parseInt(args[3].substring(1)) : Integer.parseInt(args[3]); + if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) + { + throw new NotEnoughArgumentsException("Value of coordinates cannot be over 30000000"); //todo: I18n + } + final Location location = new Location(target.getWorld(), x, y, z); + target.getTeleport().now(location, false, TeleportCause.COMMAND); + target.sendMessage(_("teleporting")); + } else { + throw new NotEnoughArgumentsException(); + } + sender.sendMessage(_("teleporting")); } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java b/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java index 865492921..7c950ae96 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtpaccept.java @@ -1,5 +1,6 @@ package com.earth2me.essentials.commands; +import com.earth2me.essentials.ChargeException; import static com.earth2me.essentials.I18n._; import com.earth2me.essentials.Trade; import com.earth2me.essentials.User; @@ -52,24 +53,24 @@ public class Commandtpaccept extends EssentialsCommand } final Trade charge = new Trade(this.getName(), ess); - if (user.isTpRequestHere()) - { - charge.isAffordableFor(user); - } - else - { - charge.isAffordableFor(target); - } user.sendMessage(_("requestAccepted")); target.sendMessage(_("requestAcceptedFrom", user.getDisplayName())); - if (user.isTpRequestHere()) + try { - target.getTeleport().teleportToMe(user, charge, TeleportCause.COMMAND); + if (user.isTpRequestHere()) + { + target.getTeleport().teleportToMe(user, charge, TeleportCause.COMMAND); + } + else + { + target.getTeleport().teleport(user, charge, TeleportCause.COMMAND); + } } - else + catch (ChargeException ex) { - target.getTeleport().teleport(user, charge, TeleportCause.COMMAND); + user.sendMessage(_("pendingTeleportCancelled")); + ess.showError(target, ex, commandLabel); } user.requestTeleport(null, false); throw new NoChargeException(); diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java b/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java index ddc86f19c..c9253c99b 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtppos.java @@ -24,9 +24,9 @@ public class Commandtppos extends EssentialsCommand throw new NotEnoughArgumentsException(); } - final int x = Integer.parseInt(args[0]); - final int y = Integer.parseInt(args[1]); - final int z = Integer.parseInt(args[2]); + final double x = args[0].startsWith("~") ? user.getLocation().getX() + Integer.parseInt(args[0].substring(1)) : Integer.parseInt(args[0]); + final double y = args[1].startsWith("~") ? user.getLocation().getY() + Integer.parseInt(args[1].substring(1)) : Integer.parseInt(args[1]); + final double z = args[2].startsWith("~") ? user.getLocation().getZ() + Integer.parseInt(args[2].substring(1)) : Integer.parseInt(args[2]); final Location location = new Location(user.getWorld(), x, y, z); if (args.length > 3) { @@ -36,7 +36,7 @@ public class Commandtppos extends EssentialsCommand { location.setPitch(Float.parseFloat(args[4])); } - if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) + if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) { throw new NotEnoughArgumentsException("Value of coordinates cannot be over 30000000"); //todo: I18n } @@ -56,9 +56,9 @@ public class Commandtppos extends EssentialsCommand } User user = ess.getUser(server.getPlayer(args[0])); - final int x = Integer.parseInt(args[1]); - final int y = Integer.parseInt(args[2]); - final int z = Integer.parseInt(args[3]); + final double x = args[1].startsWith("~") ? user.getLocation().getX() + Integer.parseInt(args[1].substring(1)) : Integer.parseInt(args[1]); + final double y = args[2].startsWith("~") ? user.getLocation().getY() + Integer.parseInt(args[2].substring(1)) : Integer.parseInt(args[2]); + final double z = args[3].startsWith("~") ? user.getLocation().getZ() + Integer.parseInt(args[3].substring(1)) : Integer.parseInt(args[3]); final Location location = new Location(user.getWorld(), x, y, z); if (args.length > 4) { @@ -68,13 +68,13 @@ public class Commandtppos extends EssentialsCommand { location.setPitch(Float.parseFloat(args[5])); } - if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) + if (x > 30000000 || y > 30000000 || z > 30000000 || x < -30000000 || y < -30000000 || z < -30000000) { throw new NotEnoughArgumentsException("Value of coordinates cannot be over 30000000"); //todo: I18n } sender.sendMessage(_("teleporting")); user.sendMessage(_("teleporting")); user.getTeleport().teleport(location, null, TeleportCause.COMMAND); - + } } \ No newline at end of file diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandunlimited.java b/Essentials/src/com/earth2me/essentials/commands/Commandunlimited.java index 38a8725ba..fd0f3be2c 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandunlimited.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandunlimited.java @@ -103,7 +103,7 @@ public class Commandunlimited extends EssentialsCommand { message = "enableUnlimited"; enableUnlimited = true; - if (!InventoryWorkaround.containsItem(target.getInventory(), true, true, stack)) + if (!target.getInventory().containsAtLeast(stack, stack.getAmount())) { target.getInventory().addItem(stack); } diff --git a/Essentials/src/com/earth2me/essentials/craftbukkit/FakeInventory.java b/Essentials/src/com/earth2me/essentials/craftbukkit/FakeInventory.java deleted file mode 100644 index 8456c956e..000000000 --- a/Essentials/src/com/earth2me/essentials/craftbukkit/FakeInventory.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.earth2me.essentials.craftbukkit; - -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import org.bukkit.Material; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; - - -public class FakeInventory implements Inventory -{ - ItemStack[] items; - - public FakeInventory(ItemStack[] items) - { - this.items = new ItemStack[items.length]; - for (int i = 0; i < items.length; i++) - { - if (items[i] == null) - { - continue; - } - this.items[i] = items[i].clone(); - } - } - - @Override - public int getSize() - { - return items.length; - } - - @Override - public String getName() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ItemStack getItem(int i) - { - return items[i]; - } - - @Override - public void setItem(int i, ItemStack is) - { - items[i] = is; - } - - @Override - public HashMap addItem(ItemStack... iss) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public HashMap removeItem(ItemStack... iss) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ItemStack[] getContents() - { - return items; - } - - @Override - public void setContents(ItemStack[] iss) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(Material mtrl) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(ItemStack is) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(int i, int i1) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(Material mtrl, int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean contains(ItemStack is, int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public HashMap all(int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public HashMap all(Material mtrl) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public HashMap all(ItemStack is) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int first(int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int first(Material mtrl) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int first(ItemStack is) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int firstEmpty() - { - for (int i = 0; i < items.length; i++) - { - if (items[i] == null || items[i].getTypeId() == 0) { - return i; - } - } - return -1; - } - - @Override - public void remove(int i) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void remove(Material mtrl) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void remove(ItemStack is) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void clear(int i) - { - items[i] = null; - } - - @Override - public void clear() - { - for (int i = 0; i < items.length; i++) - { - items[i] = null; - } - } - - @Override - public List getViewers() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getTitle() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public InventoryType getType() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public InventoryHolder getHolder() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ListIterator iterator() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getMaxStackSize() - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setMaxStackSize(int size) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ListIterator iterator(int index) - { - throw new UnsupportedOperationException("Not supported yet."); - } -} diff --git a/Essentials/src/com/earth2me/essentials/craftbukkit/FakeWorld.java b/Essentials/src/com/earth2me/essentials/craftbukkit/FakeWorld.java index 7239ea475..df7a237fa 100644 --- a/Essentials/src/com/earth2me/essentials/craftbukkit/FakeWorld.java +++ b/Essentials/src/com/earth2me/essentials/craftbukkit/FakeWorld.java @@ -735,4 +735,10 @@ public class FakeWorld implements World { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public boolean createExplosion(double d, double d1, double d2, float f, boolean bln, boolean bln1) + { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/Essentials/src/com/earth2me/essentials/craftbukkit/InventoryWorkaround.java b/Essentials/src/com/earth2me/essentials/craftbukkit/InventoryWorkaround.java index fc9cbb74b..2e05f5c43 100644 --- a/Essentials/src/com/earth2me/essentials/craftbukkit/InventoryWorkaround.java +++ b/Essentials/src/com/earth2me/essentials/craftbukkit/InventoryWorkaround.java @@ -2,6 +2,7 @@ package com.earth2me.essentials.craftbukkit; import java.util.HashMap; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -15,49 +16,17 @@ public final class InventoryWorkaround { } - public static int first(final Inventory inventory, final ItemStack item, final boolean enforceDurability, final boolean enforceAmount, final boolean enforceEnchantments) - { - return next(inventory, item, 0, enforceDurability, enforceAmount, enforceEnchantments); - } - - public static int next(final Inventory cinventory, final ItemStack item, final int start, final boolean enforceDurability, final boolean enforceAmount, final boolean enforceEnchantments) - { - final ItemStack[] inventory = cinventory.getContents(); - for (int i = start; i < inventory.length; i++) - { - final ItemStack cItem = inventory[i]; - if (cItem == null) - { - continue; - } - if (item.getTypeId() == cItem.getTypeId() && (!enforceAmount || item.getAmount() == cItem.getAmount()) && (!enforceDurability || cItem.getDurability() == item.getDurability()) && (!enforceEnchantments || cItem.getEnchantments().equals(item.getEnchantments()))) - { - return i; - } - } - return -1; - } - - public static int firstPartial(final Inventory cinventory, final ItemStack item, final boolean enforceDurability) - { - return firstPartial(cinventory, item, enforceDurability, item.getType().getMaxStackSize()); - } - - public static int firstPartial(final Inventory cinventory, final ItemStack item, final boolean enforceDurability, final int maxAmount) + private static int firstPartial(final Inventory inventory, final ItemStack item, final int maxAmount) { if (item == null) { return -1; } - final ItemStack[] inventory = cinventory.getContents(); - for (int i = 0; i < inventory.length; i++) + final ItemStack[] stacks = inventory.getContents(); + for (int i = 0; i < stacks.length; i++) { - final ItemStack cItem = inventory[i]; - if (cItem == null) - { - continue; - } - if (item.getTypeId() == cItem.getTypeId() && cItem.getAmount() < maxAmount && (!enforceDurability || cItem.getDurability() == item.getDurability()) && cItem.getEnchantments().equals(item.getEnchantments())) + final ItemStack cItem = stacks[i]; + if (cItem != null && cItem.getAmount() < maxAmount && cItem.isSimilar(item)) { return i; } @@ -65,26 +34,24 @@ public final class InventoryWorkaround return -1; } - public static boolean addAllItems(final Inventory cinventory, final boolean enforceDurability, final ItemStack... items) + public static boolean addAllItems(final Inventory inventory, final ItemStack... items) { - final Inventory fake = new FakeInventory(cinventory.getContents()); - if (addItem(fake, enforceDurability, items).isEmpty()) + final Inventory fakeInventory = Bukkit.getServer().createInventory(null, inventory.getType()); + fakeInventory.setContents(inventory.getContents()); + if (addItems(fakeInventory, items).isEmpty()) { - addItem(cinventory, enforceDurability, items); + addItems(inventory, items); return true; } - else - { - return false; - } + return false; } - public static Map addItem(final Inventory cinventory, final boolean forceDurability, final ItemStack... items) + public static Map addItems(final Inventory inventory, final ItemStack... items) { - return addItem(cinventory, forceDurability, 0, items); + return addOversizedItems(inventory, 0, items); } - public static Map addItem(final Inventory cinventory, final boolean enforceDurability, final int oversizedStacks, final ItemStack... items) + public static Map addOversizedItems(final Inventory inventory, final int oversizedStacks, final ItemStack... items) { final Map leftover = new HashMap(); @@ -95,7 +62,7 @@ public final class InventoryWorkaround // combine items - ItemStack[] combined = new ItemStack[items.length]; + final ItemStack[] combined = new ItemStack[items.length]; for (int i = 0; i < items.length; i++) { if (items[i] == null || items[i].getAmount() < 1) @@ -109,7 +76,7 @@ public final class InventoryWorkaround combined[j] = items[i].clone(); break; } - if (combined[j].getTypeId() == items[i].getTypeId() && (!enforceDurability || combined[j].getDurability() == items[i].getDurability()) && combined[j].getEnchantments().equals(items[i].getEnchantments())) + if (combined[j].isSimilar(items[i])) { combined[j].setAmount(combined[j].getAmount() + items[i].getAmount()); break; @@ -130,13 +97,13 @@ public final class InventoryWorkaround { // Do we already have a stack of it? final int maxAmount = oversizedStacks > item.getType().getMaxStackSize() ? oversizedStacks : item.getType().getMaxStackSize(); - final int firstPartial = firstPartial(cinventory, item, enforceDurability, maxAmount); + final int firstPartial = firstPartial(inventory, item, maxAmount); // Drat! no partial stack if (firstPartial == -1) { // Find a free spot! - final int firstFree = cinventory.firstEmpty(); + final int firstFree = inventory.firstEmpty(); if (firstFree == -1) { @@ -151,13 +118,13 @@ public final class InventoryWorkaround { final ItemStack stack = item.clone(); stack.setAmount(maxAmount); - cinventory.setItem(firstFree, stack); + inventory.setItem(firstFree, stack); item.setAmount(item.getAmount() - maxAmount); } else { // Just store it - cinventory.setItem(firstFree, item); + inventory.setItem(firstFree, item); break; } } @@ -165,7 +132,7 @@ public final class InventoryWorkaround else { // So, apparently it might only partially fit, well lets do just that - final ItemStack partialItem = cinventory.getItem(firstPartial); + final ItemStack partialItem = inventory.getItem(firstPartial); final int amount = item.getAmount(); final int partialAmount = partialItem.getAmount(); @@ -185,138 +152,4 @@ public final class InventoryWorkaround } return leftover; } - - public static Map removeItem(final Inventory cinventory, final boolean enforceDurability, final boolean enforceEnchantments, final ItemStack... items) - { - final Map leftover = new HashMap(); - - // TODO: optimization - - for (int i = 0; i < items.length; i++) - { - final ItemStack item = items[i]; - if (item == null) - { - continue; - } - int toDelete = item.getAmount(); - - while (true) - { - - // Bail when done - if (toDelete <= 0) - { - break; - } - - // get first Item, ignore the amount - final int first = first(cinventory, item, enforceDurability, false, enforceEnchantments); - - // Drat! we don't have this type in the inventory - if (first == -1) - { - item.setAmount(toDelete); - leftover.put(i, item); - break; - } - else - { - final ItemStack itemStack = cinventory.getItem(first); - final int amount = itemStack.getAmount(); - - if (amount <= toDelete) - { - toDelete -= amount; - // clear the slot, all used up - cinventory.clear(first); - } - else - { - // split the stack and store - itemStack.setAmount(amount - toDelete); - cinventory.setItem(first, itemStack); - toDelete = 0; - } - } - } - } - return leftover; - } - - public static boolean containsItem(final Inventory cinventory, final boolean enforceDurability, final boolean enforceEnchantments, final ItemStack... items) - { - final Map leftover = new HashMap(); - - // TODO: optimization - - // combine items - - ItemStack[] combined = new ItemStack[items.length]; - for (int i = 0; i < items.length; i++) - { - if (items[i] == null) - { - continue; - } - for (int j = 0; j < combined.length; j++) - { - if (combined[j] == null) - { - combined[j] = items[i].clone(); - break; - } - if (combined[j].getTypeId() == items[i].getTypeId() && (!enforceDurability || combined[j].getDurability() == items[i].getDurability()) && (!enforceEnchantments || combined[j].getEnchantments().equals(items[i].getEnchantments()))) - { - combined[j].setAmount(combined[j].getAmount() + items[i].getAmount()); - break; - } - } - } - - for (int i = 0; i < combined.length; i++) - { - final ItemStack item = combined[i]; - if (item == null) - { - continue; - } - int mustHave = item.getAmount(); - int position = 0; - - while (true) - { - // Bail when done - if (mustHave <= 0) - { - break; - } - - final int slot = next(cinventory, item, position, enforceDurability, false, enforceEnchantments); - - // Drat! we don't have this type in the inventory - if (slot == -1) - { - leftover.put(i, item); - break; - } - else - { - final ItemStack itemStack = cinventory.getItem(slot); - final int amount = itemStack.getAmount(); - - if (amount <= mustHave) - { - mustHave -= amount; - } - else - { - mustHave = 0; - } - position = slot + 1; - } - } - } - return leftover.isEmpty(); - } } diff --git a/Essentials/src/com/earth2me/essentials/metrics/Metrics.java b/Essentials/src/com/earth2me/essentials/metrics/Metrics.java index a0bf103e8..77e68a9d6 100644 --- a/Essentials/src/com/earth2me/essentials/metrics/Metrics.java +++ b/Essentials/src/com/earth2me/essentials/metrics/Metrics.java @@ -35,6 +35,7 @@ import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.scheduler.BukkitTask; /** @@ -51,7 +52,7 @@ public class Metrics /** * The current revision number */ - private final static int REVISION = 5; + private final static int REVISION = 6; /** * The base url of the metrics domain */ @@ -60,10 +61,6 @@ public class Metrics * The url used to report a server's status */ private static final String REPORT_URL = "/report/%s"; - /** - * The file where guid and opt out is stored in - */ - private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml"; /** * The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and * want to change it. @@ -97,14 +94,18 @@ public class Metrics * Unique server id */ private final String guid; + /** + * Debug mode + */ + private final boolean debug; /** * Lock for synchronization */ private final Object optOutLock = new Object(); /** - * Id of the scheduled task + * The scheduled task */ - private volatile int taskId = -1; + private volatile BukkitTask task = null; public Metrics(final Plugin plugin) throws IOException { @@ -116,29 +117,31 @@ public class Metrics this.plugin = plugin; // load the config - configurationFile = new File(CONFIG_FILE); + configurationFile = getConfigFile(); configuration = YamlConfiguration.loadConfiguration(configurationFile); // add some defaults configuration.addDefault("opt-out", false); configuration.addDefault("guid", UUID.randomUUID().toString()); + configuration.addDefault("debug", false); // Do we need to create the file? if (configuration.get("guid", null) == null) { - configuration.options().header("http://metrics.griefcraft.com").copyDefaults(true); + configuration.options().header("http://mcstats.org").copyDefaults(true); configuration.save(configurationFile); } // Load the guid then guid = configuration.getString("guid"); + debug = configuration.getBoolean("debug", false); } /** * Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics * website. Plotters can be added to the graph object returned. * - * @param name + * @param name The name of the graph * @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given */ public Graph createGraph(final String name) @@ -161,7 +164,7 @@ public class Metrics /** * Adds a custom data plotter to the default graph * - * @param plotter + * @param plotter The plotter to use to plot custom data */ public void addCustomData(final Plotter plotter) { @@ -193,7 +196,7 @@ public class Metrics } // Begin hitting the server with glorious data - taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() + task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() { private boolean firstPost = true; @@ -205,10 +208,15 @@ public class Metrics synchronized (optOutLock) { // Disable Task, if it is running and the server owner decided to opt-out - if (isOptOut() && taskId > 0) + if (isOptOut() && task != null) { - plugin.getServer().getScheduler().cancelTask(taskId); - taskId = -1; + task.cancel(); + task = null; + // Tell all plotters to stop gathering information. + for (Graph graph : graphs) + { + graph.onOptOut(); + } } } @@ -223,7 +231,10 @@ public class Metrics } catch (IOException e) { - Bukkit.getLogger().log(Level.FINE, "[Metrics] " + e.getMessage()); + if (debug) + { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); + } } } }, 0, PING_INTERVAL * 1200); @@ -233,7 +244,7 @@ public class Metrics /** * Has the server owner denied plugin metrics? * - * @return + * @return true if metrics should be opted out of it */ public boolean isOptOut() { @@ -242,16 +253,22 @@ public class Metrics try { // Reload the metrics file - configuration.load(CONFIG_FILE); + configuration.load(getConfigFile()); } catch (IOException ex) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + if (debug) + { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } return true; } catch (InvalidConfigurationException ex) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + if (debug) + { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } return true; } return configuration.getBoolean("opt-out", false); @@ -276,7 +293,7 @@ public class Metrics } // Enable Task, if it is not running - if (taskId < 0) + if (task == null) { start(); } @@ -297,35 +314,81 @@ public class Metrics if (!isOptOut()) { configuration.set("opt-out", true); - final File file = new File(CONFIG_FILE); - configuration.save(file); + configuration.save(configurationFile); } // Disable Task, if it is running - if (taskId >= 0) + if (task != null) { - this.plugin.getServer().getScheduler().cancelTask(taskId); - taskId = -1; + task.cancel(); + task = null; } } } + /** + * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status + * + * @return the File object for the config file + */ + public File getConfigFile() + { + // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use + // is to abuse the plugin object we already have + // plugin.getDataFolder() => base/plugins/PluginA/ + // pluginsFolder => base/plugins/ + // The base is not necessarily relative to the startup directory. + File pluginsFolder = plugin.getDataFolder().getParentFile(); + + // return => base/plugins/PluginMetrics/config.yml + return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml"); + } + /** * Generic method that posts a plugin to the metrics website */ private void postPlugin(final boolean isPing) throws IOException { - // The plugin's description file containg all of the plugin data such as name, version, author, etc - final PluginDescriptionFile description = plugin.getDescription(); + // Server software specific section + PluginDescriptionFile description = plugin.getDescription(); + String pluginName = description.getName(); + boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled + String pluginVersion = description.getVersion(); + String serverVersion = Bukkit.getVersion(); + int playersOnline = Bukkit.getServer().getOnlinePlayers().length; + + // END server software specific section -- all code below does not use any code outside of this class / Java // Construct the post data final StringBuilder data = new StringBuilder(); + + // The plugin's description file containg all of the plugin data such as name, version, author, etc data.append(encode("guid")).append('=').append(encode(guid)); - encodeDataPair(data, "version", description.getVersion()); - encodeDataPair(data, "server", Bukkit.getVersion()); - encodeDataPair(data, "players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length)); + encodeDataPair(data, "version", pluginVersion); + encodeDataPair(data, "server", serverVersion); + encodeDataPair(data, "players", Integer.toString(playersOnline)); encodeDataPair(data, "revision", String.valueOf(REVISION)); + // New data as of R6 + String osname = System.getProperty("os.name"); + String osarch = System.getProperty("os.arch"); + String osversion = System.getProperty("os.version"); + String java_version = System.getProperty("java.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + // normalize os arch .. amd64 -> x86_64 + if (osarch.equals("amd64")) + { + osarch = "x86_64"; + } + + encodeDataPair(data, "osname", osname); + encodeDataPair(data, "osarch", osarch); + encodeDataPair(data, "osversion", osversion); + encodeDataPair(data, "cores", Integer.toString(coreCount)); + encodeDataPair(data, "online-mode", Boolean.toString(onlineMode)); + encodeDataPair(data, "java_version", java_version); + // If we're pinging, append it if (isPing) { @@ -342,10 +405,6 @@ public class Metrics { final Graph graph = iter.next(); - // Because we have a lock on the graphs set already, it is reasonable to assume - // that our lock transcends down to the individual plotters in the graphs also. - // Because our methods are private, no one but us can reasonably access this list - // without reflection so this is a safe assumption without adding more code. for (Plotter plotter : graph.getPlotters()) { // The key name to send to the metrics server @@ -364,7 +423,7 @@ public class Metrics } // Create the url - final URL url = new URL(BASE_URL + String.format(REPORT_URL, description.getName())); + URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName))); // Connect to the website URLConnection connection; @@ -420,13 +479,12 @@ public class Metrics } } } - //if (response.startsWith("OK")) - We should get "OK" followed by an optional description if everything goes right } /** * Check if mineshafter is present. If it is, we need to bypass it to send POST requests * - * @return + * @return true if mineshafter is installed on the server */ private boolean isMineshafterPresent() { @@ -450,10 +508,9 @@ public class Metrics * encodeDataPair(data, "version", description.getVersion()); * * - * @param buffer - * @param key - * @param value - * @return + * @param buffer the stringbuilder to append the data pair onto + * @param key the key value + * @param value the value */ private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException { @@ -463,8 +520,8 @@ public class Metrics /** * Encode text as UTF-8 * - * @param text - * @return + * @param text the text to encode + * @return the encoded text, as UTF-8 */ private static String encode(final String text) throws UnsupportedEncodingException { @@ -495,7 +552,7 @@ public class Metrics /** * Gets the graph's name * - * @return + * @return the Graph's name */ public String getName() { @@ -505,7 +562,7 @@ public class Metrics /** * Add a plotter to the graph, which will be used to plot entries * - * @param plotter + * @param plotter the plotter to add to the graph */ public void addPlotter(final Plotter plotter) { @@ -515,7 +572,7 @@ public class Metrics /** * Remove a plotter from the graph * - * @param plotter + * @param plotter the plotter to remove from the graph */ public void removePlotter(final Plotter plotter) { @@ -525,7 +582,7 @@ public class Metrics /** * Gets an unmodifiable set of the plotter objects in the graph * - * @return + * @return an unmodifiable {@link Set} of the plotter objects */ public Set getPlotters() { @@ -549,6 +606,13 @@ public class Metrics final Graph graph = (Graph)object; return graph.name.equals(name); } + + /** + * Called when the server owner decides to opt-out of Metrics while the server is running. + */ + protected void onOptOut() + { + } } @@ -573,7 +637,7 @@ public class Metrics /** * Construct a plotter with a specific plot name * - * @param name + * @param name the name of the plotter to use, which will show up on the website */ public Plotter(final String name) { @@ -581,9 +645,11 @@ public class Metrics } /** - * Get the current value for the plotted point + * Get the current value for the plotted point. Since this function defers to an external function it may or may + * not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called + * from any thread so care should be taken when accessing resources that need to be synchronized. * - * @return + * @return the current value for the point to be plotted. */ public abstract int getValue(); @@ -607,7 +673,7 @@ public class Metrics @Override public int hashCode() { - return getColumnName().hashCode() + getValue(); + return getColumnName().hashCode(); } @Override diff --git a/Essentials/src/com/earth2me/essentials/metrics/MetricsStarter.java b/Essentials/src/com/earth2me/essentials/metrics/MetricsStarter.java index b0592855d..3e9ee9e49 100644 --- a/Essentials/src/com/earth2me/essentials/metrics/MetricsStarter.java +++ b/Essentials/src/com/earth2me/essentials/metrics/MetricsStarter.java @@ -134,6 +134,14 @@ public class MetricsStarter implements Runnable { enabledGraph.addPlotter(new SimplePlotter("Warps")); } + if (ess.getSettings().getTeleportCooldown() > 0) + { + enabledGraph.addPlotter(new SimplePlotter("TeleportCooldown")); + } + if (ess.getSettings().getTeleportDelay() > 0) + { + enabledGraph.addPlotter(new SimplePlotter("TeleportDelay")); + } if (!ess.getSettings().areSignsDisabled()) { enabledGraph.addPlotter(new SimplePlotter("Signs")); @@ -142,6 +150,14 @@ public class MetricsStarter implements Runnable { enabledGraph.addPlotter(new SimplePlotter("AutoAFK")); } + if (ess.getSettings().changePlayerListName()) + { + enabledGraph.addPlotter(new SimplePlotter("PlayerListName")); + } + if (ess.getSettings().getOperatorColor() != null) + { + enabledGraph.addPlotter(new SimplePlotter("OpColour")); + } if (ess.getSettings().changeDisplayName()) { enabledGraph.addPlotter(new SimplePlotter("DisplayName")); diff --git a/Essentials/src/com/earth2me/essentials/perm/BPermissions2Handler.java b/Essentials/src/com/earth2me/essentials/perm/BPermissions2Handler.java index 653a13441..791ffbe92 100644 --- a/Essentials/src/com/earth2me/essentials/perm/BPermissions2Handler.java +++ b/Essentials/src/com/earth2me/essentials/perm/BPermissions2Handler.java @@ -35,7 +35,7 @@ public class BPermissions2Handler extends SuperpermsHandler @Override public boolean inGroup(final Player base, final String group) { - return ApiLayer.hasGroup(base.getWorld().getName(), CalculableType.USER, base.getName(), group); + return ApiLayer.hasGroupRecursive(base.getWorld().getName(), CalculableType.USER, base.getName(), group); } @Override diff --git a/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java b/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java index b6fbe3b33..8c12acfe3 100644 --- a/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java +++ b/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java @@ -13,22 +13,22 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPluginLoader; import org.yaml.snakeyaml.TypeDescription; import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.introspector.Property; import org.yaml.snakeyaml.nodes.*; -public class BukkitConstructor extends Constructor +public class BukkitConstructor extends CustomClassLoaderConstructor { private final transient Pattern NUMPATTERN = Pattern.compile("\\d+"); private final transient Plugin plugin; public BukkitConstructor(final Class clazz, final Plugin plugin) { - super(clazz); + super(clazz, plugin.getClass().getClassLoader()); this.plugin = plugin; yamlClassConstructors.put(NodeId.scalar, new ConstructBukkitScalar()); yamlClassConstructors.put(NodeId.mapping, new ConstructBukkitMapping()); @@ -276,6 +276,7 @@ public class BukkitConstructor extends Constructor return super.construct(node); } + @Override protected Object constructJavaBean2ndStep(final MappingNode node, final Object object) { Map, TypeDescription> typeDefinitions; @@ -284,7 +285,8 @@ public class BukkitConstructor extends Constructor final Field typeDefField = Constructor.class.getDeclaredField("typeDefinitions"); typeDefField.setAccessible(true); typeDefinitions = (Map, TypeDescription>)typeDefField.get((Constructor)BukkitConstructor.this); - if (typeDefinitions == null) { + if (typeDefinitions == null) + { throw new NullPointerException(); } } @@ -402,29 +404,4 @@ public class BukkitConstructor extends Constructor return object; } } - - @Override - protected Class getClassForNode(final Node node) - { - Class clazz; - final String name = node.getTag().getClassName(); - if (plugin == null) - { - clazz = super.getClassForNode(node); - } - else - { - final JavaPluginLoader jpl = (JavaPluginLoader)plugin.getPluginLoader(); - clazz = jpl.getClassByName(name); - } - - if (clazz == null) - { - throw new YAMLException("Class not found: " + name); - } - else - { - return clazz; - } - } } diff --git a/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java b/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java index 4efb6c43f..b091e2135 100644 --- a/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java +++ b/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java @@ -47,6 +47,7 @@ public class HelpInput implements IText newLines.clear(); lines.add(_("helpFrom", p.getDescription().getName())); } + final boolean isOnWhitelist = user.isAuthorized("essentials.help." + pluginNameLow); for (Map.Entry> k : cmds.entrySet()) { @@ -81,7 +82,7 @@ public class HelpInput implements IText { permissions = value.get(PERMISSIONS); } - if (user.isAuthorized("essentials.help." + pluginNameLow)) + if (isOnWhitelist || user.isAuthorized("essentials.help." + pluginNameLow + "." + k.getKey())) { pluginLines.add(_("helpLine", k.getKey(), value.get(DESCRIPTION))); } diff --git a/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java b/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java index 4c875098b..2a95d4d84 100644 --- a/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java +++ b/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java @@ -3,6 +3,7 @@ package com.earth2me.essentials.textreader; import com.earth2me.essentials.DescParseTickFormat; import com.earth2me.essentials.IEssentials; import com.earth2me.essentials.User; +import com.earth2me.essentials.Util; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; @@ -42,7 +43,7 @@ public class KeywordReplacer implements IText userName = user.getName(); ipAddress = user.getAddress() == null || user.getAddress().getAddress() == null ? "" : user.getAddress().getAddress().toString(); address = user.getAddress() == null ? "" : user.getAddress().toString(); - balance = Double.toString(user.getMoney()); + balance = Util.displayCurrency(user.getMoney(), ess); mails = Integer.toString(user.getMails().size()); world = user.getLocation() == null || user.getLocation().getWorld() == null ? "" : user.getLocation().getWorld().getName(); worldTime12 = DescParseTickFormat.format12(user.getWorld() == null ? 0 : user.getWorld().getTime()); diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml index 84d8578a6..12e932b1c 100644 --- a/Essentials/src/config.yml +++ b/Essentials/src/config.yml @@ -32,11 +32,10 @@ change-displayname: true # The value of change-displayname (above) has to be true. #change-playerlist: true -# Adds the prefix and suffix to the displayname of the player, so it will be displayed in messages and lists. -# The prefix/suffix can be set using Permissions, Group Manager or PermissionsEx. +# When essentialschat.jar isnt used, force essentials to add the prefix and suffix from permission plugins to displayname +# This setting is ignored if essentialschat.jar is used, and defaults to 'true' # The value of change-displayname (above) has to be true. -# If you don't set this, it will default to true if essentials chat is installed. -# Don't forget to remove the # in front of the line +# Do not edit this setting unless you know what you are doing! #add-prefix-suffix: false # The delay, in seconds, required between /home, /tp, etc. @@ -65,6 +64,7 @@ item-spawn-blacklist: # - essentials.give.item-all # - essentials.give.item-[itemname] # - essentials.give.item-[itemid] +# For more information, visit http://wiki.ess3.net/wiki/Command_Reference/ICheat#Item.2FGive permission-based-item-spawn: false # Mob limit on the /spawnmob command per execution @@ -76,7 +76,7 @@ warn-on-smite: true # motd and rules are now configured in the files motd.txt and rules.txt # When a command conflicts with another plugin, by default, Essentials will try to force the OTHER plugin to take priority. -# Commands in in this list, will tell Essentials to 'not give up' the command to other plugins. +# Commands in this list, will tell Essentials to 'not give up' the command to other plugins. # In this state, which plugin 'wins' appears to be almost random. # # If you have two plugin with the same command and you wish to force Essentials to take over, you need an alias. @@ -91,6 +91,32 @@ overridden-commands: disabled-commands: # - nick +# These commands will be shown to players with socialSpy enabled +# You can add commands from other plugins you may want to track or +# remove commands that are used for something you dont want to spy on +socialspy-commands: + - msg + - w + - r + - mail + - m + - t + - whisper + - emsg + - tell + - er + - reply + - ereply + - email + - action + - describe + - eme + - eaction + - edescribe + - etell + - ewhisper + - pm + # If you do not wish to use a permission system, you can define a list of 'player perms' below. # This list has no effect if you are using a supported permissions system. # If you are using an unsupported permissions system simply delete this section. @@ -181,6 +207,7 @@ player-commands: # All kit names should be lower case, and will be treated as lower in permissions/costs. # Syntax: - itemID[:DataValue] Amount [Enchantment:Level].. # '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 kits: dtools: delay: 10 @@ -246,8 +273,10 @@ debug: false # Set the locale for all messages # If you don't set this, the default locale of the server will be used. +# For example, to set language to English, set locale to en, to use the file "messages_en.properties" # Don't forget to remove the # in front of the line -#locale: de_DE +# For more information, visit http://wiki.ess3.net/wiki/Locale +#locale: en # Turn off god mode when people exit remove-god-on-disconnect: false @@ -318,6 +347,13 @@ max-fly-speed: 0.8 #Set the maximum amount of mail that can be sent within a minute. mails-per-minute: 1000 +# Set the maximum time /tempban can be used for in seconds. +# Set to -1 to disable, and essentials.tempban.unlimited can be used to override. +max-tempban-time: -1 + +# Require users have essentials.chat before they can speak? Any users without this node will not be able to speak +enable-chat-perm: false + ############################################################ # +------------------------------------------------------+ # # | EssentialsHome | # @@ -336,6 +372,7 @@ world-home-permissions: false # Players need essentials.sethome.multiple before they can have more than 1 home, defaults to 'default' below. # Define different amounts of multiple homes for different permissions, e.g. essentials.sethome.multiple.vip # People with essentials.sethome.multiple.unlimited are not limited by these numbers. +# For more information, visit http://wiki.ess3.net/wiki/Multihome sethome-multiple: default: 3 # essentials.sethome.multiple.vip @@ -353,6 +390,8 @@ tpa-accept-cancellation: 0 # +------------------------------------------------------+ # ############################################################ +# For more information, visit http://wiki.ess3.net/wiki/Essentials_Economy + # Defines the balance with which new players begin. Defaults to 0. starting-balance: 0 @@ -371,7 +410,7 @@ command-costs: currency-symbol: '$' # Set the maximum amount of money a player can have -# The amount is always limited to 10 trillions because of the limitations of a java double +# The amount is always limited to 10 trillion because of the limitations of a java double max-money: 10000000000000 # Set the minimum amount of money a player can have (must be above the negative of max-money). @@ -573,6 +612,7 @@ protect: ############################################################ # Disable various default physics and behaviors + # For more information, visit http://wiki.ess3.net/wiki/AntiBuild # Should people with build: false in permissions be allowed to build # Set true to disable building for those people diff --git a/Essentials/src/items.csv b/Essentials/src/items.csv index 8b0f8b967..3991d2ee5 100644 --- a/Essentials/src/items.csv +++ b/Essentials/src/items.csv @@ -1878,17 +1878,23 @@ dwart,115,0 dplant,115,0 dcrop,115,0 enchantmenttable,116,0 -magictable,116,0 +enchantingtable,116,0 +enchanttable,116,0 etable,116,0 -booktable,116,0 -magicdesk,116,0 +magicaltable,116,0 +magictable,116,0 +mtable,116,0 enchantmentdesk,116,0 +enchantingdesk,116,0 +enchantdesk,116,0 edesk,116,0 +magicaldesk,116,0 +magicdesk,116,0 +mdesk,116,0 +booktable,116,0 bookdesk,116,0 btable,116,0 bdesk,116,0 -mtable,116,0 -mdesk,116,0 brewingstandblock,117,0 brewerblock,117,0 potionstandblock,117,0 @@ -5625,6 +5631,31 @@ pumpkincake,400,0 ppie,400,0 pcake,400,0 pie,400,0 +fireworkrocket,401,0 +fireworkmissle,401,0 +firework,401,0 +fworkrocket,401,0 +fworkmissle,401,0 +fwork,401,0 +fwrocket,401,0 +fwmissle,401,0 +fireworkstar,402,0 +fworkstar,402,0 +fwstar,402,0 +fireworkball,402,0 +fworkball,402,0 +fwball,402,0 +fireworkpowder,402,0 +fworkpowder,402,0 +fwpowder,402,0 +enchantmentbook,403,0 +enchantedbook,403,0 +enchantingbook,403,0 +enchantbook,403,0 +magicalbook,403,0 +magicbook,403,0 +ebook,403,0 +mbook,403,0 goldmusicrecord,2256,0 goldmusicdisk,2256,0 goldmusicdisc,2256,0 @@ -6164,4 +6195,4 @@ cd11,2266,0 11record,2266,0 11disk,2266,0 11disc,2266,0 -11cd,2266,0 \ No newline at end of file +11cd,2266,0 diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index a75198a62..acec050ff 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -194,7 +194,7 @@ listAmountHidden= \u00a76There are \u00a7c{0}\u00a76/{1}\u00a76 out of maximum \ listGroupTag={0}\u00a7r: listHiddenTag= \u00a77[HIDDEN]\u00a7r loadWarpError=\u00a74Failed to load warp {0} -localFormat=Local: <{0}> {1} +localFormat=[L]<{0}> {1} mailClear=\u00a76To mark your mail as read, type\u00a7c /mail clear mailCleared=\u00a76Mail Cleared! mailSent=\u00a76Mail sent! @@ -373,6 +373,8 @@ timeSet=\u00a76Time set in all worlds. timeSetPermission=\u00a74You are not authorized to set the time. timeWorldCurrent=\u00a76The current time in\u00a7c {0} \u00a76is \u00a7c{1} timeWorldSet=\u00a76The time was set to\u00a7c {0} \u00a76in: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=\u00a76Current TPS = {0} tradeCompleted=\u00a7aTrade completed. tradeSignEmpty=\u00a74The trade sign has nothing available for you. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_cs.properties b/Essentials/src/messages_cs.properties index be5ca4dfd..4cbf3e91e 100644 --- a/Essentials/src/messages_cs.properties +++ b/Essentials/src/messages_cs.properties @@ -376,6 +376,8 @@ timeSet=Cas nastaven ve vsech svetech. timeSetPermission=\u00a7cNejsi autorizovany ke zmene casu. timeWorldCurrent=Ve svete {0} je prave \u00a73{1} timeWorldSet=Cas byl nastaven na {0} ve: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Vymena kompletni. tradeSignEmpty=Tato cedule jiz nema dostupny material na vymenu. @@ -466,3 +468,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_da.properties b/Essentials/src/messages_da.properties index 8a6fe98be..8d66386d5 100644 --- a/Essentials/src/messages_da.properties +++ b/Essentials/src/messages_da.properties @@ -373,6 +373,8 @@ timeSet=Tid \u00c3\u00a6ndret i alle verdener. timeSetPermission=\u00a7cDu har ikke tilladelse til at \u00c3\u00a6ndre tiden. timeWorldCurrent=Tiden p\u00c3\u00a5 nuv\u00c3\u00a6rende tidspunkt i {0} er \u00a73{1} timeWorldSet=Tiden blev \u00c3\u00a6ndret til {0} i: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Handel gennemf\u00f8rt. tradeSignEmpty=Handelsskiltet har udsolgt! @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_de.properties b/Essentials/src/messages_de.properties index 7535d3cc7..f5d666727 100644 --- a/Essentials/src/messages_de.properties +++ b/Essentials/src/messages_de.properties @@ -373,6 +373,8 @@ timeSet=Zeit in allen Welten gesetzt. timeSetPermission=\u00a7cDu hast keine Berechtigung die Zeit zu \u00e4ndern. timeWorldCurrent=Die momentane Zeit in {0} ist \u00a73{1} timeWorldSet=Die Zeit in \u00a7c{1}\u00a7f wurde zu {0} gesetzt. +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Handel abgeschlossen. tradeSignEmpty=Der Bestand des Trade-Schild ist aufgebraucht. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_en.properties b/Essentials/src/messages_en.properties index a75198a62..acec050ff 100644 --- a/Essentials/src/messages_en.properties +++ b/Essentials/src/messages_en.properties @@ -194,7 +194,7 @@ listAmountHidden= \u00a76There are \u00a7c{0}\u00a76/{1}\u00a76 out of maximum \ listGroupTag={0}\u00a7r: listHiddenTag= \u00a77[HIDDEN]\u00a7r loadWarpError=\u00a74Failed to load warp {0} -localFormat=Local: <{0}> {1} +localFormat=[L]<{0}> {1} mailClear=\u00a76To mark your mail as read, type\u00a7c /mail clear mailCleared=\u00a76Mail Cleared! mailSent=\u00a76Mail sent! @@ -373,6 +373,8 @@ timeSet=\u00a76Time set in all worlds. timeSetPermission=\u00a74You are not authorized to set the time. timeWorldCurrent=\u00a76The current time in\u00a7c {0} \u00a76is \u00a7c{1} timeWorldSet=\u00a76The time was set to\u00a7c {0} \u00a76in: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=\u00a76Current TPS = {0} tradeCompleted=\u00a7aTrade completed. tradeSignEmpty=\u00a74The trade sign has nothing available for you. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_es.properties b/Essentials/src/messages_es.properties index e3d5bac59..34dacad69 100644 --- a/Essentials/src/messages_es.properties +++ b/Essentials/src/messages_es.properties @@ -373,6 +373,8 @@ timeSet=Tiempo establecido en todos los mundos. timeSetPermission=\u00a7cNo estas autorizado para establecer la hora. timeWorldCurrent=La hora actual en {0} es \u00a73{1} timeWorldSet=La hora ha sido establecida a {0} en: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=TPS actual = {0} tradeCompleted=\u00a77Intercambio completado. tradeSignEmpty=Esta tienda no tiene nada disponible para ti. @@ -463,3 +465,17 @@ userUnknown=\u00a74Peligro: El jugador '\u00a7c{0}\u00a74' Nunca a ingresado a e teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_fi.properties b/Essentials/src/messages_fi.properties index 0b8fbeb63..cf01efa93 100644 --- a/Essentials/src/messages_fi.properties +++ b/Essentials/src/messages_fi.properties @@ -373,6 +373,8 @@ timeSet=Aika asetettu kaikissa maailmoissa. timeSetPermission=\u00a7cSinulla ei ole lupaa vaihtaa aikaa. timeWorldCurrent=T\u00e4m\u00e4nhetkinen aika maailmassa {0} on \u00a73{1} timeWorldSet=Aika vaihdettiin {0} maailmassa: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=T\u00e4m\u00e4nhetkinen TPS = {0} tradeCompleted=\u00a77Vaihto suoritettu. tradeSignEmpty=Vaihtokyltill\u00e4 ei ole mit\u00e4\u00e4n tarjolla sinulle. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_fr.properties b/Essentials/src/messages_fr.properties index 2505ed700..869599d02 100644 --- a/Essentials/src/messages_fr.properties +++ b/Essentials/src/messages_fr.properties @@ -373,6 +373,8 @@ timeSet=Heure r\u00e9gl\u00e9e dans tous les mondes. timeSetPermission=\u00a7cVous n'\u00eates pas autoris\u00e9 \u00e0 r\u00e9gler l'heure. timeWorldCurrent=Il est \u00a73{1}\u00a77 dans \u00a7c{0}. timeWorldSet=L''heure a \u00e9t\u00e9 r\u00e9gl\u00e9e \u00e0 {0} dans : \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77\u00c9change termin\u00e9. tradeSignEmpty=Le panneau de vente n'as pas encore assez de stock. @@ -463,3 +465,17 @@ userUnknown=\u00a74Attention : Le joueur '\u00a7c{0}\u00a74' n'est jamais venu s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_it.properties b/Essentials/src/messages_it.properties index 272a1d574..fe001b319 100644 --- a/Essentials/src/messages_it.properties +++ b/Essentials/src/messages_it.properties @@ -373,6 +373,8 @@ timeSet=Orario definito in tutti i mondi. timeSetPermission=\u00a7cNon sei autorizzato a regolare l''orario. timeWorldCurrent=L''orario attuale in {0} e'' \u00a73{1} timeWorldSet=L''orario e'' stato regolato alle {0} in: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Affare concluso. tradeSignEmpty=L''insegna non dispone di forniture sufficienti. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_nl.properties b/Essentials/src/messages_nl.properties index 03a141a73..a4d39da29 100644 --- a/Essentials/src/messages_nl.properties +++ b/Essentials/src/messages_nl.properties @@ -373,6 +373,8 @@ timeSet=Tijd ingesteld in alle werelden. timeSetPermission=\u00a7cJe bent niet bevoegd om de tijd te veranderen. timeWorldCurrent=De actuele tijd in {0} is \u00a73{1} timeWorldSet=De tijd was veranderd naar {0} in: \u00a7c{1} +totalWorthAll=\u00a7aAlle spullen verkocht voor een totale waarde van {1}. +totalWorthBlocks=\u00a7aAlle blokken verkocht voor een totale waarde van {1}. tps=Huidige TPS = {0} tradeCompleted=\u00a77Ruil verricht. tradeSignEmpty=Dit handelsbord heeft een te kleine voorraad. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_pl.properties b/Essentials/src/messages_pl.properties index 7487679d8..45123abbe 100644 --- a/Essentials/src/messages_pl.properties +++ b/Essentials/src/messages_pl.properties @@ -373,6 +373,8 @@ timeSet=Czas ustawiono we wszystkich swiatach. timeSetPermission=\u00a7cNie masz uprawnien do ustawiania czasu. timeWorldCurrent=Obecny czas {0} to \u00a73{1}. timeWorldSet=Czas ustawiono {0} w: \u00a7c{1}. +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Handel zakonczono. tradeSignEmpty=Tabliczka handlowa nie jest dostepna dla Ciebie. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_pt.properties b/Essentials/src/messages_pt.properties index 3e24ee5b0..4a6ab2eee 100644 --- a/Essentials/src/messages_pt.properties +++ b/Essentials/src/messages_pt.properties @@ -373,6 +373,8 @@ timeSet=Horario definido em todos os mundos. timeSetPermission=\u00a7cVoc\u00ea nao tem autoriza\u00e7ao para modificar o hor\u00e1rio. timeWorldCurrent=O hor\u00e1rio atual no mundo {0} e \u00a73{1} timeWorldSet=O hor\u00e1rio foi definido para {0} no: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Current TPS = {0} tradeCompleted=\u00a77Compra concluida. tradeSignEmpty=A placa de troca nao tem abastecimento suficiente. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/messages_se.properties b/Essentials/src/messages_se.properties index 7a8115ab8..4ad4a5267 100644 --- a/Essentials/src/messages_se.properties +++ b/Essentials/src/messages_se.properties @@ -373,6 +373,8 @@ timeSet=Tid inst\u00e4lld i alla v\u00e4rldar. timeSetPermission=\u00a7cDu har inte tillst\u00e5nd att st\u00e4lla in tiden. timeWorldCurrent=Den nuvarande tiden i {0} \u00e4r \u00a73{1} timeWorldSet=Tiden \u00e4r nu {0} i: \u00a7c{1} +totalWorthAll=\u00a7aSold all items and blocks for a total worth of {1}. +totalWorthBlocks=\u00a7aSold all blocks for a total worth of {1}. tps=Nuvarande TPS = {0} tradeCompleted=\u00a77K\u00f6p avslutat. tradeSignEmpty=K\u00f6pskylten har inget tillg\u00e4ngligt f\u00f6r dig. @@ -463,3 +465,17 @@ userUnknown=\u00a74Warning: The user '\u00a7c{0}\u00a74' has never joined this s teleportationEnabledFor=\u00a76Teleportation enabled for {0} teleportationDisabledFor=\u00a76Teleportation disabled for {0} kitOnce=\u00a74You can't use that kit again. +fullStack=\u00a74You already have a full stack +oversizedTempban=\u00a74You may not ban a player for this period of time. +recipeNone=No recipes exist for {0} +invalidNumber=Invalid Number +recipeBadIndex=There is no recipe by that number +recipeNothing=nothing +recipe=\u00a76Recipe for \u00a7c{0}\u00a76 ({1} of {2}) +recipeFurnace=\u00a76Smelt \u00a7c{0} +recipeGrid=\u00a7{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X +recipeGridItem=\ \u00a7{0}X \u00a76is \u00a7c{1} +recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 to see other recipes for \u00a7c{2} +recipeWhere=\u00a76Where: {0} +recipeShapeless=\u00a76Combine \u00a7c{0} +playerChatDenied=\u00a76You do not have permission to speak. diff --git a/Essentials/src/plugin.yml b/Essentials/src/plugin.yml index 95c7e943a..37ec60147 100644 --- a/Essentials/src/plugin.yml +++ b/Essentials/src/plugin.yml @@ -233,7 +233,7 @@ commands: msg: description: Sends a private message to the specified player. usage: / - aliases: [m,t,emsg,tell,etell,whisper,ewhisper] + aliases: [w,m,t,emsg,tell,etell,whisper,ewhisper] mute: description: Mutes or unmutes a player. usage: / [datediff] @@ -278,6 +278,10 @@ commands: description: Displays the username of a user based on nick. usage: / aliases: [erealname] + recipe: + description: Displays how to craft items. + usage: / [number] + aliases: [method, formula, recipes, emethod, eformula, erecipes, erecipe] remove: description: Removes entities in your world usage: / [radius] @@ -454,4 +458,4 @@ commands: permissions: essentials.*: default: op - description: Give players with op everything by default \ No newline at end of file + description: Give players with op everything by default diff --git a/Essentials/test/com/earth2me/essentials/FakeServer.java b/Essentials/test/com/earth2me/essentials/FakeServer.java index e8b8ce01c..5d2ff0c88 100644 --- a/Essentials/test/com/earth2me/essentials/FakeServer.java +++ b/Essentials/test/com/earth2me/essentials/FakeServer.java @@ -16,10 +16,7 @@ import org.bukkit.command.PluginCommand; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; import org.bukkit.help.HelpMap; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.*; import org.bukkit.map.MapView; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -807,4 +804,16 @@ public class FakeServer implements Server { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String getShutdownMessage() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ItemFactory getItemFactory() + { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/EssentialsGroupManager/nbproject/project.properties b/EssentialsGroupManager/nbproject/project.properties index 26d72fd8a..bc26273ba 100644 --- a/EssentialsGroupManager/nbproject/project.properties +++ b/EssentialsGroupManager/nbproject/project.properties @@ -40,13 +40,13 @@ dist.jar=${dist.dir}/EssentialsGroupManager.jar dist.javadoc.dir=${dist.dir}/javadoc endorsed.classpath= excludes= -file.reference.craftbukkit.jar=../lib/craftbukkit.jar +file.reference.bukkit.jar=../lib/bukkit.jar includes=** jar.archive.disabled=${jnlp.enabled} jar.compress=true jar.index=${jnlp.enabled} javac.classpath=\ - ${file.reference.craftbukkit.jar} + ${file.reference.bukkit.jar} # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false diff --git a/EssentialsGroupManager/src/Changelog.txt b/EssentialsGroupManager/src/Changelog.txt index 077ea9163..4ea195a5d 100644 --- a/EssentialsGroupManager/src/Changelog.txt +++ b/EssentialsGroupManager/src/Changelog.txt @@ -201,4 +201,6 @@ v 2.0: - Remove info node support from GlobalGroups. It should not have them as GlobalGroups are only permission collections. - Change order of data in Users.yml to [name, Group, SubGroup, Permissions, Info nodes]. - Add alphabetically sorted user lists. - - allWorldsDataList now returns fully mirrored worlds which are not identical mirrors (fixes the /manselect list). \ No newline at end of file + - allWorldsDataList now returns fully mirrored worlds which are not identical mirrors (fixes the /manselect list). + - Add support for Rcon. + - Prevent GM commands from being used on CommandBlocks. \ No newline at end of file diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java index 3daea93eb..fe7808238 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java @@ -34,9 +34,11 @@ import org.anjocaido.groupmanager.utils.Tasks; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; +import org.bukkit.command.BlockCommandSender; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.RemoteConsoleCommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.ServicePriority; @@ -380,6 +382,12 @@ public class GroupManager extends JavaPlugin { Group senderGroup = null; User senderUser = null; boolean isOpOverride = config.isOpOverride(); + + // PREVENT GM COMMANDS BEING USED ON COMMANDBLOCKS + if (sender instanceof BlockCommandSender) { + sender.sendMessage(ChatColor.RED + "GM Commands can not be called from CommandBlocks"); + return true; + } if (sender.getClass().getName().equals("org.bukkit.craftbukkit.command.CraftBlockCommandSender")) { sender.sendMessage(ChatColor.RED + "GM Commands can not be called from CommandBlocks"); @@ -403,7 +411,7 @@ public class GroupManager extends JavaPlugin { if (isOpOverride || worldsHolder.getWorldPermissions(senderPlayer).has(senderPlayer, "groupmanager." + cmd.getName())) { playerCanDo = true; } - } else if (sender instanceof ConsoleCommandSender) { + } else if ((sender instanceof ConsoleCommandSender) || (sender instanceof RemoteConsoleCommandSender)) { if (!lastError.isEmpty() && !commandLabel.equalsIgnoreCase("manload")) { sender.sendMessage(ChatColor.RED + "All commands are locked due to an error." + ChatColor.BOLD + "" + ChatColor.UNDERLINE + "Check the log" + ChatColor.RESET + " and then try a '/manload'."); diff --git a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java index 92fec7737..12a6a5150 100644 --- a/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java +++ b/EssentialsGroupManager/src/org/anjocaido/groupmanager/dataholder/worlds/WorldsHolder.java @@ -204,10 +204,10 @@ public class WorldsHolder { mirroredWorlds.add((String)key); } else - GroupManager.logger.log(Level.WARNING, "Mirroring error with " + (String)key + ". Recursive loop detected!"); + throw new IllegalStateException("Unknown mirroring format for " + (String)key); } else { - throw new IllegalStateException("Unknown mirroring format for " + (String)key); + GroupManager.logger.log(Level.WARNING, "Mirroring error with " + (String)key + ". Recursive loop detected!"); } } diff --git a/lib/bukkit.jar b/lib/bukkit.jar index 4b282ee2b..7abca416e 100644 Binary files a/lib/bukkit.jar and b/lib/bukkit.jar differ diff --git a/lib/craftbukkit.jar b/lib/craftbukkit.jar index beff3e4a8..6f375cc83 100644 Binary files a/lib/craftbukkit.jar and b/lib/craftbukkit.jar differ