mirror of
https://github.com/songoda/EpicVouchers.git
synced 2024-11-25 11:35:30 +01:00
Try improving performance on legacy InteractEvent checks [SD-8155]
This commit is contained in:
parent
a38f3b738a
commit
8aa5173a60
@ -30,6 +30,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@ -166,13 +167,17 @@ public class EpicVouchers extends SongodaPlugin {
|
||||
}
|
||||
|
||||
private void saveVouchers() {
|
||||
Collection<Voucher> voucherList = voucherManager.getVouchers();
|
||||
|
||||
for (String voucherName : vouchersConfig.getConfigurationSection("vouchers").getKeys(false)) {
|
||||
if (voucherManager.getVouchers().stream().noneMatch(voucher -> voucher.getKey().equals(voucherName)))
|
||||
if (voucherList.stream().noneMatch(voucher -> voucher.getKey().equals(voucherName))) {
|
||||
vouchersConfig.set("vouchers." + voucherName, null);
|
||||
}
|
||||
}
|
||||
|
||||
for (Voucher voucher : voucherManager.getVouchers()) {
|
||||
for (Voucher voucher : voucherList) {
|
||||
String prefix = "vouchers." + voucher.getKey() + ".";
|
||||
|
||||
vouchersConfig.set(prefix + "permission", voucher.getPermission());
|
||||
vouchersConfig.set(prefix + "material", voucher.getMaterial().name());
|
||||
vouchersConfig.set(prefix + "data", voucher.getData());
|
||||
@ -204,13 +209,16 @@ public class EpicVouchers extends SongodaPlugin {
|
||||
vouchersConfig.set(prefix + "effects.amplifier", voucher.getEffectAmplifier());
|
||||
vouchersConfig.set(prefix + "itemstack", voucher.getItemStack());
|
||||
}
|
||||
|
||||
vouchersConfig.saveChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigReload() {
|
||||
vouchersConfig.load();
|
||||
|
||||
loadVouchersFromFile();
|
||||
|
||||
this.setLocale(getConfig().getString("System.Language Mode"), true);
|
||||
this.locale.reloadMessages();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.songoda.epicvouchers.listeners;
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.nbt.NBTItem;
|
||||
import com.songoda.epicvouchers.EpicVouchers;
|
||||
import com.songoda.epicvouchers.utils.CachedSet;
|
||||
import com.songoda.epicvouchers.voucher.Voucher;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -15,44 +16,62 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
public class PlayerInteractListener implements Listener {
|
||||
private final EpicVouchers instance;
|
||||
|
||||
private final CachedSet<ItemStack> checkedLegacyVouchers = new CachedSet<>(3 * 60);
|
||||
|
||||
public PlayerInteractListener(EpicVouchers instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void voucherListener(PlayerInteractEvent event) {
|
||||
final ItemStack item = event.getItem();
|
||||
if (item == null || (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK))
|
||||
return;
|
||||
public void voucherListener(PlayerInteractEvent e) {
|
||||
ItemStack item = e.getItem();
|
||||
|
||||
final NBTItem itemNbt = NmsManager.getNbt().of(item);
|
||||
if (item != null && (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)) {
|
||||
NBTItem itemNbt = NmsManager.getNbt().of(item);
|
||||
|
||||
for (Voucher voucher : instance.getVoucherManager().getVouchers()) {
|
||||
final ItemStack voucherItem = voucher.toItemStack();
|
||||
boolean itemHasVoucher = itemNbt.has("epicvouchers:voucher");
|
||||
String itemVoucherValue = itemNbt.getString("epicvouchers:voucher");
|
||||
|
||||
// Check voucher NBT.
|
||||
if (itemNbt.has("epicvouchers:voucher") && itemNbt.getNBTObject("epicvouchers:voucher").asString().equals(voucher.getKey())) {
|
||||
event.setCancelled(true);
|
||||
voucher.redeemVoucher(event);
|
||||
continue;
|
||||
boolean legacyChecked = checkedLegacyVouchers.contains(item);
|
||||
|
||||
if (itemHasVoucher || !legacyChecked) {
|
||||
boolean shouldBeLegacyCached = !itemHasVoucher;
|
||||
|
||||
for (Voucher voucher : instance.getVoucherManager().getVouchers()) {
|
||||
// Check voucher NBT.
|
||||
if (itemHasVoucher && itemVoucherValue.equals(voucher.getKey())) {
|
||||
e.setCancelled(true);
|
||||
voucher.redeemVoucher(e);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: eventually make the legacy check configurable as a lot of players (and vouchers) quickly cause lag
|
||||
// Legacy crap.
|
||||
// does the item they're holding match this voucher?
|
||||
ItemStack voucherItem = voucher.toItemStack();
|
||||
|
||||
if ((voucherItem == null || voucherItem.isSimilar(item)) &&
|
||||
item.getType() == voucher.getMaterial() &&
|
||||
item.getDurability() == voucher.getData()) {
|
||||
// material matches - verify the name + lore
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null && meta.hasDisplayName()
|
||||
&& ChatColor.stripColor(meta.getDisplayName()).equals(ChatColor.stripColor(voucher.getName(true)))
|
||||
&& (!meta.hasLore() || meta.getLore().equals(voucher.getLore(true)))) {
|
||||
e.setCancelled(true);
|
||||
voucher.redeemVoucher(e);
|
||||
|
||||
shouldBeLegacyCached = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldBeLegacyCached) {
|
||||
this.checkedLegacyVouchers.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy crap.
|
||||
// does the item they're holding match this voucher?
|
||||
|
||||
if (voucherItem != null && !voucherItem.isSimilar(item)) continue;
|
||||
else if (item.getType() != voucher.getMaterial() || item.getDurability() != voucher.getData()) continue;
|
||||
else {
|
||||
// material matches - verify the name + lore
|
||||
final ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null || !meta.hasDisplayName()
|
||||
|| !ChatColor.stripColor(meta.getDisplayName()).equals(ChatColor.stripColor(voucher.getName(true)))
|
||||
|| (meta.hasLore() && !meta.getLore().equals(voucher.getLore(true))))
|
||||
continue;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
voucher.redeemVoucher(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
src/main/java/com/songoda/epicvouchers/utils/CachedSet.java
Normal file
40
src/main/java/com/songoda/epicvouchers/utils/CachedSet.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.songoda.epicvouchers.utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class CachedSet<K> {
|
||||
private final Map<K, Long> cache = new WeakHashMap<>();
|
||||
private final int ttl;
|
||||
|
||||
private long lastClear = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* @param ttl Time-To-Live in seconds
|
||||
*/
|
||||
public CachedSet(int ttl) {
|
||||
this.ttl = ttl * 1000;
|
||||
}
|
||||
|
||||
public void add(K obj) {
|
||||
this.cache.put(obj, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public boolean contains(K obj) {
|
||||
if (shouldClear()) {
|
||||
clearStale();
|
||||
}
|
||||
|
||||
return this.cache.computeIfPresent(obj, (k, aLong) -> System.currentTimeMillis()) != null;
|
||||
}
|
||||
|
||||
public void clearStale() {
|
||||
this.cache.entrySet().removeIf(entry -> System.currentTimeMillis() - entry.getValue() >= ttl);
|
||||
|
||||
this.lastClear = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private boolean shouldClear() {
|
||||
return !this.cache.isEmpty() && System.currentTimeMillis() - lastClear > ttl;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user