CatAttrib

CatAttrib.java v2.5
支持自定义倍率、属性标签、提示语言配置,穿戴生效优化、手持检测,仅显示手持属性,兼容大小写及多种冒号、分隔符
作者: ScriptIrc Engine
package com.scriptirc.attribchecker;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.*;

/**
 * @pluginName CatAttrib
 * @author ScriptIrc Engine
 * @version 2.5
 * @description 支持自定义倍率、属性标签、提示语言配置,穿戴生效优化、手持检测,仅显示手持属性,兼容大小写及多种冒号、分隔符
 * [command]SmileCat|检测你手持物品的全部猫属性数值
 * [command]reloadattrib|重载所有猫属性配置文件
 * [Permission]catattrib.chatdmg|显示猫属性伤害和回血提示
 */
public class CatAttrib extends JavaPlugin implements CommandExecutor, Listener {
    private Map<String, List<String>> attrSynonyms = new HashMap<>();
    private File tagsConfigFile, mainConfigFile, langConfigFile;
    private Map<String, String> langMap = new HashMap<>();
    private Map<String, Double> rateMap = new HashMap<>();
    private static final Map<String, List<String>> DEFAULT_ATTRS = new LinkedHashMap<>();
    static {
        DEFAULT_ATTRS.put("生命值", Arrays.asList("生命值", "HP", "Health"));
        DEFAULT_ATTRS.put("防御", Arrays.asList("防御", "DEF", "防御力", "Defence"));
        DEFAULT_ATTRS.put("伤害", Arrays.asList("伤害", "攻击力", "DMG", "Damage"));
        DEFAULT_ATTRS.put("暴击", Arrays.asList("暴击", "暴击率", "Crit", "Cr"));
        DEFAULT_ATTRS.put("暴击伤害", Arrays.asList("暴击伤害", "暴伤", "CritDmg", "暴击倍数"));
        DEFAULT_ATTRS.put("移动速度", Arrays.asList("移动速度", "速度", "Speed", "MoveSpeed"));
        DEFAULT_ATTRS.put("攻击速度", Arrays.asList("攻击速度", "攻速", "AttackSpeed", "AS"));
        DEFAULT_ATTRS.put("吸血", Arrays.asList("吸血", "吸血率", "Lifesteal", "生命偷取", "ls"));
    }

    @Override
    public void onEnable() {
        getCommand("SmileCat").setExecutor(this);
        getCommand("reloadattrib").setExecutor(this);
        initMainConfig();
        initAttributeTagsConfig();
        initLangConfig();
        getLogger().info("【CatAttrib】配置加载完毕,已启用。");
    }

    private void initMainConfig() {
        mainConfigFile = new File(getDataFolder(), "catattrib_config.yml");
        if (!getDataFolder().exists()) getDataFolder().mkdirs();
        boolean writeDefault = false;
        if (!mainConfigFile.exists()) writeDefault = true;
        YamlConfiguration yml = YamlConfiguration.loadConfiguration(mainConfigFile);
        if (writeDefault) {
            yml.set("critical_base", 1.0);
            yml.set("critical_per10", 0.5);
            yml.set("lifesteal_rate", 1.0);
            yml.set("damage_bonus_rate", 1.0);
            yml.set("move_speed_base", 0.2);
            yml.set("move_speed_per", 0.01);
            yml.set("attack_speed_base", 1.0);
            try { yml.save(mainConfigFile); } catch (IOException ignore) {}
        }
        rateMap.clear();
        for(String k:yml.getKeys(false)){
            rateMap.put(k, yml.getDouble(k));
        }
    }

    private void initAttributeTagsConfig() {
        tagsConfigFile = new File(getDataFolder(), "attribute_tags.yml");
        boolean writeDefault = false;
        if (!tagsConfigFile.exists()) writeDefault = true;
        YamlConfiguration yml = YamlConfiguration.loadConfiguration(tagsConfigFile);
        if (writeDefault) {
            for (Map.Entry<String, List<String>> entry : DEFAULT_ATTRS.entrySet()) {
                yml.set(entry.getKey(), entry.getValue());
            }
            try { yml.save(tagsConfigFile); } catch (IOException ignore) {}
        }
        attrSynonyms.clear();
        for (String key : DEFAULT_ATTRS.keySet()) {
            List<String> valset = yml.getStringList(key);
            if(valset==null||valset.isEmpty()) valset = DEFAULT_ATTRS.get(key);
            attrSynonyms.put(key, new ArrayList<>(valset));
        }
    }

