mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-12-02 15:43:23 +01:00
Fixes some errors with HeadGetter (#1569)
* Add getKey and getValue for Pair calls for nicer access. * Fixes ConcurrentModificationException in HeadGetter. Fixes an issue when elements with the same name were overwritten by HeadGetter.
This commit is contained in:
parent
1d4fd435a9
commit
3581537537
@ -2,17 +2,13 @@ package world.bentobox.bentobox.api.panels;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.user.User;
|
import world.bentobox.bentobox.api.user.User;
|
||||||
@ -190,18 +186,15 @@ public class Panel implements HeadRequester, InventoryHolder {
|
|||||||
@Override
|
@Override
|
||||||
public void setHead(PanelItem item) {
|
public void setHead(PanelItem item) {
|
||||||
// Update the panel item
|
// Update the panel item
|
||||||
// Replace the item in the item list if the name is the same
|
// Find panel item index in items and replace it once more in inventory to update it.
|
||||||
items = items.entrySet().stream()
|
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> (item.getName().equals(e.getValue().getName()) ? item : e.getValue())));
|
OptionalInt index = this.items.entrySet().stream().
|
||||||
// Replace the inventory slot item
|
filter(entry -> entry.getValue() == item).
|
||||||
for (int i = 0; i < inventory.getSize(); i++) {
|
mapToInt(Map.Entry::getKey).findFirst();
|
||||||
ItemStack it = inventory.getItem(i);
|
|
||||||
if (it != null && it.getType().equals(Material.PLAYER_HEAD)) {
|
if (index.isPresent()) {
|
||||||
ItemMeta meta = it.getItemMeta();
|
// Update item inside inventory to change icon only if item is inside panel.
|
||||||
if (meta != null && ChatColor.stripColor(item.getName()).equals(ChatColor.stripColor(meta.getLocalizedName()))) {
|
this.inventory.setItem(index.getAsInt(), item.getItem());
|
||||||
inventory.setItem(i, item.getItem());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,25 @@ public class Pair<X, Z> {
|
|||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns X element as key.
|
||||||
|
* @return X element
|
||||||
|
*/
|
||||||
|
public X getKey() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Z element as value.
|
||||||
|
* @return Z element
|
||||||
|
*/
|
||||||
|
public Z getValue() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
@ -9,11 +9,11 @@ import java.net.URL;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.panels.PanelItem;
|
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||||
|
import world.bentobox.bentobox.util.Pair;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +37,7 @@ public class HeadGetter {
|
|||||||
/**
|
/**
|
||||||
* Local cache for storing requested names and items which must be updated.
|
* Local cache for storing requested names and items which must be updated.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, PanelItem> names = new HashMap<>();
|
private static final Queue<Pair<String, PanelItem>> names = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requesters of player heads.
|
* Requesters of player heads.
|
||||||
@ -89,7 +90,7 @@ public class HeadGetter {
|
|||||||
// Get the name
|
// Get the name
|
||||||
headRequesters.computeIfAbsent(panelItem.getPlayerHeadName(), k -> new HashSet<>()).
|
headRequesters.computeIfAbsent(panelItem.getPlayerHeadName(), k -> new HashSet<>()).
|
||||||
add(requester);
|
add(requester);
|
||||||
names.put(panelItem.getPlayerHeadName(), panelItem);
|
names.add(new Pair<>(panelItem.getPlayerHeadName(), panelItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,21 +118,19 @@ public class HeadGetter {
|
|||||||
*/
|
*/
|
||||||
private void runPlayerHeadGetter() {
|
private void runPlayerHeadGetter() {
|
||||||
Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> {
|
Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> {
|
||||||
synchronized (names)
|
synchronized (HeadGetter.names)
|
||||||
{
|
{
|
||||||
Iterator<Entry<String, PanelItem>> it = names.entrySet().iterator();
|
if (!HeadGetter.names.isEmpty())
|
||||||
|
|
||||||
if (it.hasNext())
|
|
||||||
{
|
{
|
||||||
Entry<String, PanelItem> elementEntry = it.next();
|
Pair<String, PanelItem> elementEntry = HeadGetter.names.poll();
|
||||||
|
|
||||||
// TODO: In theory BentoBox could use User instance to find existing user UUID's.
|
// TODO: In theory BentoBox could use User instance to find existing user UUID's.
|
||||||
// It would avoid one API call.
|
// It would avoid one API call.
|
||||||
final String userName = elementEntry.getKey();
|
final String userName = elementEntry.getKey();
|
||||||
|
|
||||||
// Use cached userId as userId will not change :)
|
// Use cached userId as userId will not change :)
|
||||||
UUID userId = cachedHeads.containsKey(userName) ?
|
UUID userId = HeadGetter.cachedHeads.containsKey(userName) ?
|
||||||
cachedHeads.get(userName).getUserId() :
|
HeadGetter.cachedHeads.get(userName).getUserId() :
|
||||||
HeadGetter.getUserIdFromName(userName);
|
HeadGetter.getUserIdFromName(userName);
|
||||||
|
|
||||||
// Create new cache object.
|
// Create new cache object.
|
||||||
@ -140,24 +139,22 @@ public class HeadGetter {
|
|||||||
HeadGetter.getTextureFromUUID(userId));
|
HeadGetter.getTextureFromUUID(userId));
|
||||||
|
|
||||||
// Save in cache
|
// Save in cache
|
||||||
cachedHeads.put(userName, cache);
|
HeadGetter.cachedHeads.put(userName, cache);
|
||||||
|
|
||||||
// Tell requesters the head came in
|
// Tell requesters the head came in
|
||||||
if (headRequesters.containsKey(userName))
|
if (HeadGetter.headRequesters.containsKey(userName))
|
||||||
{
|
{
|
||||||
for (HeadRequester req : headRequesters.get(userName))
|
for (HeadRequester req : HeadGetter.headRequesters.get(userName))
|
||||||
{
|
{
|
||||||
elementEntry.getValue().setHead(cache.getPlayerHead());
|
elementEntry.getValue().setHead(cache.getPlayerHead());
|
||||||
|
|
||||||
Bukkit.getServer().getScheduler().runTaskAsynchronously(plugin,
|
Bukkit.getServer().getScheduler().runTaskAsynchronously(this.plugin,
|
||||||
() -> req.setHead(elementEntry.getValue()));
|
() -> req.setHead(elementEntry.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 0L, 20L);
|
}, 0L, 10L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user