夜雨晨风丶
本帖最后由 夜雨晨风丶 于 2023-3-3 10:19 编辑

  1. public static List<String> protectItems = new ArrayList<>();
  2. public static void loadProtectItems() {
  3.         ItemsProtect ip = ItemsProtect.getInstance();
  4.         List<String> Items = ip.getConfig().getStringList("protectItems");
  5.         //判断物品是否符合bukkit材料名称,是则添加到集合中
  6.         List<String> itemsTemp = new ArrayList<>();
  7.         for (String item : Items) {
  8.             Material material = Material.getMaterial(item.toUpperCase());
  9.             if (material != null) {
  10.                 itemsTemp.add(item.toUpperCase());
  11.             }
  12.         }
  13.         protectItems = itemsTemp;
  14.         if(debug) {
  15.             System.out.println("protectItems的内容是: " + protectItems);
  16.         }
  17.     }

复制代码


以上是获取配置文件物品,以下是配置文件的内容(萌新开发,代码稀碎,如果大佬有更好的方法去获取并检测物品是否符合希望能教教)


  1. protectItems:
  2.   - diamond
  3.   - nether_star
  4.   - gold_block
  5.   - coal
复制代码



  1. public boolean isProtectItem(Item item) {
  2.         if(ipData.debug) {
  3.             System.out.println(ipData.protectItems);
  4.             System.out.println(ipData.protectItems.contains(item.getType().name()));
  5.         }
  6.         return ipData.protectItems.contains(item.getType().name());
  7.     }
复制代码
为什么这个判断返回的结果是false,后台输出的内容是
[05:32:36] [Server thread/INFO]: protectItems的内容是: [DIAMOND, NETHER_STAR, GOLD_BLOCK, COAL]
[05:32:39] [Server thread/INFO]: EntityDamageEvent中的itemName为:DIAMOND
[05:32:39] [Server thread/INFO]: false

不要在意下面缺少的花括号,因为这只是部分代码(
  1. public void onItemDamaged(EntityDamageEvent e) {

  2.     Entity entity = e.getEntity();

  3.     //如果实体是物品类型
  4.     if(entity instanceof Item) {
  5.         Item item = (Item) e.getEntity();
  6.         String itemName = ((Item) entity).getItemStack().getType().name();
  7.         boolean debug = ipData.debug;
  8.         if(debug) {
  9.             System.out.println("EntityDamageEvent中的itemName为:" + itemName);
  10.         }
  11.         //如果是物品掉落岩浆
  12.         if(e.getCause().equals(EntityDamageEvent.DamageCause.LAVA)) {
  13.             //如果消失的物品在列表内并且开启了LAVA保护,取消本次事件
  14.             if(ipData.LAVA && isProtectItem(item)) {
  15.                 e.setCancelled(true);
  16.                 if(debug) {
  17.                     System.out.println("保护了" + itemName + "免受岩浆破坏");
  18.                 }
复制代码


结冰的离季
本帖最后由 结冰的离季 于 2023-3-2 12:54 编辑

protectItems 配置是小写  getItemStack().getType().name()是大写,怎么匹配,
另外推荐使用HashSet ,往集合加字符串可以统一进行toLowerCase() ,查询也是
判断材质最好是 直接使用 HashSet<Material> 可以直接进行判断,读取配置的时候进行材质校验,忽略非法材质名称


夜雨晨风丶
结冰的离季 发表于 2023-3-2 12:52
protectItems 配置是小写  getItemStack().getType().name()是大写,怎么匹配,
另外推荐使用HashSet ,往 ...

但是我在获取之后不是进行了大写转换吗itemsTemp.add(item.toUpperCase());
输出的集合内容确实是大写?protectItems的内容是: [DIAMOND, NETHER_STAR, GOLD_BLOCK, COAL]

结冰的离季
夜雨晨风丶 发表于 2023-3-2 12:54
但是我在获取之后不是进行了大写转换吗itemsTemp.add(item.toUpperCase());
输出的集合内容确实是大写?p ...

你这没给上下文,我只能说可能存在的问题
一个是 你存入List的是 diamond 虽然通过 Material进行校验了,但是一个Material是可能有别名的 比如 LEGACY_DIAMOND 所以,所以存 diamond 不准确
另一个是这个List的contains方法的代码实现可能与你想象的不一样
还有一个是你获得的List不是同一个List

反正做物品黑白名单之类的我都建议用 HashSet<Material>() ,线程安全的就用  Set<Material> set = ConcurrentHashMap.newKeySet()

第一页 上一页 下一页 最后一页