package de.fanta.challenges.gravestones;
import de.fanta.challenges.Challenges;
import de.fanta.challenges.utils.ChatUtil;
import de.iani.cubesideutils.bukkit.items.ItemGroups;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Slab;
import org.bukkit.block.data.type.Snow;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
public class GravestoneUtils {
protected static final Random random = new Random();
private static final NamespacedKey UUIDKey = new NamespacedKey(Challenges.getPlugin(), "uuid_gravestone");
private static final NamespacedKey inventoryKey = new NamespacedKey(Challenges.getPlugin(), "inventory_gravestone");
public static byte[] compressString(String s) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
OutputStreamWriter osw = new OutputStreamWriter(new DeflaterOutputStream(baos, new Deflater(Deflater.BEST_COMPRESSION)), StandardCharsets.UTF_8);
osw.write(s);
osw.flush();
osw.close();
} catch (IOException e) {
throw new RuntimeException("Could not compress data", e);
}
return baos.toByteArray();
}
public static String decompressString(byte[] data) {
try {
InputStreamReader reader = new InputStreamReader(new InflaterInputStream(new ByteArrayInputStream(data)), StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
char[] temp = new char[1024];
while (true) {
int readBytes;
readBytes = reader.read(temp);
if (readBytes < 0) {
break;
}
sb.append(temp, 0, readBytes);
}
return sb.toString();
} catch (IOException e) {
throw new RuntimeException("Error while decompressing inventory string", e);
}
}
public static String createInventoryString(Player player) {
YamlConfiguration conf = new YamlConfiguration();
ItemStack[] inventory = player.getInventory().getContents();
for (int i = 0; i < inventory.length; i++) {
ItemStack stack = inventory[i];
if (stack != null) {
ItemMeta meta = stack.getItemMeta();
if (meta != null) {
if (meta.hasEnchant(Enchantment.VANISHING_CURSE)) {
inventory[i] = null;
}
}
}
}
conf.set("inv", inventory);
return conf.saveToString();
}
public static void spawnAtBlock(Block block, Player player, byte[] inventoryBytes) {
World world = block.getWorld();
double y = block.getY();
Material type = block.getType();
String typeName = type.name();
double placeableY;
if (typeName.endsWith("_SLAB")) {
Slab slab = (Slab) block.getBlockData();
placeableY = y - 0.44;
if (slab.getType() == Slab.Type.BOTTOM) {
placeableY -= 0.5;
}
} else if (typeName.endsWith("_STAIRS") || type.isOccluding() || type == Material.GLASS || ItemGroups.isStainedGlass(type) || type == Material.ICE || type == Material.PACKED_ICE || type == Material.BLUE_ICE || ItemGroups.isLeaves(type)) {
placeableY = y - 0.44;
} else if (ItemGroups.isCarpet(type)) {
placeableY = y - 1.44 + (1 / 16.0);
} else if (type == Material.SNOW) {
Snow snow = (Snow) block.getBlockData();
int layers = snow.getLayers();
placeableY = y - 1.44 + (layers / 8.0);
} else {
placeableY = y - 0.44;
}
if (!Double.isNaN(placeableY)) {
world.spawn(new Location(world, block.getX() + 0.5, placeableY, block.getZ() + 0.5, player.getLocation().getYaw(), 0), ArmorStand.class, t -> {
t.setVisible(false);
t.setGravity(false);
t.setCustomName(ChatUtil.RED + "R.I.P. " + ChatUtil.BLUE + player.getName());
t.setCustomNameVisible(true);
ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD, 1);
SkullMeta meta = (SkullMeta) itemStack.getItemMeta();
meta.setOwner(player.getName());
itemStack.setItemMeta(meta);
t.getEquipment().setHelmet(itemStack);
PersistentDataContainer container = t.getPersistentDataContainer();
container.set(UUIDKey, PersistentDataType.STRING, player.getUniqueId().toString());
container.set(inventoryKey, PersistentDataType.BYTE_ARRAY, inventoryBytes);
});
ChatUtil.sendNormalMessage(player, "Dein Grabschstein steht bei:" + ChatUtil.ORANGE + " (" + player.getLocation().getBlockX() + "/" + player.getLocation().getBlockY() + "/" + player.getLocation().getBlockZ() + ")");
}
}
public static NamespacedKey getUUIDKey() {
return UUIDKey;
}
public static NamespacedKey getInventoryKey() {
return inventoryKey;
}
}