forked from SteamWar/SteamWar
Fix AutoChecker inventory rules
Count every inventory block towards exactly one Schematic.Limited rule: filled blocks towards a rule whose Content allows all their items, empty blocks towards a rule without Content (unlimited if there is none). Each rule's Amount now caps how many blocks it covers, instead of taking the highest Amount of all rules for that block type. Inventory blocks whose items fit no rule are now checked and reported, items from different rules in one block are reported as mixed, and the auto-fix trims or removes them accordingly. Remove the hardcoded wargearseason26 wind charge handling and its 2048 limit, wind charges are configured via Limited rules now. Log a warning for Limited rules that match no blocks, e.g. a misspelled 'Materials' key. Fixes #458, #481, #502
This commit is contained in:
@@ -31,6 +31,7 @@ import org.bukkit.entity.Player;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@@ -46,12 +47,12 @@ public class AutoCheckerResult {
|
||||
public boolean isOk() {
|
||||
return blockScanResult.getRecords().isEmpty() &&
|
||||
blockScanResult.getForbiddenItems().isEmpty() &&
|
||||
blockScanResult.getMixedItems().isEmpty() &&
|
||||
blockScanResult.getForbiddenNbt().isEmpty() &&
|
||||
isSizeOk() &&
|
||||
isBlockCountOk() &&
|
||||
isLimitedBlocksOK() &&
|
||||
isInventoryItemsOK() &&
|
||||
isWindchargeCountOK() &&
|
||||
!type.isAfterDeadline() &&
|
||||
entities.isEmpty() &&
|
||||
isDesignBlastResistanceOK();
|
||||
@@ -62,23 +63,8 @@ public class AutoCheckerResult {
|
||||
!type.isAfterDeadline();
|
||||
}
|
||||
|
||||
public boolean isWindchargeCountOK() {
|
||||
if (type.Schematic.Type.getName().equals("wargearseason26")) {
|
||||
int windChargesCount = blockScanResult.getWindChargeCount().values().stream().reduce(Integer::sum).orElse(0);
|
||||
return windChargesCount <= 2048;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInventoryItemsOK() {
|
||||
return blockScanResult.getInventoryItemCounts().entrySet().stream().allMatch(posEntry -> {
|
||||
Material inventory = blockScanResult.getInventoryBlockType().get(posEntry.getKey());
|
||||
return posEntry.getValue().entrySet().stream().allMatch(itemEntry -> {
|
||||
int cap = type.Schematic.getItemAmount(inventory, itemEntry.getKey());
|
||||
return itemEntry.getValue() <= cap;
|
||||
});
|
||||
});
|
||||
return blockScanResult.getTooManyItems().isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasWarnings() {
|
||||
@@ -107,7 +93,10 @@ public class AutoCheckerResult {
|
||||
|
||||
public boolean isLimitedBlocksOK() {
|
||||
return blockScanResult.getBlockCounts().entrySet().stream()
|
||||
.allMatch(entry -> entry.getValue() <= type.Schematic.getMaxCount(entry.getKey()));
|
||||
.filter(entry -> !type.Schematic.isInventory(entry.getKey()))
|
||||
.allMatch(entry -> entry.getValue() <= type.Schematic.getMaxCount(entry.getKey())) &&
|
||||
blockScanResult.getRuleCounts().entrySet().stream()
|
||||
.allMatch(entry -> entry.getValue() <= entry.getKey().Amount);
|
||||
}
|
||||
|
||||
public boolean isDesignBlastResistanceOK() {
|
||||
@@ -132,6 +121,7 @@ public class AutoCheckerResult {
|
||||
}
|
||||
if (!isLimitedBlocksOK()) {
|
||||
blockScanResult.getBlockCounts().forEach((mat, count) -> {
|
||||
if (type.Schematic.isInventory(mat)) return;
|
||||
int maxCount = type.Schematic.getMaxCount(mat);
|
||||
if (count > maxCount) {
|
||||
if (maxCount == 0) {
|
||||
@@ -141,30 +131,25 @@ public class AutoCheckerResult {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!isWindchargeCountOK()) {
|
||||
int windChargesCount = blockScanResult.getWindChargeCount().values().stream().reduce(Integer::sum).orElse(0);
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_WIND_CHARGES", p, windChargesCount, 2048);
|
||||
blockScanResult.getWindChargeCount().entrySet().stream().filter(blockVector3IntegerEntry -> blockVector3IntegerEntry.getValue() > 0).forEach(blockVector3IntegerEntry -> {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_WIND_CHARGES_DISPENSER", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3IntegerEntry.getKey()),
|
||||
blockVector3IntegerEntry.getKey().getBlockX(),
|
||||
blockVector3IntegerEntry.getKey().getBlockY(),
|
||||
blockVector3IntegerEntry.getKey().getBlockZ(),
|
||||
blockVector3IntegerEntry.getValue());
|
||||
blockScanResult.getRuleCounts().forEach((rule, count) -> {
|
||||
if (count <= rule.Amount) return;
|
||||
String blocks = blockScanResult.getRuleBlockTypes().get(rule).stream().map(Material::name).collect(Collectors.joining(", "));
|
||||
if (rule.Amount == 0) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_BLOCK", p, blocks);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_TOO_MANY_BLOCK", p, blocks, count, rule.Amount);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
blockScanResult.getInventoryItemCounts().forEach((pos, itemCounts) -> {
|
||||
blockScanResult.getTooManyItems().forEach((pos, caps) -> {
|
||||
Material inventory = blockScanResult.getInventoryBlockType().get(pos);
|
||||
itemCounts.forEach((itemType, count) -> {
|
||||
int cap = type.Schematic.getItemAmount(inventory, itemType);
|
||||
if (count <= cap) return;
|
||||
caps.forEach((itemType, cap) -> {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_TOO_MANY_INVENTORY_ITEMS", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(pos),
|
||||
pos.getBlockX(),
|
||||
pos.getBlockY(),
|
||||
pos.getBlockZ(),
|
||||
count,
|
||||
blockScanResult.getInventoryItemCounts().get(pos).get(itemType),
|
||||
cap,
|
||||
itemType.name(),
|
||||
inventory.name());
|
||||
@@ -177,6 +162,9 @@ public class AutoCheckerResult {
|
||||
blockScanResult.getForbiddenItems().forEach((blockVector3, materials) -> {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_ITEM", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ(), setToString(materials));
|
||||
});
|
||||
blockScanResult.getMixedItems().forEach((blockVector3, materials) -> {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_MIXED_ITEMS", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ(), setToString(materials));
|
||||
});
|
||||
blockScanResult.getForbiddenNbt().forEach((blockVector3, materials) -> {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_ITEM_NBT", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ(), setToString(materials));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user