First Commit

This commit is contained in:
BuildTools 2015-09-02 13:06:48 +02:00
commit dc1bf15bf2
19 changed files with 3379 additions and 0 deletions

View File

@ -0,0 +1,332 @@
package de.epiceric.shopchest;
import java.lang.reflect.Method;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.ItemStack;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.shop.Hologram;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.ClickType;
import de.epiceric.shopchest.utils.JsonBuilder;
import de.epiceric.shopchest.utils.ClickType.EnumClickType;
import de.epiceric.shopchest.utils.JsonBuilder.ClickAction;
import de.epiceric.shopchest.utils.JsonBuilder.HoverAction;
import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.UpdateChecker;
import net.md_5.bungee.api.ChatColor;
import net.milkbowl.vault.permission.Permission;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
public class Commands extends BukkitCommand {
private ShopChest plugin;
private Permission perm = ShopChest.perm;
public Commands(ShopChest plugin, String name, String description, String usageMessage, List<String> aliases) {
super(name, description, usageMessage, aliases);
this.plugin = plugin;
}
public static void registerCommand(Command command, ShopChest plugin)
throws ReflectiveOperationException {
Method commandMap = plugin.getServer().getClass().getMethod("getCommandMap");
Object cmdmap = commandMap.invoke(plugin.getServer());
Method register = cmdmap.getClass().getMethod("register", String.class,Command.class);
register.invoke(cmdmap, command.getName(),command);
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
if (sender instanceof Player) {
Player p = (Player) sender;
if (args.length == 0) {
sendBasicHelpMessage(p);
return true;
} else {
if (args[0].equalsIgnoreCase("create")) {
if (perm.has(p, "shopchest.create")) {
if (args.length == 4) {
create(args, false, p);
return true;
} else if (args.length == 5) {
if (args[4].equalsIgnoreCase("infinite")) {
if (perm.has(p, "shopchest.create.infinite")) {
create(args, true, p);
return true;
} else {
p.sendMessage(Config.noPermission_createInfinite());
return true;
}
} else if (args[4].equalsIgnoreCase("normal")){
create(args, false, p);
return true;
} else {
sendBasicHelpMessage(p);
return true;
}
} else {
sendBasicHelpMessage(p);
return true;
}
} else {
p.sendMessage(Config.noPermission_create());
return true;
}
} else if (args[0].equalsIgnoreCase("remove")) {
remove(p);
return true;
} else if (args[0].equalsIgnoreCase("info")) {
info(p);
return true;
} else if (args[0].equalsIgnoreCase("reload")) {
if (perm.has(p, "shopchest.reload")) {
reload(p);
return true;
} else {
p.sendMessage(Config.noPermission_reload());
return true;
}
} else if (args[0].equalsIgnoreCase("update")) {
if (perm.has(p, "shopchest.update")) {
checkUpdates(p);
return true;
} else {
p.sendMessage(Config.noPermission_update());
return true;
}
}
return true;
}
} else {
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Only players can execute this command.");
return true;
}
}
private void checkUpdates(Player player) {
JsonBuilder jb = new JsonBuilder().parse(Config.checking_update());
jb.sendJson(player);
UpdateChecker uc = new UpdateChecker(ShopChest.getInstance(), ShopChest.getInstance().getDescription().getWebsite());
if (uc.updateNeeded()) {
ShopChest.latestVersion = uc.getVersion();
ShopChest.downloadLink = uc.getLink();
ShopChest.isUpdateNeeded = true;
JsonBuilder jb2 = new JsonBuilder(Config.update_available(ShopChest.latestVersion)).withHoverEvent(HoverAction.SHOW_TEXT, Config.click_to_download()).withClickEvent(ClickAction.OPEN_URL, ShopChest.downloadLink);
jb2.sendJson(player);
} else {
ShopChest.latestVersion = "";
ShopChest.downloadLink = "";
ShopChest.isUpdateNeeded = false;
JsonBuilder jb3 = new JsonBuilder().parse(Config.no_new_update());
jb3.sendJson(player);
}
}
private void reload(Player player) {
for (Shop shop : ShopUtils.getShops()) {
Hologram hologram = shop.getHologram();
shop.getItem().remove();
ShopUtils.removeShop(shop);
for (Player p : ShopChest.getInstance().getServer().getOnlinePlayers()) {
hologram.hidePlayer(p);
}
for (Object o : hologram.getEntities()) {
EntityArmorStand e = (EntityArmorStand) o;
e.getWorld().removeEntity(e);
}
}
for (String key : ShopChest.getInstance().shopChests.getKeys(false)) {
OfflinePlayer vendor = ShopChest.getInstance().shopChests.getOfflinePlayer(key + ".vendor");
int locationX = ShopChest.getInstance().shopChests.getInt(key + ".location.x");
int locationY = ShopChest.getInstance().shopChests.getInt(key + ".location.y");
int locationZ = ShopChest.getInstance().shopChests.getInt(key + ".location.z");
World locationWorld = ShopChest.getInstance().getServer().getWorld(ShopChest.getInstance().shopChests.getString(key + ".location.world"));
Location location = new Location(locationWorld, locationX, locationY, locationZ);
ItemStack product = ShopChest.getInstance().shopChests.getItemStack(key + ".product");
double buyPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.buy");
double sellPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.sell");
boolean infinite = ShopChest.getInstance().shopChests.getBoolean(key + ".infinite");
ShopUtils.addShop(new Shop(ShopChest.getInstance(), vendor, product, location, buyPrice, sellPrice, infinite));
}
for (Player p : Bukkit.getOnlinePlayers()) {
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
}
player.sendMessage(Config.reloaded_shops(ShopChest.getInstance().shopChests.getKeys(false).size()));
}
private void create(String[] args, boolean infinite, Player p) {
int amount;
double buyPrice, sellPrice;
try {
amount = Integer.parseInt(args[1]);
buyPrice = Double.parseDouble(args[2]);
sellPrice = Double.parseDouble(args[3]);
} catch (NumberFormatException e) {
p.sendMessage(Config.amount_and_price_not_number());
return;
}
boolean buyEnabled = !(buyPrice <= 0), sellEnabled = !(sellPrice <= 0);
if (!buyEnabled && !sellEnabled) {
p.sendMessage(Config.buy_and_sell_disabled());
return;
}
if (p.getItemInHand().getType().equals(Material.AIR)) {
p.sendMessage(Config.no_item_in_hand());
return;
}
for (String key : Config.minimum_prices()) {
ItemStack itemStack;
double price = plugin.getConfig().getDouble("minimum-prices." + key);
if (key.contains(":")) {
itemStack = new ItemStack(Material.getMaterial(key.split(":")[0]), 1, Short.parseShort(key.split(":")[1]));
} else {
itemStack = new ItemStack(Material.getMaterial(key), 1);
}
if (itemStack.getType().equals(p.getItemInHand().getType())) {
if (buyEnabled) {
if ((buyPrice <= amount * price) && (buyPrice > 0)) {
p.sendMessage(Config.buyPrice_too_low(amount * price));
return;
}
}
if (sellEnabled) {
if ((sellPrice <= amount * price) && (sellPrice > 0)) {
p.sendMessage(Config.sellPrice_too_low(amount * price));
return;
}
}
}
}
if (sellEnabled && buyEnabled) {
if (Config.buy_greater_or_equal_sell()) {
if (buyPrice < sellPrice) {
p.sendMessage(Config.buyPrice_too_low(sellPrice));
return;
}
}
}
ItemStack itemStack = new ItemStack(p.getItemInHand().getType(), amount, p.getItemInHand().getDurability());
itemStack.setItemMeta(p.getItemInHand().getItemMeta());
if (Enchantment.DURABILITY.canEnchantItem(itemStack)) {
if (itemStack.getDurability() > 0) {
p.sendMessage(Config.cannot_sell_broken_item());
return;
}
}
ClickType.addPlayerClickType(p, new ClickType(EnumClickType.CREATE, itemStack, buyPrice, sellPrice, infinite));
p.sendMessage(Config.click_chest_to_create());
}
private void remove(Player p) {
p.sendMessage(Config.click_chest_to_remove());
ClickType.addPlayerClickType(p, new ClickType(EnumClickType.REMOVE));
}
private void info(Player p) {
p.sendMessage(Config.click_chest_for_info());
ClickType.addPlayerClickType(p, new ClickType(EnumClickType.INFO));
}
private void sendBasicHelpMessage(Player player) {
player.sendMessage(ChatColor.GREEN + "/" + Config.main_command_name() + " create <amount> <buy-price> <sell-price> [infinite|normal]- " + Config.cmdDesc_create());
player.sendMessage(ChatColor.GREEN + "/" + Config.main_command_name() + " remove - " + Config.cmdDesc_remove());
player.sendMessage(ChatColor.GREEN + "/" + Config.main_command_name() + " info - " + Config.cmdDesc_info());
player.sendMessage(ChatColor.GREEN + "/" + Config.main_command_name() + " reload - " + Config.cmdDesc_reload());
player.sendMessage(ChatColor.GREEN + "/" + Config.main_command_name() + " update - " + Config.cmdDesc_update());
}
}

View File

