package regalowl.hyperconomy;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.metadata.MetadataValue;
public class ItemDisplayFactory implements Listener {
private HyperConomy hc;
private int refreshthreadid;
private ConcurrentHashMap<String, ItemDisplay> displays = new ConcurrentHashMap<String, ItemDisplay>();
private boolean loadActive;
ItemDisplayFactory() {
try {
hc = HyperConomy.hc;
if (hc.gYH().gFC("config").getBoolean("config.use-item-displays")) {
hc.getServer().getPluginManager().registerEvents(this, hc);
loadActive = false;
loadDisplays();
startRefreshThread();
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
public void loadDisplays() {
try {
if (!loadActive) {
loadActive = true;
unloadDisplays();
FileConfiguration disp = hc.gYH().gFC("displays");
Iterator<String> it = disp.getKeys(false).iterator();
while (it.hasNext()) {
String key = it.next().toString();
String name = disp.getString(key + ".name");
double x = disp.getDouble(key + ".x");
double y = disp.getDouble(key + ".y");
double z = disp.getDouble(key + ".z");
World w = Bukkit.getWorld(disp.getString(key + ".world"));
Location l = new Location(w, x, y, z);
Chunk locChunk = l.getChunk();
if (locChunk.isLoaded()) {
ItemDisplay display = new ItemDisplay(key, l, name);
String hkey = (int)Math.floor(x) + ":" + (int)Math.floor(y) + ":" + (int)Math.floor(z) + ":" + w.getName();
displays.put(hkey, display);
display.makeDisplay();
display.clearNearbyItems();
}
}
loadActive = false;
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
public void unloadDisplays() {
for (ItemDisplay display:displays.values()) {
display.clearNearbyItems();
display.clearDisplay();
}
displays.clear();
}
public void startRefreshThread() {
refreshthreadid = hc.getServer().getScheduler().scheduleSyncRepeatingTask(hc, new Runnable() {
public void run() {
for (ItemDisplay display:displays.values()) {
display.refresh();
}
}
}, 4800L, 4800L);
}
public void cancelRefreshThread() {
hc.getServer().getScheduler().cancelTask(refreshthreadid);
}
public boolean removeDisplay(int x, int y, int z, World w) {
String hkey = x + ":" + y + ":" + z + ":" + w.getName();
if (displays.containsKey(hkey)) {
ItemDisplay display = displays.get(hkey);
display.deleteDisplay();
displays.remove(hkey);
return true;
}
return false;
}
public boolean removeDisplay(int x, int z, World w) {
for (String key:displays.keySet()) {
int kx = Integer.parseInt(key.substring(0, key.indexOf(":")));
key = key.substring(key.indexOf(":") + 1, key.length());
int ky = Integer.parseInt(key.substring(0, key.indexOf(":")));
key = key.substring(key.indexOf(":") + 1, key.length());
int kz = Integer.parseInt(key.substring(0, key.indexOf(":")));
key = key.substring(key.indexOf(":") + 1, key.length());
String kw = key;
if (kx == x && kz == z && kw.equalsIgnoreCase(w.getName())) {
key = kx + ":" + ky + ":" + kz + ":" + kw;
ItemDisplay display = displays.get(key);
display.deleteDisplay();
displays.remove(key);
return true;
}
}
return false;
}
public boolean testDisplay(double x, double y, double z, World w, String name) {
x = Math.floor(x) + .5;
z = Math.floor(z) + .5;
FileConfiguration disp = hc.gYH().gFC("displays");
Iterator<String> it = disp.getKeys(false).iterator();
while (it.hasNext()) {
String key = it.next().toString();
double tx = disp.getDouble(key + ".x");
double ty = disp.getDouble(key + ".y");
double tz = disp.getDouble(key + ".z");
World tw = Bukkit.getWorld(disp.getString(key + ".world"));
if (x == tx && y == ty && z == tz && w == tw) {
return false;
}
}
Location l = new Location(w, x, y, z);
ItemDisplay display = new ItemDisplay(l, name);
String hkey = (int)Math.floor(x) + ":" + (int)Math.floor(y) + ":" + (int)Math.floor(z) + ":" + w.getName();
displays.put(hkey, display);
Chunk locChunk = l.getChunk();
if (locChunk.isLoaded()) {
display.makeDisplay();
display.clearNearbyItems();
}
return true;
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerDropItemEvent(PlayerDropItemEvent event) {
try {
Item droppedItem = event.getItemDrop();
for (ItemDisplay display:displays.values()) {
if (display.blockItemDrop(droppedItem)) {
event.setCancelled(true);
return;
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChunkLoad(ChunkLoadEvent event) {
try {
Chunk chunk = event.getChunk();
if (chunk == null) {
return;
}
for (ItemDisplay display:displays.values()) {
if (display == null) {
continue;
}
Location l = display.getLocation();
if (l != null && chunk.equals(l.getChunk())) {
display.removeItem();
display.makeDisplay();
return;
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChunkUnload(ChunkUnloadEvent event) {
try {
Chunk chunk = event.getChunk();
if (chunk == null) {
return;
}
for (ItemDisplay display:displays.values()) {
if (display == null) {
continue;
}
Location l = display.getLocation();
if (l != null && chunk.equals(l.getChunk())) {
display.removeItem();
return;
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerPickupItemEvent(PlayerPickupItemEvent event) {
try {
Item item = event.getItem();
if (!event.isCancelled()) {
List<MetadataValue> meta = item.getMetadata("HyperConomy");
for (MetadataValue cmeta : meta) {
if (cmeta.asString().equalsIgnoreCase("item_display")) {
event.setCancelled(true);
break;
}
}
}
for (ItemDisplay display : displays.values()) {
if (display.getEntityId() == item.getEntityId() || item.equals(display.getItem())) {
event.setCancelled(true);
break;
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockBreakEvent(BlockBreakEvent event) {
try {
Block bb = event.getBlock();
for (ItemDisplay display:displays.values()) {
if (display.getBaseBlock().equals(bb) || display.getItemBlock().equals(bb)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockPlaceEvent(BlockPlaceEvent event) {
try {
Block bb = event.getBlock();
for (ItemDisplay display : displays.values()) {
if (display.getBaseBlock().equals(bb) || display.getItemBlock().equals(bb)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
if (bb.getType().equals(Material.GRAVEL) || bb.getType().equals(Material.SAND)) {
Block below = bb.getRelative(BlockFace.DOWN);
while (below.getType().equals(Material.AIR)) {
below = below.getRelative(BlockFace.DOWN);
}
for (ItemDisplay display : displays.values()) {
if (display.getBaseBlock().equals(bb) || display.getItemBlock().equals(bb)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockPistonRetractEvent(BlockPistonRetractEvent event) {
try {
if (hc.gYH().gFC("config").getBoolean("config.use-chest-shops")) {
Location l = event.getRetractLocation();
Block b = l.getBlock();
for (ItemDisplay display : displays.values()) {
if (display.getBaseBlock().equals(b) || display.getItemBlock().equals(b)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockPistonExtendEvent(BlockPistonExtendEvent event) {
try {
List<Block> blocks = event.getBlocks();
for (Block cblock : blocks) {
for (ItemDisplay display : displays.values()) {
if (display.getBaseBlock().equals(cblock) || display.getItemBlock().equals(cblock)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onEntityExplodeEvent(EntityExplodeEvent event) {
try {
if (hc.gYH().gFC("config").getBoolean("config.use-chest-shops")) {
List<Block> blocks = event.blockList();
for (Block cblock : blocks) {
for (ItemDisplay display : displays.values()) {
if (display.getBaseBlock().equals(cblock) || display.getItemBlock().equals(cblock)) {
event.setCancelled(true);
display.removeItem();
display.makeDisplay();
}
}
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onCreatureSpawnEvent(CreatureSpawnEvent event) {
try {
for (ItemDisplay display : displays.values()) {
if (display.blockEntityPickup(event.getEntity())) {
event.getEntity().setCanPickupItems(false);
}
}
} catch (Exception e) {
hc.gDB().writeError(e);
}
}
public boolean isDisplay(Item item) {
try {
for (ItemDisplay display : displays.values()) {
if (item.equals(display.getItem())) {
return true;
}
}
return false;
} catch (Exception e) {
hc.gDB().writeError(e);
return false;
}
}
}