Made head getting async for panels.

This commit is contained in:
Tastybento 2018-03-31 18:34:49 -07:00
parent f0d3a9ab5f
commit e09cb30cb5
7 changed files with 169 additions and 29 deletions

View File

@ -19,6 +19,7 @@ import us.tastybento.bskyblock.managers.IslandsManager;
import us.tastybento.bskyblock.managers.LocalesManager;
import us.tastybento.bskyblock.managers.PlayersManager;
import us.tastybento.bskyblock.managers.RanksManager;
import us.tastybento.bskyblock.util.HeadGetter;
/**
* Main BSkyBlock class - provides an island minigame in the sky
@ -50,6 +51,8 @@ public class BSkyBlock extends JavaPlugin {
// Notifier
private Notifier notifier;
private HeadGetter headGetter;
@Override
public void onEnable(){
// Save the default config from config.yml
@ -81,6 +84,9 @@ public class BSkyBlock extends JavaPlugin {
islandsManager = new IslandsManager(this);
ranksManager = new RanksManager(this);
// Start head getter
headGetter = new HeadGetter(this);
// Load metrics
metrics = new Metrics(instance);
registerCustomCharts();
@ -272,4 +278,13 @@ public class BSkyBlock extends JavaPlugin {
public Notifier getNotifier() {
return notifier;
}
/**
* @return the headGetter
*/
public HeadGetter getHeadGetter() {
return headGetter;
}
}

View File

