forked from SteamWar/SteamWar
199 lines
10 KiB
Java
199 lines
10 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package de.steamwar.schematicsystem.autocheck;
|
|
|
|
import de.steamwar.core.Core;
|
|
import de.steamwar.schematicsystem.SchematicSystem;
|
|
import de.steamwar.sql.GameModeConfig;
|
|
import lombok.Builder;
|
|
import lombok.Getter;
|
|
import lombok.ToString;
|
|
import net.md_5.bungee.api.chat.ClickEvent;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
@Builder
|
|
@Getter
|
|
@ToString
|
|
public class AutoCheckerResult {
|
|
private final GameModeConfig<Material, String> type;
|
|
private final int width;
|
|
private final int height;
|
|
private final int depth;
|
|
private final AutoChecker.BlockScanResult blockScanResult;
|
|
private final List<BlockPos> entities;
|
|
|
|
public boolean isOk() {
|
|
return blockScanResult.getRecords().isEmpty() &&
|
|
blockScanResult.getForbiddenItems().isEmpty() &&
|
|
blockScanResult.getForbiddenNbt().isEmpty() &&
|
|
isSizeOk() &&
|
|
isBlockCountOk() &&
|
|
isLimitedBlocksOK() &&
|
|
isDispenserItemsOK() &&
|
|
isWindchargeCountOK() &&
|
|
!type.isAfterDeadline() &&
|
|
entities.isEmpty() &&
|
|
isDesignBlastResistanceOK();
|
|
}
|
|
|
|
public boolean fastOk() {
|
|
return isSizeOk() &&
|
|
!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 isDispenserItemsOK() {
|
|
return blockScanResult.getDispenserItems().values().stream().allMatch(i -> i <= type.Schematic.MaxDispenserItems);
|
|
}
|
|
|
|
public boolean hasWarnings() {
|
|
return blockScanResult.getDefunctNbt().isEmpty();
|
|
}
|
|
|
|
public boolean isSizeOk() {
|
|
return !isTooWide() && !isTooHigh() && !isTooDeep();
|
|
}
|
|
|
|
public boolean isTooWide() {
|
|
return width > type.Schematic.Size.x;
|
|
}
|
|
|
|
public boolean isTooHigh() {
|
|
return height > type.Schematic.Size.y;
|
|
}
|
|
|
|
public boolean isTooDeep() {
|
|
return depth > type.Schematic.Size.z;
|
|
}
|
|
|
|
public boolean isBlockCountOk() {
|
|
return type.Schematic.MaxBlocks == 0 || blockScanResult.getBlockCounts().entrySet().stream().filter(entry -> entry.getKey() != Material.AIR).map(Map.Entry::getValue).reduce(Integer::sum).map(i -> i <= type.Schematic.MaxBlocks).orElse(false);
|
|
}
|
|
|
|
public boolean isLimitedBlocksOK() {
|
|
try {
|
|
return type.Schematic.Limited.entrySet().stream()
|
|
.map(setIntegerEntry -> setIntegerEntry.getKey().stream().map(blockScanResult.getBlockCounts()::get).map(i -> i == null || i <= setIntegerEntry.getValue()).reduce(Boolean::logicalAnd).orElse(false))
|
|
.reduce(Boolean::logicalAnd).orElse(true);
|
|
} catch (NullPointerException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public boolean isDesignBlastResistanceOK() {
|
|
return blockScanResult.getDesignBlocks().keySet().stream()
|
|
.filter(material -> material != Material.WATER && material != Material.LAVA)
|
|
.map(Material::getBlastResistance).noneMatch(i -> i > type.Schematic.MaxDesignBlastResistance);
|
|
}
|
|
|
|
public void sendErrorMessage(Player p, String schemName) {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_HEADER", p, schemName);
|
|
if(isTooWide()) SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_WIDTH", p, width, type.Schematic.Size.x);
|
|
if(isTooHigh()) SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_HEIGHT", p, height, type.Schematic.Size.y);
|
|
if(isTooDeep()) SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_LENGTH", p, depth, type.Schematic.Size.z);
|
|
if(type.Schematic.MaxBlocks != 0 && !isBlockCountOk()) {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_BLOCKS", p, blockScanResult.getBlockCounts().values().stream().reduce(Integer::sum).orElse(0), type.Schematic.MaxBlocks);
|
|
}
|
|
if(!isLimitedBlocksOK()) {
|
|
type.Schematic.Limited.forEach((materials, integer) -> {
|
|
for (Material mat : materials) {
|
|
if(mat != null && blockScanResult.getBlockCounts().getOrDefault(mat, 0) > integer) {
|
|
if(integer == 0) {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_BLOCK", p, mat.name());
|
|
} else {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_TOO_MANY_BLOCK", p, mat.name(), blockScanResult.getBlockCounts().getOrDefault(mat, 0), integer);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
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.getDispenserItems().entrySet().stream().filter(blockVector3IntegerEntry -> blockVector3IntegerEntry.getValue() > type.Schematic.MaxDispenserItems).forEach(blockVector3IntegerEntry -> {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_TOO_MANY_DISPENSER_ITEMS", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3IntegerEntry.getKey()),
|
|
blockVector3IntegerEntry.getKey().getBlockX(),
|
|
blockVector3IntegerEntry.getKey().getBlockY(),
|
|
blockVector3IntegerEntry.getKey().getBlockZ(),
|
|
blockVector3IntegerEntry.getValue(),
|
|
type.Schematic.MaxDispenserItems);
|
|
});
|
|
|
|
blockScanResult.getRecords().forEach(blockVector3 -> {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_RECORD", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ());
|
|
});
|
|
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.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));
|
|
});
|
|
blockScanResult.getDefunctNbt().forEach(blockVector3 -> {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_DEFUNCT_NBT", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
|
});
|
|
blockScanResult.getDesignBlocks().forEach((material, poss) -> {
|
|
if (material == Material.WATER || material == Material.LAVA) return;
|
|
if(material.getBlastResistance() > type.Schematic.MaxDesignBlastResistance) {
|
|
poss.forEach(pos -> {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_DESIGN_BLOCK", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(pos), material.name(), pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
|
});
|
|
}
|
|
});
|
|
entities.forEach(blockPos -> {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_ENTITY", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockPos), blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
|
});
|
|
if(type.isAfterDeadline()) {
|
|
SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_AFTER_DEADLINE", p, type.Deadline);
|
|
}
|
|
}
|
|
|
|
private static ClickEvent tpCommandTo(BlockPos pos) {
|
|
return new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + pos.getBlockX() + " " + pos.getBlockY() + " " + pos.getBlockZ());
|
|
}
|
|
|
|
private static String setToString(Collection<Material> set) {
|
|
return set.stream().map(material -> material.getKey().getKey()).reduce((s, s2) -> s + "§7, §c" + s2).orElse("");
|
|
}
|
|
}
|