Newer
Older
ChallengeSystem / Challenge / src / main / java / de / fanta / challenge / gravestones / GravestoneUtils.java
@fanta fanta on 7 Jun 2024 7 KB ja
package de.fanta.challenge.gravestones;

import de.fanta.challenge.Challenge;
import de.fanta.challenge.utils.ChatUtil;
import de.fanta.challenge.utils.ItemStackUtil;
import de.iani.cubesideutils.bukkit.items.ItemGroups;
import net.kyori.adventure.text.Component;
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.InvalidConfigurationException;
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.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.List;
import java.util.logging.Level;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

public class GravestoneUtils {
    private static final NamespacedKey UUIDKey = new NamespacedKey(Challenge.getPlugin(), "uuid_gravestone");
    private static final NamespacedKey inventoryKey = new NamespacedKey(Challenge.getPlugin(), "inventory_gravestone");
    private static final NamespacedKey inventoryBase64Key = new NamespacedKey(Challenge.getPlugin(), "inventory_base64_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(ItemStack[] inventory) {
        YamlConfiguration conf = new YamlConfiguration();
        String[] base64Items = new String[inventory.length];
        for (int i = 0; i < inventory.length; i++) {
            ItemStack stack = inventory[i];
            if (stack != null && stack.getItemMeta() != null) {
                if (stack.getItemMeta().hasEnchant(Enchantment.VANISHING_CURSE)) {
                    base64Items[i] = null;
                } else {
                    base64Items[i] = ItemStackUtil.getBase64StringFromItemStack(stack);
                }
            }
        }
        conf.set("inv", base64Items);
        return conf.saveToString();
    }

    public static ItemStack[] createItemArrayFromString(String yamlstring) {
        ItemStack[] inventory = new ItemStack[0];

        try {
            YamlConfiguration conf = new YamlConfiguration();
            conf.loadFromString(yamlstring);
            List<?> stacks = conf.getList("inv");
            if (stacks == null) {
                return inventory;
            }
            inventory = new ItemStack[stacks.size()];
            for (int i = 0; i < stacks.size(); i++) {
                String base64Item = (String) stacks.get(i);
                if (base64Item != null) {
                    inventory[i] = ItemStackUtil.getItemStackFromBase64(base64Item);
                } else {
                    inventory[i] = null;
                }
            }
        } catch (InvalidConfigurationException ex) {
            Challenge.getPlugin().getLogger().log(Level.SEVERE, "Error while loading yaml Config", ex);
        }
        return inventory;
    }


    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.customName(Component.text("R.I.P. ", ChatUtil.RED).append(player.name().color(ChatUtil.BLUE)));
                t.setCustomNameVisible(true);
                ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD, 1);
                SkullMeta meta = (SkullMeta) itemStack.getItemMeta();
                meta.setPlayerProfile(player.getPlayerProfile());
                itemStack.setItemMeta(meta);
                t.getEquipment().setHelmet(itemStack);
                PersistentDataContainer container = t.getPersistentDataContainer();
                container.set(UUIDKey, PersistentDataType.STRING, player.getUniqueId().toString());
                container.set(inventoryBase64Key, PersistentDataType.BYTE_ARRAY, inventoryBytes);
            });
            ChatUtil.sendMessage(player, Component.text("Dein Grabschstein steht bei:", ChatUtil.GREEN).append(Component.text(" (" + player.getLocation().getBlockX() + "/" + player.getLocation().getBlockY() + "/" + player.getLocation().getBlockZ() + ")", ChatUtil.ORANGE)));
        }
    }

    public static NamespacedKey getUUIDKey() {
        return UUIDKey;
    }

    public static NamespacedKey getInventoryKey() {
        return inventoryKey;
    }

    public static NamespacedKey getInventoryBase64Key() {
        return inventoryBase64Key;
    }
}