mirror of
https://github.com/songoda/EpicHeads.git
synced 2024-11-29 14:06:29 +01:00
Updated to 2.0.2 (some manual changes).
This commit is contained in:
parent
002a5e9b68
commit
1caf138d56
@ -1,15 +1,14 @@
|
||||
package net.sothatsit.heads;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.sothatsit.blockstore.BlockStoreApi;
|
||||
import net.sothatsit.heads.cache.CacheHead;
|
||||
import net.sothatsit.heads.volatilecode.ItemNBT;
|
||||
import net.sothatsit.heads.volatilecode.Items;
|
||||
import net.sothatsit.heads.volatilecode.TextureGetter;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.BlockPosition;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.TileEntitySkull;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.World;
|
||||
import org.bukkit.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
@ -25,178 +24,185 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.sothatsit.blockstore.BlockStoreApi;
|
||||
import net.sothatsit.heads.cache.CacheHead;
|
||||
import net.sothatsit.heads.volatilecode.ItemNBT;
|
||||
import net.sothatsit.heads.volatilecode.Items;
|
||||
import net.sothatsit.heads.volatilecode.TextureGetter;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.BlockPosition;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.TileEntitySkull;
|
||||
import net.sothatsit.heads.volatilecode.reflection.nms.World;
|
||||
|
||||
public class HeadNamer implements Listener {
|
||||
|
||||
public void registerEvents() {
|
||||
Bukkit.getPluginManager().registerEvents(this, Heads.getInstance());
|
||||
}
|
||||
public void registerEvents() {
|
||||
Bukkit.getPluginManager().registerEvents(this, Heads.getInstance());
|
||||
}
|
||||
|
||||
private boolean shouldUseBlockStore() {
|
||||
return Heads.getMainConfig().shouldUseBlockStore() && Heads.isBlockStoreAvailable();
|
||||
}
|
||||
private boolean shouldUseBlockStore() {
|
||||
return Heads.getMainConfig().shouldUseBlockStore() && Heads.isBlockStoreAvailable();
|
||||
}
|
||||
|
||||
private boolean isHeadsHead(ItemStack item) {
|
||||
if(!Items.isSkull(item))
|
||||
return false;
|
||||
private boolean isHeadsHead(ItemStack item) {
|
||||
if (!Items.isSkull(item))
|
||||
return false;
|
||||
|
||||
SkullMeta meta = (SkullMeta) item.getItemMeta();
|
||||
SkullMeta meta = (SkullMeta) item.getItemMeta();
|
||||
|
||||
return meta.hasOwner() && meta.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
return meta.hasOwner() && meta.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
|
||||
private boolean isHeadsHead(Block block) {
|
||||
BlockState state = block.getState();
|
||||
if(!(state instanceof Skull))
|
||||
return false;
|
||||
private boolean isHeadsHead(Block block) {
|
||||
BlockState state = block.getState();
|
||||
if (!(state instanceof Skull))
|
||||
return false;
|
||||
|
||||
Skull skull = (Skull) state;
|
||||
Skull skull = (Skull) state;
|
||||
|
||||
return skull.getOwner() != null && skull.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
return skull.getOwner() != null && skull.getOwner().equals("SpigotHeadPlugin");
|
||||
}
|
||||
|
||||
private GameProfile getGameProfile(Block block) {
|
||||
World world = new World(block.getWorld());
|
||||
BlockPosition pos = new BlockPosition(block.getX(), block.getY(), block.getZ());
|
||||
TileEntitySkull tile = world.getTileEntity(pos).asSkullEntity();
|
||||
private GameProfile getGameProfile(Block block) {
|
||||
World world = new World(block.getWorld());
|
||||
BlockPosition pos = new BlockPosition(block.getX(), block.getY(), block.getZ());
|
||||
TileEntitySkull tile = world.getTileEntity(pos).asSkullEntity();
|
||||
|
||||
return tile.getGameProfile();
|
||||
}
|
||||
return tile.getGameProfile();
|
||||
}
|
||||
|
||||
private String findHeadName(Block block) {
|
||||
if(Heads.getMainConfig().shouldUseCacheNames()) {
|
||||
GameProfile profile = getGameProfile(block);
|
||||
String texture = TextureGetter.findTexture(profile);
|
||||
CacheHead head = Heads.getCache().findHeadByTexture(texture);
|
||||
private String findHeadName(Block block) {
|
||||
if (Heads.getMainConfig().shouldUseCacheNames()) {
|
||||
GameProfile profile = getGameProfile(block);
|
||||
String texture = TextureGetter.findTexture(profile);
|
||||
CacheHead head = Heads.getCache().findHeadByTexture(texture);
|
||||
|
||||
if(head != null)
|
||||
return ChatColor.GRAY + head.getName();
|
||||
}
|
||||
if (head != null)
|
||||
return ChatColor.GRAY + head.getName();
|
||||
}
|
||||
|
||||
return ChatColor.GRAY + Heads.getMainConfig().getDefaultHeadName();
|
||||
}
|
||||
return ChatColor.GRAY + Heads.getMainConfig().getDefaultHeadName();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onBlockPlace(BlockPlaceEvent e) {
|
||||
if(!Heads.getMainConfig().isHeadNamesEnabled() || !shouldUseBlockStore() || !isHeadsHead(e.getItemInHand()))
|
||||
return;
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onBlockPlace(BlockPlaceEvent e) {
|
||||
if (!Heads.getMainConfig().isHeadNamesEnabled() || !shouldUseBlockStore() || !isHeadsHead(e.getItemInHand()))
|
||||
return;
|
||||
|
||||
ItemMeta meta = e.getItemInHand().getItemMeta();
|
||||
ItemMeta meta = e.getItemInHand().getItemMeta();
|
||||
|
||||
if(!meta.hasDisplayName())
|
||||
return;
|
||||
if (!meta.hasDisplayName())
|
||||
return;
|
||||
|
||||
BlockStoreApi.setBlockMeta(e.getBlock(), Heads.getInstance(), "name", meta.getDisplayName());
|
||||
}
|
||||
BlockStoreApi.setBlockMeta(e.getBlock(), Heads.getInstance(), "name", meta.getDisplayName());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if(!Heads.getMainConfig().isHeadNamesEnabled())
|
||||
return;
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if (!Heads.getMainConfig().isHeadNamesEnabled())
|
||||
return;
|
||||
|
||||
Block block = e.getBlock();
|
||||
Block block = e.getBlock();
|
||||
|
||||
if(e.getPlayer().getGameMode() == GameMode.CREATIVE || !isHeadsHead(block))
|
||||
return;
|
||||
if (e.getPlayer().getGameMode() == GameMode.CREATIVE || !isHeadsHead(block))
|
||||
return;
|
||||
|
||||
// Stop the head item being dropped by the server
|
||||
e.setCancelled(true);
|
||||
// Stop the head item being dropped by the server
|
||||
e.setCancelled(true);
|
||||
|
||||
if(shouldUseBlockStore()) {
|
||||
BlockStoreApi.retrieveBlockMeta(Heads.getInstance(), block, Heads.getInstance(), "name", metaValue -> {
|
||||
String newName;
|
||||
if (shouldUseBlockStore()) {
|
||||
BlockStoreApi.retrieveBlockMeta(Heads.getInstance(), block, Heads.getInstance(), "name", metaValue -> {
|
||||
String newName;
|
||||
|
||||
if(metaValue instanceof String) {
|
||||
newName = (String) metaValue;
|
||||
} else {
|
||||
newName = findHeadName(block);
|
||||
}
|
||||
if (metaValue instanceof String) {
|
||||
newName = (String) metaValue;
|
||||
} else {
|
||||
newName = findHeadName(block);
|
||||
}
|
||||
|
||||
redropRenamedSkull(block, e.getPlayer(), newName);
|
||||
});
|
||||
} else {
|
||||
redropRenamedSkull(block, e.getPlayer(), findHeadName(block));
|
||||
}
|
||||
}
|
||||
redropRenamedSkull(block, e.getPlayer(), newName);
|
||||
});
|
||||
} else {
|
||||
redropRenamedSkull(block, e.getPlayer(), findHeadName(block));
|
||||
}
|
||||
}
|
||||
|
||||
private void redropRenamedSkull(Block block, Player player, String newName) {
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
private void redropRenamedSkull(Block block, Player player, String newName) {
|
||||
BlockBreakEvent event = new BlockBreakEvent(block, player);
|
||||
|
||||
List<RegisteredListener> listenersToCall = new ArrayList<>();
|
||||
List<RegisteredListener> listenersToCall = new ArrayList<>();
|
||||
|
||||
for (RegisteredListener listener : BlockBreakEvent.getHandlerList().getRegisteredListeners()) {
|
||||
if(!listener.getPlugin().isEnabled() || listener.getListener() instanceof HeadNamer)
|
||||
continue;
|
||||
for (RegisteredListener listener : BlockBreakEvent.getHandlerList().getRegisteredListeners()) {
|
||||
if (!listener.getPlugin().isEnabled() || listener.getListener() instanceof HeadNamer)
|
||||
continue;
|
||||
|
||||
listenersToCall.add(listener);
|
||||
}
|
||||
listenersToCall.add(listener);
|
||||
}
|
||||
|
||||
CountdownRunnable eventResultHandler = new CountdownRunnable(listenersToCall.size(), () -> {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
CountdownRunnable eventResultHandler = new CountdownRunnable(listenersToCall.size(), () -> {
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
|
||||
GameProfile profile = getGameProfile(block);
|
||||
ItemStack drop = ItemNBT.createHead(profile, newName);
|
||||
GameProfile profile = getGameProfile(block);
|
||||
ItemStack drop = ItemNBT.createHead(profile, newName);
|
||||
|
||||
Location dropLocation = block.getLocation().add(0.5, 0.5, 0.5);
|
||||
Location dropLocation = block.getLocation().add(0.5, 0.5, 0.5);
|
||||
|
||||
block.setType(Material.AIR);
|
||||
block.getWorld().dropItemNaturally(dropLocation, drop);
|
||||
});
|
||||
block.setType(Material.AIR);
|
||||
block.getWorld().dropItemNaturally(dropLocation, drop);
|
||||
});
|
||||
|
||||
for (RegisteredListener listener : listenersToCall) {
|
||||
new BlockBreakEventCaller(listener, event, eventResultHandler).scheduleTask();
|
||||
}
|
||||
}
|
||||
for (RegisteredListener listener : listenersToCall) {
|
||||
new BlockBreakEventCaller(listener, event, eventResultHandler).scheduleTask();
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlockBreakEventCaller implements Runnable {
|
||||
private static class BlockBreakEventCaller implements Runnable {
|
||||
|
||||
private final RegisteredListener listener;
|
||||
private final BlockBreakEvent event;
|
||||
private final CountdownRunnable countdown;
|
||||
private final RegisteredListener listener;
|
||||
private final BlockBreakEvent event;
|
||||
private final CountdownRunnable countdown;
|
||||
|
||||
public BlockBreakEventCaller(RegisteredListener listener, BlockBreakEvent event, CountdownRunnable countdown) {
|
||||
this.listener = listener;
|
||||
this.event = event;
|
||||
this.countdown = countdown;
|
||||
}
|
||||
public BlockBreakEventCaller(RegisteredListener listener, BlockBreakEvent event, CountdownRunnable countdown) {
|
||||
this.listener = listener;
|
||||
this.event = event;
|
||||
this.countdown = countdown;
|
||||
}
|
||||
|
||||
public void scheduleTask() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(listener.getPlugin(), this);
|
||||
}
|
||||
public void scheduleTask() {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(listener.getPlugin(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (EventException exception) {
|
||||
Heads.severe("There was an exception calling BlockBreakEvent for " + listener.getPlugin().getName());
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
countdown.countdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (EventException exception) {
|
||||
Heads.severe("There was an exception calling BlockBreakEvent for " + listener.getPlugin().getName());
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
countdown.countdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CountdownRunnable {
|
||||
private static class CountdownRunnable {
|
||||
|
||||
private final AtomicInteger countdown;
|
||||
private final Runnable runnable;
|
||||
private final AtomicInteger countdown;
|
||||
private final Runnable runnable;
|
||||
|
||||
public CountdownRunnable(int count, Runnable runnable) {
|
||||
this.countdown = new AtomicInteger(count);
|
||||
this.runnable = runnable;
|
||||
}
|
||||
public CountdownRunnable(int count, Runnable runnable) {
|
||||
this.countdown = new AtomicInteger(count);
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
public void countdown() {
|
||||
if(countdown.decrementAndGet() != 0)
|
||||
return;
|
||||
public void countdown() {
|
||||
if (countdown.decrementAndGet() != 0)
|
||||
return;
|
||||
|
||||
Heads.sync(runnable);
|
||||
}
|
||||
}
|
||||
Heads.sync(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,74 +1,78 @@
|
||||
package net.sothatsit.heads;
|
||||
|
||||
import net.sothatsit.heads.util.Checks;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import net.sothatsit.heads.util.Checks;
|
||||
|
||||
public class LegacyIDs {
|
||||
|
||||
public static final LegacyIDs EMPTY = new LegacyIDs(Collections.emptyMap());
|
||||
public static final LegacyIDs EMPTY = new LegacyIDs(Collections.emptyMap());
|
||||
|
||||
private final Map<Integer, String> idToType;
|
||||
private final Map<Integer, String> idToType;
|
||||
|
||||
public LegacyIDs(Map<Integer, String> idToType) {
|
||||
Checks.ensureNonNull(idToType, "idToType");
|
||||
public LegacyIDs(Map<Integer, String> idToType) {
|
||||
Checks.ensureNonNull(idToType, "idToType");
|
||||
|
||||
this.idToType = idToType;
|
||||
}
|
||||
this.idToType = idToType;
|
||||
}
|
||||
|
||||
public String fromId(int id) {
|
||||
return idToType.get(id);
|
||||
}
|
||||
public String fromId(int id) {
|
||||
return idToType.get(id);
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file);
|
||||
OutputStreamWriter osr = new OutputStreamWriter(fos);
|
||||
BufferedWriter writer = new BufferedWriter(osr)) {
|
||||
public void write(File file) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter osr = new OutputStreamWriter(fos); BufferedWriter writer = new BufferedWriter(osr)) {
|
||||
|
||||
write(writer);
|
||||
}
|
||||
}
|
||||
write(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(BufferedWriter writer) throws IOException {
|
||||
for(Map.Entry<Integer, String> entry : idToType.entrySet()) {
|
||||
writer.write(entry.getKey() + ":" + entry.getValue() + "\n");
|
||||
}
|
||||
}
|
||||
public void write(BufferedWriter writer) throws IOException {
|
||||
for (Map.Entry<Integer, String> entry : idToType.entrySet()) {
|
||||
writer.write(entry.getKey() + ":" + entry.getValue() + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
public static LegacyIDs create() {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
public static LegacyIDs create() {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
|
||||
for(Material type : Material.values()) {
|
||||
idToType.put(type.getId(), type.name());
|
||||
}
|
||||
for (Material type : Material.values()) {
|
||||
idToType.put(type.getId(), type.name());
|
||||
}
|
||||
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
|
||||
public static LegacyIDs readResource(String resource) throws IOException {
|
||||
try (InputStream is = Heads.getInstance().getResource(resource);
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
BufferedReader reader = new BufferedReader(isr)) {
|
||||
public static LegacyIDs readResource(String resource) throws IOException {
|
||||
try (InputStream is = Heads.getInstance().getResource(resource); InputStreamReader isr = new InputStreamReader(is); BufferedReader reader = new BufferedReader(isr)) {
|
||||
|
||||
return read(reader);
|
||||
}
|
||||
}
|
||||
return read(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public static LegacyIDs read(BufferedReader reader) throws IOException {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
public static LegacyIDs read(BufferedReader reader) throws IOException {
|
||||
Map<Integer, String> idToType = new HashMap<>();
|
||||
|
||||
String line;
|
||||
while((line = reader.readLine()) != null) {
|
||||
int splitIndex = line.indexOf(':');
|
||||
int id = Integer.valueOf(line.substring(0, splitIndex));
|
||||
String type = line.substring(splitIndex + 1);
|
||||
idToType.put(id, type);
|
||||
}
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
int splitIndex = line.indexOf(':');
|
||||
int id = Integer.valueOf(line.substring(0, splitIndex));
|
||||
String type = line.substring(splitIndex + 1);
|
||||
idToType.put(id, type);
|
||||
}
|
||||
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
return new LegacyIDs(idToType);
|
||||
}
|
||||
}
|
||||
|
7
src/net/sothatsit/heads/LiveHead.java
Normal file
7
src/net/sothatsit/heads/LiveHead.java
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sothatsit.heads;
|
||||
|
||||
public class LiveHead {
|
||||
|
||||
// TODO: Add animation heads with live (cached) texures in the next updates.
|
||||
|
||||
}
|
7
src/net/sothatsit/heads/animation/Animations.java
Normal file
7
src/net/sothatsit/heads/animation/Animations.java
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sothatsit.heads.animation;
|
||||
|
||||
public class Animations {
|
||||
|
||||
// TODO: Add animation heads with live (cached) texures in the next updates.
|
||||
|
||||
}
|
7
src/net/sothatsit/heads/animation/LiveData.java
Normal file
7
src/net/sothatsit/heads/animation/LiveData.java
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sothatsit.heads.animation;
|
||||
|
||||
public class LiveData {
|
||||
|
||||
// TODO: Add animation heads with live (cached) texures in the next updates.
|
||||
|
||||
}
|
7
src/net/sothatsit/heads/animation/Monitor.java
Normal file
7
src/net/sothatsit/heads/animation/Monitor.java
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sothatsit.heads.animation;
|
||||
|
||||
public class Monitor {
|
||||
|
||||
// TODO: Add animation heads with live (cached) texures in the next updates.
|
||||
|
||||
}
|
@ -1,21 +1,5 @@
|
||||
package net.sothatsit.heads.menu.ui.item;
|
||||
|
||||
import net.sothatsit.heads.Heads;
|
||||
import net.sothatsit.heads.config.lang.Placeholder;
|
||||
import net.sothatsit.heads.menu.ui.MenuResponse;
|
||||
import net.sothatsit.heads.util.Checks;
|
||||
import net.sothatsit.heads.util.Stringify;
|
||||
import net.sothatsit.heads.volatilecode.ItemNBT;
|
||||
import net.sothatsit.heads.volatilecode.reflection.Version;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -23,359 +7,361 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import net.sothatsit.heads.Heads;
|
||||
import net.sothatsit.heads.config.lang.Placeholder;
|
||||
import net.sothatsit.heads.menu.ui.MenuResponse;
|
||||
import net.sothatsit.heads.util.Checks;
|
||||
import net.sothatsit.heads.util.Stringify;
|
||||
import net.sothatsit.heads.volatilecode.ItemNBT;
|
||||
import net.sothatsit.heads.volatilecode.reflection.Version;
|
||||
|
||||
public final class Item {
|
||||
|
||||
private final Material type;
|
||||
private final int amount;
|
||||
private final short damage;
|
||||
private final Material type;
|
||||
private final int amount;
|
||||
private final short damage;
|
||||
|
||||
private final String name;
|
||||
private final String[] lore;
|
||||
private final String name;
|
||||
private final String[] lore;
|
||||
|
||||
private final boolean enchanted;
|
||||
private final boolean enchanted;
|
||||
|
||||
private Item(Material type) {
|
||||
this(type, 1, (short) 0, null, null, false);
|
||||
}
|
||||
private Item(Material type) {
|
||||
this(type, 1, (short) 0, null, null, false);
|
||||
}
|
||||
|
||||
private Item(Material type, int amount, short damage, String name, String[] lore, boolean enchanted) {
|
||||
Checks.ensureNonNull(type, "type");
|
||||
Checks.ensureTrue(amount > 0, "amount must be greater than 0");
|
||||
Checks.ensureTrue(damage >= 0, "damage must be greater than or equal to 0");
|
||||
private Item(Material type, int amount, short damage, String name, String[] lore, boolean enchanted) {
|
||||
Checks.ensureNonNull(type, "type");
|
||||
Checks.ensureTrue(amount > 0, "amount must be greater than 0");
|
||||
Checks.ensureTrue(damage >= 0, "damage must be greater than or equal to 0");
|
||||
|
||||
if(lore != null) {
|
||||
Checks.ensureArrayNonNull(lore, "lore");
|
||||
}
|
||||
if (lore != null) {
|
||||
Checks.ensureArrayNonNull(lore, "lore");
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.damage = damage;
|
||||
this.name = name;
|
||||
this.lore = (lore == null || lore.length == 0 ? null : lore);
|
||||
this.enchanted = enchanted;
|
||||
}
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.damage = damage;
|
||||
this.name = name;
|
||||
this.lore = (lore == null || lore.length == 0 ? null : lore);
|
||||
this.enchanted = enchanted;
|
||||
}
|
||||
|
||||
public Item amount(int amount) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
public Item amount(int amount) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item damage(short damage) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
public Item damage(short damage) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item name(String name) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
public Item name(String name) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item lore(String... lore) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
public Item lore(String... lore) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Item enchanted(boolean enchanted) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
public Item enchanted(boolean enchanted) {
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public Button buildButton(Placeholder... placeholders) {
|
||||
return new Button(build(placeholders));
|
||||
}
|
||||
public Button buildButton(Placeholder... placeholders) {
|
||||
return new Button(build(placeholders));
|
||||
}
|
||||
|
||||
public Button buildButton(Callable<MenuResponse> callable, Placeholder... placeholders) {
|
||||
return new Button(build(placeholders), callable);
|
||||
}
|
||||
public Button buildButton(Callable<MenuResponse> callable, Placeholder... placeholders) {
|
||||
return new Button(build(placeholders), callable);
|
||||
}
|
||||
|
||||
public ItemStack build(Placeholder... placeholders) {
|
||||
return build(null, placeholders);
|
||||
}
|
||||
public ItemStack build(Placeholder... placeholders) {
|
||||
return build(null, placeholders);
|
||||
}
|
||||
|
||||
public ItemStack build(Function<String, Boolean> loreFilter, Placeholder... placeholders) {
|
||||
Checks.ensureNonNull(placeholders, "placeholders");
|
||||
public ItemStack build(Function<String, Boolean> loreFilter, Placeholder... placeholders) {
|
||||
Checks.ensureNonNull(placeholders, "placeholders");
|
||||
|
||||
ItemStack item = new ItemStack(type, amount, damage);
|
||||
ItemStack item = new ItemStack(type, amount, damage);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if(meta == null)
|
||||
return item;
|
||||
if (meta == null)
|
||||
return item;
|
||||
|
||||
if(name != null) {
|
||||
String displayName = ChatColor.translateAlternateColorCodes('&', name);
|
||||
if (name != null) {
|
||||
String displayName = ChatColor.translateAlternateColorCodes('&', name);
|
||||
|
||||
displayName = Placeholder.applyAll(displayName, placeholders);
|
||||
displayName = Placeholder.applyAll(displayName, placeholders);
|
||||
|
||||
meta.setDisplayName(displayName);
|
||||
}
|
||||
meta.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
if(lore != null) {
|
||||
String[] itemLore = Placeholder.colourAll(lore);
|
||||
if (lore != null) {
|
||||
String[] itemLore = Placeholder.colourAll(lore);
|
||||
|
||||
itemLore = Placeholder.filterAndApplyAll(itemLore, loreFilter, placeholders);
|
||||
|
||||
meta.setLore(Arrays.asList(itemLore));
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
|
||||
if(enchanted) {
|
||||
item = ItemNBT.addGlow(item);
|
||||
}
|
||||
itemLore = Placeholder.filterAndApplyAll(itemLore, loreFilter, placeholders);
|
||||
|
||||
return item;
|
||||
}
|
||||
meta.setLore(Arrays.asList(itemLore));
|
||||
}
|
||||
|
||||
public void save(ConfigurationSection section, String key) {
|
||||
section.set(key, null);
|
||||
save(section.createSection(key));
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
|
||||
public void save(ConfigurationSection section) {
|
||||
section.set("type", getTypeName(type));
|
||||
if (enchanted) {
|
||||
item = ItemNBT.addGlow(item);
|
||||
}
|
||||
|
||||
if(amount != 1) {
|
||||
section.set("amount", amount);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
if(damage != 0) {
|
||||
section.set("damage", damage);
|
||||
}
|
||||
public void save(ConfigurationSection section, String key) {
|
||||
section.set(key, null);
|
||||
save(section.createSection(key));
|
||||
}
|
||||
|
||||
if(name != null) {
|
||||
section.set("name", name);
|
||||
}
|
||||
public void save(ConfigurationSection section) {
|
||||
section.set("type", getTypeName(type));
|
||||
|
||||
if(lore != null) {
|
||||
section.set("lore", Arrays.asList(lore));
|
||||
}
|
||||
if (amount != 1) {
|
||||
section.set("amount", amount);
|
||||
}
|
||||
|
||||
if(enchanted) {
|
||||
section.set("enchanted", true);
|
||||
}
|
||||
}
|
||||
if (damage != 0) {
|
||||
section.set("damage", damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof Item))
|
||||
return false;
|
||||
if (name != null) {
|
||||
section.set("name", name);
|
||||
}
|
||||
|
||||
Item other = (Item) obj;
|
||||
if (lore != null) {
|
||||
section.set("lore", Arrays.asList(lore));
|
||||
}
|
||||
|
||||
return other.type == type
|
||||
&& other.amount == amount
|
||||
&& Objects.equals(other.name, name)
|
||||
&& (other.lore == null ? lore == null : Arrays.equals(other.lore, lore))
|
||||
&& other.enchanted == enchanted;
|
||||
}
|
||||
if (enchanted) {
|
||||
section.set("enchanted", true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Stringify.Builder properties = Stringify.builder();
|
||||
{
|
||||
properties.entry("type", getTypeName(type));
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Item))
|
||||
return false;
|
||||
|
||||
if(amount != 1) {
|
||||
properties.entry("amount", amount);
|
||||
}
|
||||
Item other = (Item) obj;
|
||||
|
||||
if(name != null) {
|
||||
properties.entry("name", name);
|
||||
}
|
||||
return other.type == type && other.amount == amount && Objects.equals(other.name, name) && (other.lore == null ? lore == null : Arrays.equals(other.lore, lore)) && other.enchanted == enchanted;
|
||||
}
|
||||
|
||||
if(Version.isBelow(Version.v1_13)) {
|
||||
if(damage != 0) {
|
||||
properties.entry("data", damage);
|
||||
}
|
||||
} else {
|
||||
if(damage != 0) {
|
||||
properties.entry("damage", damage);
|
||||
}
|
||||
}
|
||||
|
||||
if(lore != null) {
|
||||
properties.entry("lore", lore);
|
||||
}
|
||||
|
||||
if(enchanted) {
|
||||
properties.entry("enchanted", true);
|
||||
}
|
||||
}
|
||||
return properties.toString();
|
||||
}
|
||||
|
||||
public static Item create(Material type) {
|
||||
return new Item(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated data is only supported pre-1.13
|
||||
*/
|
||||
@Deprecated
|
||||
public static Item create(Material type, byte data) {
|
||||
return new Item(type, 1, data, null, null, false);
|
||||
}
|
||||
|
||||
public static Item create(ItemStack itemStack) {
|
||||
Item item = create(itemStack.getType())
|
||||
.amount(itemStack.getAmount())
|
||||
.damage(itemStack.getDurability());
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if(meta == null)
|
||||
return item;
|
||||
|
||||
if(meta.hasDisplayName()) {
|
||||
String name = meta.getDisplayName().replace(ChatColor.COLOR_CHAR, '&');
|
||||
|
||||
item = item.name(name);
|
||||
}
|
||||
|
||||
if(meta.hasLore()) {
|
||||
List<String> rawLore = meta.getLore();
|
||||
String[] lore = new String[rawLore.size()];
|
||||
|
||||
for(int index = 0; index < lore.length; ++index) {
|
||||
lore[index] = rawLore.get(index).replace(ChatColor.COLOR_CHAR, '&');
|
||||
}
|
||||
|
||||
item = item.lore(lore);
|
||||
}
|
||||
|
||||
if(meta.hasEnchants()) {
|
||||
item = item.enchanted(true);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private static void updateLegacyTypes(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
if(!section.isSet("type"))
|
||||
return;
|
||||
|
||||
if(Version.isBelow(Version.v1_13) && section.isSet("data")) {
|
||||
section.set("damage", section.get("data"));
|
||||
section.set("data", null);
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
String typeData = section.getString("damage", null);
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if(type != null && !section.isInt("type"))
|
||||
return;
|
||||
|
||||
if(section.isInt("type")) {
|
||||
int typeId = section.getInt("type");
|
||||
String convertedType = Heads.getLegacyIDs().fromId(typeId);
|
||||
|
||||
if(convertedType == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", " +
|
||||
"unknown type id " + typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Version.isBelow(Version.v1_13)) {
|
||||
type = Material.matchMaterial(convertedType);
|
||||
} else {
|
||||
type = null;
|
||||
}
|
||||
|
||||
section.set("type", convertedType.toLowerCase());
|
||||
}
|
||||
|
||||
boolean legacy = false;
|
||||
if(type == null && !Version.isBelow(Version.v1_13)) {
|
||||
type = Material.valueOf("LEGACY_" + section.getString("type").toUpperCase().replace(' ', '_'));
|
||||
legacy = true;
|
||||
}
|
||||
|
||||
if(type == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", could not find type " + typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
if(legacy && !Version.isBelow(Version.v1_13)) {
|
||||
Material legacyType = type;
|
||||
int data = section.getInt("damage");
|
||||
byte byteData = (byte) (data >= 0 && data < 16 ? data : 0);
|
||||
|
||||
// Get a type to begin with, to check if the data is a damage value
|
||||
Material withoutData = fromLegacyType(legacyType, (byte) 0);
|
||||
type = fromLegacyType(legacyType, byteData);
|
||||
if(type == null) {
|
||||
Heads.warning("Invalid legacy type of item " + section.getCurrentPath() + ": " +
|
||||
"Could not convert " + legacyType + ":" + data + " to non-legacy format");
|
||||
return;
|
||||
}
|
||||
|
||||
if(withoutData != type) {
|
||||
section.set("damage", null);
|
||||
}
|
||||
}
|
||||
|
||||
section.set("type", type.name().toLowerCase());
|
||||
|
||||
String from = typeName + (typeData != null ? ":" + typeData : "");
|
||||
String to = type.name().toLowerCase() + (section.isSet("damage") ? ":" + section.get("damage") : "");
|
||||
Heads.info("1.13 Update - " + from + " converted to " + to +
|
||||
" for " + filename + " -> " + section.getCurrentPath());
|
||||
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
public static Item load(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
// Convert from legacy type ids to type names
|
||||
updateLegacyTypes(filename, section, shouldSave);
|
||||
|
||||
if (!section.isSet("type") || !section.isString("type")) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + " in " + filename + ", " +
|
||||
"expected a type name");
|
||||
return null;
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
|
||||
if(type == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", " +
|
||||
"unknown material for type name " + typeName);
|
||||
return null;
|
||||
}
|
||||
|
||||
short damage = (short) section.getInt("damage", 0);
|
||||
|
||||
if(damage < 0) {
|
||||
Heads.warning("Invalid damage of item " + section.getCurrentPath() + ", " +
|
||||
"damage must be at least 0");
|
||||
return null;
|
||||
}
|
||||
|
||||
int amount = section.getInt("amount", 1);
|
||||
|
||||
if(amount < 1) {
|
||||
Heads.warning("Invalid amount of item " + section.getCurrentPath() + ", " +
|
||||
"amount must be at least 1");
|
||||
return null;
|
||||
}
|
||||
|
||||
String name = section.getString("name", null);
|
||||
String[] lore = section.getStringList("lore").toArray(new String[0]);
|
||||
boolean enchanted = section.getBoolean("enchanted", false);
|
||||
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public static String getTypeName(Material type) {
|
||||
return type.name().toLowerCase();
|
||||
}
|
||||
|
||||
public static Material getType(String typeName) {
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if(type != null || Version.isBelow(Version.v1_13))
|
||||
return type;
|
||||
|
||||
return Material.matchMaterial(typeName, true);
|
||||
}
|
||||
|
||||
public static Material fromLegacyType(Material legacyType, byte data) {
|
||||
return Bukkit.getUnsafe().fromLegacy(new MaterialData(legacyType, data));
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
Stringify.Builder properties = Stringify.builder();
|
||||
{
|
||||
properties.entry("type", getTypeName(type));
|
||||
|
||||
if (amount != 1) {
|
||||
properties.entry("amount", amount);
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
properties.entry("name", name);
|
||||
}
|
||||
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
if (damage != 0) {
|
||||
properties.entry("data", damage);
|
||||
}
|
||||
} else {
|
||||
if (damage != 0) {
|
||||
properties.entry("damage", damage);
|
||||
}
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
properties.entry("lore", lore);
|
||||
}
|
||||
|
||||
if (enchanted) {
|
||||
properties.entry("enchanted", true);
|
||||
}
|
||||
}
|
||||
return properties.toString();
|
||||
}
|
||||
|
||||
public static Item create(Material type) {
|
||||
return new Item(type);
|
||||
}
|
||||
|
||||
public static Item create(Material type, byte data) {
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
return new Item(type, 1, data, null, null, false);
|
||||
}
|
||||
return new Item(type, 1, (short) 0, null, null, false);
|
||||
}
|
||||
|
||||
public static Item create(ItemStack itemStack) {
|
||||
Item item = create(itemStack.getType()).amount(itemStack.getAmount()).damage(itemStack.getDurability());
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null)
|
||||
return item;
|
||||
|
||||
if (meta.hasDisplayName()) {
|
||||
String name = meta.getDisplayName().replace(ChatColor.COLOR_CHAR, '&');
|
||||
|
||||
item = item.name(name);
|
||||
}
|
||||
|
||||
if (meta.hasLore()) {
|
||||
List<String> rawLore = meta.getLore();
|
||||
String[] lore = new String[rawLore.size()];
|
||||
|
||||
for (int index = 0; index < lore.length; ++index) {
|
||||
lore[index] = rawLore.get(index).replace(ChatColor.COLOR_CHAR, '&');
|
||||
}
|
||||
|
||||
item = item.lore(lore);
|
||||
}
|
||||
|
||||
if (meta.hasEnchants()) {
|
||||
item = item.enchanted(true);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private static void updateLegacyTypes(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
if (!section.isSet("type"))
|
||||
return;
|
||||
|
||||
if (Version.isBelow(Version.v1_13) && section.isSet("data")) {
|
||||
section.set("damage", section.get("data"));
|
||||
section.set("data", null);
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
String typeData = section.getString("damage", null);
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if (type != null && !section.isInt("type"))
|
||||
return;
|
||||
|
||||
if (section.isInt("type")) {
|
||||
int typeId = section.getInt("type");
|
||||
String convertedType = Heads.getLegacyIDs().fromId(typeId);
|
||||
|
||||
if (convertedType == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", " + "unknown type id " + typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Version.isBelow(Version.v1_13)) {
|
||||
type = Material.matchMaterial(convertedType);
|
||||
} else {
|
||||
type = null;
|
||||
}
|
||||
|
||||
section.set("type", convertedType.toLowerCase());
|
||||
}
|
||||
|
||||
boolean legacy = false;
|
||||
if (type == null && !Version.isBelow(Version.v1_13)) {
|
||||
type = Material.valueOf("LEGACY_" + section.getString("type").toUpperCase().replace(' ', '_'));
|
||||
legacy = true;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", could not find type " + typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (legacy && !Version.isBelow(Version.v1_13)) {
|
||||
Material legacyType = type;
|
||||
int data = section.getInt("damage");
|
||||
byte byteData = (byte) (data >= 0 && data < 16 ? data : 0);
|
||||
|
||||
// Get a type to begin with, to check if the data is a damage value
|
||||
Material withoutData = fromLegacyType(legacyType, (byte) 0);
|
||||
type = fromLegacyType(legacyType, byteData);
|
||||
if (type == null) {
|
||||
Heads.warning("Invalid legacy type of item " + section.getCurrentPath() + ": " + "Could not convert " + legacyType + ":" + data + " to non-legacy format");
|
||||
return;
|
||||
}
|
||||
|
||||
if (withoutData != type) {
|
||||
section.set("damage", null);
|
||||
}
|
||||
}
|
||||
|
||||
section.set("type", type.name().toLowerCase());
|
||||
|
||||
String from = typeName + (typeData != null ? ":" + typeData : "");
|
||||
String to = type.name().toLowerCase() + (section.isSet("damage") ? ":" + section.get("damage") : "");
|
||||
Heads.info("1.13 Update - " + from + " converted to " + to + " for " + filename + " -> " + section.getCurrentPath());
|
||||
|
||||
shouldSave.set(true);
|
||||
}
|
||||
|
||||
public static Item load(String filename, ConfigurationSection section, AtomicBoolean shouldSave) {
|
||||
// Convert from legacy type ids to type names
|
||||
updateLegacyTypes(filename, section, shouldSave);
|
||||
|
||||
if (!section.isSet("type") || !section.isString("type")) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + " in " + filename + ", " + "expected a type name");
|
||||
return null;
|
||||
}
|
||||
|
||||
String typeName = section.getString("type");
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
|
||||
if (type == null) {
|
||||
Heads.warning("Invalid type of item " + section.getCurrentPath() + ", " + "unknown material for type name " + typeName);
|
||||
return null;
|
||||
}
|
||||
|
||||
short damage = (short) section.getInt("damage", 0);
|
||||
|
||||
if (damage < 0) {
|
||||
Heads.warning("Invalid damage of item " + section.getCurrentPath() + ", " + "damage must be at least 0");
|
||||
return null;
|
||||
}
|
||||
|
||||
int amount = section.getInt("amount", 1);
|
||||
|
||||
if (amount < 1) {
|
||||
Heads.warning("Invalid amount of item " + section.getCurrentPath() + ", " + "amount must be at least 1");
|
||||
return null;
|
||||
}
|
||||
|
||||
String name = section.getString("name", null);
|
||||
String[] lore = section.getStringList("lore").toArray(new String[0]);
|
||||
boolean enchanted = section.getBoolean("enchanted", false);
|
||||
|
||||
return new Item(type, amount, damage, name, lore, enchanted);
|
||||
}
|
||||
|
||||
public static String getTypeName(Material type) {
|
||||
return type.name().toLowerCase();
|
||||
}
|
||||
|
||||
public static Material getType(String typeName) {
|
||||
Material type = Material.matchMaterial(typeName);
|
||||
if (type != null || Version.isBelow(Version.v1_13))
|
||||
return type;
|
||||
|
||||
return Material.matchMaterial(typeName, true);
|
||||
}
|
||||
|
||||
public static Material fromLegacyType(Material legacyType, byte data) {
|
||||
return Bukkit.getUnsafe().fromLegacy(new MaterialData(legacyType, data));
|
||||
}
|
||||
}
|
||||
|
@ -2,44 +2,47 @@ package net.sothatsit.heads.util;
|
||||
|
||||
public abstract class ExceptionDetailer {
|
||||
|
||||
private static class DetailException extends Exception {
|
||||
public DetailException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
}
|
||||
private static class DetailException extends Exception {
|
||||
|
||||
public RuntimeException detail(RuntimeException exception) {
|
||||
return (RuntimeException) detail((Exception) exception);
|
||||
}
|
||||
private static final long serialVersionUID = 7714839411923164464L;
|
||||
|
||||
public abstract Exception detail(Exception exception);
|
||||
public DetailException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
}
|
||||
|
||||
public static ExceptionDetailer constructorDetailer() {
|
||||
final DetailException constructorStackTrace = new DetailException("Object constructed at");
|
||||
public RuntimeException detail(RuntimeException exception) {
|
||||
return (RuntimeException) detail((Exception) exception);
|
||||
}
|
||||
|
||||
return new ExceptionDetailer() {
|
||||
@Override
|
||||
public Exception detail(Exception exception) {
|
||||
try {
|
||||
return appendInfo(exception, constructorStackTrace);
|
||||
} catch(Exception e) {
|
||||
new Exception("Exception appending info to exception", e).printStackTrace();
|
||||
public abstract Exception detail(Exception exception);
|
||||
|
||||
constructorStackTrace.printStackTrace();
|
||||
public static ExceptionDetailer constructorDetailer() {
|
||||
final DetailException constructorStackTrace = new DetailException("Object constructed at");
|
||||
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return new ExceptionDetailer() {
|
||||
@Override
|
||||
public Exception detail(Exception exception) {
|
||||
try {
|
||||
return appendInfo(exception, constructorStackTrace);
|
||||
} catch (Exception e) {
|
||||
new Exception("Exception appending info to exception", e).printStackTrace();
|
||||
|
||||
public static Exception appendInfo(Exception exception, DetailException info) {
|
||||
Checks.ensureNonNull(exception, "exception");
|
||||
Checks.ensureNonNull(info, "info");
|
||||
constructorStackTrace.printStackTrace();
|
||||
|
||||
exception.addSuppressed(info);
|
||||
return exception;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
public static Exception appendInfo(Exception exception, DetailException info) {
|
||||
Checks.ensureNonNull(exception, "exception");
|
||||
Checks.ensureNonNull(info, "info");
|
||||
|
||||
exception.addSuppressed(info);
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,64 +1,65 @@
|
||||
package net.sothatsit.heads.volatilecode;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.sothatsit.heads.menu.ui.item.Item;
|
||||
import net.sothatsit.heads.volatilecode.reflection.Version;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Methods to deal with items on different Spigot versions.
|
||||
*/
|
||||
public class Items {
|
||||
|
||||
public static boolean isSkull(ItemStack item) {
|
||||
if(item == null)
|
||||
return false;
|
||||
public static boolean isSkull(ItemStack item) {
|
||||
if (item == null)
|
||||
return false;
|
||||
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return item.getType().name().equals("SKULL_ITEM") && item.getDurability() == 3;
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return item.getType().name().equals("SKULL_ITEM") && item.getDurability() == 3;
|
||||
|
||||
return item.getType() == Material.PLAYER_HEAD;
|
||||
}
|
||||
return item.getType() == Material.PLAYER_HEAD;
|
||||
}
|
||||
|
||||
public static Item createSkull() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("SKULL_ITEM"), (byte) 3);
|
||||
public static Item createSkull() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("SKULL_ITEM"), (byte) 3);
|
||||
|
||||
return Item.create(Material.PLAYER_HEAD);
|
||||
}
|
||||
return Item.create(Material.PLAYER_HEAD);
|
||||
}
|
||||
|
||||
public static Item createRedStainedClay() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 14);
|
||||
public static Item createRedStainedClay() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 14);
|
||||
|
||||
return Item.create(Material.RED_TERRACOTTA);
|
||||
}
|
||||
return Item.create(Material.RED_TERRACOTTA);
|
||||
}
|
||||
|
||||
public static Item createGreenStainedClay() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 5);
|
||||
public static Item createGreenStainedClay() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_CLAY"), (byte) 5);
|
||||
|
||||
return Item.create(Material.GREEN_TERRACOTTA);
|
||||
}
|
||||
return Item.create(Material.GREEN_TERRACOTTA);
|
||||
}
|
||||
|
||||
public static Item createRedStainedGlassPane() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 14);
|
||||
public static Item createRedStainedGlassPane() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 14);
|
||||
|
||||
return Item.create(Material.RED_STAINED_GLASS_PANE);
|
||||
}
|
||||
return Item.create(Material.RED_STAINED_GLASS_PANE);
|
||||
}
|
||||
|
||||
public static Item createBlackStainedGlassPane() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 15);
|
||||
public static Item createBlackStainedGlassPane() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("STAINED_GLASS_PANE"), (byte) 15);
|
||||
|
||||
return Item.create(Material.BLACK_STAINED_GLASS_PANE);
|
||||
}
|
||||
return Item.create(Material.BLACK_STAINED_GLASS_PANE);
|
||||
}
|
||||
|
||||
public static Item createEmptyMap() {
|
||||
if(Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("EMPTY_MAP"));
|
||||
public static Item createEmptyMap() {
|
||||
if (Version.isBelow(Version.v1_13))
|
||||
return Item.create(Material.valueOf("EMPTY_MAP"));
|
||||
|
||||
return Item.create(Material.MAP);
|
||||
}
|
||||
return Item.create(Material.MAP);
|
||||
}
|
||||
}
|
||||
|
@ -1,119 +1,118 @@
|
||||
package net.sothatsit.heads.volatilecode.reflection;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public final class ReflectionUtils {
|
||||
|
||||
public static String getServerVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String ClassName) {
|
||||
String className = "net.minecraft.server." + getServerVersion() + "." + ClassName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class<?> getCraftBukkitClass(String ClassPackageName) {
|
||||
String className = "org.bukkit.craftbukkit." + getServerVersion() + "." + ClassPackageName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) {
|
||||
outer: for (Constructor<?> c : clazz.getDeclaredConstructors()) {
|
||||
Class<?>[] para = c.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
reportNotFound("Could not find constructor in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name) {
|
||||
for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (m.getName().equals(name)) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, name, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, staticMethod, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
outer: for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (name != null && !m.getName().equals(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (staticMethod != Modifier.isStatic(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m.getReturnType().equals(returnType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] para = m.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void reportNotFound(String message) {
|
||||
new Exception(message).printStackTrace();
|
||||
}
|
||||
public static String getServerVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String ClassName) {
|
||||
String className = "net.minecraft.server." + getServerVersion() + "." + ClassName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class<?> getCraftBukkitClass(String ClassPackageName) {
|
||||
String className = "org.bukkit.craftbukkit." + getServerVersion() + "." + ClassPackageName;
|
||||
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) {
|
||||
outer: for (Constructor<?> c : clazz.getDeclaredConstructors()) {
|
||||
Class<?>[] para = c.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
reportNotFound("Could not find constructor in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name) {
|
||||
for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (m.getName().equals(name)) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, name, false, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
return getMethod(clazz, null, staticMethod, returnType, params);
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, boolean staticMethod, Class<?> returnType, Class<?>... params) {
|
||||
outer: for (Method m : clazz.getDeclaredMethods()) {
|
||||
if (name != null && !m.getName().equals(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (staticMethod != Modifier.isStatic(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m.getReturnType().equals(returnType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] para = m.getParameterTypes();
|
||||
|
||||
if (para.length != params.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < para.length; i++) {
|
||||
if (!para[i].equals(params[i])) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
reportNotFound("Could not find method " + name + " in class " + clazz);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void reportNotFound(String message) {
|
||||
new Exception(message).printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
main: net.sothatsit.heads.Heads
|
||||
author: Marido
|
||||
name: Heads
|
||||
version: 2.0.1
|
||||
version: 2.0.2
|
||||
api-version: 1.13
|
||||
softdepend: [Vault, PlayerPoints, BlockStore]
|
||||
loadbefore: [DeluxeMenus]
|
||||
|
Loading…
Reference in New Issue
Block a user