@ -0,0 +1,230 @@
package de.epiceric.shopchest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.InteractShop;
import de.epiceric.shopchest.event.NotifyUpdate;
import de.epiceric.shopchest.event.ProtectChest;
import de.epiceric.shopchest.event.RegenerateShopItem;
import de.epiceric.shopchest.event.UpdateHolograms;
import de.epiceric.shopchest.shop.Hologram;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.JsonBuilder;
import de.epiceric.shopchest.utils.JsonBuilder.ClickAction;
import de.epiceric.shopchest.utils.JsonBuilder.HoverAction;
import de.epiceric.shopchest.utils.Metrics;
import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.UpdateChecker;
import de.epiceric.shopchest.utils.Utils;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
public class ShopChest extends JavaPlugin{
private static ShopChest instance;
public File shopChestsFile;
public YamlConfiguration shopChests;
public static Logger logger = Logger.getLogger("Minecraft");
public static Economy econ = null;
public static Permission perm = null;
public static boolean isUpdateNeeded = false;
public static String latestVersion = "";
public static String downloadLink = "";
public static ShopChest getInstance() {
return instance;
}
private boolean setupEconomy() {
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return econ != null;
}
private boolean setupPermissions() {
RegisteredServiceProvider<Permission> rsp = getServer().getServicesManager().getRegistration(Permission.class);
perm = rsp.getProvider();
return perm != null;
}
@Override
public void onLoad() {
getLogger().info(Utils.getVersion());
}
@Override
public void onEnable() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
logger.severe("[ShopChest] Could not find plugin 'Vault'!");
getServer().getPluginManager().disablePlugin(this);
return;
}
if (!setupEconomy() ) {
logger.severe("[ShopChest] Could not find any Vault dependency!");
getServer().getPluginManager().disablePlugin(this);
return;
}
try {
Metrics metrics = new Metrics(this);
metrics.start();
} catch (IOException e) {
logger.severe("[ShopChest] [PluginMetrics] Could not submit stats.");
}
setupPermissions();
instance = this;
reloadConfig();
saveDefaultConfig();
UpdateChecker uc = new UpdateChecker(this, getDescription().getWebsite());
logger.info("[ShopChest] Checking for Updates");
if(uc.updateNeeded()) {
latestVersion = uc.getVersion();
downloadLink = uc.getLink();
isUpdateNeeded = true;
Bukkit.getConsoleSender().sendMessage("[ShopChest] " + ChatColor.GOLD + "New version available: " + ChatColor.RED + latestVersion);
} else {
logger.info("[ShopChest] No new version available");
isUpdateNeeded = false;
}
if (isUpdateNeeded) {
for (Player p : getServer().getOnlinePlayers()) {
if (p.isOp() || perm.has(p, "shopchest.notification.update")) {
JsonBuilder jb = new JsonBuilder(Config.update_available(latestVersion)).withHoverEvent(HoverAction.SHOW_TEXT, Config.click_to_download()).withClickEvent(ClickAction.OPEN_URL, downloadLink);
jb.sendJson(p);
}
}
}
File shopChestDataFolder = new File(getDataFolder(), "data");
shopChestDataFolder.mkdirs();
shopChestsFile = new File(getDataFolder(), "/data/shops.yml");
if (!shopChestsFile.exists())
try {shopChestsFile.createNewFile();} catch (IOException e) {e.printStackTrace();}
File itemNamesFile = new File(getDataFolder(), "item_names.txt");
if (!itemNamesFile.exists())
try {itemNamesFile.createNewFile();} catch (IOException e) {e.printStackTrace();}
copy(getResource("item_names"), itemNamesFile);
shopChests = YamlConfiguration.loadConfiguration(shopChestsFile);
try {
Commands.registerCommand(new Commands(this, Config.main_command_name(), "Manage Shops.", "", new ArrayList<String>()), this);
} catch (Exception e) {
e.printStackTrace();
}
initializeShops();
getServer().getPluginManager().registerEvents(new UpdateHolograms(), this);
getServer().getPluginManager().registerEvents(new RegenerateShopItem(), this);
getServer().getPluginManager().registerEvents(new InteractShop(this), this);
getServer().getPluginManager().registerEvents(new NotifyUpdate(), this);
getServer().getPluginManager().registerEvents(new ProtectChest(), this);
}
@Override
public void onDisable() {
for (Shop shop : ShopUtils.getShops()) {
Hologram hologram = shop.getHologram();
for (Player p : getServer().getOnlinePlayers()) {
hologram.hidePlayer(p);
}
for (Object o : hologram.getEntities()) {
EntityArmorStand e = (EntityArmorStand) o;
e.getWorld().removeEntity(e);
}
shop.getItem().remove();
}
}
private void initializeShops() {
Bukkit.getConsoleSender().sendMessage("[ShopChest] Found " + String.valueOf(shopChests.getKeys(false).size()) + " Shops");
for (String key : shopChests.getKeys(false)) {
OfflinePlayer vendor = shopChests.getOfflinePlayer(key + ".vendor");
int locationX = shopChests.getInt(key + ".location.x");
int locationY = shopChests.getInt(key + ".location.y");
int locationZ = shopChests.getInt(key + ".location.z");
World locationWorld = getServer().getWorld(shopChests.getString(key + ".location.world"));
Location location = new Location(locationWorld, locationX, locationY, locationZ);
ItemStack product = shopChests.getItemStack(key + ".product");
double buyPrice = shopChests.getDouble(key + ".price.buy");
double sellPrice = shopChests.getDouble(key + ".price.sell");
boolean infinite = shopChests.getBoolean(key + ".infinite");
ShopUtils.addShop(new Shop(this, vendor, product, location, buyPrice, sellPrice, infinite));
}
}
public static void copy(InputStream in, File file) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,126 @@
package de.epiceric.shopchest.config;
import java.util.HashSet;
import java.util.Set;
import de.epiceric.shopchest.ShopChest;
public class Config {
private static ShopChest plugin = ShopChest.getInstance();
public static Set<String> minimum_prices() {return (plugin.getConfig().getConfigurationSection("minimum-prices") == null) ? new HashSet<String>() : plugin.getConfig().getConfigurationSection("minimum-prices").getKeys(true);}
public static boolean buy_greater_or_equal_sell() {return plugin.getConfig().getBoolean("buy-greater-or-equal-sell");}
public static double maximal_distance() {return plugin.getConfig().getDouble("maximal-distance");}
public static String main_command_name() { return plugin.getConfig().getString("main-command-name");}
public static String currency_symbol() { return plugin.getConfig().getString("currency-symbol").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String shop_created() { return plugin.getConfig().getString("messages.shop-created").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String chest_already_shop() { return plugin.getConfig().getString("messages.chest-already-shop").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String shop_removed() { return plugin.getConfig().getString("messages.shop-removed").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String chest_no_shop() { return plugin.getConfig().getString("messages.chest-no-shop").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String block_no_chest() { return plugin.getConfig().getString("messages.block-no-chest").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String not_enough_inventory_space() { return plugin.getConfig().getString("messages.not-enough-inventory-space").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String chest_not_enough_inventory_space() { return plugin.getConfig().getString("messages.chest-not-enough-inventory-space").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String not_enough_money() { return plugin.getConfig().getString("messages.not-enough-money").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String not_enough_items() { return plugin.getConfig().getString("messages.not-enough-items").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String vendor_not_enough_money() { return plugin.getConfig().getString("messages.vendor-not-enough-money").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String out_of_stock() { return plugin.getConfig().getString("messages.out-of-stock").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String amount_and_price_not_number() { return plugin.getConfig().getString("messages.amount-and-price-not-number").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String no_item_in_hand() { return plugin.getConfig().getString("messages.no-item-in-hand").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String click_chest_to_create() { return plugin.getConfig().getString("messages.click-chest-to-create-shop").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String click_chest_to_remove() { return plugin.getConfig().getString("messages.click-chest-to-remove-shop").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String click_chest_for_info() { return plugin.getConfig().getString("messages.click-chest-for-info").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cmdDesc_create() { return plugin.getConfig().getString("messages.command-description.create").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cmdDesc_remove() { return plugin.getConfig().getString("messages.command-description.remove").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cmdDesc_info() { return plugin.getConfig().getString("messages.command-description.info").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cmdDesc_reload() { return plugin.getConfig().getString("messages.command-description.reload").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cmdDesc_update() { return plugin.getConfig().getString("messages.command-description.update").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String shopInfo_isInfinite() { return plugin.getConfig().getString("messages.shop-info.is-infinite").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");};
public static String shopInfo_isNormal() { return plugin.getConfig().getString("messages.shop-info.is-not-infinite").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");};
public static String noPermission_create() { return plugin.getConfig().getString("messages.no-permission.create").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_createInfinite() { return plugin.getConfig().getString("messages.no-permission.create-infinite").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_openOthers() { return plugin.getConfig().getString("messages.no-permission.open-others").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_removeOthers() { return plugin.getConfig().getString("messages.no-permission.remove-others").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_buy() { return plugin.getConfig().getString("messages.no-permission.buy").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_sell() { return plugin.getConfig().getString("messages.no-permission.sell").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_reload() { return plugin.getConfig().getString("messages.no-permission.reload").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String noPermission_update() { return plugin.getConfig().getString("messages.no-permission.update").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cannot_break_shop() { return plugin.getConfig().getString("messages.cannot-break-shop").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String cannot_sell_broken_item() { return plugin.getConfig().getString("messages.cannot-sell-broken-item").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String disabled() {return plugin.getConfig().getString("messages.shop-info.disabled").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String buy_and_sell_disabled() {return plugin.getConfig().getString("messages.buy-and-sell-disabled").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String selling_disabled() {return plugin.getConfig().getString("messages.selling-disabled").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String buying_disabled() {return plugin.getConfig().getString("messages.buying-disabled").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String checking_update() {return plugin.getConfig().getString("messages.update.checking").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String no_new_update() {return plugin.getConfig().getString("messages.update.no-update").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String click_to_download() {return plugin.getConfig().getString("messages.update.click-to-download").replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");}
public static String reloaded_shops(int amount) {
return plugin.getConfig().getString("messages.reloaded-shops").replace(Regex.amount, String.valueOf(amount)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String opened_shop(String vendor) {
return plugin.getConfig().getString("messages.opened-shop").replace(Regex.vendor, vendor).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String buyPrice_too_low(double minPrice) {
return plugin.getConfig().getString("messages.buy-price-too-low").replace(Regex.minPrice, String.valueOf(minPrice)).replace(Regex.currencySymbol, currency_symbol()).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String sellPrice_too_low(double minPrice) {
return plugin.getConfig().getString("messages.sell-price-too-low").replace(Regex.minPrice, String.valueOf(minPrice)).replace(Regex.currencySymbol, currency_symbol()).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String update_available(String version) {
return plugin.getConfig().getString("messages.update.update-available").replace(Regex.version, version);
}
public static String hologram_buy_sell(double buyPrice, double sellPrice) {
return plugin.getConfig().getString("messages.hologram.buy-and-sell").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice, String.valueOf(buyPrice)).replace(Regex.sellPrice, String.valueOf(sellPrice)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String hologram_buy(double buyPrice) {
return plugin.getConfig().getString("messages.hologram.only-buy").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice, String.valueOf(buyPrice)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String hologram_sell(double sellPrice) {
return plugin.getConfig().getString("messages.hologram.only-sell").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.sellPrice, String.valueOf(sellPrice)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String error_occurred(String error) {
return plugin.getConfig().getString("messages.error-occurred").replace(Regex.error, error).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String shopInfo_vendor(String vendor) {
return plugin.getConfig().getString("messages.shop-info.vendor").replace(Regex.vendor, vendor).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String shopInfo_product(int amount, String itemName) {
return plugin.getConfig().getString("messages.shop-info.product").replace(Regex.amount, String.valueOf(amount)).replace(Regex.itemName, itemName).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String shopInfo_enchantment(String enchantment) {
return plugin.getConfig().getString("messages.shop-info.enchantments").replace(Regex.enchantment, enchantment).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String shopInfo_price(double buyPrice, double sellPrice) {
if ((buyPrice <= 0) && (sellPrice > 0)) {
return plugin.getConfig().getString("messages.shop-info.price").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice + currency_symbol(), disabled()).replace(Regex.sellPrice, String.valueOf(sellPrice)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
} else if ((sellPrice <= 0) && (buyPrice > 0)) {
return plugin.getConfig().getString("messages.shop-info.price").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice, String.valueOf(buyPrice)).replace(Regex.sellPrice + currency_symbol(), disabled()).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
} else if ((sellPrice > 0) && (buyPrice > 0)) {
return plugin.getConfig().getString("messages.shop-info.price").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice, String.valueOf(buyPrice)).replace(Regex.sellPrice, String.valueOf(sellPrice)).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
} else {
return plugin.getConfig().getString("messages.shop-info.price").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.buyPrice + currency_symbol(), disabled()).replace(Regex.sellPrice + currency_symbol(), disabled()).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
}
public static String buy_success(int amount, String itemName, double buyPrice, String vendor) {
return plugin.getConfig().getString("messages.buy-success").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.amount, String.valueOf(amount)).replace(Regex.itemName, itemName).replace(Regex.buyPrice, String.valueOf(buyPrice)).replace(Regex.vendor, vendor).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
public static String sell_success(int amount, String itemName, double sellPrice, String vendor) {
return plugin.getConfig().getString("messages.sell-success").replace(Regex.currencySymbol, currency_symbol()).replace(Regex.amount, String.valueOf(amount)).replace(Regex.itemName, itemName).replace(Regex.sellPrice, String.valueOf(sellPrice)).replace(Regex.vendor, vendor).replaceAll("(&([a-f0-9k-or]))", "\u00A7$2");
}
}

View File

@ -0,0 +1,17 @@
package de.epiceric.shopchest.config;
public class Regex {
public static String vendor = "%VENDOR%";
public static String amount = "%AMOUNT%";
public static String itemName = "%ITEMNAME%";
public static String price = "%PRICE%";
public static String currencySymbol = "%CURRENCY-SYMBOL%";
public static String error = "%ERROR%";
public static String enchantment = "%ENCHANTMENT%";
public static String minPrice = "%MIN-PRICE%";
public static String version = "%VERSION%";
public static String buyPrice = "%BUY-PRICE%";
public static String sellPrice = "%SELL-PRICE%";
}

View File

@ -0,0 +1,426 @@
package de.epiceric.shopchest.event;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.ClickType;
import de.epiceric.shopchest.utils.EnchantmentNames;
import de.epiceric.shopchest.utils.ItemNames;
import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.Utils;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse;
import net.milkbowl.vault.permission.Permission;
public class InteractShop implements Listener{
private ShopChest plugin;
private Permission perm = ShopChest.perm;
private Economy econ = ShopChest.econ;
private YamlConfiguration shopChests;
public InteractShop(ShopChest plugin) {
this.plugin = plugin;
shopChests = plugin.shopChests;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
Block b = e.getClickedBlock();
Player p = e.getPlayer();
if (e.getAction() == Action.RIGHT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_BLOCK) {
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (ClickType.getPlayerClickType(p) != null) {
switch (ClickType.getPlayerClickType(p).getClickType()) {
case CREATE:
e.setCancelled(true);
if (!ShopUtils.isShop(b.getLocation())) {
ClickType clickType = ClickType.getPlayerClickType(p);
ItemStack product = clickType.getProduct();
double buyPrice = clickType.getBuyPrice();
double sellPrice = clickType.getSellPrice();
boolean infinite = clickType.isInfinite();
create(p, b.getLocation(), product, buyPrice, sellPrice, infinite);
} else {
p.sendMessage(Config.chest_already_shop());
}
ClickType.removePlayerClickType(p);
break;
case INFO:
e.setCancelled(true);
if (ShopUtils.isShop(b.getLocation())) {
Shop shop = ShopUtils.getShop(b.getLocation());
info(p, shop);
} else {
p.sendMessage(Config.chest_no_shop());
}
ClickType.removePlayerClickType(p);
break;
case REMOVE:
e.setCancelled(true);
if (ShopUtils.isShop(b.getLocation())) {
Shop shop = ShopUtils.getShop(b.getLocation());
if (shop.getVendor().equals(p) || perm.has(p, "shopchest.removeOther")) {
remove(p, shop);
} else {
p.sendMessage(Config.noPermission_removeOthers());
}
} else {
p.sendMessage(Config.chest_no_shop());
}
ClickType.removePlayerClickType(p);
break;
}
} else {
if (ShopUtils.isShop(b.getLocation())) {
e.setCancelled(true);
Shop shop = ShopUtils.getShop(b.getLocation());
if (p.equals(shop.getVendor())) {
e.setCancelled(false);
return;
} else {
if (p.isSneaking()) {
if (perm.has(p, "shopchest.openOther")) {
p.sendMessage(Config.opened_shop(shop.getVendor().getName()));
e.setCancelled(false);
} else {
p.sendMessage(Config.noPermission_openOthers());
e.setCancelled(true);
}
} else {
if (shop.getBuyPrice() > 0) {
e.setCancelled(true);
if (perm.has(p, "shopchest.buy")) {
if (shop.isInfinite()) {
buy(p, shop);
} else {
Chest c = (Chest) b.getState();
if (Utils.getAmount(c.getInventory(), shop.getProduct().clone().getType(), shop.getProduct().clone().getDurability(), shop.getProduct().getItemMeta()) >= shop.getProduct().getAmount()) {
buy(p, shop);
} else {
p.sendMessage(Config.out_of_stock());
}
}
} else {
p.sendMessage(Config.noPermission_buy());
}
} else {
p.sendMessage(Config.buying_disabled());
}
}
}
}
}
} else if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
if (ShopUtils.isShop(b.getLocation())) {
Shop shop = ShopUtils.getShop(b.getLocation());
if (!p.equals(shop.getVendor())) {
if (shop.getSellPrice() > 0) {
if (perm.has(p, "shopchest.sell")) {
if (Utils.getAmount(p.getInventory(), shop.getProduct().getType(), shop.getProduct().getDurability(), shop.getProduct().getItemMeta()) >= shop.getProduct().getAmount()) {
sell(p, shop);
} else {
p.sendMessage(Config.not_enough_items());
}
} else {
p.sendMessage(Config.noPermission_sell());
}
} else {
p.sendMessage(Config.selling_disabled());
}
}
}
}
}
} else {
if (ClickType.getPlayerClickType(p) != null) ClickType.removePlayerClickType(p);
}
}
private void create(Player executor, Location location, ItemStack product, double buyPrice, double sellPrice, boolean infinite) {
Shop shop = new Shop(plugin, executor, product, location, buyPrice, sellPrice, infinite);
shopChests.set(ShopUtils.getConfigTitle(location) + ".vendor", executor);
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.world", location.getWorld().getName());
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.x", location.getBlockX());
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.y", location.getBlockY());
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.z", location.getBlockZ());
shopChests.set(ShopUtils.getConfigTitle(location) + ".product", product);
shopChests.set(ShopUtils.getConfigTitle(location) + ".price.buy", buyPrice);
shopChests.set(ShopUtils.getConfigTitle(location) + ".price.sell", sellPrice);
shopChests.set(ShopUtils.getConfigTitle(location) + ".infinite", infinite);
try {shopChests.save(plugin.shopChestsFile);} catch (IOException ex) {ex.printStackTrace();}
ShopUtils.addShop(shop);
executor.sendMessage(Config.shop_created());
for (Player p : Bukkit.getOnlinePlayers()) {
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
}
}
private void remove(Player executor, Shop shop) {
shop.getItem().remove();
ShopUtils.removeShop(shop);
shopChests.set(ShopUtils.getConfigTitle(shop.getLocation()), null);
try {shopChests.save(plugin.shopChestsFile);} catch (IOException ex) {ex.printStackTrace();}
for (Player player : plugin.getServer().getOnlinePlayers()) {
shop.getHologram().hidePlayer(player);
}
executor.sendMessage(Config.shop_removed());
}
private void info(Player executor, Shop shop) {
String vendor = Config.shopInfo_vendor(shop.getVendor().getName());
String product = Config.shopInfo_product(shop.getProduct().getAmount(), ItemNames.lookup(shop.getProduct()));
String enchantmentString = "";
String price = Config.shopInfo_price(shop.getBuyPrice(), shop.getSellPrice());
String infinite = (shop.isInfinite() ? Config.shopInfo_isInfinite() : Config.shopInfo_isNormal());
Map<Enchantment, Integer> enchantmentMap = shop.getProduct().getItemMeta().getEnchants();
Enchantment[] enchantments = enchantmentMap.keySet().toArray(new Enchantment[enchantmentMap.size()]);
for (int i = 0; i < enchantments.length; i++) {
Enchantment enchantment = enchantments[i];
if (i == enchantments.length - 1) {
enchantmentString += EnchantmentNames.lookup(enchantment, enchantmentMap.get(enchantment));
} else {
enchantmentString += EnchantmentNames.lookup(enchantment, enchantmentMap.get(enchantment)) + ", ";
}
}
executor.sendMessage(" ");
executor.sendMessage(vendor);
executor.sendMessage(product);
if (enchantmentString.length() > 0) executor.sendMessage(Config.shopInfo_enchantment(enchantmentString));
executor.sendMessage(price);
executor.sendMessage(infinite);
executor.sendMessage(" ");
}
private void buy(Player executor, Shop shop) {
if (econ.getBalance(executor) >= shop.getBuyPrice()) {
Block b = shop.getLocation().getBlock();
Chest c = (Chest) b.getState();
HashMap<Integer, Integer> slotFree = new HashMap<>();
ItemStack product = shop.getProduct().clone();
Inventory inventory = executor.getInventory();
for (int i = 0; i < 36; i++) {
ItemStack item = inventory.getItem(i);
if (item == null) {
slotFree.put(i, product.getMaxStackSize());
} else {
if ((item.getType().equals(product.getType())) && (item.getDurability() == product.getDurability()) && (item.getItemMeta().equals(product.getItemMeta())) && (item.getData().equals(product.getData()))) {
int amountInSlot = item.getAmount();
int amountToFullStack = product.getMaxStackSize() - amountInSlot;
slotFree.put(i, amountToFullStack);
}
}
}
int leftAmount = product.getAmount();
int freeAmount = 0;
for (int value : slotFree.values()) {
freeAmount += value;
}
EconomyResponse r = econ.withdrawPlayer(executor, shop.getBuyPrice());
EconomyResponse r2 = econ.depositPlayer(shop.getVendor(), shop.getBuyPrice());
if (r.transactionSuccess()) {
if (r2.transactionSuccess()) {
if (freeAmount >= leftAmount) {
for (int slot : slotFree.keySet()) {
if (leftAmount >= 0) {
int amountInSlot = -(slotFree.get(slot) - product.getMaxStackSize());
if (amountInSlot == -0) amountInSlot = 0;
for (int i = amountInSlot; i < product.getMaxStackSize() + 1; i++) {
if (leftAmount > 0) {
ItemStack boughtProduct = new ItemStack(product.clone().getType(), 1, product.clone().getDurability());
boughtProduct.setItemMeta(product.clone().getItemMeta());
if (!shop.isInfinite()) c.getInventory().removeItem(boughtProduct);
inventory.addItem(boughtProduct);
executor.updateInventory();
leftAmount--;
} else if (leftAmount == 0) {
executor.sendMessage(Config.buy_success(product.getAmount(), ItemNames.lookup(product), shop.getBuyPrice(), shop.getVendor().getName()));
return;
}
}
}
}
} else {
executor.sendMessage(Config.not_enough_inventory_space());
}
} else {
executor.sendMessage(Config.error_occurred(r2.errorMessage));
}
} else {
executor.sendMessage(Config.error_occurred(r.errorMessage));
}
} else {
executor.sendMessage(Config.not_enough_money());
}
}
private void sell(Player executor, Shop shop) {
if (econ.getBalance(shop.getVendor()) >= shop.getSellPrice()) {
Block block = shop.getLocation().getBlock();
Chest chest = (Chest) block.getState();
HashMap<Integer, Integer> slotFree = new HashMap<>();
ItemStack product = shop.getProduct().clone();
Inventory inventory = chest.getInventory();
for (int i = 0; i < chest.getInventory().getSize(); i++) {
ItemStack item = inventory.getItem(i);
if (item == null) {
slotFree.put(i, product.getMaxStackSize());
} else {
if ((item.getType().equals(product.getType())) && (item.getDurability() == product.getDurability()) && (item.getItemMeta().equals(product.getItemMeta())) && (item.getData().equals(product.getData()))) {
int amountInSlot = item.getAmount();
int amountToFullStack = product.getMaxStackSize() - amountInSlot;
slotFree.put(i, amountToFullStack);
}
}
}
int leftAmount = product.getAmount();
int freeAmount = 0;
for (int value : slotFree.values()) {
freeAmount += value;
}
EconomyResponse r = econ.withdrawPlayer(shop.getVendor(), shop.getSellPrice());
EconomyResponse r2 = econ.depositPlayer(executor, shop.getSellPrice());
if (r.transactionSuccess()) {
if (r2.transactionSuccess()) {
if (freeAmount >= leftAmount) {
for (int slot : slotFree.keySet()) {
if (leftAmount >= 0) {
int amountInSlot = -(slotFree.get(slot) - product.getMaxStackSize());
if (amountInSlot == -0) amountInSlot = 0;
for (int i = amountInSlot; i < product.getMaxStackSize() + 1; i++) {
if (leftAmount > 0) {
ItemStack boughtProduct = new ItemStack(product.clone().getType(), 1, product.clone().getDurability());
boughtProduct.setItemMeta(product.clone().getItemMeta());
if (!shop.isInfinite()) inventory.addItem(boughtProduct);
executor.getInventory().removeItem(boughtProduct);
executor.updateInventory();
leftAmount--;
} else if (leftAmount == 0) {
executor.sendMessage(Config.sell_success(product.getAmount(), ItemNames.lookup(product), shop.getSellPrice(), shop.getVendor().getName()));
return;
}
}
}
}
} else {
executor.sendMessage(Config.chest_not_enough_inventory_space());
}
} else {
executor.sendMessage(Config.error_occurred(r2.errorMessage));
}
} else {
executor.sendMessage(Config.error_occurred(r.errorMessage));
}
} else {
executor.sendMessage(Config.vendor_not_enough_money());
}
}
}

View File

@ -0,0 +1,37 @@
package de.epiceric.shopchest.event;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.utils.JsonBuilder;
import de.epiceric.shopchest.utils.JsonBuilder.ClickAction;
import de.epiceric.shopchest.utils.JsonBuilder.HoverAction;
import net.milkbowl.vault.permission.Permission;
public class NotifyUpdate implements Listener {
private Permission perm = ShopChest.perm;
public NotifyUpdate() {}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
if (ShopChest.isUpdateNeeded) {
if (p.isOp() || perm.has(p, "shopchest.notification.update")) {
String version = ShopChest.latestVersion;
String link = ShopChest.downloadLink;
JsonBuilder jb = new JsonBuilder(Config.update_available(version)).withHoverEvent(HoverAction.SHOW_TEXT, Config.click_to_download()).withClickEvent(ClickAction.OPEN_URL, link);
jb.sendJson(p);
}
}
}
}

View File

@ -0,0 +1,22 @@
package de.epiceric.shopchest.event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.utils.ShopUtils;
public class ProtectChest implements Listener {
public ProtectChest() {}
@EventHandler
public void onBlockBreak(BlockBreakEvent e) {
if (ShopUtils.isShop(e.getBlock().getLocation())) {
e.setCancelled(true);
e.getPlayer().sendMessage(Config.cannot_break_shop());
}
}
}

View File

@ -0,0 +1,27 @@
package de.epiceric.shopchest.event;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemDespawnEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
public class RegenerateShopItem implements Listener{
public RegenerateShopItem() {}
@EventHandler(priority = EventPriority.HIGH)
public void onItemDespawn(ItemDespawnEvent e) {
Item item = e.getEntity();
if (item.hasMetadata("shopItem")) e.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerPickUpItem(PlayerPickupItemEvent e) {
if (e.getItem().hasMetadata("shopItem")) e.setCancelled(true);
}
}

View File

@ -0,0 +1,50 @@
package de.epiceric.shopchest.event;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.ShopUtils;
public class UpdateHolograms implements Listener{
public UpdateHolograms() {}
@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
Player p = e.getPlayer();
Location playerLocation = p.getLocation();
for (Shop shop : ShopUtils.getShops()) {
Location shopLocation = shop.getLocation();
if (playerLocation.getWorld().equals(shopLocation.getWorld())) {
if (playerLocation.distance(shop.getHologram().getLocation()) <= Config.maximal_distance()) {
if (!shop.getHologram().isVisible(p)) {
shop.getHologram().showPlayer(p);
}
} else {
if (shop.getHologram().isVisible(p)) {
shop.getHologram().hidePlayer(p);
}
}
}
}
}
}

View File

@ -0,0 +1,89 @@
package de.epiceric.shopchest.shop;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
public class Hologram {
private List<EntityArmorStand> entitylist = new ArrayList<EntityArmorStand>();
private String[] text;
private Location location;
private double DISTANCE = 0.25D;
int count;
private HashMap<OfflinePlayer, Boolean> visible = new HashMap<OfflinePlayer, Boolean>();
public Hologram(String[] text, Location location) {
this.text = text;
this.location = location;
create();
}
public Hologram(String text, Location location) {
this.text = new String[] {text};
this.location = location;
create();
}
public String getText(int line) {
return text[line];
}
public Location getLocation() {
return location;
}
public List<EntityArmorStand> getEntities() {
return entitylist;
}
public void showPlayer(OfflinePlayer p) {
for (EntityArmorStand armor : entitylist) {
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(armor);
((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet);
}
visible.put(p, true);
}
public void hidePlayer(OfflinePlayer p) {
for (EntityArmorStand armor : entitylist) {
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(armor.getId());
((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet);
}
visible.put(p, false);
}
public boolean isVisible(OfflinePlayer p) {
if (visible.containsKey(p)) return visible.get(p); else return false;
}
private void create() {
for (String text : this.text) {
EntityArmorStand entity = new EntityArmorStand(((CraftWorld) this.location.getWorld()).getHandle(),this.location.getX(), this.location.getY(),this.location.getZ());
entity.setCustomName(text);
entity.setCustomNameVisible(true);
entity.setInvisible(true);
entity.setGravity(false);
entitylist.add(entity);
this.location.subtract(0, this.DISTANCE, 0);
count++;
}
for (int i = 0; i < count; i++) {
this.location.add(0, this.DISTANCE, 0);
}
this.count = 0;
}
}

View File

@ -0,0 +1,176 @@
package de.epiceric.shopchest.shop;
import java.util.ArrayList;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Item;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.utils.ItemNames;
public class Shop {
private ShopChest plugin;
private OfflinePlayer vendor;
private ItemStack product;
private Location location;
private Hologram hologram;
private Item item;
private double buyPrice;
private double sellPrice;
private boolean infinite;
public Shop(ShopChest plugin, OfflinePlayer vendor, ItemStack product, Location location, double buyPrice, double sellPrice, boolean infinite) {
this.plugin = plugin;
this.vendor = vendor;
this.product = product;
this.location = location;
this.buyPrice = buyPrice;
this.sellPrice = sellPrice;
this.infinite = infinite;
this.hologram = createHologram(product, location, buyPrice, sellPrice);
this.item = createItem(product, location);
}
public Item createItem(ItemStack product, Location location) {
Item item;
Location itemLocation;
ItemStack itemStack;
itemLocation = new Location(location.getWorld(), hologram.getLocation().getX(), location.getY() + 1, hologram.getLocation().getZ());
itemStack = new ItemStack(product.getType(), 1, product.getDurability());
itemStack.setItemMeta(product.getItemMeta());
ArrayList<String> lore = new ArrayList<String>();
lore.add("This is an Item of ShopChest");
lore.add("This text is just to prevent merging.");
lore.add("ID: " + String.valueOf(new Random().nextInt()));
itemStack.getItemMeta().setLore(lore);
item = location.getWorld().dropItem(itemLocation, itemStack);
item.setVelocity(new Vector(0, 0, 0));
item.setMetadata("shopItem", new FixedMetadataValue(plugin, true));
return item;
}
public Hologram createHologram(ItemStack product, Location shopLocation, double buyPrice, double sellPrice) {
boolean doubleChest;
Hologram hologram;
Chest[] chests = new Chest[2];
Block b = shopLocation.getBlock();
if (b.getType().equals(Material.CHEST)) {
Chest c = (Chest) b.getState();
InventoryHolder ih = c.getInventory().getHolder();
if (ih instanceof DoubleChest) {
DoubleChest dc = (DoubleChest) ih;
Chest r = (Chest) dc.getRightSide();
Chest l = (Chest) dc.getLeftSide();
chests[0] = r;
chests[1] = l;
doubleChest = true;
} else {
doubleChest = false;
chests[0] = c;
}
} else {
return null;
}
Location holoLocation;
String[] holoText = new String[2];
if (doubleChest) {
Chest r = chests[0];
Chest l = chests[1];
if (b.getLocation().equals(r.getLocation())) {
if (r.getX() != l.getX()) holoLocation = new Location(b.getWorld(), b.getX(), b.getY() - 0.6, b.getZ() + 0.5);
else if (r.getZ() != l.getZ()) holoLocation = new Location(b.getWorld(), b.getX() + 0.5, b.getY() - 0.6, b.getZ());
else holoLocation = new Location(b.getWorld(), b.getX() + 0.5, b.getY() - 0.6, b.getZ() + 0.5);
} else {
if (r.getX() != l.getX()) holoLocation = new Location(b.getWorld(), b.getX() + 1, b.getY() - 0.6, b.getZ() + 0.5);
else if (r.getZ() != l.getZ()) holoLocation = new Location(b.getWorld(), b.getX() + 0.5, b.getY() - 0.6, b.getZ() + 1);
else holoLocation = new Location(b.getWorld(), b.getX() + 0.5, b.getY() - 0.6, b.getZ() + 0.5);
}
} else holoLocation = new Location(b.getWorld(), b.getX() + 0.5, b.getY() - 0.6, b.getZ() + 0.5);
holoText[0] = String.valueOf(product.getAmount()) + " x " + ItemNames.lookup(product);
if ((buyPrice <= 0) && (sellPrice > 0)) holoText[1] = Config.hologram_sell(sellPrice);
else if ((buyPrice > 0) && (sellPrice <= 0)) holoText[1] = Config.hologram_buy(buyPrice);
else if ((buyPrice > 0) && (sellPrice > 0)) holoText[1] = Config.hologram_buy_sell(buyPrice, sellPrice);
else holoText[1] = Config.hologram_buy_sell(buyPrice, sellPrice);
hologram = new Hologram(holoText, holoLocation);
return hologram;
}
public OfflinePlayer getVendor() {
return vendor;
}
public ItemStack getProduct() {
return product;
}
public Location getLocation() {
return location;
}
public double getBuyPrice() {
return buyPrice;
}
public double getSellPrice() {
return sellPrice;
}
public boolean isInfinite() {
return infinite;
}
public Hologram getHologram() {
return hologram;
}
public Item getItem() {
return item;
}
}

View File

@ -0,0 +1,69 @@
package de.epiceric.shopchest.utils;
import java.util.HashMap;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
public class ClickType {
private static HashMap<OfflinePlayer, ClickType> playerClickType = new HashMap<>();
public static ClickType getPlayerClickType(OfflinePlayer player) {
if (playerClickType.containsKey(player))
return playerClickType.get(player);
else
return null;
}
public static void removePlayerClickType(OfflinePlayer player) {
playerClickType.remove(player);
}
public static void addPlayerClickType(OfflinePlayer player, ClickType clickType) {
playerClickType.put(player, clickType);
}
public enum EnumClickType {
CREATE, REMOVE, INFO;
}
private EnumClickType enumClickType;
private ItemStack product;
private double buyPrice;
private double sellPrice;
private boolean infinite;
public ClickType(EnumClickType enumClickType) {
this.enumClickType = enumClickType;
}
public ClickType(EnumClickType enumClickType, ItemStack product, double buyPrice, double sellPrice, boolean infinite) {
this.enumClickType = enumClickType;
this.product = product;
this.sellPrice = sellPrice;
this.buyPrice = buyPrice;
this.infinite = infinite;
}
public EnumClickType getClickType() {
return enumClickType;
}
public ItemStack getProduct() {
return product;
}
public double getBuyPrice() {
return buyPrice;
}
public double getSellPrice() {
return sellPrice;
}
public boolean isInfinite() {
return infinite;
}
}

View File

@ -0,0 +1,84 @@
package de.epiceric.shopchest.utils;
import java.util.LinkedHashMap;
import java.util.Map;
import org.bukkit.enchantments.Enchantment;
import com.google.common.collect.ImmutableMap;
public class EnchantmentNames {
private static final Map<String, String> enchMap = ImmutableMap.<String, String>builder()
.put("PROTECTION_ENVIRONMENTAL", "Protection")
.put("PROTECTION_FIRE", "Fire Protection")
.put("PROTECTION_FALL", "Feather Falling")
.put("PROTECTION_EXPLOSIONS", "Blast Protection")
.put("OXYGEN", "Respiration")
.put("WATER_WORKER", "Aqua Affinity")
.put("THORNS", "Thorns")
.put("DEPTH_STRIDER", "Depth Strider")
.put("DAMAGE_ALL", "Sharpness")
.put("DAMAGE_UNDEAD", "smite")
.put("DAMAGE_ARTHROPODS", "Bane of Arthropods")
.put("KNOCKBACK", "Knockback")
.put("FIRE_ASPECT", "Fire Aspect")
.put("LOOT_BONUS_MOBS", "Looting")
.put("DIG_SPEED", "Efficiency")
.put("SILK_TOUCH", "Silk Touch")
.put("DURABILITY", "Unbreaking")
.put("LOOT_BONUS_BLOCKS", "Fortune")
.put("ARROW_DAMAGE", "Power")
.put("ARROW_KNOCKBACK", "Punch")
.put("ARROW_FIRE", "Flame")
.put("ARROW_INFINITE", "Infinity")
.put("LUCK", "Luck of the Sea")
.put("LURE", "Lure")
.build();
public static String lookup(Enchantment enchantment, int level) {
String key = enchantment.getName();
String name = enchMap.get(key);
String levelString = getRomanNumber(level);
return name + " " + levelString;
}
public static String getRomanNumber(int Int) {
LinkedHashMap<String, Integer> roman_numerals = new LinkedHashMap<String, Integer>();
roman_numerals.put("M", 1000);
roman_numerals.put("CM", 900);
roman_numerals.put("D", 500);
roman_numerals.put("CD", 400);
roman_numerals.put("C", 100);
roman_numerals.put("XC", 90);
roman_numerals.put("L", 50);
roman_numerals.put("XL", 40);
roman_numerals.put("X", 10);
roman_numerals.put("IX", 9);
roman_numerals.put("V", 5);
roman_numerals.put("IV", 4);
roman_numerals.put("I", 1);
String res = "";
for(Map.Entry<String, Integer> entry : roman_numerals.entrySet()){
int matches = Int/entry.getValue();
res += repeat(entry.getKey(), matches);
Int = Int % entry.getValue();
}
return res;
}
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}

View File

@ -0,0 +1,617 @@
package de.epiceric.shopchest.utils;
import java.util.Map;
import org.apache.commons.lang.WordUtils;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import com.google.common.collect.ImmutableMap;
public class ItemNames {
private static final Map<String,String> map = ImmutableMap.<String,String>builder()
.put("1", "Stone")
.put("1:1", "Granite")
.put("1:2", "Polished Granite")
.put("1:3", "Diorite")
.put("1:4", "Polished Diorite")
.put("1:5", "Andesite")
.put("1:6", "Polished Andesite")
.put("2", "Grass Block")
.put("3", "Dirt")
.put("3:1", "Coarse Dirt")
.put("3:2", "Podzol")
.put("4", "Cobblestone")
.put("5", "Oak Wood Planks")
.put("5:1", "Spruce Wood Planks")
.put("5:2", "Birch Wood Planks")
.put("5:3", "Jungle Wood Planks")
.put("5:4", "Acacia Wood Planks")
.put("5:5", "Dark Oak Wood Planks")
.put("6", "Oak Sapling")
.put("6:1", "Spruce Sapling")
.put("6:2", "Birch Sapling")
.put("6:3", "Jungle Sapling")
.put("6:4", "Acacia Sapling")
.put("6:5", "Dark Oak Sapling")
.put("7", "Bedrock")
.put("8", "Water (No Spread)")
.put("9", "Water")
.put("10", "Lava (No Spread)")
.put("11", "Lava")
.put("12", "Sand")
.put("12:1", "Red Sand")
.put("13", "Gravel")
.put("14", "Gold Ore")
.put("15", "Iron Ore")
.put("16", "Coal Ore")
.put("17", "Oak Wood")
.put("17:1", "Spruce Wood")
.put("17:2", "Birch Wood")
.put("17:3", "Jungle Wood")
.put("18", "Oak Leaves")
.put("18:1", "Spruce Leaves")
.put("18:2", "Birch Leaves")
.put("18:3", "Jungle Leaves")
.put("19", "Sponge")
.put("19:1", "Wet Sponge")
.put("20", "Glass")
.put("21", "Lapis Lazuli Ore")
.put("22", "Lapis Lazuli Block")
.put("23", "Dispenser")
.put("24", "Sandstone")
.put("24:1", "Chiseled Sandstone")
.put("24:2", "Smooth Sandstone")
.put("25", "Note Block")
.put("26", "Bed")
.put("27", "Powered Rail")
.put("28", "Detector Rail")
.put("29", "Sticky Piston")
.put("30", "Web")
.put("31", "Shrub")
.put("31:1", "Grass")
.put("31:2", "Fern")
.put("32", "Dead Bush")
.put("33", "Piston")
.put("34", "Piston (Head)")
.put("35", "Wool")
.put("35:1", "Orange Wool")
.put("35:2", "Magenta Wool")
.put("35:3", "Light Blue Wool")
.put("35:4", "Yellow Wool")
.put("35:5", "Lime Wool")
.put("35:6", "Pink Wool")
.put("35:7", "Gray Wool")
.put("35:8", "Light Gray Wool")
.put("35:9", "Cyan Wool")
.put("35:10", "Purple Wool")
.put("35:11", "Blue Wool")
.put("35:12", "Brown Wool")
.put("35:13", "Green Wool")
.put("35:14", "Red Wool")
.put("35:15", "Black Wool")
.put("37", "Dandelion")
.put("38", "Rose")
.put("38:1", "Blue Orchid")
.put("38:2", "Allium")
.put("38:3", "Azure Bluet")
.put("38:4", "Red Tulip")
.put("38:5", "Orange Tulip")
.put("38:6", "White Tulip")
.put("38:7", "Pink Tulip")
.put("38:8", "Oxeye Daisy")
.put("39", "Brown Mushroom")
.put("40", "Red Mushroom")
.put("41", "Gold Block")
.put("42", "Iron Block")
.put("43", "Stone Slab (Double)")
.put("43:1", "Sandstone Slab (Double)")
.put("43:2", "Wooden Slab (Double)")
.put("43:3", "Cobblestone Slab (Double)")
.put("43:4", "Brick Slab (Double)")
.put("43:5", "Stone Brick Slab (Double)")
.put("43:6", "Nether Brick Slab (Double)")
.put("43:7", "Quartz Slab (Double)")
.put("43:8", "Smooth Stone Slab (Double)")
.put("43:9", "Smooth Sandstone Slab (Double)")
.put("44", "Stone Slab")
.put("44:1", "Sandstone Slab")
.put("44:2", "Wooden Slab")
.put("44:3", "Cobblestone Slab")
.put("44:4", "Brick Slab")
.put("44:5", "Stone Brick Slab")
.put("44:6", "Nether Brick Slab")
.put("44:7", "Quartz Slab")
.put("45", "Brick")
.put("46", "TNT")
.put("47", "Bookcase")
.put("48", "Moss Stone")
.put("49", "Obsidian")
.put("50", "Torch")
.put("51", "Fire")
.put("52", "Mob Spawner")
.put("53", "Oak Wood Stairs")
.put("54", "Chest")
.put("55", "Redstone Wire")
.put("56", "Diamond Ore")
.put("57", "Diamond Block")
.put("58", "Crafting Table")
.put("59", "Wheat (Crop)")
.put("60", "Farmland")
.put("61", "Furnace")
.put("62", "Furnace (Smelting)")
.put("63", "Sign (Block)")
.put("64", "Wood Door (Block)")
.put("65", "Ladder")
.put("66", "Rails")
.put("67", "Stone Stairs")
.put("68", "Sign (Wall Block)")
.put("69", "Lever")
.put("70", "Pressure Plate")
.put("71", "Iron Door (Block)")
.put("72", "Pressure Plate")
.put("73", "Redstone Ore")
.put("74", "Redstone Ore (Glowing)")
.put("75", "Redstone Torch (Off)")
.put("76", "Redstone Torch")
.put("77", "Button")
.put("78", "Snow")
.put("79", "Ice")
.put("80", "Snow Block")
.put("81", "Cactus")
.put("82", "Clay Block")
.put("83", "Sugar Cane (Block)")
.put("84", "Jukebox")
.put("85", "Fence")
.put("86", "Pumpkin")
.put("87", "Netherrack")
.put("88", "Soul Sand")
.put("89", "Glowstone")
.put("90", "Portal")
.put("91", "Jack-O-Lantern")
.put("92", "Cake (Block)")
.put("93", "Redstone Repeater (Block Off)")
.put("94", "Redstone Repeater (Block On)")
.put("95", "Stained Glass")
.put("96", "Wooden Trapdoor")
.put("97", "Stone Monster Egg")
.put("97:1", "Cobblestone Monster Egg")
.put("97:2", "Stone Brick Monster Egg")
.put("97:3", "Mossy Stone Brick Monster Egg")
.put("97:4", "Cracked Stone Brick Monster Egg")
.put("97:5", "Chiseled Stone Brick Monster Egg")
.put("98", "Stone Bricks")
.put("98:1", "Mossy Stone Bricks")
.put("98:2", "Cracked Stone Bricks")
.put("98:3", "Chiseled Stone Bricks")
.put("99", "Brown Mushroom (Block)")
.put("100", "Red Mushroom (Block)")
.put("101", "Iron Bars")
.put("102", "Glass Pane")
.put("103", "Melon (Block)")
.put("104", "Pumpkin Vine")
.put("105", "Melon Vine")
.put("106", "Vines")
.put("107", "Fence Gate")
.put("108", "Brick Stairs")
.put("109", "Stone Brick Stairs")
.put("110", "Mycelium")
.put("111", "Lily Pad")
.put("112", "Nether Brick")
.put("113", "Nether Brick Fence")
.put("114", "Nether Brick Stairs")
.put("115", "Nether Wart")
.put("116", "Enchantment Table")
.put("117", "Brewing Stand (Block)")
.put("118", "Cauldron (Block)")
.put("119", "End Portal")
.put("120", "End Portal Frame")
.put("121", "End Stone")
.put("122", "Dragon Egg")
.put("123", "Redstone Lamp (Inactive)")
.put("124", "Redstone Lamp (Active)")
.put("125", "Double Wood Slab")
.put("126", "Oak Wood Slab")
.put("126:1", "Spruce Wood Slab")
.put("126:2", "Birch Slab")
.put("126:3", "Jungle Slab")
.put("126:4", "Acacia Wood Slab")
.put("126:5", "Dark Oak Wood Slab")
.put("127", "Cocoa Plant")
.put("128", "Sandstone Stairs")
.put("129", "Emerald Ore")
.put("130", "Ender Chest")
.put("131", "Tripwire Hook")
.put("132", "Tripwire")
.put("133", "Emerald Block")
.put("134", "Spruce Wood Stairs")
.put("135", "Birch Wood Stairs")
.put("136", "Jungle Wood Stairs")
.put("137", "Command Block")
.put("138", "Beacon Block")
.put("139", "Cobblestone Wall")
.put("139:1", "Mossy Cobblestone Wall")
.put("140", "Flower Pot")
.put("141", "Carrots")
.put("142", "Potatoes")
.put("143", "Button")
.put("144", "Head")
.put("145", "Anvil")
.put("146", "Trapped Chest")
.put("147", "Weighted Pressure Plate (Light)")
.put("148", "Weighted Pressure Plate (Heavy)")
.put("149", "Redstone Comparator (inactive)")
.put("150", "Redstone Comparator (active)")
.put("151", "Daylight Sensor")
.put("152", "Redstone Block")
.put("153", "Nether Quartz Ore")
.put("154", "Hopper")
.put("155", "Quartz Block")
.put("155:1", "Chiseled Quartz Block")
.put("155:2", "Pillar Quartz Block")
.put("156", "Quartz Stairs")
.put("157", "Activator Rail")
.put("158", "Dropper")
.put("159", "Stained Clay")
.put("160", "Stained Glass Pane")
.put("161", "Acacia Leaves")
.put("161:1", "Dark Oak Leaves")
.put("162", "Acacia Wood")
.put("162:1", "Dark Oak Wood")
.put("163", "Acacia Wood Stairs")
.put("164", "Dark Oak Wood Stairs")
.put("165", "Slime Block")
.put("166", "Barrier")
.put("167", "Iron Trapdoor")
.put("168", "Prismarine")
.put("168:1", "Prismarine Bricks")
.put("168:2", "Dark Prismarine")
.put("169", "Sea Lantern")
.put("170", "Hay Block")
.put("171", "Carpet")
.put("172", "Hardened Clay")
.put("173", "Block of Coal")
.put("174", "Packed Ice")
.put("175", "Sunflower")
.put("175:1", "Lilac")
.put("175:2", "Double Tallgrass")
.put("175:3", "Large Fern")
.put("175:4", "Rose Bush")
.put("175:5", "Peony")
.put("256", "Iron Shovel")
.put("257", "Iron Pickaxe")
.put("258", "Iron Axe")
.put("259", "Flint and Steel")
.put("260", "Apple")
.put("261", "Bow")
.put("262", "Arrow")
.put("263", "Coal")
.put("263:1", "Charcoal")
.put("264", "Diamond")
.put("265", "Iron Ingot")
.put("266", "Gold Ingot")
.put("267", "Iron Sword")
.put("268", "Wooden Sword")
.put("269", "Wooden Shovel")
.put("270", "Wooden Pickaxe")
.put("271", "Wooden Axe")
.put("272", "Stone Sword")
.put("273", "Stone Shovel")
.put("274", "Stone Pickaxe")
.put("275", "Stone Axe")
.put("276", "Diamond Sword")
.put("277", "Diamond Shovel")
.put("278", "Diamond Pickaxe")
.put("279", "Diamond Axe")
.put("280", "Stick")
.put("281", "Bowl")
.put("282", "Mushroom Stew")
.put("283", "Gold Sword")
.put("284", "Gold Shovel")
.put("285", "Gold Pickaxe")
.put("286", "Gold Axe")
.put("287", "String")
.put("288", "Feather")
.put("289", "Gunpowder")
.put("290", "Wooden Hoe")
.put("291", "Stone Hoe")
.put("292", "Iron Hoe")
.put("293", "Diamond Hoe")
.put("294", "Gold Hoe")
.put("295", "Seeds")
.put("296", "Wheat")
.put("297", "Bread")
.put("298", "Leather Helmet")
.put("299", "Leather Chestplate")
.put("300", "Leather Leggings")
.put("301", "Leather Boots")
.put("302", "Chainmail Helmet")
.put("303", "Chainmail Chestplate")
.put("304", "Chainmail Leggings")
.put("305", "Chainmail Boots")
.put("306", "Iron Helmet")
.put("307", "Iron Chestplate")
.put("308", "Iron Leggings")
.put("309", "Iron Boots")
.put("310", "Diamond Helmet")
.put("311", "Diamond Chestplate")
.put("312", "Diamond Leggings")
.put("313", "Diamond Boots")
.put("314", "Gold Helmet")
.put("315", "Gold Chestplate")
.put("316", "Gold Leggings")
.put("317", "Gold Boots")
.put("318", "Flint")
.put("319", "Raw Porkchop")
.put("320", "Cooked Porkchop")
.put("321", "Painting")
.put("322", "Gold Apple")
.put("322:1", "Gold Apple (Enchanted)")
.put("323", "Sign")
.put("324", "Wooden Door")
.put("325", "Bucket")
.put("326", "Water Bucket")
.put("327", "Lava Bucket")
.put("328", "Minecart")
.put("329", "Saddle")
.put("330", "Iron Door")
.put("331", "Redstone")
.put("332", "Snowball")
.put("333", "Boat")
.put("334", "Leather")
.put("335", "Milk Bucket")
.put("336", "Brick")
.put("337", "Clay")
.put("338", "Sugar Cane")
.put("339", "Paper")
.put("340", "Book")
.put("341", "Slime Ball")
.put("342", "Storage Minecart")
.put("343", "Powered Minecart")
.put("344", "Egg")
.put("345", "Compass")
.put("346", "Fishing Rod")
.put("347", "Watch")
.put("348", "Glowstone Dust")
.put("349", "Raw Fish")
.put("349:1", "Raw Salmon")
.put("349:2", "Clownfish")
.put("349:3", "Pufferfish")
.put("350", "Cooked Fish")
.put("350:1", "Cooked Salmon")
.put("351", "Ink Sack [Black Dye]")
.put("351:1", "Rose Red [Red Dye]")
.put("351:2", "Cactus Green [Green Dye]")
.put("351:3", "Cocoa Bean [Brown Dye]")
.put("351:4", "Lapis Lazuli [Blue Dye]")
.put("351:5", "Purple Dye")
.put("351:6", "Cyan Dye")
.put("351:7", "Light Gray Dye")
.put("351:8", "Gray Dye")
.put("351:9", "Pink Dye")
.put("351:10", "Lime Dye")
.put("351:11", "Dandelion Yellow [Yellow Dye]")
.put("351:12", "Light Blue Dye")
.put("351:13", "Magenta Dye")
.put("351:14", "Orange Dye")
.put("351:15", "Bone Meal [White Dye]")
.put("352", "Bone")
.put("353", "Sugar")
.put("354", "Cake")
.put("355", "Bed")
.put("356", "Redstone Repeater")
.put("357", "Cookie")
.put("358", "Map")
.put("359", "Shears")
.put("360", "Melon")
.put("361", "Pumpkin Seeds")
.put("362", "Melon Seeds")
.put("363", "Raw Beef")
.put("364", "Steak")
.put("365", "Raw Chicken")
.put("366", "Roast Chicken")
.put("367", "Rotten Flesh")
.put("368", "Ender Pearl")
.put("369", "Blaze Rod")
.put("370", "Ghast Tear")
.put("371", "Gold Nugget")
.put("372", "Nether Wart")
.put("373", "Water Bottle")
.put("373:16", "Awkward Potion")
.put("373:32", "Thick Potion")
.put("373:64", "Mundane Potion")
.put("373:8193", "Regeneration Potion (0:45)")
.put("373:8194", "Swiftness Potion (3:00)")
.put("373:8195", "Fire Resistance Potion (3:00)")
.put("373:8196", "Poison Potion (0:45)")
.put("373:8197", "Healing Potion")
.put("373:8200", "Weakness Potion (1:30)")
.put("373:8201", "Strength Potion (3:00)")
.put("373:8202", "Slowness Potion (1:30)")
.put("373:8203", "Potion of Leaping (3:00)")
.put("373:8204", "Harming Potion")
.put("373:8225", "Regeneration Potion II (0:22)")
.put("373:8226", "Swiftness Potion II (1:30)")
.put("373:8228", "Poison Potion II (0:22)")
.put("373:8229", "Healing Potion II")
.put("373:8230", "Night Vision Potion (3:00)")
.put("373:8233", "Strength Potion II (1:30)")
.put("373:8235", "Potion of Leaping (1:30)")
.put("373:8236", "Harming Potion II")
.put("373:8237", "Water Breathing Potion (3:00)")
.put("373:8238", "Invisibility Potion (3:00)")
.put("373:8257", "Regeneration Potion (2:00)")
.put("373:8258", "Swiftness Potion (8:00)")
.put("373:8259", "Fire Resistance Potion (8:00)")
.put("373:8260", "Poison Potion (2:00)")
.put("373:8262", "Night Vision Potion (8:00)")
.put("373:8264", "Weakness Potion (4:00)")
.put("373:8265", "Strength Potion (8:00)")
.put("373:8266", "Slowness Potion (4:00)")
.put("373:8269", "Water Breathing Potion (8:00)")
.put("373:8270", "Invisibility Potion (8:00)")
.put("373:16378", "Fire Resistance Splash (2:15)")
.put("373:16385", "Regeneration Splash (0:33)")
.put("373:16386", "Swiftness Splash (2:15)")
.put("373:16388", "Poison Splash (0:33)")
.put("373:16389", "Healing Splash")
.put("373:16392", "Weakness Splash (1:07)")
.put("373:16393", "Strength Splash (2:15)")
.put("373:16394", "Slowness Splash (1:07)")
.put("373:16396", "Harming Splash")
.put("373:16418", "Swiftness Splash II (1:07)")
.put("373:16420", "Poison Splash II (0:16)")
.put("373:16421", "Healing Splash II")
.put("373:16422", "Night Vision Splash (2:15)")
.put("373:16425", "Strength Splash II (1:07)")
.put("373:16428", "Harming Splash II")
.put("373:16429", "Water Breathing Splash (2:15)")
.put("373:16430", "Invisibility Splash (2:15)")
.put("373:16449", "Regeneration Splash (1:30)")
.put("373:16450", "Swiftness Splash (6:00)")
.put("373:16451", "Fire Resistance Splash (6:00)")
.put("373:16452", "Poison Splash (1:30)")
.put("373:16454", "Night Vision Splash (6:00)")
.put("373:16456", "Weakness Splash (3:00)")
.put("373:16457", "Strength Splash (6:00)")
.put("373:16458", "Slowness Splash (3:00)")
.put("373:16461", "Water Breathing Splash (6:00)")
.put("373:16462", "Invisibility Splash (6:00)")
.put("373:16471", "Regeneration Splash II (0:16)")
.put("374", "Glass Bottle")
.put("375", "Spider Eye")
.put("376", "Fermented Spider Eye")
.put("377", "Blaze Powder")
.put("378", "Magma Cream")
.put("379", "Brewing Stand")
.put("380", "Cauldron")
.put("381", "Eye of Ender")
.put("382", "Glistering Melon")
.put("383", "Spawn Egg")
.put("383:50", "Spawn Creeper")
.put("383:51", "Spawn Skeleton")
.put("383:52", "Spawn Spider")
.put("383:54", "Spawn Zombie")
.put("383:55", "Spawn Slime")
.put("383:56", "Spawn Ghast")
.put("383:57", "Spawn Pigman")
.put("383:58", "Spawn Enderman")
.put("383:59", "Spawn Cave Spider")
.put("383:60", "Spawn Silverfish")
.put("383:61", "Spawn Blaze")
.put("383:62", "Spawn Magma Cube")
.put("383:65", "Spawn Bat")
.put("383:66", "Spawn Witch")
.put("383:67", "Spawn Endermite")
.put("383:68", "Spawn Guardian")
.put("383:90", "Spawn Pig")
.put("383:91", "Spawn Sheep")
.put("383:92", "Spawn Cow")
.put("383:93", "Spawn Chicken")
.put("383:94", "Spawn Squid")
.put("383:95", "Spawn Wolf")
.put("383:96", "Spawn Mooshroom")
.put("383:98", "Spawn Ocelot")
.put("383:100", "Spawn Horse")
.put("383:101", "Spawn Rabbit")
.put("383:120", "Spawn Villager")
.put("384", "Bottle o' Enchanting")
.put("385", "Fire Charge")
.put("386", "Book and Quill")
.put("387", "Written Book")
.put("388", "Emerald")
.put("389", "Item Frame")
.put("390", "Flower Pot")
.put("391", "Carrot")
.put("392", "Potato")
.put("393", "Baked Potato")
.put("394", "Poisonous Potato")
.put("395", "Empty Map")
.put("396", "Golden Carrot")
.put("397", "Skull Item")
.put("397:0", "Skeleton Skull")
.put("397:1", "Wither Skeleton Skull")
.put("397:2", "Zombie Head")
.put("373:3", "Head")
.put("373:4", "Creeper Head")
.put("398", "Carrot on a Stick")
.put("399", "Nether Star")
.put("400", "Pumpkin Pie")
.put("401", "Firework Rocket")
.put("402", "Firework Star")
.put("403", "Enchanted Book")
.put("404", "Redstone Comparator")
.put("405", "Nether Brick")
.put("406", "Nether Quartz")
.put("407", "Minecart with TNT")
.put("408", "Minecart with Hopper")
.put("409", "Prismarine Shard")
.put("410", "Prismarine Crystals")
.put("411", "Raw Rabbit")
.put("412", "Cooked Rabbit")
.put("413", "Rabbit Stew")
.put("414", "Rabbit Foot")
.put("415", "Rabbit Hide")
.put("417", "Iron Horse Armor")
.put("418", "Gold Horse Armor")
.put("419", "Diamond Horse Armor")
.put("420", "Lead")
.put("421", "Name Tag")
.put("422", "Minecart with Command Block")
.put("423", "Raw Mutton")
.put("424", "Cooked Mutton")
.put("2256", "Music Disk (13)")
.put("2257", "Music Disk (Cat)")
.put("2258", "Music Disk (Blocks)")
.put("2259", "Music Disk (Chirp)")
.put("2260", "Music Disk (Far)")
.put("2261", "Music Disk (Mall)")
.put("2262", "Music Disk (Mellohi)")
.put("2263", "Music Disk (Stal)")
.put("2264", "Music Disk (Strad)")
.put("2265", "Music Disk (Ward)")
.put("2266", "Music Disk (11)")
.put("2267", "Music Disk (wait)")
.build();
public static String lookup(ItemStack stack) {
if (stack.hasItemMeta()) {
ItemMeta meta = stack.getItemMeta();
if (meta.getDisplayName() != null) {
return meta.getDisplayName();
} else if (meta instanceof BookMeta) {
return ((BookMeta)meta).getTitle();
}
}
String result;
String key = Integer.toString(stack.getTypeId());
Material mat = stack.getType();
if ((mat == Material.WOOL || mat == Material.CARPET) && stack.getDurability() == 0) {
// special case: white wool/carpet is just called "Wool" or "Carpet"
result = map.get(key);
} else if (mat == Material.WOOL || mat == Material.CARPET || mat == Material.STAINED_CLAY || mat == Material.STAINED_GLASS || mat == Material.STAINED_GLASS_PANE) {
DyeColor dc = DyeColor.getByWoolData((byte)stack.getDurability());
result = dc == null ? map.get(key) : WordUtils.capitalizeFully(dc.toString().replace("_", " ")) + " " + map.get(key);
} else if (mat == Material.LEATHER_HELMET || mat == Material.LEATHER_CHESTPLATE || mat == Material.LEATHER_LEGGINGS || mat == Material.LEATHER_BOOTS) {
LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) stack.getItemMeta();
DyeColor dc = DyeColor.getByColor(leatherArmorMeta.getColor());
result = dc == null ? map.get(key) : WordUtils.capitalizeFully(dc.toString()).replace("_", " ") + " " + map.get(key);
} else if (stack.getDurability() != 0) {
result = map.get(key + ":" + stack.getDurability());
if (result == null) {
result = map.get(key);
}
} else {
result = map.containsKey(key) ? map.get(key) : stack.getType().toString();
}
return result;
}
}

View File

@ -0,0 +1,106 @@
package de.epiceric.shopchest.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.bukkit.ChatColor;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer;
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
public class JsonBuilder {
/* JsonBuilder by FisheyLP */
public enum ClickAction {
RUN_COMMAND, SUGGEST_COMMAND, OPEN_URL
}
public enum HoverAction {
SHOW_TEXT
}
private List<String> extras = new ArrayList<String>();
public JsonBuilder(String... text) {
for(String extra : text)
parse(extra);
}
public JsonBuilder parse(String text) {
String regex = "[&§]{1}([a-fA-Fl-oL-O0-9]){1}";
text = text.replaceAll(regex, "§$1");
if(!Pattern.compile(regex).matcher(text).find()) {
withText(text);
return this;
}
String[] words = text.split(regex);
int index = words[0].length();
for(String word : words) {
try {
if(index != words[0].length())
withText(word).withColor("§"+text.charAt(index - 1));
} catch(Exception e){}
index += word.length() + 2;
}
return this;
}
public JsonBuilder withText(String text) {
extras.add("{text:\"" + text + "\"}");
return this;
}
public JsonBuilder withColor(ChatColor color) {
String c = color.name().toLowerCase();
addSegment(color.isColor() ? "color:" + c : c + ":true");
return this;
}
public JsonBuilder withColor(String color) {
while(color.length() != 1) color = color.substring(1).trim();
withColor(ChatColor.getByChar(color));
return this;
}
public JsonBuilder withClickEvent(ClickAction action, String value) {
addSegment("clickEvent:{action:" + action.toString().toLowerCase()
+ ",value:\"" + value + "\"}");
return this;
}
public JsonBuilder withHoverEvent(HoverAction action, String value) {
addSegment("hoverEvent:{action:" + action.toString().toLowerCase()
+ ",value:\"" + value + "\"}");
return this;
}
private void addSegment(String segment) {
String lastText = extras.get(extras.size() - 1);
lastText = lastText.substring(0, lastText.length() - 1)
+ ","+segment+"}";
extras.remove(extras.size() - 1);
extras.add(lastText);
}
public String toString() {
if(extras.size() <= 1) return extras.size() == 0 ? "{text:\"\"}" : extras.get(0);
String text = extras.get(0).substring(0, extras.get(0).length() - 1) + ",extra:[";
extras.remove(0);;
for (String extra : extras)
text = text + extra + ",";
text = text.substring(0, text.length() - 1) + "]}";
return text;
}
public void sendJson(Player p) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket(
new PacketPlayOutChat(ChatSerializer.a(toString())));
}
}

View File

@ -0,0 +1,785 @@
/*
* Copyright 2011-2013 Tyler Blair. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package de.epiceric.shopchest.utils;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
public class Metrics {
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private static final int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* All of the custom graphs to submit to metrics
*/
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* The scheduled task
*/
private volatile BukkitTask task = null;
public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
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://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 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) {
if (name == null) {
throw new IllegalArgumentException("Graph name cannot be null");
}
// Construct the graph object
final Graph graph = new Graph(name);
// Now we can add our graph
graphs.add(graph);
// and return back
return graph;
}
/**
* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
*
* @param graph The name of the graph
*/
public void addGraph(final Graph graph) {
if (graph == null) {
throw new IllegalArgumentException("Graph cannot be null");
}
graphs.add(graph);
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
* ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
public void run() {
try {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && task != null) {
task.cancel();
task = null;
// Tell all plotters to stop gathering information.
for (Graph graph : graphs) {
graph.onOptOut();
}
}
}
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
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");
}
/**
* Gets the online player (backwards compatibility)
*
* @return online player amount
*/
private int getOnlinePlayers() {
try {
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
if(onlinePlayerMethod.getReturnType().equals(Collection.class)) {
return ((Collection<?>)onlinePlayerMethod.invoke(Bukkit.getServer())).size();
} else {
return ((Player[])onlinePlayerMethod.invoke(Bukkit.getServer())).length;
}
} catch (Exception ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
}
return 0;
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(final boolean isPing) throws IOException {
// 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 = this.getOnlinePlayers();
// END server software specific section -- all code below does not use any code outside of this class / Java
// Construct the post data
StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as name, version, author, etc
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// 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";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
if (graphs.size() > 0) {
synchronized (graphs) {
json.append(',');
json.append('"');
json.append("graphs");
json.append('"');
json.append(':');
json.append('{');
boolean firstGraph = true;
final Iterator<Graph> iter = graphs.iterator();
while (iter.hasNext()) {
Graph graph = iter.next();
StringBuilder graphJson = new StringBuilder();
graphJson.append('{');
for (Plotter plotter : graph.getPlotters()) {
appendJSONPair(graphJson, plotter.getColumnName(), Integer.toString(plotter.getValue()));
}
graphJson.append('}');
if (!firstGraph) {
json.append(',');
}
json.append(escapeJSON(graph.getName()));
json.append(':');
json.append(graphJson);
firstGraph = false;
}
json.append('}');
}
}
// close json
json.append('}');
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
byte[] uncompressed = json.toString().getBytes();
byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (debug) {
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
} else {
// Is this the first update this hour?
if (response.equals("1") || response.contains("This is your first update this hour")) {
synchronized (graphs) {
final Iterator<Graph> iter = graphs.iterator();
while (iter.hasNext()) {
final Graph graph = iter.next();
for (Plotter plotter : graph.getPlotters()) {
plotter.reset();
}
}
}
}
}
}
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) try {
gzos.close();
} catch (IOException ignore) {
}
}
return baos.toByteArray();
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
/**
* Represents a custom graph on the website
*/
public static class Graph {
/**
* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
* rejected
*/
private final String name;
/**
* The set of plotters that are contained within this graph
*/
private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
private Graph(final String name) {
this.name = name;
}
/**
* Gets the graph's name
*
* @return the Graph's name
*/
public String getName() {
return name;
}
/**
* Add a plotter to the graph, which will be used to plot entries
*
* @param plotter the plotter to add to the graph
*/
public void addPlotter(final Plotter plotter) {
plotters.add(plotter);
}
/**
* Remove a plotter from the graph
*
* @param plotter the plotter to remove from the graph
*/
public void removePlotter(final Plotter plotter) {
plotters.remove(plotter);
}
/**
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
*
* @return an unmodifiable {@link java.util.Set} of the plotter objects
*/
public Set<Plotter> getPlotters() {
return Collections.unmodifiableSet(plotters);
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(final Object object) {
if (!(object instanceof Graph)) {
return false;
}
final Graph graph = (Graph) object;
return graph.name.equals(name);
}
/**
* Called when the server owner decides to opt-out of BukkitMetrics while the server is running.
*/
protected void onOptOut() {
}
}
/**
* Interface used to collect custom data for a plugin
*/
public static abstract class Plotter {
/**
* The plot's name
*/
private final String name;
/**
* Construct a plotter with the default plot name
*/
public Plotter() {
this("Default");
}
/**
* Construct a plotter with a specific plot name
*
* @param name the name of the plotter to use, which will show up on the website
*/
public Plotter(final String name) {
this.name = name;
}
/**
* 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 the current value for the point to be plotted.
*/
public abstract int getValue();
/**
* Get the column name for the plotted point
*
* @return the plotted point's column name
*/
public String getColumnName() {
return name;
}
/**
* Called after the website graphs have been updated
*/
public void reset() {
}
@Override
public int hashCode() {
return getColumnName().hashCode();
}
@Override
public boolean equals(final Object object) {
if (!(object instanceof Plotter)) {
return false;
}
final Plotter plotter = (Plotter) object;
return plotter.name.equals(name) && plotter.getValue() == getValue();
}
}
}

View File

@ -0,0 +1,107 @@
package de.epiceric.shopchest.utils;
import java.util.ArrayList;
import java.util.HashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.inventory.InventoryHolder;
import de.epiceric.shopchest.shop.Shop;
public class ShopUtils {
private static HashMap<Location, Shop> shopLocation = new HashMap<>();
public static Shop getShop(Location location) {
Location newLocation = new Location(location.getWorld(), location.getX(), location.getY(), location.getZ());
if (shopLocation.containsKey(newLocation)) {
return shopLocation.get(newLocation);
} else {
return null;
}
}
public static boolean isShop(Location location) {
Location newLocation = new Location(location.getWorld(), location.getX(), location.getY(), location.getZ());
return shopLocation.containsKey(newLocation);
}
public static Shop[] getShops() {
ArrayList<Shop> shops = new ArrayList<>();
for (Shop shop : shopLocation.values()) {
shops.add(shop);
}
return shops.toArray(new Shop[shops.size()]);
}
public static void addShop(Shop shop) {
Location loc = shop.getLocation();
Block b = loc.getBlock();
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
Chest c = (Chest) b.getState();
InventoryHolder ih = c.getInventory().getHolder();
if (ih instanceof DoubleChest) {
DoubleChest dc = (DoubleChest) ih;
Chest r = (Chest) dc.getRightSide();
Chest l = (Chest) dc.getLeftSide();
shopLocation.put(r.getLocation(), shop);
shopLocation.put(l.getLocation(), shop);
return;
}
}
shopLocation.put(shop.getLocation(), shop);
}
public static void removeShop(Shop shop) {
Location loc = shop.getLocation();
Block b = loc.getBlock();
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
Chest c = (Chest) b.getState();
InventoryHolder ih = c.getInventory().getHolder();
if (ih instanceof DoubleChest) {
DoubleChest dc = (DoubleChest) ih;
Chest r = (Chest) dc.getRightSide();
Chest l = (Chest) dc.getLeftSide();
shopLocation.remove(r.getLocation());
shopLocation.remove(l.getLocation());
return;
}
}
shopLocation.remove(shop.getLocation());
}
public static String getConfigTitle(Location location) {
World w = location.getWorld();
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
return w.getName() + "_" + String.valueOf(x) + "_" + String.valueOf(y) + "_" + String.valueOf(z);
}
}

View File

@ -0,0 +1,50 @@
package de.epiceric.shopchest.utils;
import org.bukkit.Bukkit;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import de.epiceric.shopchest.ShopChest;
import net.md_5.bungee.api.ChatColor;
public class UpdateChecker {
private ShopChest plugin;
private String url;
private String version;
private String link;
public UpdateChecker(ShopChest plugin, String url) {
this.plugin = plugin;
this.url = url;
}
public boolean updateNeeded() {
try {
Connection con = Jsoup.connect("http://textuploader.com/all1l/raw");
con.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0");
Document doc = con.get();
version = doc.text().split("\\|")[0];
link = url + "download?version=" + doc.text().split("\\|")[1];
return !plugin.getDescription().getVersion().equals(version);
} catch (Exception | Error e) {
Bukkit.getConsoleSender().sendMessage("[ShopChest] " + ChatColor.RED + "Error while checking for updates");
return false;
}
}
public String getVersion() {
return version;
}
public String getLink() {
return link;
}
}

View File

@ -0,0 +1,29 @@
package de.epiceric.shopchest.utils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class Utils {
public static int getAmount(Inventory inventory, Material type, short damage, ItemMeta itemMeta) {
ItemStack[] items = inventory.getContents();
int amount = 0;
for (ItemStack item : items) {
if ((item != null) && (item.getType().equals(type)) && (item.getDurability() == damage) && (item.getAmount() > 0) && (item.getItemMeta().equals(itemMeta))) {
amount += item.getAmount();
}
}
return amount;
}
public static String getVersion() {
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
}