Added config option to confirm buying and selling

Closes #128
This commit is contained in:
Eric 2017-08-15 12:38:38 +02:00
parent 21fd9bb5ed
commit 2340eb67e1
7 changed files with 120 additions and 39 deletions

View File

@ -104,6 +104,9 @@ public class Config {
/** Whether shops should be protected by explosions **/ /** Whether shops should be protected by explosions **/
public boolean explosion_protection; public boolean explosion_protection;
/** Whether buys and sells must be confirmed **/
public boolean confirm_shopping;
/** Whether quality mode should be enabled **/ /** Whether quality mode should be enabled **/
public boolean enable_quality_mode; public boolean enable_quality_mode;
@ -365,6 +368,8 @@ public class Config {
blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList<String>() : plugin.getConfig().getStringList("blacklist"); blacklist = (plugin.getConfig().getStringList("blacklist") == null) ? new ArrayList<String>() : plugin.getConfig().getStringList("blacklist");
buy_greater_or_equal_sell = plugin.getConfig().getBoolean("buy-greater-or-equal-sell"); buy_greater_or_equal_sell = plugin.getConfig().getBoolean("buy-greater-or-equal-sell");
hopper_protection = plugin.getConfig().getBoolean("hopper-protection"); hopper_protection = plugin.getConfig().getBoolean("hopper-protection");
explosion_protection = plugin.getConfig().getBoolean("explosion-protection");
confirm_shopping = plugin.getConfig().getBoolean("confirm-shopping");
enable_quality_mode = plugin.getConfig().getBoolean("enable-quality-mode"); enable_quality_mode = plugin.getConfig().getBoolean("enable-quality-mode");
enable_hologram_interaction = plugin.getConfig().getBoolean("enable-hologram-interaction"); enable_hologram_interaction = plugin.getConfig().getBoolean("enable-hologram-interaction");
enable_debug_log = plugin.getConfig().getBoolean("enable-debug-log"); enable_debug_log = plugin.getConfig().getBoolean("enable-debug-log");
@ -379,7 +384,6 @@ public class Config {
enable_griefprevention_integration = plugin.getConfig().getBoolean("enable-griefprevention-integration"); enable_griefprevention_integration = plugin.getConfig().getBoolean("enable-griefprevention-integration");
enable_areashop_integration = plugin.getConfig().getBoolean("enable-areashop-integration"); enable_areashop_integration = plugin.getConfig().getBoolean("enable-areashop-integration");
enable_vendor_messages = plugin.getConfig().getBoolean("enable-vendor-messages"); enable_vendor_messages = plugin.getConfig().getBoolean("enable-vendor-messages");
explosion_protection = plugin.getConfig().getBoolean("explosion-protection");
only_show_shops_in_sight = plugin.getConfig().getBoolean("only-show-shops-in-sight"); only_show_shops_in_sight = plugin.getConfig().getBoolean("only-show-shops-in-sight");
only_show_first_shop_in_sight = plugin.getConfig().getBoolean("only-show-first-shop-in-sight"); only_show_first_shop_in_sight = plugin.getConfig().getBoolean("only-show-first-shop-in-sight");
exclude_admin_shops = plugin.getConfig().getBoolean("shop-limits.exclude-admin-shops"); exclude_admin_shops = plugin.getConfig().getBoolean("shop-limits.exclude-admin-shops");

View File

@ -1043,6 +1043,7 @@ public class LanguageUtils {
messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_REMOVE, langConfig.getString("message.click-chest-to-remove-shop", "&aClick a shop within 15 seconds to remove it."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_REMOVE, langConfig.getString("message.click-chest-to-remove-shop", "&aClick a shop within 15 seconds to remove it.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_INFO, langConfig.getString("message.click-chest-for-info", "&aClick a shop within 15 seconds to retrieve information."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_INFO, langConfig.getString("message.click-chest-for-info", "&aClick a shop within 15 seconds to retrieve information.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_OPEN, langConfig.getString("message.click-chest-to-open-shop", "&aClick a shop within 15 seconds to open it."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_CHEST_OPEN, langConfig.getString("message.click-chest-to-open-shop", "&aClick a shop within 15 seconds to open it.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM, langConfig.getString("message.click-to-confirm", "&aClick again to confirm.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.OPENED_SHOP, langConfig.getString("message.opened-shop", "&aYou opened %VENDOR%'s shop."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.OPENED_SHOP, langConfig.getString("message.opened-shop", "&aYou opened %VENDOR%'s shop.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.CANNOT_BREAK_SHOP, langConfig.getString("message.cannot-break-shop", "&cYou can't break a shop."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.CANNOT_BREAK_SHOP, langConfig.getString("message.cannot-break-shop", "&cYou can't break a shop.")));
messages.add(new LocalizedMessage(LocalizedMessage.Message.CANNOT_SELL_BROKEN_ITEM, langConfig.getString("message.cannot-sell-broken-item", "&cYou can't sell a broken item."))); messages.add(new LocalizedMessage(LocalizedMessage.Message.CANNOT_SELL_BROKEN_ITEM, langConfig.getString("message.cannot-sell-broken-item", "&cYou can't sell a broken item.")));

View File

@ -74,6 +74,7 @@ public class LocalizedMessage {
CLICK_CHEST_REMOVE, CLICK_CHEST_REMOVE,
CLICK_CHEST_INFO, CLICK_CHEST_INFO,
CLICK_CHEST_OPEN, CLICK_CHEST_OPEN,
CLICK_TO_CONFIRM,
OPENED_SHOP, OPENED_SHOP,
CANNOT_BREAK_SHOP, CANNOT_BREAK_SHOP,
CANNOT_SELL_BROKEN_ITEM, CANNOT_SELL_BROKEN_ITEM,

View File

@ -70,7 +70,10 @@ import pl.islandworld.api.IslandWorldApi;
import us.talabrek.ultimateskyblock.api.IslandInfo; import us.talabrek.ultimateskyblock.api.IslandInfo;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class ShopInteractListener implements Listener { public class ShopInteractListener implements Listener {
@ -326,6 +329,8 @@ public class ShopInteractListener implements Listener {
} }
} }
private Map<UUID, Set<Integer>> needsConfirmation = new HashMap<>();
private void handleInteractEvent(PlayerInteractEvent e) { private void handleInteractEvent(PlayerInteractEvent e) {
Block b = e.getClickedBlock(); Block b = e.getClickedBlock();
Player p = e.getPlayer(); Player p = e.getPlayer();
@ -339,18 +344,13 @@ public class ShopInteractListener implements Listener {
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) { if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
if (ClickType.getPlayerClickType(p) != null) { if (ClickType.getPlayerClickType(p) != null) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Shop shop = shopUtils.getShop(b.getLocation());
if (shop != null || ClickType.getPlayerClickType(p).getClickType() == ClickType.EnumClickType.CREATE) {
switch (ClickType.getPlayerClickType(p).getClickType()) { switch (ClickType.getPlayerClickType(p).getClickType()) {
case INFO: case INFO:
e.setCancelled(true); e.setCancelled(true);
if (shopUtils.isShop(b.getLocation())) {
Shop shop = shopUtils.getShop(b.getLocation());
info(p, shop); info(p, shop);
} else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NO_SHOP));
plugin.debug("Chest is not a shop");
}
ClickType.removePlayerClickType(p); ClickType.removePlayerClickType(p);
break; break;
@ -358,9 +358,6 @@ public class ShopInteractListener implements Listener {
case REMOVE: case REMOVE:
e.setCancelled(true); e.setCancelled(true);
if (shopUtils.isShop(b.getLocation())) {
Shop shop = shopUtils.getShop(b.getLocation());
if (shop.getShopType() == ShopType.ADMIN) { if (shop.getShopType() == ShopType.ADMIN) {
if (p.hasPermission(Permissions.REMOVE_ADMIN)) { if (p.hasPermission(Permissions.REMOVE_ADMIN)) {
remove(p, shop); remove(p, shop);
@ -376,10 +373,6 @@ public class ShopInteractListener implements Listener {
plugin.debug(p.getName() + " is not permitted to remove another player's shop"); plugin.debug(p.getName() + " is not permitted to remove another player's shop");
} }
} }
} else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NO_SHOP));
plugin.debug("Chest is not a shop");
}
ClickType.removePlayerClickType(p); ClickType.removePlayerClickType(p);
break; break;
@ -387,35 +380,39 @@ public class ShopInteractListener implements Listener {
case OPEN: case OPEN:
e.setCancelled(true); e.setCancelled(true);
if (shopUtils.isShop(b.getLocation())) {
Shop shop = shopUtils.getShop(b.getLocation());
if (p.getUniqueId().equals(shop.getVendor().getUniqueId()) || p.hasPermission(Permissions.OPEN_OTHER)) { if (p.getUniqueId().equals(shop.getVendor().getUniqueId()) || p.hasPermission(Permissions.OPEN_OTHER)) {
open(p, shop, true); open(p, shop, true);
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_OPEN_OTHERS)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_OPEN_OTHERS));
plugin.debug(p.getName() + " is not permitted to open another player's shop"); plugin.debug(p.getName() + " is not permitted to open another player's shop");
} }
} else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NO_SHOP));
plugin.debug("Chest is not a shop");
}
ClickType.removePlayerClickType(p); ClickType.removePlayerClickType(p);
break; break;
} }
} else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CHEST_NO_SHOP));
plugin.debug("Chest is not a shop");
}
} }
} else { } else {
Shop shop = shopUtils.getShop(b.getLocation()); Shop shop = shopUtils.getShop(b.getLocation());
boolean confirmed = needsConfirmation.containsKey(p.getUniqueId()) && needsConfirmation.get(p.getUniqueId()).contains(shop.getID());
if (shop != null) { if (shop != null) {
if (e.getAction() == Action.LEFT_CLICK_BLOCK && p.isSneaking() && Utils.hasAxeInHand(p)) { if (e.getAction() == Action.LEFT_CLICK_BLOCK && p.isSneaking() && Utils.hasAxeInHand(p)) {
return; return;
} }
ItemStack infoItem = config.shop_info_item; ItemStack infoItem = config.shop_info_item;
if (infoItem != null) { if (infoItem != null) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_BLOCK) { if (e.getAction() == Action.RIGHT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_BLOCK) {
ItemStack item = Utils.getItemInMainHand(p); ItemStack item = Utils.getItemInMainHand(p);
if (item == null || !(infoItem.getType() == item.getType() && infoItem.getDurability() == item.getDurability())) { if (item == null || !(infoItem.getType() == item.getType() && infoItem.getDurability() == item.getDurability())) {
item = Utils.getItemInOffHand(p); item = Utils.getItemInOffHand(p);
if (item != null && infoItem.getType() == item.getType() && infoItem.getDurability() == item.getDurability()) { if (item != null && infoItem.getType() == item.getType() && infoItem.getDurability() == item.getDurability()) {
e.setCancelled(true); e.setCancelled(true);
info(p, shop); info(p, shop);
@ -468,7 +465,21 @@ public class ShopInteractListener implements Listener {
if (shop.getShopType() == ShopType.ADMIN) { if (shop.getShopType() == ShopType.ADMIN) {
if (externalPluginsAllowed || p.hasPermission(Permissions.BYPASS_EXTERNAL_PLUGIN)) { if (externalPluginsAllowed || p.hasPermission(Permissions.BYPASS_EXTERNAL_PLUGIN)) {
if (confirmed || !config.confirm_shopping) {
buy(p, shop, p.isSneaking()); buy(p, shop, p.isSneaking());
if (config.confirm_shopping) {
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.remove(shop.getID());
if (ids.isEmpty()) needsConfirmation.remove(p.getUniqueId());
else needsConfirmation.put(p.getUniqueId(), ids);
}
} else {
plugin.debug("Needs confirmation");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM));
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.add(shop.getID());
needsConfirmation.put(p.getUniqueId(), ids);
}
} else { } else {
plugin.debug(p.getName() + " doesn't have external plugin's permission"); plugin.debug(p.getName() + " doesn't have external plugin's permission");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_BUY_HERE)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_BUY_HERE));
@ -479,10 +490,38 @@ public class ShopInteractListener implements Listener {
int amount = (p.isSneaking() ? shop.getProduct().getMaxStackSize() : shop.getProduct().getAmount()); int amount = (p.isSneaking() ? shop.getProduct().getMaxStackSize() : shop.getProduct().getAmount());
if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= amount) { if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= amount) {
if (confirmed || !config.confirm_shopping) {
buy(p, shop, p.isSneaking()); buy(p, shop, p.isSneaking());
if (config.confirm_shopping) {
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.remove(shop.getID());
if (ids.isEmpty()) needsConfirmation.remove(p.getUniqueId());
else needsConfirmation.put(p.getUniqueId(), ids);
}
} else {
plugin.debug("Needs confirmation");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM));
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.add(shop.getID());
needsConfirmation.put(p.getUniqueId(), ids);
}
} else { } else {
if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) { if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) {
if (confirmed || !config.confirm_shopping) {
buy(p, shop, p.isSneaking()); buy(p, shop, p.isSneaking());
if (config.confirm_shopping) {
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.remove(shop.getID());
if (ids.isEmpty()) needsConfirmation.remove(p.getUniqueId());
else needsConfirmation.put(p.getUniqueId(), ids);
}
} else {
plugin.debug("Needs confirmation");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM));
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.add(shop.getID());
needsConfirmation.put(p.getUniqueId(), ids);
}
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK));
if (shop.getVendor().isOnline() && config.enable_vendor_messages) { if (shop.getVendor().isOnline() && config.enable_vendor_messages) {
@ -541,10 +580,38 @@ public class ShopInteractListener implements Listener {
int amount = stack ? shop.getProduct().getMaxStackSize() : shop.getProduct().getAmount(); int amount = stack ? shop.getProduct().getMaxStackSize() : shop.getProduct().getAmount();
if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= amount) { if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= amount) {
if (confirmed || !config.confirm_shopping) {
sell(p, shop, stack); sell(p, shop, stack);
if (config.confirm_shopping) {
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.remove(shop.getID());
if (ids.isEmpty()) needsConfirmation.remove(p.getUniqueId());
else needsConfirmation.put(p.getUniqueId(), ids);
}
} else {
plugin.debug("Needs confirmation");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM));
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.add(shop.getID());
needsConfirmation.put(p.getUniqueId(), ids);
}
} else { } else {
if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) { if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) {
if (confirmed || !config.confirm_shopping) {
sell(p, shop, stack); sell(p, shop, stack);
if (config.confirm_shopping) {
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.remove(shop.getID());
if (ids.isEmpty()) needsConfirmation.remove(p.getUniqueId());
else needsConfirmation.put(p.getUniqueId(), ids);
}
} else {
plugin.debug("Needs confirmation");
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.CLICK_TO_CONFIRM));
Set<Integer> ids = needsConfirmation.containsKey(p.getUniqueId()) ? needsConfirmation.get(p.getUniqueId()) : new HashSet<Integer>();
ids.add(shop.getID());
needsConfirmation.put(p.getUniqueId(), ids);
}
} else { } else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS)); p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS));
plugin.debug(p.getName() + " doesn't have enough items"); plugin.debug(p.getName() + " doesn't have enough items");

