mirror of
https://github.com/AppleDash/SaneEconomy.git
synced 2024-11-29 21:43:28 +01:00
Weird sign shop stuff.
This commit is contained in:
parent
934d92fbf9
commit
4df22729aa
@ -39,8 +39,17 @@ public class TransactionResult {
|
||||
}
|
||||
|
||||
public enum Status {
|
||||
SUCCESS,
|
||||
SUCCESS("Success."),
|
||||
ERR_NOT_ENOUGH_FUNDS("Not enough money is available for you to complete that transaction.");
|
||||
|
||||
ERR_NOT_ENOUGH_FUNDS
|
||||
private final String message;
|
||||
|
||||
Status(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import org.appledash.saneeconomysignshop.listeners.SignChangeListener;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShopManager;
|
||||
import org.appledash.saneeconomysignshop.signshop.storage.SignShopStorageFlatfile;
|
||||
import org.appledash.saneeconomysignshop.util.ItemDatabase;
|
||||
import org.appledash.saneeconomysignshop.util.LimitManager;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
@ -19,6 +20,7 @@ import java.io.File;
|
||||
public class SaneEconomySignShop extends JavaPlugin {
|
||||
private ISaneEconomy saneEconomy;
|
||||
private final SignShopManager signShopManager = new SignShopManager(new SignShopStorageFlatfile(new File(getDataFolder(), "shops.db")));
|
||||
private final LimitManager limitManager = new LimitManager();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@ -50,4 +52,8 @@ public class SaneEconomySignShop extends JavaPlugin {
|
||||
public ISaneEconomy getSaneEconomy() {
|
||||
return saneEconomy;
|
||||
}
|
||||
|
||||
public LimitManager getLimitManager() {
|
||||
return limitManager;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
package org.appledash.saneeconomysignshop.listeners;
|
||||
|
||||
import org.appledash.saneeconomy.economy.EconomyManager;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.economy.transaction.Transaction;
|
||||
import org.appledash.saneeconomy.economy.transaction.TransactionReason;
|
||||
import org.appledash.saneeconomy.economy.transaction.TransactionResult;
|
||||
import org.appledash.saneeconomy.utils.MessageUtils;
|
||||
import org.appledash.saneeconomysignshop.SaneEconomySignShop;
|
||||
import org.appledash.saneeconomysignshop.signshop.ShopTransaction;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShop;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -84,26 +83,30 @@ public class InteractListener implements Listener {
|
||||
private void doBuy(SignShop shop, Player player) {
|
||||
EconomyManager ecoMan = plugin.getSaneEconomy().getEconomyManager();
|
||||
int quantity = player.isSneaking() ? 1 : shop.getQuantity();
|
||||
double price = shop.getBuyPrice(quantity);
|
||||
|
||||
if (!ecoMan.hasBalance(Economable.wrap(player), price)) {
|
||||
MessageUtils.sendMessage(player, "You do not have enough money to buy {1} {2}.", quantity, shop.getItem());
|
||||
ShopTransaction shopTransaction = shop.makeTransaction(player, ShopTransaction.TransactionDirection.BUY, quantity);
|
||||
|
||||
if (!plugin.getLimitManager().shouldAllowTransaction(shopTransaction)) {
|
||||
MessageUtils.sendMessage(player, "You have reached your buying limit for the time being. Try back in an hour or so.");
|
||||
return;
|
||||
}
|
||||
|
||||
TransactionResult result = ecoMan.transact(new Transaction(Economable.wrap(player), Economable.PLUGIN, price, TransactionReason.PLUGIN_TAKE));
|
||||
plugin.getLimitManager().setRemainingLimit(player, ShopTransaction.TransactionDirection.BUY, shop.getItem(), plugin.getLimitManager().getRemainingLimit(player, ShopTransaction.TransactionDirection.BUY, shop.getItem()) - quantity);
|
||||
|
||||
Transaction ecoTransaction = shopTransaction.makeEconomyTransaction();
|
||||
TransactionResult result = ecoMan.transact(ecoTransaction);
|
||||
|
||||
if (result.getStatus() != TransactionResult.Status.SUCCESS) {
|
||||
MessageUtils.sendMessage(player, "An error occurred attempting to perform that transaction: {1}", result.getStatus());
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = shop.getItem().clone();
|
||||
ItemStack stack = shop.getItemStack().clone();
|
||||
stack.setAmount(quantity);
|
||||
|
||||
player.getInventory().addItem(stack);
|
||||
MessageUtils.sendMessage(player, "You have bought {1} {2} for {3}.", quantity, shop.getItem(), ecoMan.getCurrency().formatAmount(price));
|
||||
LOGGER.info(String.format("%s just bought %s for %s.", player.getName(), shop.getItem(), ecoMan.getCurrency().formatAmount(price)));
|
||||
|
||||
MessageUtils.sendMessage(player, "You have bought {1} {2} for {3}.", quantity, shop.getItemStack().getType().name(), ecoMan.getCurrency().formatAmount(shopTransaction.getPrice()));
|
||||
LOGGER.info(String.format("%s just bought %s for %s.", player.getName(), shop.getItemStack(), ecoMan.getCurrency().formatAmount(shopTransaction.getPrice())));
|
||||
}
|
||||
|
||||
private void doSell(SignShop shop, Player player) { // TODO: Selling enchanted items
|
||||
@ -111,17 +114,29 @@ public class InteractListener implements Listener {
|
||||
int quantity = player.isSneaking() ? 1 : shop.getQuantity();
|
||||
double price = shop.getSellPrice(quantity);
|
||||
|
||||
if (!player.getInventory().containsAtLeast(new ItemStack(shop.getItem()), quantity)) {
|
||||
MessageUtils.sendMessage(player, "You do not have {1} {2}!", quantity, shop.getItem());
|
||||
if (!player.getInventory().containsAtLeast(new ItemStack(shop.getItemStack()), quantity)) {
|
||||
MessageUtils.sendMessage(player, "You do not have {1} {2}!", quantity, shop.getItemStack().getType().name());
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = shop.getItem().clone();
|
||||
stack.setAmount(quantity);
|
||||
ShopTransaction shopTransaction = shop.makeTransaction(player, ShopTransaction.TransactionDirection.SELL, quantity);
|
||||
|
||||
if (!plugin.getLimitManager().shouldAllowTransaction(shopTransaction)) {
|
||||
MessageUtils.sendMessage(player, "You have reached your selling limit for the time being. Try back in an hour or so.");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getLimitManager().setRemainingLimit(player, ShopTransaction.TransactionDirection.SELL, shop.getItem(), plugin.getLimitManager().getRemainingLimit(player, ShopTransaction.TransactionDirection.BUY, shop.getItem()) - quantity);
|
||||
|
||||
|
||||
ItemStack stack = shop.getItemStack().clone();
|
||||
stack.setAmount(quantity);
|
||||
player.getInventory().removeItem(stack); // FIXME: This does not remove items with damage values that were detected by contains()
|
||||
ecoMan.transact(new Transaction(Economable.PLUGIN, Economable.wrap(player), price, TransactionReason.PLUGIN_GIVE));
|
||||
MessageUtils.sendMessage(player, "You have sold {1} {2} for {3}.", quantity, shop.getItem(), ecoMan.getCurrency().formatAmount(price));
|
||||
LOGGER.info(String.format("%s just sold %s for %s.", player.getName(), shop.getItem(), ecoMan.getCurrency().formatAmount(price)));
|
||||
|
||||
ecoMan.transact(shopTransaction.makeEconomyTransaction());
|
||||
|
||||
MessageUtils.sendMessage(player, "You have sold {1} {2} for {3}.", quantity, shop.getItemStack().getType().name(), ecoMan.getCurrency().formatAmount(price));
|
||||
LOGGER.info(String.format("%s just sold %s for %s.", player.getName(), shop.getItemStack(), ecoMan.getCurrency().formatAmount(price)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class SignChangeListener implements Listener {
|
||||
plugin.getSignShopManager().addSignShop(signShop);
|
||||
evt.setLine(0, ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString("admin-shop-title")));
|
||||
MessageUtils.sendMessage(evt.getPlayer(), "Sign shop created!");
|
||||
MessageUtils.sendMessage(evt.getPlayer(), "Item: {1} x {2}", signShop.getQuantity(), signShop.getItem());
|
||||
MessageUtils.sendMessage(evt.getPlayer(), "Item: {1} x {2}", signShop.getQuantity(), signShop.getItemStack());
|
||||
|
||||
if (signShop.canBuy()) { // The player be buying from the shop, not the other way around.
|
||||
MessageUtils.sendMessage(evt.getPlayer(), "Will sell to players for {!}.",
|
||||
|
@ -0,0 +1,60 @@
|
||||
package org.appledash.saneeconomysignshop.signshop;
|
||||
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.economy.transaction.Transaction;
|
||||
import org.appledash.saneeconomy.economy.transaction.TransactionReason;
|
||||
import org.appledash.saneeconomysignshop.util.ItemInfo;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Created by appledash on 1/1/17.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class ShopTransaction {
|
||||
// Direction is always what the player is doing. BUY = player is buying from shop.
|
||||
private final TransactionDirection direction;
|
||||
private final Player player;
|
||||
private final ItemInfo item;
|
||||
private final int quantity;
|
||||
private final double price;
|
||||
|
||||
public ShopTransaction(TransactionDirection direction, Player player, ItemInfo item, int quantity, double price) {
|
||||
this.direction = direction;
|
||||
this.player = player;
|
||||
this.item = item;
|
||||
this.quantity = quantity;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public TransactionDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public ItemInfo getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public Transaction makeEconomyTransaction() {
|
||||
if (direction == TransactionDirection.BUY) {
|
||||
return new Transaction(Economable.wrap(player), Economable.PLUGIN, price, TransactionReason.PLUGIN_TAKE);
|
||||
} else {
|
||||
return new Transaction(Economable.PLUGIN, Economable.wrap(player), price, TransactionReason.PLUGIN_GIVE);
|
||||
}
|
||||
}
|
||||
|
||||
public enum TransactionDirection {
|
||||
BUY, SELL
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package org.appledash.saneeconomysignshop.signshop;
|
||||
|
||||
import org.appledash.saneeconomysignshop.signshop.ShopTransaction.TransactionDirection;
|
||||
import org.appledash.saneeconomysignshop.util.ItemInfo;
|
||||
import org.appledash.saneeconomysignshop.util.SerializableLocation;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -49,10 +51,18 @@ public class SignShop implements Serializable {
|
||||
* Get the type of item this SignShop is selling
|
||||
* @return Material representing item/block type
|
||||
*/
|
||||
public ItemStack getItem() {
|
||||
public ItemStack getItemStack() {
|
||||
return item.toItemStack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ItemInfo for the item this SignShop is selling
|
||||
* @return ItemInfo representing the type and quantity of item
|
||||
*/
|
||||
public ItemInfo getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price that the player can buy this item from the server for
|
||||
* @return Buy price for this.getQuantity() items
|
||||
@ -120,4 +130,8 @@ public class SignShop implements Serializable {
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public ShopTransaction makeTransaction(Player player, TransactionDirection direction, int quantity) {
|
||||
return new ShopTransaction(direction, player, item, quantity, (direction == TransactionDirection.BUY) ? getBuyPrice(quantity) : getSellPrice(quantity));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.appledash.saneeconomysignshop.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Created by appledash on 1/1/17.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class DefaultHashMap<K, V> extends HashMap<K, V> {
|
||||
private final Supplier<V> defaultSupplier;
|
||||
|
||||
public DefaultHashMap(Supplier<V> defaultSupplier) {
|
||||
if (defaultSupplier == null) {
|
||||
throw new NullPointerException("defaultSupplier is null");
|
||||
}
|
||||
|
||||
this.defaultSupplier = defaultSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object k) {
|
||||
V v = super.get(k);
|
||||
|
||||
if (v == null) {
|
||||
v = defaultSupplier.get();
|
||||
this.put((K) k, v);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
@ -4,27 +4,48 @@ import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Created by appledash on 11/3/16.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class ItemInfo implements Serializable {
|
||||
private Material id;
|
||||
private short damage;
|
||||
private int amount;
|
||||
private final Material material;
|
||||
private final short damage;
|
||||
private final int amount;
|
||||
|
||||
public ItemInfo(ItemStack stack) {
|
||||
this(stack.getType(), stack.getDurability(), stack.getAmount());
|
||||
}
|
||||
|
||||
public ItemInfo(Material id, short damage, int amount) {
|
||||
this.id = id;
|
||||
public ItemInfo(Material material, short damage, int amount) {
|
||||
this.material = material;
|
||||
this.damage = damage;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public ItemStack toItemStack() {
|
||||
return new ItemStack(id, amount, damage);
|
||||
return new ItemStack(material, amount, damage);
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ItemInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemInfo other = ((ItemInfo) o);
|
||||
|
||||
return (other.material == this.material) && (other.damage == this.damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(material, damage);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package org.appledash.saneeconomysignshop.util;
|
||||
|
||||
/**
|
||||
* Created by appledash on 1/1/17.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class ItemLimits {
|
||||
// The default limit for items that have no limit.
|
||||
public static final ItemLimits DEFAULT = new ItemLimits(10, 1);
|
||||
|
||||
private final int limit;
|
||||
private final int hourlyGain;
|
||||
|
||||
public ItemLimits(int limit, int hourlyGain) {
|
||||
this.limit = limit;
|
||||
this.hourlyGain = hourlyGain;
|
||||
}
|
||||
|
||||
public int getHourlyGain() {
|
||||
return hourlyGain;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.appledash.saneeconomysignshop.util;
|
||||
|
||||
import org.appledash.saneeconomysignshop.signshop.ShopTransaction;
|
||||
import org.appledash.saneeconomysignshop.signshop.ShopTransaction.TransactionDirection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by appledash on 1/1/17.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class LimitManager {
|
||||
private final Map<TransactionDirection, Map<ItemInfo, ItemLimits>> itemLimits = new DefaultHashMap<>(() -> new DefaultHashMap<>(() -> ItemLimits.DEFAULT));
|
||||
// This is a slightly complex data structure. It works like this:
|
||||
// It's a map of (limit types to (maps of players to (maps of materials to the remaning limit))).
|
||||
// All the TransactionDirections defaults to an empty map, which defaults to an empty map, which defaults to 0.
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
private final Map<TransactionDirection, Map<UUID, Map<ItemInfo, Integer>>> playerLimits = new DefaultHashMap<>(() -> new DefaultHashMap<>(() -> new DefaultHashMap<>(() -> 0)));
|
||||
|
||||
public int getRemainingLimit(Player player, TransactionDirection type, ItemInfo stack) {
|
||||
return playerLimits.get(type).get(player.getUniqueId()).get(stack);
|
||||
}
|
||||
|
||||
public void setRemainingLimit(Player player, TransactionDirection type, ItemInfo stack, int limit) {
|
||||
if (playerLimits.get(type).get(player.getUniqueId()).get(stack) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
limit = Math.min(limit, itemLimits.get(type).get(stack).getLimit());
|
||||
limit = Math.max(0, limit);
|
||||
|
||||
playerLimits.get(type).get(player.getUniqueId()).put(stack, limit);
|
||||
}
|
||||
|
||||
public boolean shouldAllowTransaction(ShopTransaction transaction) {
|
||||
return getRemainingLimit(transaction.getPlayer(), transaction.getDirection(), transaction.getItem()) >= transaction.getQuantity();
|
||||
}
|
||||
|
||||
public void incrementLimitsHourly() {
|
||||
// For every limit type
|
||||
// For every player
|
||||
// For every limit
|
||||
// Increment limit by the limit for the specific direction and item.
|
||||
|
||||
playerLimits.forEach((transactionDirection, playerToLimit) -> {
|
||||
playerToLimit.forEach((playerUuid, itemToLimit) -> {
|
||||
Map<ItemInfo, Integer> newLimits = new HashMap<>();
|
||||
|
||||
itemToLimit.forEach((itemInfo, currentLimit) -> {
|
||||
newLimits.put(itemInfo, currentLimit + (itemLimits.get(transactionDirection).get(itemInfo).getHourlyGain()));
|
||||
});
|
||||
|
||||
itemToLimit.putAll(newLimits);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user