diff --git a/pom.xml b/pom.xml index e270ec2..e5abfc0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.acrobot.chestshop chestshop - 3.10.2-SNAPSHOT + 3.11-SNAPSHOT Chest-and-sign shop plugin for Bukkit ChestShop @@ -70,6 +70,20 @@ compile + + de.themoep.utils + lang-bukkit + 1.2-SNAPSHOT + compile + + + + de.themoep + minedown + 1.6.1-SNAPSHOT + compile + + org.apache.logging.log4j @@ -348,6 +362,8 @@ + de.themoep:* + de.themoep.utils:* org.bstats:* net.gravitydevelopment.updater com.j256.ormlite @@ -356,6 +372,14 @@ + + de.themoep.utils.lang + com.Acrobot.ChestShop.Lang + + + de.themoep.minedown + com.Acrobot.ChestShop.MineDown + org.bstats com.Acrobot.ChestShop.Metrics.BStats @@ -406,7 +430,7 @@ default - !bukkit + !spigot @@ -426,7 +450,7 @@ - bukkit + spigot spigotmc-repo @@ -435,8 +459,8 @@ - org.bukkit - bukkit + org.spigotmc + spigot-api 1.13.2-R0.1-SNAPSHOT provided @@ -445,7 +469,7 @@ true - ${project.name}-Bukkit + ${project.name}-Spigot maven-compiler-plugin diff --git a/src/main/java/com/Acrobot/Breeze/Utils/MaterialUtil.java b/src/main/java/com/Acrobot/Breeze/Utils/MaterialUtil.java index ee6801e..171fd9f 100644 --- a/src/main/java/com/Acrobot/Breeze/Utils/MaterialUtil.java +++ b/src/main/java/com/Acrobot/Breeze/Utils/MaterialUtil.java @@ -2,14 +2,17 @@ package com.Acrobot.Breeze.Utils; import com.Acrobot.Breeze.Collection.SimpleCache; import com.Acrobot.ChestShop.ChestShop; +import com.Acrobot.ChestShop.Configuration.Messages; import com.Acrobot.ChestShop.Configuration.Properties; import com.Acrobot.ChestShop.Events.ItemParseEvent; import com.Acrobot.ChestShop.Events.MaterialParseEvent; import com.google.common.collect.ImmutableMap; import de.themoep.ShowItem.api.ShowItem; +import de.themoep.minedown.Replacer; import info.somethingodd.OddItem.OddItem; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.configuration.file.YamlConstructor; import org.bukkit.configuration.file.YamlRepresenter; @@ -25,6 +28,7 @@ import org.yaml.snakeyaml.nodes.Tag; import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -520,7 +524,7 @@ public class MaterialUtil { * @param message The raw message * @param stock The items in stock */ - public static boolean sendMessage(Player player, String message, ItemStack[] stock) { + public static boolean sendMessage(Player player, Messages.Message message, ItemStack[] stock, Map replacementMap, String... replacements) { if (showItem == null) { return false; } @@ -537,6 +541,15 @@ public class MaterialUtil { String joinedItemJson = itemJson.stream().collect(Collectors.joining("," + new JSONObject(ImmutableMap.of("text", " ")).toJSONString() + ", ")); + Map newMap = new LinkedHashMap<>(replacementMap); + newMap.put("material", "item"); + BaseComponent[] components = message.getComponents(player, true, newMap, replacements); + player.spigot().sendMessage(new Replacer() + .placeholderSuffix("") + .replace("item", ComponentSerializer.parse("[" + joinedItemJson + "]")) + .replaceIn(components)); + + /* String prevColor = ""; List parts = new ArrayList<>(); for (String s : message.split("%item")) { @@ -554,7 +567,7 @@ public class MaterialUtil { } showItem.tellRaw(player, messageJsonString); - return true; + */return true; } } } diff --git a/src/main/java/com/Acrobot/ChestShop/ChestShop.java b/src/main/java/com/Acrobot/ChestShop/ChestShop.java index b3b7234..65ef7bc 100644 --- a/src/main/java/com/Acrobot/ChestShop/ChestShop.java +++ b/src/main/java/com/Acrobot/ChestShop/ChestShop.java @@ -167,11 +167,12 @@ public class ChestShop extends JavaPlugin { public void loadConfig() { Configuration.pairFileAndClass(loadFile("config.yml"), Properties.class, getBukkitLogger()); - Configuration.pairFileAndClass(loadFile("local.yml"), Messages.class, getBukkitLogger()); + + Messages.load(); NameManager.load(); - commands.forEach(c -> c.setPermissionMessage(Messages.prefix(Messages.ACCESS_DENIED))); + commands.forEach(c -> c.setPermissionMessage(Messages.ACCESS_DENIED.getTextWithPrefix(null))); } private void turnOffDatabaseLogging() { @@ -517,6 +518,11 @@ public class ChestShop extends JavaPlugin { Bukkit.getPluginManager().callEvent(event); } + public static void sendBungeeMessage(String playerName, Messages.Message message, Map replacementMap, String... replacements) { + // TODO: Component support for bungee messages? + sendBungeeMessage(playerName, message.getTextWithPrefix(null, replacementMap, replacements)); + } + public static void sendBungeeMessage(String playerName, String message) { if (Properties.BUNGEECORD_MESSAGES && !Bukkit.getOnlinePlayers().isEmpty()) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); diff --git a/src/main/java/com/Acrobot/ChestShop/Commands/AccessToggle.java b/src/main/java/com/Acrobot/ChestShop/Commands/AccessToggle.java index f79182a..79769ef 100644 --- a/src/main/java/com/Acrobot/ChestShop/Commands/AccessToggle.java +++ b/src/main/java/com/Acrobot/ChestShop/Commands/AccessToggle.java @@ -26,9 +26,9 @@ public class AccessToggle implements CommandExecutor { Player player = (Player) sender; if (setIgnoring(player, !isIgnoring(player))) { - player.sendMessage(Messages.prefix(Messages.TOGGLE_ACCESS_OFF)); + Messages.TOGGLE_ACCESS_OFF.sendWithPrefix(player); } else { - player.sendMessage(Messages.prefix(Messages.TOGGLE_ACCESS_ON)); + Messages.TOGGLE_ACCESS_ON.sendWithPrefix(player); } return true; diff --git a/src/main/java/com/Acrobot/ChestShop/Commands/Give.java b/src/main/java/com/Acrobot/ChestShop/Commands/Give.java index 6a7941a..817d973 100644 --- a/src/main/java/com/Acrobot/ChestShop/Commands/Give.java +++ b/src/main/java/com/Acrobot/ChestShop/Commands/Give.java @@ -58,23 +58,21 @@ public class Give implements CommandExecutor { } if (receiver == null) { - sender.sendMessage(Messages.prefix(Messages.PLAYER_NOT_FOUND)); + Messages.PLAYER_NOT_FOUND.sendWithPrefix(sender); return true; } ItemStack item = getItem(args, disregardedIndexes); if (MaterialUtil.isEmpty(item)) { - sender.sendMessage(Messages.prefix(Messages.INCORRECT_ITEM_ID)); + Messages.INCORRECT_ITEM_ID.sendWithPrefix(sender); return true; } item.setAmount(quantity); InventoryUtil.add(item, receiver.getInventory()); - sender.sendMessage(Messages.prefix(Messages.ITEM_GIVEN - .replace("%item", MaterialUtil.getName(item)) - .replace("%player", receiver.getName()))); + Messages.ITEM_GIVEN.send(sender, "item", MaterialUtil.getName(item), "player", receiver.getName()); return true; } diff --git a/src/main/java/com/Acrobot/ChestShop/Commands/ItemInfo.java b/src/main/java/com/Acrobot/ChestShop/Commands/ItemInfo.java index 8505cea..1c9c66d 100644 --- a/src/main/java/com/Acrobot/ChestShop/Commands/ItemInfo.java +++ b/src/main/java/com/Acrobot/ChestShop/Commands/ItemInfo.java @@ -44,9 +44,9 @@ public class ItemInfo implements CommandExecutor { return false; } - sender.sendMessage(replace(iteminfo)); + iteminfo.send(sender); try { - sender.sendMessage(replace(iteminfo_fullname, "item", MaterialUtil.getName(item))); + iteminfo_fullname.send(sender, "item", MaterialUtil.getName(item)); } catch (IllegalArgumentException e) { sender.sendMessage(ChatColor.RED + "Error while generating full name. Please contact an admin or take a look at the console/log!"); ChestShop.getPlugin().getLogger().log(Level.SEVERE, "Error while generating full item name", e); @@ -54,7 +54,7 @@ public class ItemInfo implements CommandExecutor { } try { - sender.sendMessage(replace(iteminfo_shopname, "item", MaterialUtil.getSignName(item))); + iteminfo_shopname.send(sender, "item", MaterialUtil.getSignName(item)); } catch (IllegalArgumentException e) { sender.sendMessage(ChatColor.RED + "Error while generating shop sign name. Please contact an admin or take a look at the console/log!"); ChestShop.getPlugin().getLogger().log(Level.SEVERE, "Error while generating shop sign item name", e); diff --git a/src/main/java/com/Acrobot/ChestShop/Commands/Metrics.java b/src/main/java/com/Acrobot/ChestShop/Commands/Metrics.java index b5f5340..079bb7e 100644 --- a/src/main/java/com/Acrobot/ChestShop/Commands/Metrics.java +++ b/src/main/java/com/Acrobot/ChestShop/Commands/Metrics.java @@ -12,7 +12,7 @@ import org.bukkit.command.CommandSender; */ public class Metrics implements CommandExecutor { public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - sender.sendMessage(Messages.replace(Messages.METRICS, + Messages.METRICS.send(sender, "accounts", String.valueOf(NameManager.getAccountCount()), "totalTransactions", String.valueOf(MetricsModule.getTotalTransactions()), "buyTransactions", String.valueOf(MetricsModule.getBuyTransactions()), @@ -20,7 +20,7 @@ public class Metrics implements CommandExecutor { "totalItems", String.valueOf(MetricsModule.getTotalItemsCount()), "boughtItems", String.valueOf(MetricsModule.getBoughtItemsCount()), "soldItems", String.valueOf(MetricsModule.getSoldItemsCount()) - )); + ); return true; } } diff --git a/src/main/java/com/Acrobot/ChestShop/Commands/Toggle.java b/src/main/java/com/Acrobot/ChestShop/Commands/Toggle.java index 2742d11..cb50706 100644 --- a/src/main/java/com/Acrobot/ChestShop/Commands/Toggle.java +++ b/src/main/java/com/Acrobot/ChestShop/Commands/Toggle.java @@ -32,9 +32,9 @@ public class Toggle implements CommandExecutor { } if (setIgnoring(player, !isIgnoring(player))) { - player.sendMessage(Messages.prefix(Messages.TOGGLE_MESSAGES_OFF)); + Messages.TOGGLE_MESSAGES_OFF.sendWithPrefix(player); } else { - player.sendMessage(Messages.prefix(Messages.TOGGLE_MESSAGES_ON)); + Messages.TOGGLE_MESSAGES_ON.sendWithPrefix(player); } return true; diff --git a/src/main/java/com/Acrobot/ChestShop/Configuration/Messages.java b/src/main/java/com/Acrobot/ChestShop/Configuration/Messages.java index abd5426..190ea42 100644 --- a/src/main/java/com/Acrobot/ChestShop/Configuration/Messages.java +++ b/src/main/java/com/Acrobot/ChestShop/Configuration/Messages.java @@ -1,116 +1,194 @@ package com.Acrobot.ChestShop.Configuration; -import com.Acrobot.Breeze.Configuration.Annotations.PrecededBySpace; import com.Acrobot.Breeze.Configuration.Configuration; +import com.Acrobot.ChestShop.ChestShop; +import de.themoep.minedown.MineDown; +import de.themoep.utils.lang.bukkit.BukkitLanguageConfig; +import de.themoep.utils.lang.bukkit.LanguageManager; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.command.CommandSender; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.Map; +import java.util.logging.Level; /** * @author Acrobot */ public class Messages { - public static String prefix = "&a[Shop] &r"; - public static String iteminfo = "&aItem Information: &r"; - public static String iteminfo_fullname = "&fFull Name: &7%item"; - public static String iteminfo_shopname = "&fShop Sign: &7%item"; - public static String iteminfo_repaircost = "&fRepair Cost: &7%cost"; - public static String iteminfo_book = "&fBook Title: &7%title\n&fBook Author: &7%author\n&fBook Pages: &7%pages"; - public static String iteminfo_book_generatopm = "&fBook Generation: &7%generation"; - public static String iteminfo_lore = "&fLore: \n&r%lore"; + public static Message prefix; + public static Message iteminfo; + public static Message iteminfo_fullname; + public static Message iteminfo_shopname; + public static Message iteminfo_repaircost; + public static Message iteminfo_book; + public static Message iteminfo_book_generatopm; + public static Message iteminfo_lore; - @PrecededBySpace - public static String METRICS = "&a[Shop] &fMetrics:\n" + - "&fAccounts: &7%accounts\n" + - "&fAverage transactions: &7%totalTransactions &f(buy: &7%buyTransactions &fsell: &7%sellTransactions&f)\n" + - "&fAverage items traded: &7%totalItems &f(bought: &7%boughtItems &fsold: &7%soldItems&f)"; + public static Message METRICS; - @PrecededBySpace - public static String ACCESS_DENIED = "You don't have permission to access that shop's storage container!"; - public static String TRADE_DENIED = "You don't have permission to trade with that shop!"; + public static Message ACCESS_DENIED; + public static Message TRADE_DENIED; - @PrecededBySpace - public static String NOT_ENOUGH_MONEY = "You don't have enough money!"; - public static String NOT_ENOUGH_MONEY_SHOP = "Shop owner doesn't have enough money!"; + public static Message NOT_ENOUGH_MONEY; + public static Message NOT_ENOUGH_MONEY_SHOP; - @PrecededBySpace - public static String CLIENT_DEPOSIT_FAILED = "Money deposit to your account failed!"; - public static String SHOP_DEPOSIT_FAILED = "Money deposit to shop owner failed!"; - public static String NO_ECONOMY_ACCOUNT = "Economy account from shop owner doesn't exist!"; + public static Message CLIENT_DEPOSIT_FAILED; + public static Message SHOP_DEPOSIT_FAILED; + public static Message NO_ECONOMY_ACCOUNT; - @PrecededBySpace - public static String NO_BUYING_HERE = "You can't buy here!"; - public static String NO_SELLING_HERE = "You can't sell here!"; + public static Message NO_BUYING_HERE; + public static Message NO_SELLING_HERE; - @PrecededBySpace - public static String NOT_ENOUGH_SPACE_IN_INVENTORY = "You haven't got enough space in inventory!"; - public static String NOT_ENOUGH_SPACE_IN_CHEST = "There isn't enough space in chest!"; - public static String NOT_ENOUGH_ITEMS_TO_SELL = "You don't have enough items to sell!"; - public static String NOT_ENOUGH_SPACE_IN_YOUR_SHOP = "%price %item&7 shop at &r%world/%x/%y/%z&7 is full! (%seller tried to sell)"; + public static Message NOT_ENOUGH_SPACE_IN_INVENTORY; + public static Message NOT_ENOUGH_SPACE_IN_CHEST; + public static Message NOT_ENOUGH_ITEMS_TO_SELL; + public static Message NOT_ENOUGH_SPACE_IN_YOUR_SHOP; - @PrecededBySpace - public static String NOT_ENOUGH_STOCK = "This shop is out of stock."; - public static String NOT_ENOUGH_STOCK_IN_YOUR_SHOP = "%price %item&7 shop at &r%world/%x/%y/%z&7 is out of stock! (%buyer tried to buy)"; + public static Message NOT_ENOUGH_STOCK; + public static Message NOT_ENOUGH_STOCK_IN_YOUR_SHOP; - @PrecededBySpace - public static String YOU_BOUGHT_FROM_SHOP = "You bought %item from %owner for %price."; - public static String SOMEBODY_BOUGHT_FROM_YOUR_SHOP = "%buyer bought %item for %price from your shop at %world/%x/%y/%z."; + public static Message YOU_BOUGHT_FROM_SHOP; + public static Message SOMEBODY_BOUGHT_FROM_YOUR_SHOP; - @PrecededBySpace - public static String YOU_SOLD_TO_SHOP = "You sold %item to %buyer for %price."; - public static String SOMEBODY_SOLD_TO_YOUR_SHOP = "%seller sold %item for %price to your shop at %world/%x/%y/%z."; + public static Message YOU_SOLD_TO_SHOP; + public static Message SOMEBODY_SOLD_TO_YOUR_SHOP; - @PrecededBySpace - public static String YOU_CANNOT_CREATE_SHOP = "You can't create this type of shop!"; - public static String NO_CHEST_DETECTED = "Couldn't find a chest!"; - public static String INVALID_SHOP_DETECTED = "The shop cannot be used!"; - public static String INVALID_SHOP_PRICE = "The shop has an invalid price!"; - public static String INVALID_SHOP_QUANTITY = "The shop has an invalid quantity!"; - public static String CANNOT_ACCESS_THE_CHEST = "You don't have permissions to access this chest!"; + public static Message YOU_CANNOT_CREATE_SHOP; + public static Message NO_CHEST_DETECTED; + public static Message INVALID_SHOP_DETECTED; + public static Message INVALID_SHOP_PRICE; + public static Message INVALID_SHOP_QUANTITY; + public static Message CANNOT_ACCESS_THE_CHEST; - @PrecededBySpace - public static String SELL_PRICE_ABOVE_MAX = "Sell price is above maximum!"; - public static String SELL_PRICE_BELOW_MIN ="Sell price is below minimum!"; - public static String BUY_PRICE_ABOVE_MAX = "Buy price is above maximum!"; - public static String BUY_PRICE_BELOW_MIN ="Buy price is below minimum!"; + public static Message SELL_PRICE_ABOVE_MAX; + public static Message SELL_PRICE_BELOW_MIN; + public static Message BUY_PRICE_ABOVE_MAX; + public static Message BUY_PRICE_BELOW_MIN; - @PrecededBySpace - public static String CLICK_TO_AUTOFILL_ITEM = "Click the sign with the item that this shop is for!"; - public static String NO_ITEM_IN_HAND = "You don't have an item in your hand to autofill!"; + public static Message CLICK_TO_AUTOFILL_ITEM; + public static Message NO_ITEM_IN_HAND; - @PrecededBySpace - public static String PROTECTED_SHOP = "Successfully protected the shop with LWC!"; - public static String PROTECTED_SHOP_SIGN = "Successfully protected the shop sign with LWC!"; - public static String SHOP_CREATED = "Shop successfully created!"; - public static String SHOP_FEE_PAID = "You have been charged %amount"; - public static String SHOP_REFUNDED = "You have been refunded %amount."; - public static String ITEM_GIVEN = "Given %item to %player."; + public static Message PROTECTED_SHOP; + public static Message PROTECTED_SHOP_SIGN; + public static Message SHOP_CREATED; + public static Message SHOP_FEE_PAID; + public static Message SHOP_REFUNDED; + public static Message ITEM_GIVEN; - @PrecededBySpace - public static String RESTRICTED_SIGN_CREATED = "Sign successfully created!"; + public static Message RESTRICTED_SIGN_CREATED; - @PrecededBySpace - public static String PLAYER_NOT_FOUND = "Player not found!"; - public static String NO_PERMISSION = "You don't have permissions to do that!"; - public static String INCORRECT_ITEM_ID = "You have specified an invalid item id!"; - public static String NOT_ENOUGH_PROTECTIONS = "Could not create a protection!"; + public static Message PLAYER_NOT_FOUND; + public static Message NO_PERMISSION; + public static Message INCORRECT_ITEM_ID; + public static Message NOT_ENOUGH_PROTECTIONS; - @PrecededBySpace - public static String CANNOT_CREATE_SHOP_HERE = "You can't create shop here!"; + public static Message CANNOT_CREATE_SHOP_HERE; - @PrecededBySpace - public static String TOGGLE_MESSAGES_OFF = "You will no longer receive messages from your shop(s)."; - public static String TOGGLE_MESSAGES_ON = "You will now receive messages from your shop(s)."; + public static Message TOGGLE_MESSAGES_OFF; + public static Message TOGGLE_MESSAGES_ON; - @PrecededBySpace - public static String TOGGLE_ACCESS_ON = "You can no longer trade at shops that you have access to"; - public static String TOGGLE_ACCESS_OFF = "You can now trade at shops that you have access to"; + public static Message TOGGLE_ACCESS_ON; + public static Message TOGGLE_ACCESS_OFF; + @Deprecated public static String prefix(String message) { - return Configuration.getColoured(prefix + message); + return Configuration.getColoured(prefix.getLang(null) + message); } + @Deprecated public static String replace(String message, String... replacements) { for (int i = 0; i + 1 < replacements.length; i+=2) { message = message.replace("%" + replacements[i], replacements[i+1]); } return Configuration.getColoured(message); } + + private static LanguageManager manager; + + public static void load() { + for (Field field : Messages.class.getFields()) { + if (!Modifier.isStatic(field.getModifiers())) { + continue; + } + try { + field.set(null, new Message(field.getName())); + } catch (IllegalAccessException e) { + ChestShop.getBukkitLogger().log(Level.SEVERE, "Error while setting Message " + field.getName() + "!", e); + } + } + manager = new LanguageManager(ChestShop.getPlugin(), Properties.DEFAULT_LANGUAGE); + + // Legacy locale.yml file + File legacyFile = new File(ChestShop.getPlugin().getDataFolder(), "local.yml"); + if (legacyFile.exists()) { + ChestShop.getBukkitLogger().log(Level.INFO, "Found legacy local.yml. Loading it as 'legacy' language and using that for all messages."); + ChestShop.getBukkitLogger().log(Level.INFO, "As long as the legacy file is used automatic language switching based on the client settings will not be supported!"); + ChestShop.getBukkitLogger().log(Level.INFO, "Import it into the corresponding language file and remove/rename the file if you don't want it anymore!"); + manager.addConfig(new BukkitLanguageConfig(ChestShop.getPlugin(), "", legacyFile, "legacy", false)); + Properties.DEFAULT_LANGUAGE = "legacy"; + Properties.USE_CLIENT_LOCALE = false; + } + + if (!Properties.USE_CLIENT_LOCALE) { + manager.setProvider(sender -> null); + } + } + + public static class Message { + private String key; + + public Message(String key) { + this.key = key; + } + + public void sendWithPrefix(CommandSender sender, Map replacementMap, String... replacements) { + sender.spigot().sendMessage(getComponents(sender, true, replacementMap, replacements)); + } + + public void sendWithPrefix(CommandSender sender, Map replacements) { + sender.spigot().sendMessage(getComponents(sender, true, replacements)); + } + + public void sendWithPrefix(CommandSender sender, String... replacements) { + sender.spigot().sendMessage(getComponents(sender, true, Collections.emptyMap(), replacements)); + } + + public void send(CommandSender sender, String... replacements) { + sender.spigot().sendMessage(getComponents(sender, false, Collections.emptyMap(), replacements)); + } + + public BaseComponent[] getComponents(CommandSender sender, boolean prefixSuffix, Map replacementMap, String... replacements) { + MineDown mineDown = new MineDown("%prefix" + getLang(sender)); + mineDown.placeholderSuffix(""); + mineDown.replace("prefix", prefixSuffix ? prefix.getLang(sender) : ""); + mineDown.replace(replacementMap); + mineDown.replace(replacements); + return mineDown.toComponent(); + } + + private String getLang(CommandSender sender) { + return manager.getConfig(sender).get(key); + } + + public String getTextWithPrefix(CommandSender sender, Map replacementMap, String... replacements) { + return TextComponent.toLegacyText(getComponents(sender, true, replacementMap, replacements)); + } + + public String getTextWithPrefix(CommandSender sender, String... replacements) { + return getTextWithPrefix(sender, Collections.emptyMap(), replacements); + } + + public String getTextWithPrefix(CommandSender sender, Map replacements) { + return getTextWithPrefix(sender, replacements, new String[0]); + } + + public String getKey() { + return key; + } + } } diff --git a/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java b/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java index 0f732c6..bf53ace 100644 --- a/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java +++ b/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java @@ -112,6 +112,13 @@ public class Properties { @ConfigurationComment("How large should the internal caches be?") public static int CACHE_SIZE = 1000; + @PrecededBySpace + @ConfigurationComment("The default language when the client's language can't be found.") + public static String DEFAULT_LANGUAGE = "en"; + + @ConfigurationComment("Should the plugin try to use a language file that matches the client's locale setting?") + public static boolean USE_CLIENT_LOCALE = true; + @PrecededBySpace @ConfigurationComment("What containers are allowed to hold a shop? (Only blocks with inventories work!)") @Parser("MaterialSet") diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java b/src/main/java/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java index 781734d..e67372b 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/Block/BlockPlace.java @@ -37,14 +37,14 @@ public class BlockPlace implements Listener { } if (!Security.canAccess(player, placed)) { - event.getPlayer().sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(event.getPlayer()); event.setCancelled(true); } Block neighbor = uBlock.findNeighbor(placed); if (neighbor != null && !Security.canAccess(event.getPlayer(), neighbor)) { - event.getPlayer().sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(event.getPlayer()); event.setCancelled(true); } @@ -88,7 +88,7 @@ public class BlockPlace implements Listener { } if (!Security.canAccess(event.getPlayer(), relative)) { - event.getPlayer().sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(event.getPlayer()); event.setCancelled(true); return; } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java b/src/main/java/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java index 7ba0f03..f1db89d 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/ItemInfoListener.java @@ -37,7 +37,7 @@ public class ItemInfoListener implements Listener { public static void addRepairCost(ItemInfoEvent event) { ItemMeta meta = event.getItem().getItemMeta(); if (meta instanceof Repairable && ((Repairable) meta).getRepairCost() > 0) { - event.getSender().sendMessage(replace(iteminfo_repaircost, "cost", String.valueOf(((Repairable) meta).getRepairCost()))); + iteminfo_repaircost.send(event.getSender(), "cost", String.valueOf(((Repairable) meta).getRepairCost())); } } @@ -104,15 +104,15 @@ public class ItemInfoListener implements Listener { ItemMeta meta = event.getItem().getItemMeta(); if (meta instanceof BookMeta) { BookMeta book = (BookMeta) meta; - event.getSender().sendMessage(replace(iteminfo_book, + iteminfo_book.send(event.getSender(), "title", book.getTitle(), "author", book.getAuthor(), "pages", String.valueOf(book.getPageCount()) - )); + ); if (book.hasGeneration()) { - event.getSender().sendMessage(replace(iteminfo_book_generatopm, + iteminfo_book_generatopm.send(event.getSender(), "generation", StringUtil.capitalizeFirstLetter(book.getGeneration().name(), '_') - )); + ); } } } @@ -121,7 +121,7 @@ public class ItemInfoListener implements Listener { public static void addLoreInfo(ItemInfoEvent event) { ItemMeta meta = event.getItem().getItemMeta(); if (meta.hasLore()) { - event.getSender().sendMessage(replace(iteminfo_lore, "lore", String.join("\n", meta.getLore()))); + iteminfo_lore.send(event.getSender(), "lore", String.join("\n", meta.getLore())); } } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java index 9117149..42d3bd3 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInteract.java @@ -66,7 +66,7 @@ public class PlayerInteract implements Listener { } if (!Security.canAccess(player, block)) { - player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(player); event.setCancelled(true); } @@ -105,10 +105,10 @@ public class PlayerInteract implements Listener { sign.update(); } } else { - player.sendMessage(Messages.prefix(Messages.NO_ITEM_IN_HAND)); + Messages.NO_ITEM_IN_HAND.sendWithPrefix(player); } } else { - player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(player); } return; } @@ -136,7 +136,7 @@ public class PlayerInteract implements Listener { } if (Properties.CHECK_ACCESS_FOR_SHOP_USE && !Security.canAccess(player, block, true)) { - player.sendMessage(Messages.prefix(Messages.TRADE_DENIED)); + Messages.TRADE_DENIED.sendWithPrefix(player); return; } @@ -163,7 +163,7 @@ public class PlayerInteract implements Listener { Bukkit.getPluginManager().callEvent(accountQueryEvent); Account account = accountQueryEvent.getAccount(); if (account == null) { - player.sendMessage(Messages.prefix(Messages.PLAYER_NOT_FOUND)); + Messages.PLAYER_NOT_FOUND.sendWithPrefix(player); return null; } @@ -174,7 +174,7 @@ public class PlayerInteract implements Listener { AccountCheckEvent event = new AccountCheckEvent(account.getUuid(), player.getWorld()); Bukkit.getPluginManager().callEvent(event); if(!event.hasAccount()) { - player.sendMessage(Messages.prefix(Messages.NO_ECONOMY_ACCOUNT)); + Messages.NO_ECONOMY_ACCOUNT.sendWithPrefix(player); return null; } } @@ -189,7 +189,7 @@ public class PlayerInteract implements Listener { Bukkit.getPluginManager().callEvent(parseEvent); ItemStack item = parseEvent.getItem(); if (item == null) { - player.sendMessage(Messages.prefix(Messages.INVALID_SHOP_DETECTED)); + Messages.INVALID_SHOP_DETECTED.sendWithPrefix(player); return null; } @@ -199,7 +199,7 @@ public class PlayerInteract implements Listener { } catch (NumberFormatException notANumber) {} if (amount < 1 || amount > Properties.MAX_SHOP_AMOUNT) { - player.sendMessage(Messages.prefix(Messages.INVALID_SHOP_PRICE)); + Messages.INVALID_SHOP_PRICE.sendWithPrefix(player); return null; } @@ -270,7 +270,7 @@ public class PlayerInteract implements Listener { Container container = uBlock.findConnectedContainer(sign); if (container == null) { - player.sendMessage(Messages.prefix(Messages.NO_CHEST_DETECTED)); + Messages.NO_CHEST_DETECTED.sendWithPrefix(player); return; } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInventory.java b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInventory.java index 628cb0a..2f7ca6d 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInventory.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/Player/PlayerInventory.java @@ -46,7 +46,7 @@ public class PlayerInventory implements Listener { } if (!Security.canAccess(player, container)) { - player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(player); event.setCancelled(true); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PostShopCreation/MessageSender.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PostShopCreation/MessageSender.java index 30f0fd0..dededdf 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PostShopCreation/MessageSender.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PostShopCreation/MessageSender.java @@ -13,6 +13,6 @@ public class MessageSender implements Listener { @EventHandler(priority = EventPriority.MONITOR) public static void onShopCreation(ShopCreatedEvent event) { - event.getPlayer().sendMessage(Messages.prefix(Messages.SHOP_CREATED)); + Messages.SHOP_CREATED.sendWithPrefix(event.getPlayer()); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PostTransaction/TransactionMessageSender.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PostTransaction/TransactionMessageSender.java index 5cf1d23..a6e66e7 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PostTransaction/TransactionMessageSender.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PostTransaction/TransactionMessageSender.java @@ -14,6 +14,9 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import java.util.LinkedHashMap; +import java.util.Map; + /** * @author Acrobot */ @@ -53,26 +56,28 @@ public class TransactionMessageSender implements Listener { } } - private static void sendMessage(Player player, String playerName, String rawMessage, TransactionEvent event, String... replacements) { + private static void sendMessage(Player player, String playerName, Messages.Message rawMessage, TransactionEvent event, String... replacements) { Location loc = event.getSign().getLocation(); - String message = Messages.prefix(rawMessage) - .replace("%price", Economy.formatBalance(event.getExactPrice())) - .replace("%world", loc.getWorld().getName()) - .replace("%x", String.valueOf(loc.getBlockX())) - .replace("%y", String.valueOf(loc.getBlockY())) - .replace("%z", String.valueOf(loc.getBlockZ())); + Map replacementMap = new LinkedHashMap<>(); + replacementMap.put("price", Economy.formatBalance(event.getExactPrice())); + replacementMap.put("world", loc.getWorld().getName()); + replacementMap.put("x", String.valueOf(loc.getBlockX())); + replacementMap.put("y", String.valueOf(loc.getBlockY())); + replacementMap.put("z", String.valueOf(loc.getBlockZ())); for (int i = 0; i + 1 < replacements.length; i+=2) { - message = message.replace("%" + replacements[i], replacements[i + 1]); + replacementMap.put(replacements[i], replacements[i + 1]); } if (player != null) { - if (Properties.SHOWITEM_MESSAGE && MaterialUtil.Show.sendMessage(player, message, event.getStock())) { + if (Properties.SHOWITEM_MESSAGE && MaterialUtil.Show.sendMessage(player, rawMessage, event.getStock(), replacementMap)) { return; } - player.sendMessage(message.replace("%item", MaterialUtil.getItemList(event.getStock()))); + replacementMap.put("item", MaterialUtil.getItemList(event.getStock())); + rawMessage.sendWithPrefix(player, replacementMap); } else if (playerName != null) { - ChestShop.sendBungeeMessage(playerName, message.replace("%item", MaterialUtil.getItemList(event.getStock()))); + replacementMap.put("item", MaterialUtil.getItemList(event.getStock())); + ChestShop.sendBungeeMessage(playerName, rawMessage, replacementMap); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/CreationFeeGetter.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/CreationFeeGetter.java index 754c89d..10d8ab0 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/CreationFeeGetter.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/CreationFeeGetter.java @@ -60,6 +60,6 @@ public class CreationFeeGetter implements Listener { ChestShop.callEvent(currencyAddEvent); } - player.sendMessage(Messages.prefix(Messages.SHOP_FEE_PAID.replace("%amount", Economy.formatBalance(shopCreationPrice)))); + Messages.SHOP_FEE_PAID.sendWithPrefix(player, "amount", Economy.formatBalance(shopCreationPrice)); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/ErrorMessageSender.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/ErrorMessageSender.java index 80ef17b..e738ac6 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/ErrorMessageSender.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PreShopCreation/ErrorMessageSender.java @@ -17,7 +17,7 @@ public class ErrorMessageSender implements Listener { return; } - String message = null; + Messages.Message message = null; switch (event.getOutcome()) { case UNKNOWN_PLAYER: @@ -70,7 +70,7 @@ public class ErrorMessageSender implements Listener { } if (message != null) { - event.getPlayer().sendMessage(Messages.prefix(message)); + message.sendWithPrefix(event.getPlayer()); } } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/ErrorMessageSender.java b/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/ErrorMessageSender.java index 540c4de..8f4ecc6 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/ErrorMessageSender.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/PreTransaction/ErrorMessageSender.java @@ -9,6 +9,7 @@ import com.Acrobot.ChestShop.Database.Account; import com.Acrobot.ChestShop.Economy.Economy; import com.Acrobot.ChestShop.Events.PreTransactionEvent; import com.google.common.collect.HashBasedTable; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Table; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -19,6 +20,9 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.UUID; import static com.Acrobot.ChestShop.Configuration.Messages.CLIENT_DEPOSIT_FAILED; @@ -45,7 +49,7 @@ public class ErrorMessageSender implements Listener { return; } - String message = null; + Messages.Message message = null; switch (event.getTransactionOutcome()) { case SHOP_DOES_NOT_BUY_THIS_ITEM: @@ -66,14 +70,14 @@ public class ErrorMessageSender implements Listener { case NOT_ENOUGH_SPACE_IN_CHEST: if (Properties.SHOW_MESSAGE_FULL_SHOP && !Properties.CSTOGGLE_TOGGLES_FULL_SHOP || !Toggle.isIgnoring(event.getOwnerAccount().getUuid())) { Location loc = event.getSign().getLocation(); - String messageNotEnoughSpace = Messages.prefix(NOT_ENOUGH_SPACE_IN_YOUR_SHOP) - .replace("%price", Economy.formatBalance(event.getExactPrice())) - .replace("%seller", event.getClient().getName()) - .replace("%world", loc.getWorld().getName()) - .replace("%x", String.valueOf(loc.getBlockX())) - .replace("%y", String.valueOf(loc.getBlockY())) - .replace("%z", String.valueOf(loc.getBlockZ())); - sendMessageToOwner(event.getOwnerAccount(), messageNotEnoughSpace, event.getStock()); + sendMessageToOwner(event.getOwnerAccount(), NOT_ENOUGH_SPACE_IN_YOUR_SHOP, new String[]{ + "price", Economy.formatBalance(event.getExactPrice()), + "seller", event.getClient().getName(), + "world", loc.getWorld().getName(), + "x", String.valueOf(loc.getBlockX()), + "y", String.valueOf(loc.getBlockY()), + "z", String.valueOf(loc.getBlockZ()) + }, event.getStock()); } message = Messages.NOT_ENOUGH_SPACE_IN_CHEST; break; @@ -86,14 +90,14 @@ public class ErrorMessageSender implements Listener { case NOT_ENOUGH_STOCK_IN_CHEST: if (Properties.SHOW_MESSAGE_OUT_OF_STOCK && !Properties.CSTOGGLE_TOGGLES_OUT_OF_STOCK || !Toggle.isIgnoring(event.getOwnerAccount().getUuid())) { Location loc = event.getSign().getLocation(); - String messageOutOfStock = Messages.prefix(NOT_ENOUGH_STOCK_IN_YOUR_SHOP) - .replace("%price", Economy.formatBalance(event.getExactPrice())) - .replace("%buyer", event.getClient().getName()) - .replace("%world", loc.getWorld().getName()) - .replace("%x", String.valueOf(loc.getBlockX())) - .replace("%y", String.valueOf(loc.getBlockY())) - .replace("%z", String.valueOf(loc.getBlockZ())); - sendMessageToOwner(event.getOwnerAccount(), messageOutOfStock, event.getStock()); + sendMessageToOwner(event.getOwnerAccount(), NOT_ENOUGH_STOCK_IN_YOUR_SHOP, new String[]{ + "%price", Economy.formatBalance(event.getExactPrice()), + "%buyer", event.getClient().getName(), + "%world", loc.getWorld().getName(), + "%x", String.valueOf(loc.getBlockX()), + "%y", String.valueOf(loc.getBlockY()), + "%z", String.valueOf(loc.getBlockZ()) + }, event.getStock()); } message = Messages.NOT_ENOUGH_STOCK; break; @@ -101,8 +105,7 @@ public class ErrorMessageSender implements Listener { message = Messages.CLIENT_DEPOSIT_FAILED; break; case SHOP_DEPOSIT_FAILED: - String messageDepositFailed = Messages.prefix(CLIENT_DEPOSIT_FAILED); - sendMessageToOwner(event.getOwnerAccount(), messageDepositFailed); + sendMessageToOwner(event.getOwnerAccount(), CLIENT_DEPOSIT_FAILED, new String[0]); message = Messages.SHOP_DEPOSIT_FAILED; break; case SHOP_IS_RESTRICTED: @@ -116,31 +119,34 @@ public class ErrorMessageSender implements Listener { } if (message != null) { - event.getClient().sendMessage(Messages.prefix(message)); + message.sendWithPrefix(event.getClient()); } } - private static void sendMessageToOwner(Account ownerAccount, String message, ItemStack... stock) { + private static void sendMessageToOwner(Account ownerAccount, Messages.Message message, String[] replacements, ItemStack... stock) { Player player = Bukkit.getPlayer(ownerAccount.getUuid()); if (player != null || Properties.BUNGEECORD_MESSAGES) { - message = message.replace("%material", "%item"); - String replacedMessage = message.replace("%item", MaterialUtil.getItemList(stock)); if (Properties.NOTIFICATION_MESSAGE_COOLDOWN > 0) { - Long last = notificationCooldowns.get(ownerAccount.getUuid(), replacedMessage); + String cacheKey = message.getKey() + "|" + String.join(",", replacements) + "|" + MaterialUtil.getItemList(stock); + Long last = notificationCooldowns.get(ownerAccount.getUuid(), cacheKey); if (last != null && last + Properties.NOTIFICATION_MESSAGE_COOLDOWN * 1000 > System.currentTimeMillis()) { return; } - notificationCooldowns.put(ownerAccount.getUuid(), replacedMessage, System.currentTimeMillis()); + notificationCooldowns.put(ownerAccount.getUuid(), cacheKey, System.currentTimeMillis()); } if (player != null) { - if (Properties.SHOWITEM_MESSAGE && MaterialUtil.Show.sendMessage(player, message, stock)) { + if (Properties.SHOWITEM_MESSAGE && MaterialUtil.Show.sendMessage(player, message, stock, Collections.emptyMap(), replacements)) { return; } - player.sendMessage(replacedMessage); + String items = MaterialUtil.getItemList(stock); + message.sendWithPrefix(player, + ImmutableMap.of("material", items, "item", items), replacements); } else { - ChestShop.sendBungeeMessage(ownerAccount.getName(), replacedMessage); + String items = MaterialUtil.getItemList(stock); + ChestShop.sendBungeeMessage(ownerAccount.getName(), message, + ImmutableMap.of("material", items, "item", items), replacements); } } } diff --git a/src/main/java/com/Acrobot/ChestShop/Listeners/ShopRemoval/ShopRefundListener.java b/src/main/java/com/Acrobot/ChestShop/Listeners/ShopRemoval/ShopRefundListener.java index 78e5761..9b73c95 100644 --- a/src/main/java/com/Acrobot/ChestShop/Listeners/ShopRemoval/ShopRefundListener.java +++ b/src/main/java/com/Acrobot/ChestShop/Listeners/ShopRemoval/ShopRefundListener.java @@ -59,7 +59,6 @@ public class ShopRefundListener implements Listener { ChestShop.callEvent(currencySubtractEvent); } - String message = Messages.SHOP_REFUNDED.replace("%amount", Economy.formatBalance(refundPrice)); - event.getDestroyer().sendMessage(Messages.prefix(message)); + Messages.SHOP_REFUNDED.sendWithPrefix(event.getDestroyer(), "amount", Economy.formatBalance(refundPrice)); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java b/src/main/java/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java index fda4184..8630fc3 100644 --- a/src/main/java/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java +++ b/src/main/java/com/Acrobot/ChestShop/Plugins/LightweightChestProtection.java @@ -82,7 +82,7 @@ public class LightweightChestProtection implements Listener { Sign sign = event.getSign(); Container connectedContainer = event.getContainer(); - String message = null; + Messages.Message message = null; if (Properties.PROTECT_SIGN_WITH_LWC) { if (Security.protect(player, sign.getBlock(), event.getOwnerAccount() != null ? event.getOwnerAccount().getUuid() : player.getUniqueId(), Properties.LWC_SIGN_PROTECTION_TYPE)) { message = Messages.PROTECTED_SHOP_SIGN; @@ -100,7 +100,7 @@ public class LightweightChestProtection implements Listener { } if (message != null) { - player.sendMessage(Messages.prefix(message)); + message.sendWithPrefix(player); } } diff --git a/src/main/java/com/Acrobot/ChestShop/Signs/RestrictedSign.java b/src/main/java/com/Acrobot/ChestShop/Signs/RestrictedSign.java index ebe59dc..d3466fe 100644 --- a/src/main/java/com/Acrobot/ChestShop/Signs/RestrictedSign.java +++ b/src/main/java/com/Acrobot/ChestShop/Signs/RestrictedSign.java @@ -45,7 +45,7 @@ public class RestrictedSign implements Listener { if (isRestricted(lines)) { if (!hasPermission(player, lines)) { - player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED)); + Messages.ACCESS_DENIED.sendWithPrefix(player); dropSignAndCancelEvent(event); return; } @@ -63,7 +63,7 @@ public class RestrictedSign implements Listener { return; } - player.sendMessage(Messages.prefix(Messages.RESTRICTED_SIGN_CREATED)); + Messages.RESTRICTED_SIGN_CREATED.sendWithPrefix(player); } } diff --git a/src/main/resources/languages/lang.en.yml b/src/main/resources/languages/lang.en.yml new file mode 100644 index 0000000..ed82289 --- /dev/null +++ b/src/main/resources/languages/lang.en.yml @@ -0,0 +1,83 @@ +prefix: "&a[Shop] &r" +iteminfo: "&aItem Information: &r" +iteminfo_fullname: "&fFull Name: &7%item" +iteminfo_shopname: "&fShop Sign: &7%item" +iteminfo_repaircost: "&fRepair Cost: &7%cost" +iteminfo_book: |- + &fBook Title: &7%title + &fBook Author: &7%author + &fBook Pages: &7%pages +iteminfo_book_generatopm: "&fBook Generation: &7%generation" +iteminfo_lore: |- + &fLore: + &r%lore + +METRICS: |- + &a[Shop] &fMetrics: + &fAccounts: &7%accounts + &fAverage transactions: &7%totalTransactions &f(buy: &7%buyTransactions &fsell: &7%sellTransactions&f) + &fAverage items traded: &7%totalItems &f(bought: &7%boughtItems &fsold: &7%soldItems&f) + +ACCESS_DENIED: "You don't have permission to access that shop's storage container!" +TRADE_DENIED: "You don't have permission to trade with that shop!" + +NOT_ENOUGH_MONEY: "You don't have enough money!" +NOT_ENOUGH_MONEY_SHOP: "Shop owner doesn't have enough money!" + +CLIENT_DEPOSIT_FAILED: "Money deposit to your account failed!" +SHOP_DEPOSIT_FAILED: "Money deposit to shop owner failed!" +NO_ECONOMY_ACCOUNT: "Economy account from shop owner doesn't exist!" + +NO_BUYING_HERE: "You can't buy here!" +NO_SELLING_HERE: "You can't sell here!" + +NOT_ENOUGH_SPACE_IN_INVENTORY: "You haven't got enough space in inventory!" +NOT_ENOUGH_SPACE_IN_CHEST: "There isn't enough space in chest!" +NOT_ENOUGH_ITEMS_TO_SELL: "You don't have enough items to sell!" +NOT_ENOUGH_SPACE_IN_YOUR_SHOP: "[%price %item&7 shop](At world: &f%world\nPosition: &f%x/%y/%z)&7 is full! (%seller tried to sell)" + +NOT_ENOUGH_STOCK: "This shop is out of stock." +NOT_ENOUGH_STOCK_IN_YOUR_SHOP: "[%price %item&7 shop](At world: &f%world\nPosition: &f%x/%y/%z)&7 is out of stock! (%buyer tried to buy)" + +YOU_BOUGHT_FROM_SHOP: "You bought %item from %owner for %price." +SOMEBODY_BOUGHT_FROM_YOUR_SHOP: "%buyer bought %item for %price from your shop at %world/%x/%y/%z." + +YOU_SOLD_TO_SHOP: "You sold %item to %buyer for %price." +SOMEBODY_SOLD_TO_YOUR_SHOP: "%seller sold %item for %price to your shop at %world/%x/%y/%z." + +YOU_CANNOT_CREATE_SHOP: "You can't create this type of shop!" +NO_CHEST_DETECTED: "Couldn't find a chest!" +INVALID_SHOP_DETECTED: "The shop cannot be used!" +INVALID_SHOP_PRICE: "The shop has an invalid price!" +INVALID_SHOP_QUANTITY: "The shop has an invalid quantity!" +CANNOT_ACCESS_THE_CHEST: "You don't have permissions to access this chest!" + +SELL_PRICE_ABOVE_MAX: "Sell price is above maximum!" +SELL_PRICE_BELOW_MIN: "Sell price is below minimum!" +BUY_PRICE_ABOVE_MAX: "Buy price is above maximum!" +BUY_PRICE_BELOW_MIN: "Buy price is below minimum!" + +CLICK_TO_AUTOFILL_ITEM: "Click the sign with the item that this shop is for!" +NO_ITEM_IN_HAND: "You don't have an item in your hand to autofill!" + +PROTECTED_SHOP: "Successfully protected the shop with LWC!" +PROTECTED_SHOP_SIGN: "Successfully protected the shop sign with LWC!" +SHOP_CREATED: "Shop successfully created!" +SHOP_FEE_PAID: "You have been charged %amount" +SHOP_REFUNDED: "You have been refunded %amount." +ITEM_GIVEN: "Given %item to %player." + +RESTRICTED_SIGN_CREATED: "Sign successfully created!" + +PLAYER_NOT_FOUND: "Player not found!" +NO_PERMISSION: "You don't have permissions to do that!" +INCORRECT_ITEM_ID: "You have specified an invalid item id!" +NOT_ENOUGH_PROTECTIONS: "Could not create a protection!" + +CANNOT_CREATE_SHOP_HERE: "You can't create shop here!" + +TOGGLE_MESSAGES_OFF: "You will no longer receive messages from your shop(s)." +TOGGLE_MESSAGES_ON: "You will now receive messages from your shop(s)." + +TOGGLE_ACCESS_ON: "You can no longer trade at shops that you have access to" +TOGGLE_ACCESS_OFF: "You can now trade at shops that you have access to" \ No newline at end of file