@ -4,13 +4,18 @@ import java.util.Map;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.listeners.PanelListenerManager;
import us.tastybento.bskyblock.util.HeadGetter;
import us.tastybento.bskyblock.util.HeadRequester;
public class Panel {
public class Panel implements HeadRequester {
private Inventory inventory;
private Map<Integer, PanelItem> items;
@ -33,6 +38,10 @@ public class Panel {
for (Map.Entry<Integer, PanelItem> en: items.entrySet()) {
//TODO allow multi-paging
if (en.getKey() < 54) inventory.setItem(en.getKey(), en.getValue().getItem());
// Get player head async
if (en.getValue().isPlayerHead()) {
HeadGetter.getHead(en.getValue(), this);
}
}
} else {
inventory = Bukkit.createInventory(null, 9, name);
@ -110,4 +119,20 @@ public class Panel {
public void setUser(User user) {
this.user = user;
}
@Override
public void setHead(PanelItem item) {
// Update the panel item
items.values().stream().filter(i -> i.getName().equals(item.getName())).forEach(i -> i = item);
for (int i = 0; i < inventory.getSize(); i++) {
ItemStack it = inventory.getItem(i);
if (it != null && it.getType().equals(Material.SKULL_ITEM)) {
ItemMeta meta = it.getItemMeta();
if (item.getName().equals(meta.getLocalizedName())) {
inventory.setItem(i, item.getItem());
return;
}
}
}
}
}

View File

@ -23,9 +23,12 @@ public class PanelItem {
private String name;
private boolean glow;
private ItemMeta meta;
private boolean playerHead;
public PanelItem(ItemStack icon, String name, List<String> description, boolean glow, ClickHandler clickHandler) {
public PanelItem(ItemStack icon, String name, List<String> description, boolean glow, ClickHandler clickHandler, boolean playerHead) {
this.icon = icon;
this.playerHead = playerHead;
setMeta();
// Get the meta
meta = icon.getItemMeta();
@ -44,6 +47,11 @@ public class PanelItem {
icon.setItemMeta(meta);
}
private void setMeta() {
// TODO Auto-generated method stub
}
public ItemStack getItem() {
return icon;
}
@ -85,6 +93,13 @@ public class PanelItem {
}
}
/**
* @return the playerHead
*/
public boolean isPlayerHead() {
return playerHead;
}
/**
* Click handler interface
*
@ -98,4 +113,22 @@ public class PanelItem {
*/
boolean onClick(User user, ClickType click);
}
public void setHead(ItemStack itemStack) {
this.icon = itemStack;
setMeta();
// Get the meta
meta = icon.getItemMeta();
// Create the final item
setName(name);
setDescription(description);
setGlow(glow);
// Set flags to neaten up the view
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_DESTROYS);
meta.addItemFlags(ItemFlag.HIDE_PLACED_ON);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
icon.setItemMeta(meta);
}
}

View File

@ -3,12 +3,9 @@ package us.tastybento.bskyblock.api.panels.builders;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler;
@ -19,6 +16,7 @@ public class PanelItemBuilder {
private List<String> description = new ArrayList<>();
private boolean glow = false;
private PanelItem.ClickHandler clickHandler;
private boolean playerHead;
public PanelItemBuilder icon(Material icon) {
this.icon = new ItemStack(icon);
@ -35,26 +33,15 @@ public class PanelItemBuilder {
* @param playerUUID - player's UUID
* @return PanelItemBuilder
*/
public PanelItemBuilder icon(UUID playerUUID) {
return icon(Bukkit.getServer().getOfflinePlayer(playerUUID).getName());
}
/**
* Set icon to player's head
* @param playerName - player's name
* @return PanelItemBuilder
*/
@SuppressWarnings("deprecation")
public PanelItemBuilder icon(String playerName) {
ItemStack item = new ItemStack(Material.SKULL_ITEM, 1, (short) 3);
SkullMeta meta = (SkullMeta)item.getItemMeta();
// This is deprecated, but apparently the only way to make it work right now
meta.setOwner(playerName);
item.setItemMeta(meta);
this.icon = item;
this.name = playerName;
this.playerHead = true;
return this;
}
public PanelItemBuilder name(String name) {
this.name = name;
return this;
@ -107,7 +94,7 @@ public class PanelItemBuilder {
}
public PanelItem build() {
return new PanelItem(icon, name, description, glow, clickHandler);
return new PanelItem(icon, name, description, glow, clickHandler, playerHead);
}
}

View File

@ -0,0 +1,78 @@
package us.tastybento.bskyblock.util;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.panels.PanelItem;
public class HeadGetter {
private static Map<String,ItemStack> cachedHeads = new HashMap<>();
private static Map<String, PanelItem> names = new HashMap<>();
private BSkyBlock plugin;
private static Map<String,Set<HeadRequester>> headRequesters = new HashMap<>();
/**
* @param plugin
*/
public HeadGetter(BSkyBlock plugin) {
super();
this.plugin = plugin;
runPlayerHeadGetter();
}
@SuppressWarnings("deprecation")
private void runPlayerHeadGetter() {
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> {
synchronized(names) {
Iterator<Entry<String, PanelItem>> it = names.entrySet().iterator();
if (it.hasNext()) {
Entry<String, PanelItem> en = it.next();
ItemStack playerSkull = new ItemStack(Material.SKULL_ITEM, 1, (short) 3);
SkullMeta meta = (SkullMeta) playerSkull.getItemMeta();
meta.setOwner(en.getKey());
playerSkull.setItemMeta(meta);
// Save in cache
cachedHeads.put(en.getKey(), playerSkull);
// Tell requesters the head came in
if (headRequesters.containsKey(en.getKey())) {
for (HeadRequester req : headRequesters.get(en.getKey())) {
en.getValue().setHead(playerSkull.clone());
plugin.getServer().getScheduler().runTask(plugin, () -> req.setHead(en.getValue()));
}
}
it.remove();
}
}
}, 0L, 20L);
}
/**
* @param panelItem - head to update
* @param requester - callback class
*/
public static void getHead(PanelItem panelItem, HeadRequester requester) {
// Check if in cache
if (cachedHeads.containsKey(panelItem.getName())) {
panelItem.setHead(cachedHeads.get(panelItem.getName()).clone());
requester.setHead(panelItem);
} else {
// Get the name
//Bukkit.getLogger().info("DEBUG:Not in cache. Adding");
headRequesters.putIfAbsent(panelItem.getName(), new HashSet<>());
Set<HeadRequester> requesters = headRequesters.get(panelItem.getName());
requesters.add(requester);
headRequesters.put(panelItem.getName(), requesters);
names.put(panelItem.getName(), panelItem);
}
}
}

View File

@ -0,0 +1,11 @@
package us.tastybento.bskyblock.util;
import us.tastybento.bskyblock.api.panels.PanelItem;
public interface HeadRequester {
/**
* @param item - panel item
*/
public void setHead(PanelItem item);
}

View File

@ -85,15 +85,6 @@ public class PanelItemBuilderTest {
assertEquals(Material.IRON_ORE, item.getItem().getType());
}
@Test
public void testIconUUID() {
PanelItemBuilder builder = new PanelItemBuilder();
builder.icon(UUID.fromString("5988eecd-1dcd-4080-a843-785b62419"));
PanelItem item = builder.build();
assertNotNull(item.getItem().getType());
assertEquals(Material.SKULL_ITEM, item.getItem().getType());
}
@SuppressWarnings("deprecation")
@Test
public void testIconString() {