summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKHobbits <rob@khobbits.co.uk>2012-12-19 12:54:00 +0000
committerKHobbits <rob@khobbits.co.uk>2012-12-19 12:54:00 +0000
commit4e399778b4ca83a8371cf426e44094a27a6ebbba (patch)
tree5d888cf58eeeb508a508b2c0d14d44ca1ca04037
parent9ba5f43315238795b2d3c25a306a2ad2f3b35a2f (diff)
parent0bde3641256aa48a104cd8bb6eaeb5201fcd1844 (diff)
downloadEssentials-4e399778b4ca83a8371cf426e44094a27a6ebbba.tar
Essentials-4e399778b4ca83a8371cf426e44094a27a6ebbba.tar.gz
Essentials-4e399778b4ca83a8371cf426e44094a27a6ebbba.tar.lz
Essentials-4e399778b4ca83a8371cf426e44094a27a6ebbba.tar.xz
Essentials-4e399778b4ca83a8371cf426e44094a27a6ebbba.zip
Merge branch '2.9' of github.com:essentials/Essentials into 2.9
-rw-r--r--Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java19
-rw-r--r--Essentials/src/com/earth2me/essentials/ISettings.java2
-rw-r--r--Essentials/src/com/earth2me/essentials/Settings.java6
-rw-r--r--Essentials/src/com/earth2me/essentials/User.java11
-rwxr-xr-xEssentials/src/com/earth2me/essentials/commands/Commandrecipe.java167
-rw-r--r--Essentials/src/com/earth2me/essentials/commands/Commandtempban.java11
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java28
-rw-r--r--Essentials/src/config.yml4
-rw-r--r--Essentials/src/messages.properties12
-rw-r--r--Essentials/src/messages_cs.properties12
-rw-r--r--Essentials/src/messages_da.properties12
-rw-r--r--Essentials/src/messages_de.properties12
-rw-r--r--Essentials/src/messages_en.properties12
-rw-r--r--Essentials/src/messages_es.properties12
-rw-r--r--Essentials/src/messages_fi.properties12
-rw-r--r--Essentials/src/messages_fr.properties12
-rw-r--r--Essentials/src/messages_it.properties12
-rw-r--r--Essentials/src/messages_nl.properties12
-rw-r--r--Essentials/src/messages_pl.properties12
-rw-r--r--Essentials/src/messages_pt.properties12
-rw-r--r--Essentials/src/messages_se.properties12
-rw-r--r--Essentials/src/plugin.yml4
22 files changed, 380 insertions, 28 deletions
diff --git a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java
index 2b0704779..433fe816f 100644
--- a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java
+++ b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java
@@ -538,6 +538,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)
@@ -553,8 +561,17 @@ 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)
{
diff --git a/Essentials/src/com/earth2me/essentials/ISettings.java b/Essentials/src/com/earth2me/essentials/ISettings.java
index fb0073c8a..1ad9b0207 100644
--- a/Essentials/src/com/earth2me/essentials/ISettings.java
+++ b/Essentials/src/com/earth2me/essentials/ISettings.java
@@ -183,4 +183,6 @@ public interface ISettings extends IConf
public int getMailsPerMinute();
public void setEssentialsChatActive(boolean b);
+
+ long getMaxTempban();
}
diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java
index a8ef1a344..43b7dea30 100644
--- a/Essentials/src/com/earth2me/essentials/Settings.java
+++ b/Essentials/src/com/earth2me/essentials/Settings.java
@@ -986,4 +986,10 @@ public class Settings implements ISettings
{
return mailsPerMinute;
}
+
+ @Override
+ public long getMaxTempban()
+ {
+ return config.getLong("max-tempban-time", -1);
+ }
}
diff --git a/Essentials/src/com/earth2me/essentials/User.java b/Essentials/src/com/earth2me/essentials/User.java
index 5de4b7609..1c5d04530 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<User>, 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");
@@ -743,4 +744,14 @@ public class User extends UserData implements Comparable<User>, 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/Commandrecipe.java b/Essentials/src/com/earth2me/essentials/commands/Commandrecipe.java
new file mode 100755
index 000000000..80f7ed71a
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/commands/Commandrecipe.java
@@ -0,0 +1,167 @@
+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 item = ess.getItemDb().get(args[0]);
+ final List<Recipe> recipes = ess.getServer().getRecipesFor(item);
+ if (recipes.size() < 1)
+ {
+ throw new Exception(_("recipeNone", getMaterialName(item)));
+ }
+ int recipeNo = 0;
+ if (args.length > 1)
+ {
+ if (Util.isInt(args[1]))
+ {
+ recipeNo = Integer.parseInt(args[1]) - 1;
+ }
+ else
+ {
+ throw new Exception(_("invalidNumber"));
+ }
+ }
+ if (recipeNo < 0 || recipeNo >= recipes.size())
+ {
+ throw new Exception(_("recipeBadIndex"));
+ }
+ final Recipe recipe = recipes.get(recipeNo);
+ sender.sendMessage(_("recipe", getMaterialName(item), recipeNo + 1, recipes.size()));
+ if (recipe instanceof FurnaceRecipe)
+ {
+ furnaceRecipe(sender, (FurnaceRecipe)recipe);
+ }
+ else if (recipe instanceof ShapedRecipe)
+ {
+ shapedRecipe(sender, (ShapedRecipe)recipe);
+ }
+ else if (recipe instanceof ShapelessRecipe)
+ {
+ shapelessRecipe(sender, (ShapelessRecipe)recipe);
+ }
+ if (recipes.size() > 1 && args.length == 1)
+ {
+ sender.sendMessage(_("recipeMore", commandLabel, args[0], getMaterialName(item)));
+ }
+ }
+
+ public void furnaceRecipe(CommandSender sender, FurnaceRecipe recipe)
+ {
+ sender.sendMessage(_("recipeFurnace", getMaterialName(recipe.getInput())));
+ }
+
+ public void shapedRecipe(CommandSender sender, ShapedRecipe recipe)
+ {
+ Map<Character, ItemStack> recipeMap = recipe.getIngredientMap();
+ if (!(sender instanceof Player))
+ {
+ HashMap<ItemStack, String> colorMap = new HashMap<ItemStack, String>();
+ int i = 1;
+ for (Character c : "abcdefghi".toCharArray())
+ {
+ if (!colorMap.containsKey(recipeMap.get(c)))
+ {
+ colorMap.put(recipeMap.get(c), String.valueOf(i++));
+ }
+ }
+ sender.sendMessage(_("recipeGrid", colorMap.get(recipeMap.get('a')), colorMap.get(recipeMap.get('b')), colorMap.get(recipeMap.get('c'))));
+ sender.sendMessage(_("recipeGrid", colorMap.get(recipeMap.get('d')), colorMap.get(recipeMap.get('e')), colorMap.get(recipeMap.get('f'))));
+ sender.sendMessage(_("recipeGrid", colorMap.get(recipeMap.get('g')), colorMap.get(recipeMap.get('h')), colorMap.get(recipeMap.get('i'))));
+
+ StringBuilder s = new StringBuilder();
+ for (ItemStack items : colorMap.keySet().toArray(new ItemStack[colorMap.size()]))
+ {
+ s.append(_("recipeGridItem", colorMap.get(items), getMaterialName(items)));
+ }
+ sender.sendMessage(_("recipeWhere", s.toString()));
+ }
+ else
+ {
+ User user = ess.getUser(sender);
+ user.setRecipeSee(true);
+ InventoryView view = user.openWorkbench(null, true);
+ for (Entry<Character, ItemStack> e : ((ShapedRecipe)recipe).getIngredientMap().entrySet())
+ {
+ view.setItem(" abcdefghi".indexOf(e.getKey()), e.getValue());
+ }
+ }
+ }
+
+ public void shapelessRecipe(CommandSender sender, ShapelessRecipe recipe)
+ {
+ List<ItemStack> ingredients = recipe.getIngredientList();
+ if (!(sender instanceof Player))
+ {
+ 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()));
+ }
+ else
+ {
+ User user = ess.getUser(sender);
+ user.setRecipeSee(true);
+ InventoryView view = user.openWorkbench(null, true);
+ for (int i = 0; i < ingredients.size(); i++)
+ {
+ view.setItem(i + 1, ingredients.get(i));
+ }
+ }
+ }
+
+ public String getMaterialName(ItemStack stack)
+ {
+ if (stack == null)
+ {
+ return _("recipeNothing");
+ }
+ return getMaterialName(stack.getType());
+ }
+
+ public String getMaterialName(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/Commandtempban.java b/Essentials/src/com/earth2me/essentials/commands/Commandtempban.java
index 0549e9c0d..4ac2db89c 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 max = ess.getSettings().getMaxTempban();
+ if(max != 0 && banTimestamp - GregorianCalendar.getInstance().getTimeInMillis() > max * 1000 && 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/storage/BukkitConstructor.java b/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java
index b6fbe3b33..e5fc19ea3 100644
--- a/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java
+++ b/Essentials/src/com/earth2me/essentials/storage/BukkitConstructor.java
@@ -284,7 +284,8 @@ public class BukkitConstructor extends Constructor
final Field typeDefField = Constructor.class.getDeclaredField("typeDefinitions");
typeDefField.setAccessible(true);
typeDefinitions = (Map<Class<? extends Object>, TypeDescription>)typeDefField.get((Constructor)BukkitConstructor.this);
- if (typeDefinitions == null) {
+ if (typeDefinitions == null)
+ {
throw new NullPointerException();
}
}
@@ -402,29 +403,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/config.yml b/Essentials/src/config.yml
index a766e0549..e428354a8 100644
--- a/Essentials/src/config.yml
+++ b/Essentials/src/config.yml
@@ -351,6 +351,10 @@ sethome-multiple:
# Set to 0 for no timeout
tpa-accept-cancellation: 0
+# 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
+
############################################################
# +------------------------------------------------------+ #
# | EssentialsEco | #
diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties
index 8a17513cf..170f4b371 100644
--- a/Essentials/src/messages.properties
+++ b/Essentials/src/messages.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_cs.properties b/Essentials/src/messages_cs.properties
index 5cc095f15..37a2e5c78 100644
--- a/Essentials/src/messages_cs.properties
+++ b/Essentials/src/messages_cs.properties
@@ -469,3 +469,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_da.properties b/Essentials/src/messages_da.properties
index 6beff781a..bf8105ea6 100644
--- a/Essentials/src/messages_da.properties
+++ b/Essentials/src/messages_da.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_de.properties b/Essentials/src/messages_de.properties
index 4db624c6a..1e4af4cb6 100644
--- a/Essentials/src/messages_de.properties
+++ b/Essentials/src/messages_de.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_en.properties b/Essentials/src/messages_en.properties
index 8a17513cf..170f4b371 100644
--- a/Essentials/src/messages_en.properties
+++ b/Essentials/src/messages_en.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_es.properties b/Essentials/src/messages_es.properties
index 8d0ad7892..c9eb4562e 100644
--- a/Essentials/src/messages_es.properties
+++ b/Essentials/src/messages_es.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_fi.properties b/Essentials/src/messages_fi.properties
index fef0aeb78..ccfe32b4b 100644
--- a/Essentials/src/messages_fi.properties
+++ b/Essentials/src/messages_fi.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_fr.properties b/Essentials/src/messages_fr.properties
index e5cfd4975..1a45b51c4 100644
--- a/Essentials/src/messages_fr.properties
+++ b/Essentials/src/messages_fr.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_it.properties b/Essentials/src/messages_it.properties
index f24899599..c6ee3e5d8 100644
--- a/Essentials/src/messages_it.properties
+++ b/Essentials/src/messages_it.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_nl.properties b/Essentials/src/messages_nl.properties
index 0c4fd2cd0..589ca60e1 100644
--- a/Essentials/src/messages_nl.properties
+++ b/Essentials/src/messages_nl.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_pl.properties b/Essentials/src/messages_pl.properties
index 804784f19..9b9ff06b8 100644
--- a/Essentials/src/messages_pl.properties
+++ b/Essentials/src/messages_pl.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_pt.properties b/Essentials/src/messages_pt.properties
index 4c039bc1c..a0ebd8ad5 100644
--- a/Essentials/src/messages_pt.properties
+++ b/Essentials/src/messages_pt.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/messages_se.properties b/Essentials/src/messages_se.properties
index b6017786b..4b8f5ae4e 100644
--- a/Essentials/src/messages_se.properties
+++ b/Essentials/src/messages_se.properties
@@ -466,3 +466,15 @@ 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
+recipeShapeless=\u00a7eCombine \u00a7c{0}
+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 <number> to see other recipes for \u00a7c{2}
+recipeWhere=\u00a76Where: {0}
diff --git a/Essentials/src/plugin.yml b/Essentials/src/plugin.yml
index ab9b2438e..bd6aea253 100644
--- a/Essentials/src/plugin.yml
+++ b/Essentials/src/plugin.yml
@@ -278,6 +278,10 @@ commands:
description: Displays the username of a user based on nick.
usage: /<command> <nickname>
aliases: [erealname]
+ recipe:
+ description: Displays how to craft items.
+ usage: /<command> <item> [number]
+ aliases: [erecipe]
remove:
description: Removes entities in your world
usage: /<command> <drops|arrows|boats|minecarts|xp|paintings> [radius]