View File

@ -27,6 +27,10 @@ update-quality: NORMAL
# You can set this to an empty string to disable this feature. # You can set this to an empty string to disable this feature.
shop-info-item: "STICK" shop-info-item: "STICK"
# Set whether buys or sells need to be confirmed by the player
# in order to prevent accidental purchases or sells.
confirm-shopping: false
# Set whether interaction with the hologram should be enabled. # Set whether interaction with the hologram should be enabled.
# If set to true, a player can do the exact same thing with the # If set to true, a player can do the exact same thing with the
# hologram, as with the chest. You can even open the chest if you # hologram, as with the chest. You can even open the chest if you

View File

@ -44,6 +44,7 @@ message.click-chest-to-create-shop=&aKlicke innerhalb von 15 Sekunden auf eine T
message.click-chest-to-remove-shop=&aKlicke innerhalb von 15 Sekunden auf einen Shop, um ihn zu entfernen. message.click-chest-to-remove-shop=&aKlicke innerhalb von 15 Sekunden auf einen Shop, um ihn zu entfernen.
message.click-chest-for-info=&aKlicke innerhalb von 15 Sekunden auf einen Shop, um Informationen über ihn zu bekommen. message.click-chest-for-info=&aKlicke innerhalb von 15 Sekunden auf einen Shop, um Informationen über ihn zu bekommen.
message.click-chest-to-open-shop=&Klicke innerhalb von 15 Sekunden auf einen Shop, um ihn zu öffnen. message.click-chest-to-open-shop=&Klicke innerhalb von 15 Sekunden auf einen Shop, um ihn zu öffnen.
message.click-to-confirm=&aKlicke noch einmal zum Bestätigen.
message.opened-shop=&aDu hast &6%VENDOR%&as Shop geöffnet. message.opened-shop=&aDu hast &6%VENDOR%&as Shop geöffnet.
message.cannot-break-shop=&cDu kannst einen Shop nicht zerstören. message.cannot-break-shop=&cDu kannst einen Shop nicht zerstören.
message.cannot-sell-broken-item=&cDu kannst kein kaputtes Artikel verkaufen. message.cannot-sell-broken-item=&cDu kannst kein kaputtes Artikel verkaufen.

View File

@ -161,6 +161,9 @@ message.click-chest-for-info=&aClick a shop within 15 seconds to retrieve inform
# Set the message when the player must click a shop to open it. # Set the message when the player must click a shop to open it.
message.click-chest-to-open-shop=&aClick a shop within 15 seconds to open it. message.click-chest-to-open-shop=&aClick a shop within 15 seconds to open it.
# Set the message when the player must click the shop again to confirm the buy/sell.
message.click-to-confirm=&aClick again to confirm.
# Set the message when the player opened a shop. # Set the message when the player opened a shop.
# Usable Placeholders: %VENDOR% # Usable Placeholders: %VENDOR%
message.opened-shop=&aYou opened %VENDOR%'s shop. message.opened-shop=&aYou opened %VENDOR%'s shop.