    private void initLangConfig() {
        langConfigFile = new File(getDataFolder(), "catattrib_lang.yml");
        boolean writeDefault = false;
        if (!langConfigFile.exists()) writeDefault = true;
        YamlConfiguration yml = YamlConfiguration.loadConfiguration(langConfigFile);
        if (writeDefault) {
            yml.set("cat_check_title", "§a[猫属性检测 - 手持物品]:");
            yml.set("no_attrib", "§7你未手持具有属性的物品。");
            yml.set("reload_success", "§a[CatAttrib] 属性配置文件重载成功。");
            try { yml.save(langConfigFile); } catch(IOException ignore) {}
        }
        langMap.clear();
        for(String key : yml.getKeys(false)){
            langMap.put(key, yml.getString(key));
        }
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (label.equalsIgnoreCase("reloadattrib")) {
            initMainConfig();
            initAttributeTagsConfig();
            initLangConfig();
            sender.sendMessage(langMap.getOrDefault("reload_success","[CatAttrib] 配置文件重载成功!"));
            sender.sendMessage("§e倍率配置: "+rateMap);
            sender.sendMessage("§e属性别名: "+attrSynonyms);
            return true;
        }
        if (label.equalsIgnoreCase("SmileCat")) {
            if (!(sender instanceof Player)) {
                sender.sendMessage("喵~ 只有玩家可以检测自己的猫属性哦!");
                return true;
            }
            Player p = (Player)sender;
            ItemStack main = p.getInventory().getItemInMainHand();
            Map<String, Double> attrs = attribFromItem(main);
            p.sendMessage(langMap.getOrDefault("cat_check_title", "§a[猫属性检测 - 手持物品]:"));
            if(main == null || main.getType()==Material.AIR || attrs.isEmpty()){
                p.sendMessage(langMap.getOrDefault("no_attrib", "§7你未手持具有属性的物品。"));
                return true;
            }
            for (String k : attrSynonyms.keySet()) {
                double v = attrs.getOrDefault(k,0d);
                p.sendMessage(String.format("§e%s§f: §b%s",k,formatNum(v)));
            }
            return true;
        }
        return false;
    }

    private Map<String, Double> attribFromItem(ItemStack item) {
        Map<String, Double> at = new HashMap<>();
        if (item==null || !item.hasItemMeta() || !item.getItemMeta().hasLore()) return at;
        ItemMeta meta = item.getItemMeta();
        List<String> lore = meta.getLore();
        // 兼容全半角、所有类型“冒号”与空格分隔符,允许如“生命值:10”或“HP : 20”
        Pattern pattern = Pattern.compile("([\\u4e00-\\u9fa5A-Za-z]+)[\\s::·•.・]+([-+]?\\d+\\.?\\d*)");
        for (String line : lore) {
            String plain = line.replaceAll("§[0-9a-fk-orA-FK-OR]", "");
            Matcher m = pattern.matcher(plain);
            while (m.find()) {
                String key = m.group(1);
                String vstr = m.group(2);
                for (Map.Entry<String, List<String>> syn : attrSynonyms.entrySet()) {
                    if (syn.getValue().stream().anyMatch(alias -> alias.equalsIgnoreCase(key))) {
                        try {
                            double val = Double.parseDouble(vstr);
                            at.put(syn.getKey(), at.getOrDefault(syn.getKey(), 0d)+val);
                        } catch (Exception ignored) {}
                        break;
                    }
                }
            }
        }
        return at;
    }

    private String formatNum(double d) {
        return String.format("%.1f", d);
    }
}
上一篇: AuthSystemTutorial下一篇: ShulkerBoxDuplicate

举报内容

意见反馈