diff --git a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java index 906a9c87..b6765758 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java +++ b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java @@ -687,6 +687,9 @@ public final class GameModeConfig { */ public final Map, Integer> Limited; + /** */ + public final List> AllowedItems; + private SchematicConfig(YMLWrapper loader) { loaded = loader.canLoad(); Size = new SizeConfig(loader.with("Size")); @@ -706,6 +709,7 @@ public final class GameModeConfig { MaxDispenserItems = loader.getInt("MaxDispenserItems", 128); MaxBlastResistance = loader.getDouble("MaxBlastResistance", Double.MAX_VALUE); MaxDesignBlastResistance = loader.getDouble("MaxDesignBlastResistance", MaxBlastResistance); + AllowedItems = loader.withEvery("AllowedItems").stream().map(AllowedItemsConfig::new).collect(Collectors.toList()); Map, Integer> Limited = new HashMap<>(); for (Map entry : loader.getMapList("Limited")) { @@ -790,6 +794,32 @@ public final class GameModeConfig { bottom = loader.getInt("bottom", 0); } } + + public static final class AllowedItemsConfig { + /** + * The materials of the items that may be included in inventories + */ + public final List AllowedMaterials; + /** + * The materials of inventory blocks that may contain the listed items + */ + public final List AllowedIn; + /** + * The maximum amount of items of the listed items contained per inventory + */ + public final Integer MaxPerInventory; + /** + * The maximum amount of items of the listed items contained in total within all inventories + */ + public final Integer TotalMax; + + private AllowedItemsConfig(YMLWrapper loader) { + AllowedMaterials = loader.getMaterialList("AllowedMaterials"); + AllowedIn = loader.getMaterialList("AllowedIn"); + MaxPerInventory = loader.getInt("MaxPerInventory", Integer.MAX_VALUE); + TotalMax = loader.getInt("TotalMax", Integer.MAX_VALUE); + } + } } @ToString diff --git a/CommonCore/SQL/src/de/steamwar/sql/YMLWrapper.java b/CommonCore/SQL/src/de/steamwar/sql/YMLWrapper.java index 39eff9bb..221bb7fd 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/YMLWrapper.java +++ b/CommonCore/SQL/src/de/steamwar/sql/YMLWrapper.java @@ -76,6 +76,20 @@ final class YMLWrapper { return new YMLWrapper<>(false, Collections.emptyMap(), materialMapper, winconditionMapper); } + public List> withEvery(String path) { + if (document.containsKey(path)) { + Object value = document.get(path); + if(value instanceof List) { + List list = (List) value; + return list.stream().map(o -> new YMLWrapper<>(true, Collections.singletonMap("value", o), materialMapper, winconditionMapper)).collect(Collectors.toList()); + } + } + + return Collections.emptyList(); + } + + + public T get(String path, T defaultValue, Function mapper) { Object value = this.document.get(path); if (value == null) return defaultValue; diff --git a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java index 8ed1bd4c..0340606a 100644 --- a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; import de.steamwar.core.Core; +import de.steamwar.schematicsystem.autocheck.AutoChecker.InventoryScanResult; import de.steamwar.sql.GameModeConfig; import de.steamwar.sql.SchematicType; import org.bukkit.Material; @@ -50,7 +51,8 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { result.getBlockCounts().merge(material, 1, Integer::sum); if(AutoCheckerItems.impl.getInventoryMaterials().contains(material)) { - checkInventory(result, block, material, new BlockPos(x, y, z)); + InventoryScanResult inventoryResult = checkInventory(result, block, material, new BlockPos(x, y, z)); + result.getInventoryScans().put(new BlockPos(x, y, z), inventoryResult); } if(x == min.getBlockX() || x == max.getBlockX() || y == max.getBlockY() || z == min.getBlockZ() || z == max.getBlockZ()) { @@ -62,41 +64,24 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { return result; } - private static final Map> itemsInInv = new EnumMap<>(Material.class); - - static { - itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); - itemsInInv.put(Material.TNT, EnumSet.of( - Material.CHEST, Material.BARREL, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, - Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, - Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, - Material.LIGHT_GRAY_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, - Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, - Material.RED_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX - )); - itemsInInv.put(Material.FIRE_CHARGE, EnumSet.of(Material.DISPENSER)); - itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); - AutoCheckerItems.impl.getAllowedMaterialsInInventory().forEach(material -> itemsInInv.put(material, AutoCheckerItems.impl.getInventoryMaterials())); - } - - private void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { + private InventoryScanResult checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { CompoundTag nbt = block.getNbtData(); if(nbt == null) { result.getDefunctNbt().add(pos); - return; + return null; } if(material == Material.JUKEBOX && nbt.getValue().containsKey("RecordItem")){ result.getRecords().add(pos); - return; + return null; } List items = nbt.getList("Items", CompoundTag.class); if(items.isEmpty()) - return; //Leeres Inventar + return null; //Leeres Inventar - int counter = 0; + Map inventoryItemCounts = new HashMap<>(); for(CompoundTag item : items){ if(!item.containsKey("id")){ result.getDefunctNbt().add(pos); @@ -107,16 +92,18 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { if(itemType == null) //Leere Slots continue; - if (!itemsInInv.getOrDefault(itemType, EnumSet.noneOf(Material.class)).contains(material)) { - result.getForbiddenItems().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); - } else if(material == Material.DISPENSER && (itemType == Material.ARROW || itemType == Material.FIRE_CHARGE)) { - counter += Core.getVersion() >= 21 ? item.getInt("count") : item.getByte("Count"); - } + + + if (item.containsKey("tag")) { result.getForbiddenNbt().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); } + else { + int count = Core.getVersion() >= 21 ? item.getInt("count") : item.getByte("Count"); + inventoryItemCounts.merge(itemType, count, Integer::sum); + } } - result.getDispenserItems().put(pos, counter); + return new InventoryScanResult(material, inventoryItemCounts); } @Override diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java index eb464553..98a58e6e 100644 --- a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java @@ -24,6 +24,7 @@ import de.steamwar.core.VersionDependent; import de.steamwar.sql.GameModeConfig; import de.steamwar.schematicsystem.SchematicSystem; import de.steamwar.sql.SchematicType; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; import org.bukkit.Material; @@ -47,6 +48,14 @@ public class AutoChecker { AutoCheckerResult sizeCheck(Clipboard clipboard, GameModeConfig type); } + @AllArgsConstructor + @Getter + @ToString + public static class InventoryScanResult { + private final Material inventoryMaterial; + private final Map itemCounts; + } + @Getter @ToString public static class BlockScanResult { @@ -54,8 +63,7 @@ public class AutoChecker { private final List defunctNbt = new ArrayList<>(); private final List records = new ArrayList<>(); private final Map> designBlocks = new EnumMap<>(Material.class); - private final Map dispenserItems = new HashMap<>(); - private final Map> forbiddenItems = new HashMap<>(); + private final Map inventoryScans = new HashMap<>(); private final Map> forbiddenNbt = new HashMap<>(); } }