Merge 7d5ce492b1
into 9537d93688
This commit is contained in:
commit
2548dfe691
|
@ -121,6 +121,11 @@ public class Config {
|
|||
**/
|
||||
public static List<String> blacklist;
|
||||
|
||||
/**
|
||||
* Percentage of VAT.
|
||||
**/
|
||||
public static double vat;
|
||||
|
||||
/**
|
||||
* Whether prices may contain decimals
|
||||
**/
|
||||
|
@ -473,6 +478,7 @@ public class Config {
|
|||
autoCalculateItemAmount = (allowDecimalsInPrice && plugin.getConfig().getBoolean("auto-calculate-item-amount"));
|
||||
creativeSelectItem = plugin.getConfig().getBoolean("creative-select-item");
|
||||
blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList<String>() : plugin.getConfig().getStringList("blacklist");
|
||||
vat = plugin.getConfig().getDouble("vat");
|
||||
buyGreaterOrEqualSell = plugin.getConfig().getBoolean("buy-greater-or-equal-sell");
|
||||
confirmShopping = plugin.getConfig().getBoolean("confirm-shopping");
|
||||
refundShopCreation = plugin.getConfig().getBoolean("refund-shop-creation");
|
||||
|
|
|
@ -12,6 +12,7 @@ public enum Placeholder {
|
|||
MAX_PRICE("%MAX-PRICE%"),
|
||||
VERSION("%VERSION%"),
|
||||
BUY_PRICE("%BUY-PRICE%"),
|
||||
BUY_TAXED_PRICE("%BUY-TAXED-PRICE%"),
|
||||
SELL_PRICE("%SELL-PRICE%"),
|
||||
LIMIT("%LIMIT%"),
|
||||
PLAYER("%PLAYER%"),
|
||||
|
|
|
@ -12,13 +12,15 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable {
|
|||
private Type type;
|
||||
private int newAmount;
|
||||
private double newPrice;
|
||||
private double newTaxedPrice;
|
||||
private boolean cancelled;
|
||||
|
||||
public ShopBuySellEvent(Player player, Shop shop, Type type, int newAmount, double newPrice) {
|
||||
public ShopBuySellEvent(Player player, Shop shop, Type type, int newAmount, double newPrice, double newTaxedPrice) {
|
||||
super(player, shop);
|
||||
this.type = type;
|
||||
this.newAmount = newAmount;
|
||||
this.newPrice = newPrice;
|
||||
this.newTaxedPrice = newTaxedPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,6 +44,13 @@ public class ShopBuySellEvent extends ShopEvent implements Cancellable {
|
|||
return newPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The taxed price which might be modified because of automatic item amount calculation
|
||||
*/
|
||||
public double getNewTaxedPrice() {
|
||||
return newTaxedPrice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
|
|
|
@ -626,6 +626,7 @@ public class ShopInteractListener implements Listener {
|
|||
|
||||
String priceString = LanguageUtils.getMessage(Message.SHOP_INFO_PRICE,
|
||||
new Replacement(Placeholder.BUY_PRICE, (shop.getBuyPrice() > 0 ? String.valueOf(shop.getBuyPrice()) : disabled)),
|
||||
new Replacement(Placeholder.BUY_TAXED_PRICE, (shop.getTaxedBuyPrice() > 0 ? String.valueOf(shop.getTaxedBuyPrice()) : disabled)),
|
||||
new Replacement(Placeholder.SELL_PRICE, (shop.getSellPrice() > 0 ? String.valueOf(shop.getSellPrice()) : disabled)));
|
||||
|
||||
String shopType = LanguageUtils.getMessage(shop.getShopType() == ShopType.NORMAL ?
|
||||
|
@ -743,12 +744,16 @@ public class ShopInteractListener implements Listener {
|
|||
|
||||
String worldName = shop.getLocation().getWorld().getName();
|
||||
|
||||
double price = shop.getBuyPrice();
|
||||
if (stack) price = (price / shop.getProduct().getAmount()) * amount;
|
||||
double realPrice = shop.getBuyPrice();
|
||||
double taxedPrice = shop.getTaxedBuyPrice();
|
||||
if (stack) {
|
||||
realPrice = (realPrice / shop.getProduct().getAmount()) * amount;
|
||||
taxedPrice = (taxedPrice / shop.getProduct().getAmount()) * amount;
|
||||
}
|
||||
|
||||
if (econ.getBalance(executor, worldName) >= price || Config.autoCalculateItemAmount) {
|
||||
if (econ.getBalance(executor, worldName) >= taxedPrice || Config.autoCalculateItemAmount) {
|
||||
|
||||
int amountForMoney = (int) (amount / price * econ.getBalance(executor, worldName));
|
||||
int amountForMoney = (int) (amount / taxedPrice * econ.getBalance(executor, worldName));
|
||||
|
||||
if (amountForMoney == 0 && Config.autoCalculateItemAmount) {
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.NOT_ENOUGH_MONEY));
|
||||
|
@ -791,29 +796,30 @@ public class ShopInteractListener implements Listener {
|
|||
if (newAmount > amount) newAmount = amount;
|
||||
|
||||
ShopProduct newProduct = new ShopProduct(product, newAmount);
|
||||
double newPrice = (price / amount) * newAmount;
|
||||
double newRealPrice = (realPrice / amount) * newAmount;
|
||||
double newTaxedPrice = (taxedPrice / amount) * newAmount;
|
||||
|
||||
if (freeSpace >= newAmount) {
|
||||
plugin.debug(executor.getName() + " has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")");
|
||||
|
||||
EconomyResponse r = econ.withdrawPlayer(executor, worldName, newPrice);
|
||||
EconomyResponse r = econ.withdrawPlayer(executor, worldName, newTaxedPrice);
|
||||
|
||||
if (r.transactionSuccess()) {
|
||||
EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), worldName, newPrice) : null;
|
||||
EconomyResponse r2 = (shop.getShopType() != ShopType.ADMIN) ? econ.depositPlayer(shop.getVendor(), worldName, newRealPrice) : null;
|
||||
|
||||
if (r2 != null) {
|
||||
if (r2.transactionSuccess()) {
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newPrice);
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newRealPrice, newTaxedPrice);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
econ.depositPlayer(executor, worldName, newPrice);
|
||||
econ.withdrawPlayer(shop.getVendor(), worldName, newPrice);
|
||||
econ.depositPlayer(executor, worldName, newTaxedPrice);
|
||||
econ.withdrawPlayer(shop.getVendor(), worldName, newRealPrice);
|
||||
plugin.debug("Buy event cancelled (#" + shop.getID() + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, ShopBuySellEvent.Type.BUY, null);
|
||||
database.logEconomy(executor, shop, newProduct, newRealPrice, newTaxedPrice, ShopBuySellEvent.Type.BUY, null);
|
||||
|
||||
addToInventory(inventory, newProduct);
|
||||
removeFromInventory(c.getInventory(), newProduct);
|
||||
|
@ -830,14 +836,14 @@ public class ShopInteractListener implements Listener {
|
|||
|
||||
String vendorName = (shop.getVendor().getName() == null ? shop.getVendor().getUniqueId().toString() : shop.getVendor().getName());
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.BUY_SUCCESS, new Replacement(Placeholder.AMOUNT, String.valueOf(newAmount)),
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newPrice)),
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newTaxedPrice)),
|
||||
new Replacement(Placeholder.VENDOR, vendorName)));
|
||||
|
||||
plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")");
|
||||
|
||||
if (shop.getVendor().isOnline() && Config.enableVendorMessages) {
|
||||
shop.getVendor().getPlayer().sendMessage(LanguageUtils.getMessage(Message.SOMEONE_BOUGHT, new Replacement(Placeholder.AMOUNT, String.valueOf(newAmount)),
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newPrice)),
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newRealPrice)),
|
||||
new Replacement(Placeholder.PLAYER, executor.getName())));
|
||||
} else if(!shop.getVendor().isOnline() && Config.enableVendorBungeeMessages){
|
||||
String message = LanguageUtils.getMessage( Message.SOMEONE_BOUGHT, new Replacement(Placeholder.AMOUNT, String.valueOf(newAmount)),
|
||||
|
@ -849,20 +855,20 @@ public class ShopInteractListener implements Listener {
|
|||
} else {
|
||||
plugin.debug("Economy transaction failed (r2): " + r2.errorMessage + " (#" + shop.getID() + ")");
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED, new Replacement(Placeholder.ERROR, r2.errorMessage)));
|
||||
econ.withdrawPlayer(shop.getVendor(), worldName, newPrice);
|
||||
econ.depositPlayer(executor, worldName, newPrice);
|
||||
econ.withdrawPlayer(shop.getVendor(), worldName, newRealPrice);
|
||||
econ.depositPlayer(executor, worldName, newTaxedPrice);
|
||||
}
|
||||
} else {
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newPrice);
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.BUY, newAmount, newRealPrice, newTaxedPrice);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
econ.depositPlayer(executor, worldName, newPrice);
|
||||
econ.depositPlayer(executor, worldName, newTaxedPrice);
|
||||
plugin.debug("Buy event cancelled (#" + shop.getID() + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, ShopBuySellEvent.Type.BUY, null);
|
||||
database.logEconomy(executor, shop, newProduct, newRealPrice, newTaxedPrice, ShopBuySellEvent.Type.BUY, null);
|
||||
|
||||
addToInventory(inventory, newProduct);
|
||||
executor.updateInventory();
|
||||
|
@ -877,14 +883,14 @@ public class ShopInteractListener implements Listener {
|
|||
}.runTaskLater(plugin, 1L);
|
||||
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.BUY_SUCCESS_ADMIN, new Replacement(Placeholder.AMOUNT, String.valueOf(newAmount)),
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newPrice))));
|
||||
new Replacement(Placeholder.ITEM_NAME, newProduct.getLocalizedName()), new Replacement(Placeholder.BUY_PRICE, String.valueOf(newTaxedPrice))));
|
||||
|
||||
plugin.debug(executor.getName() + " successfully bought (#" + shop.getID() + ")");
|
||||
}
|
||||
} else {
|
||||
plugin.debug("Economy transaction failed (r): " + r.errorMessage + " (#" + shop.getID() + ")");
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED, new Replacement(Placeholder.ERROR, r.errorMessage)));
|
||||
econ.depositPlayer(executor, worldName, newPrice);
|
||||
econ.depositPlayer(executor, worldName, newTaxedPrice);
|
||||
}
|
||||
} else {
|
||||
executor.sendMessage(LanguageUtils.getMessage(Message.NOT_ENOUGH_INVENTORY_SPACE));
|
||||
|
@ -971,7 +977,7 @@ public class ShopInteractListener implements Listener {
|
|||
|
||||
if (r2 != null) {
|
||||
if (r2.transactionSuccess()) {
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice);
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice, 0);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
|
@ -981,7 +987,7 @@ public class ShopInteractListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, ShopBuySellEvent.Type.SELL, null);
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, 0, ShopBuySellEvent.Type.SELL, null);
|
||||
|
||||
addToInventory(inventory, newProduct);
|
||||
removeFromInventory(executor.getInventory(), newProduct);
|
||||
|
@ -1022,7 +1028,7 @@ public class ShopInteractListener implements Listener {
|
|||
}
|
||||
|
||||
} else {
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice);
|
||||
ShopBuySellEvent event = new ShopBuySellEvent(executor, shop, ShopBuySellEvent.Type.SELL, newAmount, newPrice, 0);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
|
@ -1031,7 +1037,7 @@ public class ShopInteractListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, ShopBuySellEvent.Type.SELL, null);
|
||||
database.logEconomy(executor, shop, newProduct, newPrice, 0, ShopBuySellEvent.Type.SELL, null);
|
||||
|
||||
removeFromInventory(executor.getInventory(), newProduct);
|
||||
executor.updateInventory();
|
||||
|
|
|
@ -55,6 +55,7 @@ public class Shop {
|
|||
private final ShopProduct product;
|
||||
private final Location location;
|
||||
private final double buyPrice;
|
||||
private final double taxedBuyPrice;
|
||||
private final double sellPrice;
|
||||
private final ShopType shopType;
|
||||
|
||||
|
@ -71,6 +72,7 @@ public class Shop {
|
|||
this.product = product;
|
||||
this.location = location;
|
||||
this.buyPrice = buyPrice;
|
||||
this.taxedBuyPrice = buyPrice + calculateVat(buyPrice, Config.vat, Config.allowDecimalsInPrice);
|
||||
this.sellPrice = sellPrice;
|
||||
this.shopType = shopType;
|
||||
}
|
||||
|
@ -79,6 +81,23 @@ public class Shop {
|
|||
this(-1, plugin, vendor, product, location, buyPrice, sellPrice, shopType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate VAT on the given price
|
||||
*
|
||||
* @param price to make calculation on
|
||||
* @param vat in percentage
|
||||
* @param allowDecimal if round to int
|
||||
* @return VAT, returns 0 if price is equal to 0
|
||||
*/
|
||||
private double calculateVat(double price, double vat, boolean allowDecimal) {
|
||||
if (Double.compare(vat, 0) == 0) { // zero if disabled
|
||||
return 0;
|
||||
}
|
||||
|
||||
double result = vat * price;
|
||||
return allowDecimal ? result : (int) Math.max(result, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if this shop is equals to another
|
||||
*
|
||||
|
@ -286,6 +305,7 @@ public class Shop {
|
|||
placeholders.put(Placeholder.ITEM_NAME, getProduct().getLocalizedName());
|
||||
placeholders.put(Placeholder.ENCHANTMENT, LanguageUtils.getEnchantmentString(ItemUtils.getEnchantments(itemStack)));
|
||||
placeholders.put(Placeholder.BUY_PRICE, getBuyPrice());
|
||||
placeholders.put(Placeholder.BUY_TAXED_PRICE, getTaxedBuyPrice());
|
||||
placeholders.put(Placeholder.SELL_PRICE, getSellPrice());
|
||||
placeholders.put(Placeholder.POTION_EFFECT, LanguageUtils.getPotionEffectName(itemStack));
|
||||
placeholders.put(Placeholder.MUSIC_TITLE, LanguageUtils.getMusicDiscName(itemStack.getType()));
|
||||
|
@ -305,7 +325,7 @@ public class Shop {
|
|||
|
||||
switch (placeholder) {
|
||||
case BUY_PRICE:
|
||||
replace = plugin.getEconomy().format(getBuyPrice());
|
||||
replace = plugin.getEconomy().format(getTaxedBuyPrice());
|
||||
break;
|
||||
case SELL_PRICE:
|
||||
replace = plugin.getEconomy().format(getSellPrice());
|
||||
|
@ -427,6 +447,13 @@ public class Shop {
|
|||
return buyPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Taxed price of the shop
|
||||
*/
|
||||
public double getTaxedBuyPrice() {
|
||||
return taxedBuyPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Sell price of the shop
|
||||
*/
|
||||
|
|
|
@ -641,9 +641,9 @@ public abstract class Database {
|
|||
* @param type Whether the executor bought or sold
|
||||
* @param callback Callback that - if succeeded - returns {@code null}
|
||||
*/
|
||||
public void logEconomy(final Player executor, Shop shop, ShopProduct product, double price, Type type, final Callback<Void> callback) {
|
||||
public void logEconomy(final Player executor, Shop shop, ShopProduct product, double price, double taxedPrice, Type type, final Callback<Void> callback) {
|
||||
final String query = "INSERT INTO " + tableLogs + " (shop_id,timestamp,time,player_name,player_uuid,product_name,product,amount,"
|
||||
+ "vendor_name,vendor_uuid,admin,world,x,y,z,price,type) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
+ "vendor_name,vendor_uuid,admin,world,x,y,z,price,taxed_price,type) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
|
||||
if (Config.enableEconomyLog) {
|
||||
new BukkitRunnable() {
|
||||
|
@ -670,7 +670,8 @@ public abstract class Database {
|
|||
ps.setInt(14, shop.getLocation().getBlockY());
|
||||
ps.setInt(15, shop.getLocation().getBlockZ());
|
||||
ps.setDouble(16, price);
|
||||
ps.setString(17, type.toString());
|
||||
ps.setDouble(17, taxedPrice);
|
||||
ps.setString(18, type.toString());
|
||||
ps.executeUpdate();
|
||||
|
||||
if (callback != null) {
|
||||
|
|
|
@ -86,6 +86,7 @@ public class MySQL extends Database {
|
|||
+ "y INTEGER NOT NULL,"
|
||||
+ "z INTEGER NOT NULL,"
|
||||
+ "price FLOAT NOT NULL,"
|
||||
+ "taxed_price FLOAT NOT NULL,"
|
||||
+ "type TINYTEXT NOT NULL)";
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ public class SQLite extends Database {
|
|||
+ "y INTEGER NOT NULL,"
|
||||
+ "z INTEGER NOT NULL,"
|
||||
+ "price FLOAT NOT NULL,"
|
||||
+ "taxed_price FLOAT NOT NULL,"
|
||||
+ "type TINYTEXT NOT NULL)";
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,9 @@ maximum-prices:
|
|||
blacklist:
|
||||
# - "DIORITE"
|
||||
|
||||
# Set the percentage of VAT.
|
||||
vat: 0.1
|
||||
|
||||
# Set the price a player has to pay in order to create...
|
||||
# You can set this to 0 to disable costs.
|
||||
shop-creation-price:
|
||||
|
|
Loading…
Reference in New Issue