forked from SteamWar/SteamWar
Cleanup SchematicSystem
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SafeSchematicNode {
|
||||
|
||||
public static Result setParent(@NonNull SteamwarUser user, @NonNull SchematicNode node, SchematicNode newParent) {
|
||||
if(user.getId() != node.getOwner()) {
|
||||
return Result.NOT_OWNER;
|
||||
}
|
||||
if(newParent == null) {
|
||||
if(SchematicNode.list(user, null)
|
||||
.stream().map(SchematicNode::getName).anyMatch(s -> s.equalsIgnoreCase(node.getName()))) {
|
||||
return Result.ALREADY_IN_DIRECTORY;
|
||||
}
|
||||
|
||||
node.setParent(null);
|
||||
} else {
|
||||
if(!newParent.isDir()) {
|
||||
return Result.NOT_A_DIR;
|
||||
}
|
||||
|
||||
if(SchematicNode.list(user, newParent.getId())
|
||||
.stream().map(SchematicNode::getName).anyMatch(s -> s.equalsIgnoreCase(node.getName()))) {
|
||||
return Result.ALREADY_IN_DIRECTORY;
|
||||
}
|
||||
|
||||
node.setParent(newParent.getId());
|
||||
}
|
||||
return Result.DONE;
|
||||
}
|
||||
|
||||
public static Result setName(@NonNull SteamwarUser user, @NonNull SchematicNode node, @NonNull String name) {
|
||||
if(user.getId() != node.getOwner()) {
|
||||
return Result.NOT_OWNER;
|
||||
}
|
||||
|
||||
if(SchematicNode.invalidSchemName(new String[]{name})) {
|
||||
return Result.INVALID_NAME;
|
||||
}
|
||||
|
||||
if(SchematicNode.list(user, node.getParent()).stream().map(SchematicNode::getName).anyMatch(s -> s.equalsIgnoreCase(name))) {
|
||||
return Result.ALREADY_IN_DIRECTORY;
|
||||
}
|
||||
|
||||
node.setName(name);
|
||||
return Result.DONE;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum Result {
|
||||
DONE,
|
||||
NOT_A_DIR,
|
||||
ALREADY_IN_DIRECTORY,
|
||||
INVALID_NAME,
|
||||
NOT_OWNER;
|
||||
|
||||
public void sendError(Player player) {
|
||||
SchematicSystem.MESSAGE.send("SAFE_NODE_" + this.name(), player);
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return this == DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import de.steamwar.linkage.AbstractLinker;
|
||||
import de.steamwar.linkage.SpigotLinker;
|
||||
import de.steamwar.message.Message;
|
||||
import de.steamwar.sql.GameModeConfig;
|
||||
import de.steamwar.sql.SchematicType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class SchematicSystem extends JavaPlugin {
|
||||
public static final Message MESSAGE = new Message("SchematicSystem", SchematicSystem.class.getClassLoader());
|
||||
|
||||
private static SchematicSystem instance;
|
||||
|
||||
public static GameModeConfig<Material, String> getGameModeConfig(SchematicType type){
|
||||
GameModeConfig<Material, String> gameModeConfig = GameModeConfig.getBySchematicType(type);
|
||||
if (gameModeConfig == null) return null;
|
||||
if (gameModeConfig.CheckQuestions.isEmpty() && gameModeConfig.Schematic.ManualCheck) return null;
|
||||
return gameModeConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
SpigotLinker spigotLinker = new SpigotLinker(this, MESSAGE);
|
||||
try {
|
||||
spigotLinker.link();
|
||||
} catch (AbstractLinker.LinkException e) {
|
||||
e.printStackTrace();
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static SchematicSystem getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
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.sql.GameModeConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AutoChecker {
|
||||
|
||||
public static final AutoChecker impl = new AutoChecker();
|
||||
|
||||
public AutoCheckerResult check(Clipboard clipboard, GameModeConfig<Material, String> type) {
|
||||
return AutoCheckerResult.builder().type(type).height(clipboard.getDimensions().getBlockY()).width(clipboard.getDimensions().getBlockX())
|
||||
.depth(clipboard.getDimensions().getBlockZ()).blockScanResult(scan(clipboard, type))
|
||||
.entities(clipboard.getEntities().stream().map(Entity::getLocation)
|
||||
.map(blockVector3 -> new BlockPos(blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ()))
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public AutoCheckerResult sizeCheck(Clipboard clipboard, GameModeConfig<Material, String> type) {
|
||||
return AutoCheckerResult.builder().type(type).height(clipboard.getDimensions().getBlockY()).width(clipboard.getDimensions().getBlockX())
|
||||
.depth(clipboard.getDimensions().getBlockZ()).build();
|
||||
}
|
||||
|
||||
public AutoChecker.BlockScanResult scan(Clipboard clipboard, GameModeConfig<Material, String> type) {
|
||||
AutoChecker.BlockScanResult result = new AutoChecker.BlockScanResult();
|
||||
BlockVector3 min = clipboard.getMinimumPoint();
|
||||
BlockVector3 max = clipboard.getMaximumPoint();
|
||||
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
|
||||
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||
final BaseBlock block = clipboard.getFullBlock(BlockVector3.at(x, y, z));
|
||||
final Material material = Material.matchMaterial(block.getBlockType().getId());
|
||||
if (material == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.getBlockCounts().merge(material, 1, Integer::sum);
|
||||
|
||||
if (AutoCheckerItems.impl.getInventoryMaterials().contains(material)) {
|
||||
checkInventory(result, block, material, new BlockPos(x, y, z), type);
|
||||
}
|
||||
|
||||
if (x == min.getBlockX() || x == max.getBlockX() || y == max.getBlockY() || z == min.getBlockZ() || z == max.getBlockZ()) {
|
||||
result.getDesignBlocks().computeIfAbsent(material, m -> new ArrayList<>()).add(new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final Map<Material, Set<Material>> 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, GameModeConfig<Material, String> type) {
|
||||
CompoundTag nbt = block.getNbtData();
|
||||
if (nbt == null) {
|
||||
result.getDefunctNbt().add(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (material == Material.JUKEBOX && nbt.getValue().containsKey("RecordItem")) {
|
||||
result.getRecords().add(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
List<CompoundTag> items = nbt.getList("Items", CompoundTag.class);
|
||||
if (items.isEmpty())
|
||||
return; // Leeres Inventar
|
||||
|
||||
int counter = 0;
|
||||
int windChargeCount = 0;
|
||||
for (CompoundTag item : items) {
|
||||
if (!item.containsKey("id")) {
|
||||
result.getDefunctNbt().add(pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
Material itemType = Material.matchMaterial(item.getString("id"));
|
||||
if (itemType == null) // Leere Slots
|
||||
continue;
|
||||
|
||||
if(type.Schematic.Type.getName().equals("wargearseason26") && material == Material.DISPENSER && itemType == Material.WIND_CHARGE) {
|
||||
windChargeCount += item.getInt("count");
|
||||
}
|
||||
else 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);
|
||||
}
|
||||
}
|
||||
result.getDispenserItems().put(pos, counter);
|
||||
result.getWindChargeCount().put(pos, windChargeCount);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public static class BlockScanResult {
|
||||
private final Map<Material, Integer> blockCounts = new EnumMap<>(Material.class);
|
||||
private final List<BlockPos> defunctNbt = new ArrayList<>();
|
||||
private final List<BlockPos> records = new ArrayList<>();
|
||||
private final Map<Material, List<BlockPos>> designBlocks = new EnumMap<>(Material.class);
|
||||
private final Map<BlockPos, Integer> dispenserItems = new HashMap<>();
|
||||
private final Map<BlockPos, Integer> windChargeCount = new HashMap<>();
|
||||
private final Map<BlockPos, Set<Material>> forbiddenItems = new HashMap<>();
|
||||
private final Map<BlockPos, Set<Material>> forbiddenNbt = new HashMap<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 org.bukkit.Material;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class AutoCheckerItems {
|
||||
|
||||
public static final AutoCheckerItems impl = new AutoCheckerItems();
|
||||
|
||||
private static final Set<Material> INVENTORY = EnumSet.of(Material.BARREL, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CAMPFIRE,
|
||||
Material.CHEST, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.JUKEBOX, Material.SHULKER_BOX,
|
||||
Material.WHITE_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX,
|
||||
Material.LIME_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.CYAN_SHULKER_BOX,
|
||||
Material.PURPLE_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.RED_SHULKER_BOX,
|
||||
Material.BLACK_SHULKER_BOX, Material.SMOKER, Material.TRAPPED_CHEST);
|
||||
|
||||
private static final Set<Material> FLOWERS = EnumSet.of(Material.CORNFLOWER, Material.POPPY, Material.FERN, Material.DANDELION, Material.BLUE_ORCHID,
|
||||
Material.ALLIUM, Material.AZURE_BLUET, Material.RED_TULIP, Material.ORANGE_TULIP, Material.WHITE_TULIP, Material.PINK_TULIP, Material.OXEYE_DAISY,
|
||||
Material.LILY_OF_THE_VALLEY, Material.WITHER_ROSE, Material.SUNFLOWER, Material.DIAMOND_HORSE_ARMOR, Material.IRON_HORSE_ARMOR,
|
||||
Material.GOLDEN_HORSE_ARMOR, Material.LEATHER_HORSE_ARMOR, Material.HONEY_BOTTLE, Material.LILAC, Material.ROSE_BUSH, Material.PEONY,
|
||||
Material.TALL_GRASS, Material.LARGE_FERN);
|
||||
|
||||
public Set<Material> getInventoryMaterials() {
|
||||
return INVENTORY;
|
||||
}
|
||||
|
||||
public Set<Material> getAllowedMaterialsInInventory() {
|
||||
return FLOWERS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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());
|
||||
});
|
||||
if(Core.getVersion() > 12) {
|
||||
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("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
/*
|
||||
* Can be removed with 1.12 support removal
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class BlockPos {
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
|
||||
public int getBlockX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getBlockY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getBlockZ() {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.commands;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Linked
|
||||
public class DownloadCommand extends SWCommand {
|
||||
public DownloadCommand() {
|
||||
super("download", "/download");
|
||||
}
|
||||
|
||||
@Register(help = true)
|
||||
public void genericCommand(Player player, String... args) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", (Integer) null);
|
||||
boolean newSchem = false;
|
||||
if (copyNode == null) {
|
||||
copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", null, SchematicType.Normal.toDB(), "");
|
||||
newSchem = true;
|
||||
}
|
||||
|
||||
try {
|
||||
SchematicData.saveFromPlayer(player, copyNode);
|
||||
} catch (IOException e) {
|
||||
SchematicSystem.MESSAGE.send("DOWNLOAD_ERROR", player);
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
throw new SecurityException(e);
|
||||
} catch (NoClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_CLIPBOARD_EMPTY", player);
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SchematicCommandUtils.download(player, copyNode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.data.CMDs;
|
||||
import de.steamwar.inventory.*;
|
||||
import de.steamwar.schematicsystem.SafeSchematicNode;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoChecker;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.getUser;
|
||||
|
||||
public class GUI {
|
||||
private GUI() {}
|
||||
|
||||
public static void list(Player player) {
|
||||
SchematicSelector selector = new SchematicSelector(player, SchematicSelector.selectSchematic(), new SchematicSelectorInjectable() {
|
||||
@Override
|
||||
public String createTitle(Player player) {
|
||||
return SchematicSystem.MESSAGE.parse("GUI_TITLE", player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListRender(SchematicSelector selector, SWListInv<SchematicNode> inv, SchematicNode parent) {
|
||||
inv.setCallback(-999, (ClickType click) -> {
|
||||
if(parent == null) {
|
||||
player.closeInventory();
|
||||
} else {
|
||||
selector.reOpenDirUp();
|
||||
}
|
||||
});
|
||||
if(parent == null) {
|
||||
inv.setItem(49, Material.AIR, "", clickType -> {});
|
||||
} else {
|
||||
inv.setItem(49, Material.ANVIL, SchematicSystem.MESSAGE.parse("GUI_FOLDER_PROPERTIES", player), clickType -> {
|
||||
info(selector.getPlayer(), parent, selector);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnvilInvCloseAction onAnvilInvCloseAction(SchematicSelector selector) {
|
||||
return AnvilInvCloseAction.REOPEN;
|
||||
}
|
||||
}, node -> {});
|
||||
selector.setCallback(node -> info(player, node, selector));
|
||||
selector.setSingleDirOpen(false);
|
||||
selector.open();
|
||||
}
|
||||
|
||||
private static void setCloseLeftCallback(SWAnvilInv inv, Runnable action) {
|
||||
AtomicBoolean left = new AtomicBoolean(false);
|
||||
inv.addCloseCallback(() -> {
|
||||
if(!left.get()) {
|
||||
Bukkit.getScheduler().runTaskLater(SchematicSystem.getInstance(), action, 1);
|
||||
}
|
||||
});
|
||||
inv.addLeftCallback(() -> {
|
||||
left.set(true);
|
||||
action.run();
|
||||
});
|
||||
}
|
||||
|
||||
private static void info(Player player, SchematicNode node, SchematicSelector back) {
|
||||
SteamwarUser user = getUser(player);
|
||||
SWInventory inv = new SWInventory(player, 9 * 2, node.generateBreadcrumbs(user));
|
||||
if(!node.isDir()) {
|
||||
inv.setItem(0, SWItem.getMaterial("WOOD_AXE"), SchematicSystem.MESSAGE.parse("GUI_INFO_LOAD", player), Arrays.asList(
|
||||
SchematicSystem.MESSAGE.parse("GUI_LOAD_LATEST", player),
|
||||
SchematicSystem.MESSAGE.parse("GUI_LOAD_REVISION", player)
|
||||
), false, click -> {
|
||||
if (click.isLeftClick()) {
|
||||
player.closeInventory();
|
||||
SchematicCommandUtils.loadSchem(player, node, -1);
|
||||
} else if (click.isRightClick()) {
|
||||
List<SWListInv.SWListEntry<Integer>> entries = new ArrayList<>();
|
||||
List<NodeData> datas = NodeData.get(node);
|
||||
for (int i = 0; i < datas.size(); i++) {
|
||||
entries.add(new SWListInv.SWListEntry<>(new SWItem(SWItem.getMaterial(node.getItem()), "§e" + SchematicSystem.MESSAGE.parse("BLANK", player, datas.get(i).getCreatedAt())), i));
|
||||
}
|
||||
|
||||
SWListInv<Integer> listInv = new SWListInv<>(player, SchematicSystem.MESSAGE.parse("GUI_LOAD_REVISION_TITLE", player, node.generateBreadcrumbs(user)), entries, (clickType, revision) -> {
|
||||
if(revision == null) return;
|
||||
player.closeInventory();
|
||||
SchematicCommandUtils.loadSchem(player, node, revision);
|
||||
});
|
||||
listInv.setCallback(-999, click2 -> player.closeInventory());
|
||||
listInv.open();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
inv.setItem(9, new SWItem(SWItem.getMaterial("LEASH"), SchematicSystem.MESSAGE.parse("GUI_INFO_BACK", player), clickType -> {
|
||||
back.reOpen();
|
||||
}).setCustomModelData(CMDs.Schematic.BACK));
|
||||
|
||||
if(node.getOwner() == user.getId()){
|
||||
if(!node.isDir() && node.getSchemtype().writeable()){
|
||||
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic ->
|
||||
inv.setItem(1, SWItem.getDye(10), (byte) 10, SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS", player, node.getSchemtype().name()), Collections.singletonList(SchematicSystem.MESSAGE.parse("GUI_INFO_STATUS_LORE", player, checkedSchematic.getDeclineReason().replaceAll("&", "§"))), false, click -> {}));
|
||||
}
|
||||
Material mat = SWItem.getMaterial(node.getItem());
|
||||
|
||||
inv.setItemEvent(node.isDir()?7:5, mat, SchematicSystem.MESSAGE.parse("GUI_INFO_MAT", player, mat.name()), Arrays.asList(SchematicSystem.MESSAGE.parse("CHANGE", player), SchematicSystem.MESSAGE.parse("CLICK_DRAG_ITEM", player)), false, event -> {
|
||||
if(event.getCursor() != null && event.getCursor().getType() != Material.AIR) {
|
||||
node.setItem(event.getCursor().getType().name());
|
||||
info(player, node, back);
|
||||
} else {
|
||||
changeItem(player, node, back);
|
||||
}
|
||||
});
|
||||
if(!node.isDir()) {
|
||||
inv.setItem(6, SWItem.getMaterial(node.getSchemtype().getMaterial()), SchematicSystem.MESSAGE.parse("GUI_INFO_TYPE", player, node.getSchemtype().name()), Arrays.asList(SchematicSystem.MESSAGE.parse("CHANGE", player), SchematicSystem.MESSAGE.parse("CLICK", player)), node.getSchemtype().fightType(), click -> {
|
||||
changeType(player, node);
|
||||
});
|
||||
inv.setItem(7, SWItem.getMaterial("MAGENTA_GLAZED_TERRACOTTA"), SchematicSystem.MESSAGE.parse("GUI_INFO_DOWNLOAD", player), click -> {
|
||||
player.closeInventory();
|
||||
SchematicCommandUtils.download(player, node);
|
||||
});
|
||||
if(node.getSchemtype().fightType()) {
|
||||
inv.setItem(14, SWItem.getMaterial(node.replaceColor() ? "PINK_WOOL" : "LIGHT_GRAY_WOOL"), SchematicSystem.MESSAGE.parse("GUI_INFO_COLOR", player), Arrays.asList(SchematicSystem.MESSAGE.parse("CURRENT", player, SchematicSystem.MESSAGE.parse(node.replaceColor()?"ON":"OFF", player)), SchematicSystem.MESSAGE.parse("CHANGE", player), SchematicSystem.MESSAGE.parse("CLICK", player)), false, clickType -> {
|
||||
node.setReplaceColor(!node.replaceColor());
|
||||
info(player, node, back);
|
||||
});
|
||||
inv.setItem(13, SWItem.getMaterial(node.allowReplay() ? "EYE_OF_ENDER" : "ENDER_PEARL"), SchematicSystem.MESSAGE.parse("GUI_INFO_REPLAY", player), Arrays.asList(SchematicSystem.MESSAGE.parse("CURRENT", player, SchematicSystem.MESSAGE.parse(node.allowReplay()?"ON":"OFF", player)), SchematicSystem.MESSAGE.parse("GUI_INFO_REPLAY_OFF", player), SchematicSystem.MESSAGE.parse("CLICK", player)), false, clickType -> {
|
||||
if(node.allowReplay()) {
|
||||
SWInventory confInv = new SWInventory(player, 9, SchematicSystem.MESSAGE.parse("GUI_INFO_REPLAY_TITLE", player));
|
||||
confInv.setItem(0, SWItem.getDye(10), (byte) 10, SchematicSystem.MESSAGE.parse("CONFIRM", player), type -> {
|
||||
node.setAllowReplay(false);
|
||||
info(player, node, back);
|
||||
});
|
||||
confInv.setItem(8, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("CANCEL", player), type -> {
|
||||
info(player, node, back);
|
||||
});
|
||||
confInv.open();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
SWItem skull = SWItem.getPlayerSkull("MHF_STEVE");
|
||||
skull.setCallback(click -> {
|
||||
player.closeInventory();
|
||||
delmembers(player, node);
|
||||
});
|
||||
skull.setName(SchematicSystem.MESSAGE.parse("GUI_INFO_MEMBER", player));
|
||||
inv.setItem(8, skull);
|
||||
inv.setItem(16, Material.NAME_TAG, SchematicSystem.MESSAGE.parse("GUI_INFO_RENAME", player), clickType -> {
|
||||
SWAnvilInv anvilInv = new SWAnvilInv(player, SchematicSystem.MESSAGE.parse("GUI_INFO_RENAME_TITLE", player, node.getName()), node.getName());
|
||||
anvilInv.setItem(mat, Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_CLICK_BACK", player)), false);
|
||||
anvilInv.setCallback(s -> {
|
||||
SafeSchematicNode.Result result = SafeSchematicNode.setName(user, node, s);
|
||||
if(result.isSuccessful()) {
|
||||
info(player, SchematicNode.byIdAndUser(user, node.getId()), back);
|
||||
} else {
|
||||
result.sendError(player);
|
||||
}
|
||||
});
|
||||
setCloseLeftCallback(anvilInv, () -> info(player, node, back));
|
||||
anvilInv.open();
|
||||
});
|
||||
if(node.getOwner() != 0) {
|
||||
inv.setItem(17, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("GUI_INFO_DELETE", player), click -> {
|
||||
delete(player, node, back);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
if(!node.isDir()) {
|
||||
inv.setItem(4, SWItem.getMaterial("CAULDRON_ITEM"), SchematicSystem.MESSAGE.parse("GUI_INFO_TYPE", player, node.getSchemtype().name()), Collections.emptyList(), node.getSchemtype().fightType(), click -> {});
|
||||
}
|
||||
|
||||
SteamwarUser owneruser = SteamwarUser.byId(node.getOwner());
|
||||
SWItem skull = SWItem.getPlayerSkull(owneruser.getUserName());
|
||||
skull.setName(SchematicSystem.MESSAGE.parse("GUI_INFO_MEMBER_FROM", player, owneruser.getUserName()));
|
||||
inv.setItem(8, skull.getItemStack(), clickType -> {});
|
||||
|
||||
if(NodeMember.getNodeMember(node.getId(), user.getId()) != null) {
|
||||
inv.setItem(17, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("GUI_INFO_MEMBER_REMOVE", player), click -> {
|
||||
delete(player, node, back);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(node.getOwner() == user.getId() || NodeMember.getNodeMember(node.getId(), user.getId()) != null) {
|
||||
inv.setItem(15, Material.ARROW, SchematicSystem.MESSAGE.parse("GUI_INFO_MOVE", player), clickType -> {
|
||||
SchematicSelector selector = new SchematicSelector(player, SchematicSelector.selectDirectory(), npar -> {
|
||||
if(npar != null && SchematicNode.parentsOfNode(user, npar.getId()).stream().anyMatch(n -> n.getId() == node.getId())) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_MOVE_RECURSIVE", player);
|
||||
return;
|
||||
}
|
||||
if(node.getOwner() == user.getId()) {
|
||||
SafeSchematicNode.Result result = SafeSchematicNode.setParent(user, node, npar);
|
||||
if(result.isSuccessful()) {
|
||||
info(player, SchematicNode.getSchematicNode(node.getId()), back);
|
||||
} else {
|
||||
result.sendError(player);
|
||||
}
|
||||
} else {
|
||||
NodeMember.getNodeMember(node.getId(), user.getId()).setParentId(Optional.ofNullable(npar).map(SchematicNode::getId).orElse(null));
|
||||
}
|
||||
});
|
||||
selector.open();
|
||||
});
|
||||
}
|
||||
|
||||
inv.setCallback(-999, click -> back.reOpen());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
static void changeType(Player p, SchematicNode schem){
|
||||
Clipboard clipboard = null;
|
||||
try {
|
||||
clipboard = new SchematicData(schem).load();
|
||||
} catch (IOException ignored) { }
|
||||
|
||||
Clipboard finalClipboard = clipboard;
|
||||
List<SchematicType> types = SchematicType.values().parallelStream()
|
||||
.filter(SchematicType::isAssignable)
|
||||
.filter(type -> finalClipboard == null || SchematicSystem.getGameModeConfig(type) == null || AutoChecker.impl.sizeCheck(finalClipboard, SchematicSystem.getGameModeConfig(type)).fastOk())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<SWListInv.SWListEntry<SchematicType>> items = types.stream()
|
||||
.map(type -> new SWListInv.SWListEntry<>(new SWItem(SWItem.getMaterial(type.getMaterial()), type.name(), Collections.emptyList(), type.fightType(), null), type))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
items.addAll(SchematicType.values().stream()
|
||||
.filter(SchematicType::isAssignable)
|
||||
.filter(type -> !types.contains(type))
|
||||
.map(type -> new SWListInv.SWListEntry<>(new SWItem(SWItem.getMaterial(type.getMaterial()), SchematicSystem.MESSAGE.parse("GUI_CHANGE_TYPE_NOT_POSSIBLE_COLOR", p, type.name()), Collections.singletonList(SchematicSystem.MESSAGE.parse("GUI_CHANGE_TYPE_NOT_POSSIBLE", p)), false, null), (SchematicType) null))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
SWListInv<SchematicType> inv = new SWListInv<>(p, SchematicSystem.MESSAGE.parse("GUI_CHANGE_TYPE", p), items, (clickType, schematicType) -> {
|
||||
if(schematicType == null) return;
|
||||
p.closeInventory();
|
||||
SchematicCommandUtils.changeType(p, schem, schematicType, null);
|
||||
});
|
||||
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
private static void deleteOwn(Player p, SchematicNode schem, SchematicSelector back){
|
||||
SteamwarUser user = getUser(p);
|
||||
SWInventory inv = new SWInventory(p, 9, SchematicSystem.MESSAGE.parse("GUI_DELETE_OWN_TITLE", p, schem.generateBreadcrumbs(user)));
|
||||
inv.setItem(0, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("CONFIRM", p), click -> {
|
||||
p.performCommand("schematic delete " + schem.generateBreadcrumbs(user));
|
||||
|
||||
if(back != null) {
|
||||
if(schem.isDir()) {
|
||||
back.reOpenDirUp();
|
||||
} else {
|
||||
back.reOpen();
|
||||
}
|
||||
}
|
||||
});
|
||||
inv.setItem(8, SWItem.getDye(14), (byte) 14, SchematicSystem.MESSAGE.parse("CANCEL", p), click -> p.closeInventory());
|
||||
inv.setCallback(-999, click -> p.closeInventory());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
private static void deleteMembership(Player p, SchematicNode schem, SchematicSelector back){
|
||||
SteamwarUser user = getUser(p);
|
||||
SWInventory inv = new SWInventory(p, 9, SchematicSystem.MESSAGE.parse("GUI_DELETE_MEMBER_TITLE", p, schem.generateBreadcrumbs(user)));
|
||||
inv.setItem(0, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("CONFIRM", p), click -> {
|
||||
NodeMember member = NodeMember.getNodeMember(schem.getId(), user.getId());
|
||||
if(member != null)
|
||||
member.delete();
|
||||
SchematicSystem.MESSAGE.send("GUI_DELETE_MEMBER_DONE", p, schem.generateBreadcrumbs(user));
|
||||
if(back != null) {
|
||||
if(schem.isDir()) {
|
||||
back.reOpenDirUp();
|
||||
} else {
|
||||
back.reOpen();
|
||||
}
|
||||
}
|
||||
});
|
||||
inv.setItem(8, SWItem.getDye(14), (byte) 14, SchematicSystem.MESSAGE.parse("CANCEL", p), click -> p.closeInventory());
|
||||
inv.setCallback(-999, click -> p.closeInventory());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
static void delete(Player p, SchematicNode schem, SchematicSelector back){
|
||||
if(SteamwarUser.get(p.getUniqueId()).getId() == schem.getOwner())
|
||||
deleteOwn(p, schem, back);
|
||||
else
|
||||
deleteMembership(p, schem, back);
|
||||
}
|
||||
|
||||
static void delmembers(Player p, SchematicNode schem){
|
||||
List<SWListInv.SWListEntry<NodeMember>> members = new LinkedList<>();
|
||||
for(NodeMember member : schem.getMembers()){
|
||||
SteamwarUser user = SteamwarUser.byId(member.getMember());
|
||||
members.add(new SWListInv.SWListEntry<>(SWItem.getPlayerSkull(user.getUserName()), member));
|
||||
}
|
||||
|
||||
SWListInv<NodeMember> inv = new SWListInv<>(p, SchematicSystem.MESSAGE.parse("GUI_DELETE_MEMBERS_TITLE", p), members, (clickType, member) -> {
|
||||
member.delete();
|
||||
p.closeInventory();
|
||||
delmembers(p, schem);
|
||||
});
|
||||
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
private static void changeItem(Player p, SchematicNode schem, SchematicSelector back){
|
||||
UtilGui.openMaterialSelector(p, SchematicSystem.MESSAGE.parse("GUI_CHANGE_ITEM", p), material -> {
|
||||
schem.setItem(material.name());
|
||||
p.closeInventory();
|
||||
info(p, schem, back);
|
||||
});
|
||||
}
|
||||
}
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTagBuilder;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.command.TypeValidator;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoCheckerResult;
|
||||
import de.steamwar.schematicsystem.autocheck.BlockPos;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandHelp.*;
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.togglePublic;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Linked
|
||||
public class SchematicCommand extends SWCommand {
|
||||
|
||||
public SchematicCommand() {
|
||||
super("schematic", new String[] {"schem", "/schem", "/schematic"});
|
||||
}
|
||||
|
||||
@Register("help")
|
||||
public void pagedHelp(Player player, HelpPage page) {
|
||||
printHelpPage(player, page);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericHelp(Player player, String... args) {
|
||||
printHelpMainPage(player);
|
||||
}
|
||||
|
||||
@Register(value = "togglepublic", noTabComplete = true)
|
||||
public void togglePublicMode(Player player) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
if (!user.hasPerm(UserPerm.MODERATION)) {
|
||||
genericHelp(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (togglePublic(player)) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_PUBLIC_ON", player);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_PUBLIC_OFF", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Mapper("publicMapper")
|
||||
public TypeMapper<SchematicNode> publicNodeTypeMapper() {
|
||||
return SchematicMapper.publicNodeTypeMapper();
|
||||
}
|
||||
|
||||
@Mapper("memberMapper")
|
||||
public static TypeMapper<NodeMember> nodeMemberTypeMapper() {
|
||||
return SchematicMapper.nodeMemberTypeMapper();
|
||||
}
|
||||
|
||||
@Mapper("dirMapper")
|
||||
public static TypeMapper<SchematicNode> dirNodeTypeMapper() {
|
||||
return SchematicMapper.dirNodeTypeMapper();
|
||||
}
|
||||
|
||||
@Mapper("publicDirMapper")
|
||||
public static TypeMapper<SchematicNode> publicDirNodeTypeMapper() {
|
||||
return SchematicMapper.publicDirNodeTypeMapper();
|
||||
}
|
||||
|
||||
@Mapper("dirStringMapper")
|
||||
public static TypeMapper<String> stringTabMapper() {
|
||||
return SchematicMapper.stringTabMapper();
|
||||
}
|
||||
|
||||
@Mapper("stringMapper")
|
||||
public static TypeMapper<String> stringMapper() {
|
||||
return SchematicMapper.stringMapper();
|
||||
}
|
||||
|
||||
@ClassMapper(SchematicType.class)
|
||||
public static TypeMapper<SchematicType> typeTypeMapper() {
|
||||
return SchematicMapper.typeTypeMapper();
|
||||
}
|
||||
|
||||
@AbstractSWCommand.ClassMapper(value = SchematicNode.class, local = true)
|
||||
public static TypeMapper<SchematicNode> nodeTypeMapper() {
|
||||
return SchematicMapper.nodeTypeMapper();
|
||||
}
|
||||
|
||||
@ClassMapper(value = GameModeConfig.class, local = true)
|
||||
public static TypeMapper<GameModeConfig<Material, String>> gameModeConfigTypeMapper() {
|
||||
return SchematicMapper.gameModeConfigTypeMapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(CommandSender sender, String message, Object[] args) {
|
||||
SchematicSystem.MESSAGE.send(message, sender, args);
|
||||
}
|
||||
|
||||
@Validator(value = "isSchemValidator", local = true)
|
||||
public static TypeValidator<SchematicNode> isSchemValidator() {
|
||||
return SchematicValidator.isSchemValidator();
|
||||
}
|
||||
|
||||
@Validator(value = "isDirValidator", local = true)
|
||||
public static TypeValidator<SchematicNode> isDirValidator() {
|
||||
return SchematicValidator.isDirValidator();
|
||||
}
|
||||
|
||||
@Validator(value = "isOwnerValidator", local = true)
|
||||
public static TypeValidator<SchematicNode> isOwnerValidator() {
|
||||
return SchematicValidator.isOwnerValidator();
|
||||
}
|
||||
|
||||
@Validator(value = "isOwnerSchematicValidator", local = true)
|
||||
public static TypeValidator<SchematicNode> isOwnerSchematicValidator() {
|
||||
return SchematicValidator.isOwnerSchematicValidator();
|
||||
}
|
||||
|
||||
public enum Extend {
|
||||
AUSFAHREN,
|
||||
NORMAL
|
||||
}
|
||||
|
||||
private static final Function<CompoundTag, Integer> getCount = item -> Core.getVersion() >= 21 ? item.getInt("count") : item.getByte("Count");
|
||||
private static final BiFunction<CompoundTag, Integer, CompoundTag> setCount = (item, count) -> Core.getVersion() >= 21 ?
|
||||
item.createBuilder().putInt("count", count).build() :
|
||||
item.createBuilder().putByte("Count", count.byteValue()).build();
|
||||
|
||||
public static Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, GameModeConfig<Material, String> type) throws Exception {
|
||||
for (BlockPos blockPos : result.getBlockScanResult().getRecords()) {
|
||||
BlockVector3 vector = BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
clipboard.setBlock(vector, clipboard.getFullBlock(vector).toBaseBlock(new CompoundTag(Collections.emptyMap())));
|
||||
}
|
||||
|
||||
Map<BlockPos, Set<Material>> toBeCheckedInvs = new HashMap<>();
|
||||
|
||||
toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenItems());
|
||||
toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenNbt());
|
||||
|
||||
for (Map.Entry<BlockPos, Set<Material>> entry: toBeCheckedInvs.entrySet()) {
|
||||
BlockPos pos = entry.getKey();
|
||||
Set<Material> materials = entry.getValue();
|
||||
BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ());
|
||||
BaseBlock block = clipboard.getFullBlock(vector);
|
||||
CompoundTag tag = block.getNbtData();
|
||||
CompoundTagBuilder builder = CompoundTagBuilder.create();
|
||||
List<CompoundTag> list = new ArrayList<>();
|
||||
for (CompoundTag items : tag.getList("Items", CompoundTag.class)) {
|
||||
if(materials.contains(Material.matchMaterial(items.getString("id")))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(items.containsKey("tag")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list.add(items);
|
||||
}
|
||||
builder.put("Items", new ListTag(CompoundTag.class, list));
|
||||
clipboard.setBlock(vector, block.toBaseBlock(builder.build()));
|
||||
}
|
||||
|
||||
if(type.Schematic.MaxDispenserItems > 0 ) {
|
||||
for (Map.Entry<BlockPos, Integer> entry : result.getBlockScanResult().getDispenserItems().entrySet()) {
|
||||
if(entry.getValue() <= type.Schematic.MaxDispenserItems) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockPos pos = entry.getKey();
|
||||
BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ());
|
||||
BaseBlock block = clipboard.getFullBlock(vector);
|
||||
CompoundTag tag = block.getNbtData();
|
||||
CompoundTagBuilder builder = tag.createBuilder();
|
||||
List<CompoundTag> items = new ArrayList<>(tag.getList("Items", CompoundTag.class));
|
||||
Collections.reverse(items); // To let the first item be in the Dispenser
|
||||
List<CompoundTag> list = new ArrayList<>();
|
||||
int diff = entry.getValue() - type.Schematic.MaxDispenserItems;
|
||||
for (CompoundTag item : items) {
|
||||
if(item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(diff == 0) {
|
||||
list.add(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(diff > getCount.apply(item)) {
|
||||
diff -= getCount.apply(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
item = setCount.apply(item, getCount.apply(item) - diff);
|
||||
diff = 0;
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
builder.put("Items", new ListTag(CompoundTag.class, list));
|
||||
clipboard.setBlock(vector, block.toBaseBlock(builder.build()));
|
||||
}
|
||||
}
|
||||
|
||||
if(!result.isLimitedBlocksOK()) {
|
||||
Set<Material> toReplace = type.Schematic.Limited.entrySet().stream()
|
||||
.filter(setIntegerEntry -> setIntegerEntry.getValue() == 0)
|
||||
.flatMap(setIntegerEntry -> setIntegerEntry.getKey().stream())
|
||||
.collect(Collectors.toSet());
|
||||
BlockState replaceType = Objects.requireNonNull(toReplace.contains(Material.END_STONE) ? BlockTypes.IRON_BLOCK : BlockTypes.END_STONE).getDefaultState();
|
||||
BlockVector3 min = clipboard.getMinimumPoint();
|
||||
BlockVector3 max = clipboard.getMaximumPoint();
|
||||
for (int i = min.getBlockX(); i <= max.getBlockX(); i++) {
|
||||
for (int j = min.getBlockY(); j <= max.getBlockY(); j++) {
|
||||
for (int k = min.getBlockZ(); k <= max.getBlockZ(); k++) {
|
||||
BlockVector3 vector = BlockVector3.at(i, j, k);
|
||||
BaseBlock block = clipboard.getFullBlock(vector);
|
||||
if(toReplace.contains(Material.matchMaterial(block.getBlockType().getId()))) {
|
||||
clipboard.setBlock(vector, replaceType.toBaseBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
public static void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException {
|
||||
Operations.complete(new ForwardExtentCopy(editSession, clipboard.getRegion(), clipboard, clipboard.getMinimumPoint()));
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SchematicCommandHelp {
|
||||
private SchematicCommandHelp() {
|
||||
}
|
||||
|
||||
public static void printHelpMainPage(Player player) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("HELP_HEADER", player);
|
||||
for (HelpPage page : HelpPage.values()) {
|
||||
TextComponent pageComp = new TextComponent(SchematicSystem.MESSAGE.parse(page.mainText, player));
|
||||
pageComp.setColor(ChatColor.GRAY);
|
||||
pageComp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§e" + SchematicSystem.MESSAGE.parse(page.hover, player))));
|
||||
pageComp.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem help " + page.name()));
|
||||
player.spigot().sendMessage(pageComp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void printHelpPage(Player player, HelpPage page) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("HELP_HEADER", player);
|
||||
for (String s : page.content) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless(s, player);
|
||||
}
|
||||
}
|
||||
|
||||
public enum HelpPage {
|
||||
ANSICHT("HELP_VIEW", "HELP_VIEW_HOVER", new String[]{
|
||||
"HELP_VIEW_1",
|
||||
"HELP_VIEW_2",
|
||||
"HELP_VIEW_3",
|
||||
"HELP_VIEW_4",
|
||||
"HELP_VIEW_5",
|
||||
"HELP_VIEW_6",
|
||||
"HELP_VIEW_7",
|
||||
"HELP_VIEW_8"
|
||||
}),
|
||||
BEARBEITUNG("HELP_EDIT", "HELP_EDIT_HOVER", new String[]{
|
||||
"HELP_EDIT_1",
|
||||
"HELP_EDIT_2",
|
||||
"HELP_EDIT_3",
|
||||
"HELP_EDIT_4",
|
||||
"HELP_EDIT_5",
|
||||
"HELP_EDIT_6",
|
||||
"HELP_EDIT_7",
|
||||
"HELP_EDIT_8",
|
||||
"HELP_EDIT_9"
|
||||
}),
|
||||
MEMBER("HELP_SHARE", "HELP_SHARE_HOVER", new String[]{
|
||||
"HELP_SHARE_1",
|
||||
"HELP_SHARE_2",
|
||||
"HELP_SHARE_3",
|
||||
"HELP_SHARE_4",
|
||||
"HELP_SHARE_5",
|
||||
"HELP_SHARE_6"
|
||||
});
|
||||
|
||||
private final String mainText;
|
||||
private final String[] content;
|
||||
private final String hover;
|
||||
|
||||
HelpPage(String mainText, String hover, String[] content) {
|
||||
this.mainText = mainText;
|
||||
this.hover = hover;
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
+526
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.network.NetworkSender;
|
||||
import de.steamwar.network.packets.client.PrepareSchemPacket;
|
||||
import de.steamwar.providers.BauServerInfo;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoChecker;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoCheckerResult;
|
||||
import de.steamwar.sql.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.With;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SchematicCommandUtils {
|
||||
|
||||
public static final int CHUNK_SIZE = 15;
|
||||
private static final List<Player> PUBLIC_TOGGLED = new ArrayList<>();
|
||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||
private static final Map<Player, CachedSchematicList> CACHED_LISTS = new HashMap<>();
|
||||
|
||||
|
||||
private SchematicCommandUtils() {
|
||||
}
|
||||
|
||||
public static boolean invalidSchemName(Player player, String[] layers) {
|
||||
for (String layer : layers) {
|
||||
if (layer.isEmpty()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_NAME_REQUIRED", player);
|
||||
return true;
|
||||
}
|
||||
if(layer.length() > 64) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_NAME_TOO_LONG", player);
|
||||
return true;
|
||||
}
|
||||
if (layer.contains("/") ||
|
||||
layer.contains("\\") ||
|
||||
layer.contains("<") ||
|
||||
layer.contains(">") ||
|
||||
layer.contains("^") ||
|
||||
layer.contains("°") ||
|
||||
layer.contains("'") ||
|
||||
layer.contains("\"") ||
|
||||
layer.contains(" ")) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_NAME_INVALID_CHAR", player);
|
||||
return true;
|
||||
}
|
||||
if (FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_NAME_FORBIDDEN", player, layer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void createCachedSchemList(Player player, List<SchematicNode> nodes, int chunk, SchematicNode parent, SchematicListBehavior behavior) {
|
||||
CachedSchematicList cachedSchematicList = new CachedSchematicList(nodes, chunk, (int) Math.ceil(nodes.size() / (double) CHUNK_SIZE), parent, behavior.withPageCommandGen((page) -> "/schematic page " + (page - 1)));
|
||||
CACHED_LISTS.put(player, cachedSchematicList);
|
||||
renderSchemlist(player, cachedSchematicList.nodes, chunk, parent, cachedSchematicList.behavior);
|
||||
}
|
||||
|
||||
public static void cachedSchemList(Player player, int chunk) {
|
||||
CACHED_LISTS.computeIfPresent(player, (p, cachedSchematicList) -> {
|
||||
renderSchemlist(player, cachedSchematicList.nodes, chunk, null, cachedSchematicList.behavior);
|
||||
return cachedSchematicList.withPage(chunk);
|
||||
});
|
||||
}
|
||||
|
||||
public static void renderSchemlist(Player player,
|
||||
List<SchematicNode> nodes,
|
||||
int chunk,
|
||||
SchematicNode parent,
|
||||
SchematicListBehavior behavior) {
|
||||
SteamwarUser user = getUser(player);
|
||||
int pageCount = (int) Math.ceil(nodes.size() / (double) CHUNK_SIZE);
|
||||
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_LIST_HEAD", player, nodes.size());
|
||||
String breadcrumbs = parent == null ? "" : parent.generateBreadcrumbs(user);
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_LIST_PATH", player, (breadcrumbs.isEmpty() ? "/" : breadcrumbs));
|
||||
if (!breadcrumbs.isEmpty()) {
|
||||
String str = breadcrumbs.substring(0, Math.max(0, breadcrumbs.substring(0, breadcrumbs.length() - 1).lastIndexOf("/")));
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_LIST_BACK", player, SchematicSystem.MESSAGE.parse("UTIL_LIST_BACK_HOVER", player, str), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem list " + (behavior.isPublics() ? "public" : "") + " " + str));
|
||||
}
|
||||
for (int i = chunk * CHUNK_SIZE; i < nodes.size() && i < (chunk + 1) * CHUNK_SIZE; i++) {
|
||||
SchematicNode node = nodes.get(i);
|
||||
|
||||
StringBuilder nodeString = new StringBuilder();
|
||||
|
||||
if (node.isDir()) {
|
||||
nodeString.append(SchematicSystem.MESSAGE.parse("UTIL_LIST_DIR", player)).append(" ");
|
||||
} else {
|
||||
SchematicType type = node.getSchemtype();
|
||||
if (type != SchematicType.Normal) {
|
||||
nodeString.append(SchematicSystem.MESSAGE.parse("UTIL_LIST_TYPE", player, type.getKuerzel())).append(" ");
|
||||
}
|
||||
}
|
||||
nodeString.append(SchematicSystem.MESSAGE.parse("UTIL_LIST_BASE", player));
|
||||
|
||||
nodeString.append(behavior.getRenderHook().apply(node.getName()));
|
||||
|
||||
if (node.isDir()) {
|
||||
nodeString.append("/");
|
||||
}
|
||||
|
||||
if (node.getOwner() != user.getId()) {
|
||||
nodeString.append(" ").append(SchematicSystem.MESSAGE.parse("UTIL_LIST_FROM", player, SteamwarUser.byId(node.getOwner()).getUserName()));
|
||||
}
|
||||
TextComponent schematics = new TextComponent(nodeString.toString());
|
||||
|
||||
if (node.isDir()) {
|
||||
schematics.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(SchematicSystem.MESSAGE.parse("UTIL_LIST_OPEN_DIR", player)).create()));
|
||||
schematics.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem list " + (behavior.isPublics() ? "public " : "") + (behavior.nonCachedBreadcrumbs ? node.generateBreadcrumbs(user) : breadcrumbs + node.getName() + "/")));
|
||||
} else {
|
||||
schematics.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(SchematicSystem.MESSAGE.parse("UTIL_LIST_OPEN_SCHEM", player)).create()));
|
||||
schematics.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem info " + (behavior.isPublics() ? "public " : "") + (behavior.nonCachedBreadcrumbs ? node.generateBreadcrumbs(user) : breadcrumbs + node.getName())));
|
||||
}
|
||||
|
||||
player.spigot().sendMessage(schematics);
|
||||
}
|
||||
|
||||
if (parent != null && parent.getOwner() != user.getId() && NodeMember.getNodeMember(parent.getId(), user.getId()) != null) {
|
||||
TextComponent deadd = SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_REMOVE", false, player);
|
||||
deadd.setColor(ChatColor.RED);
|
||||
deadd.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_REMOVE_HOVER", false, player)}));
|
||||
deadd.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem delete " + parent.generateBreadcrumbs(user)));
|
||||
player.spigot().sendMessage(deadd);
|
||||
}
|
||||
|
||||
TextComponent beforePage = SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_BACK_ARROW", false, player);
|
||||
beforePage.addExtra(" ");
|
||||
if (chunk > 0) {
|
||||
beforePage.setColor(ChatColor.YELLOW);
|
||||
beforePage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_BACK_ARROW_HOVER", false, player)}));
|
||||
beforePage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, behavior.getPageCommandGen().apply(chunk)));
|
||||
} else {
|
||||
beforePage.setColor(ChatColor.RED);
|
||||
}
|
||||
|
||||
TextComponent nextPage = SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_NEXT", false, player, chunk + 1, Math.max(pageCount, 1));
|
||||
if (chunk < pageCount - 1) {
|
||||
nextPage.setColor(ChatColor.YELLOW);
|
||||
nextPage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_LIST_NEXT_HOVER", false, player)}));
|
||||
nextPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, behavior.getPageCommandGen().apply(chunk + 2)));
|
||||
} else {
|
||||
nextPage.setColor(ChatColor.RED);
|
||||
}
|
||||
|
||||
beforePage.addExtra(nextPage);
|
||||
player.spigot().sendMessage(beforePage);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Builder(setterPrefix = "set")
|
||||
@With
|
||||
public static class SchematicListBehavior {
|
||||
public static final SchematicListBehavior DEFAULT = SchematicListBehavior.builder().build();
|
||||
|
||||
@Builder.Default private boolean showPath = true;
|
||||
@Builder.Default private boolean publics = false;
|
||||
@Builder.Default private boolean nonCachedBreadcrumbs = false;
|
||||
@Builder.Default private UnaryOperator<String> renderHook = s -> s;
|
||||
@Builder.Default private IntFunction<String> pageCommandGen = value -> "/schem list " + value;
|
||||
}
|
||||
|
||||
public static void printSchemInfo(Player player, SchematicNode node) {
|
||||
SteamwarUser user = getUser(player);
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_SCHEM", player, node.generateBreadcrumbs(user));
|
||||
if(node.getOwner() == user.getId()) {
|
||||
player.spigot().sendMessage(
|
||||
new ComponentBuilder(SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_NAME", false, player, node.getName()))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_RENAME_HOVER", false, player)}))
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem rename " + node.generateBreadcrumbs(user) + " "))
|
||||
.create()
|
||||
);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_NAME", player, node.getName());
|
||||
}
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_OWNER", player, node.getOwner() == user.getId() ? user.getUserName() : SteamwarUser.byId(node.getOwner()).getUserName());
|
||||
if(node.getOwner() == user.getId()) {
|
||||
player.spigot().sendMessage(
|
||||
new ComponentBuilder(SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_PARENT", false, player, node.getParent() == null ? "/" : node.getParentNode().generateBreadcrumbs(user)))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_MOVE_HOVER", false, player)}))
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem move " + node.generateBreadcrumbs(user) + " " + node.generateBreadcrumbs(user).replace("/" + node.getName(), "")))
|
||||
.create()
|
||||
);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_PARENT", player, node.getParent() == null ? "/" : node.getParentNode().generateBreadcrumbs(user));
|
||||
}
|
||||
player.spigot().sendMessage(
|
||||
new ComponentBuilder(SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_REVISIONS", false, player, NodeData.getRevisions(node)))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_REVISIONS_HOVER", false, player)}))
|
||||
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem revisions " + node.generateBreadcrumbs(user)))
|
||||
.create());
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_UPDATED", player, node.getLastUpdate());
|
||||
if (!node.isDir()) {
|
||||
if(node.getOwner() == user.getId()) {
|
||||
player.spigot().sendMessage(
|
||||
new ComponentBuilder(SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_TYPE", false, player, node.getSchemtype().name()))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[] {SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_TYPE_HOVER", false, player)}))
|
||||
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem changetype " + node.generateBreadcrumbs(user)))
|
||||
.create()
|
||||
);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_TYPE", player, node.getSchemtype().name());
|
||||
}
|
||||
if (node.getRank() > 0) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_RANK", player, node.getRank());
|
||||
}
|
||||
|
||||
if (node.getSchemtype().fightType()) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_COLOR", player, SchematicSystem.MESSAGE.parse(node.replaceColor() ? "ON" : "OFF", player));
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_REPLAY", player, SchematicSystem.MESSAGE.parse(node.allowReplay() ? "ON" : "OFF", player));
|
||||
}
|
||||
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getFileEnding());
|
||||
CheckedSchematic.getLastDeclinedOfNode(node.getId()).stream().findFirst().ifPresent(checkedSchematic -> SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_STATUS", player, checkedSchematic.getEndTime(), checkedSchematic.getDeclineReason()));
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_TYPE", player, SchematicSystem.MESSAGE.parse("UTIL_INFO_TYPE_DIR", player));
|
||||
}
|
||||
|
||||
|
||||
if(node.getOwner() == user.getId()) {
|
||||
ComponentBuilder memberBuilder = new ComponentBuilder(SchematicSystem.MESSAGE.parse("UTIL_INFO_MEMBER_STRING", player) + " ").color(ChatColor.GRAY);
|
||||
NodeMember.getNodeMembers(node.getId()).forEach(nodeMember -> {
|
||||
SteamwarUser member = SteamwarUser.byId(nodeMember.getMember());
|
||||
memberBuilder.append(member.getUserName())
|
||||
.color(ChatColor.YELLOW)
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem delmember " + node.generateBreadcrumbs(user) + " " + member.getUserName()))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_REMOVE_HOVER", false, player, member.getUserName())}))
|
||||
.append(" ", ComponentBuilder.FormatRetention.NONE);
|
||||
});
|
||||
memberBuilder.append("(+)", ComponentBuilder.FormatRetention.NONE)
|
||||
.color(ChatColor.GREEN)
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_ADD_HOVER", false, player)}))
|
||||
.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem addmember " + node.generateBreadcrumbs(user) + " "));
|
||||
player.spigot().sendMessage(memberBuilder.create());
|
||||
} else {
|
||||
List<String> schematicMembers = new ArrayList<>();
|
||||
NodeMember.getNodeMembers(node.getId()).forEach(nodeMember -> schematicMembers.add(SteamwarUser.byId(nodeMember.getMember()).getUserName()));
|
||||
if(!schematicMembers.isEmpty()) {
|
||||
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_MEMBER", player, schematicMembers.stream().reduce((s, s2) -> s + ", " + s2).orElse(""));
|
||||
}
|
||||
}
|
||||
|
||||
TextComponent base = new TextComponent();
|
||||
|
||||
if (!node.isDir()) {
|
||||
TextComponent load = SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_LOAD", false, player);
|
||||
load.setColor(ChatColor.GREEN);
|
||||
load.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_LOAD_HOVER", false, player)}));
|
||||
load.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem load " + (node.getOwner() == 0 ? "public " : "") + node.generateBreadcrumbs(user)));
|
||||
base.addExtra(load);
|
||||
|
||||
if (node.getOwner() == user.getId()) {
|
||||
TextComponent download = SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_DOWNLOAD", false, player);
|
||||
download.setColor(ChatColor.GOLD);
|
||||
download.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_DOWNLOAD_HOVER", false, player)}));
|
||||
download.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem download " + node.generateBreadcrumbs(user)));
|
||||
base.addExtra(download);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.getOwner() != 0) {
|
||||
TextComponent delete = SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_DELETE", false, player);
|
||||
delete.setColor(ChatColor.DARK_RED);
|
||||
delete.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_DELETE_HOVER", false, player)}));
|
||||
delete.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem delete " + node.generateBreadcrumbs(user)));
|
||||
base.addExtra(delete);
|
||||
}
|
||||
|
||||
if (!base.getExtra().isEmpty()) {
|
||||
player.spigot().sendMessage(base);
|
||||
}
|
||||
}
|
||||
|
||||
public static void check(Player player, Clipboard clipboard, GameModeConfig<Material, String> type, String schemName, boolean gui) {
|
||||
AutoCheckerResult result = AutoChecker.impl.check(clipboard, type);
|
||||
if(!result.isOk()) {
|
||||
result.sendErrorMessage(player, schemName);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("UTIL_CHECK_SUCCESS", player, schemName);
|
||||
}
|
||||
}
|
||||
|
||||
public static SchematicNode mkdirs(String[] layers, SteamwarUser user, int minus) {
|
||||
Optional<SchematicNode> currentNode = Optional.empty();
|
||||
for (int i = 0; i < layers.length - minus; i++) {
|
||||
int finalI = i;
|
||||
List<SchematicNode> nodes = SchematicNode.list(user, currentNode.map(SchematicNode::getId).orElse(null)).stream()
|
||||
.filter(node -> node.getName().equalsIgnoreCase(layers[finalI]))
|
||||
.collect(Collectors.toList());
|
||||
if (nodes.isEmpty()) {
|
||||
currentNode = Optional.ofNullable(SchematicNode.byIdAndUser(user, SchematicNode.createSchematicDirectory(user.getId(), layers[i], currentNode.map(SchematicNode::getId).orElse(null)).getId()));
|
||||
} else {
|
||||
if(nodes.stream().anyMatch(SchematicNode::isDir)) {
|
||||
currentNode = nodes.stream().filter(SchematicNode::isDir).findFirst();
|
||||
} else {
|
||||
currentNode = Optional.ofNullable(SchematicNode.byIdAndUser(user, SchematicNode.createSchematicDirectory(user.getId(), layers[i] + "-dir-" + System.currentTimeMillis() % 100, currentNode.map(SchematicNode::getId).orElse(null)).getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentNode.orElse(null);
|
||||
}
|
||||
|
||||
public static SteamwarUser getUser(Player player) {
|
||||
if (PUBLIC_TOGGLED.contains(player)) {
|
||||
return SteamwarUser.byId(0);
|
||||
} else {
|
||||
return SteamwarUser.get(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean togglePublic(Player player) {
|
||||
if (PUBLIC_TOGGLED.contains(player)) {
|
||||
PUBLIC_TOGGLED.remove(player);
|
||||
return false;
|
||||
} else {
|
||||
PUBLIC_TOGGLED.add(player);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void turnOffPublic(Player player) {
|
||||
PUBLIC_TOGGLED.remove(player);
|
||||
}
|
||||
|
||||
public static void loadSchem(Player player, SchematicNode node, int revision) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if(BauServerInfo.isBauServer() && BauServerInfo.getOwnerId() != user.getId() &&
|
||||
(Punishment.isPunished(user, Punishment.PunishmentType.NoSchemSharing, punishment ->
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_NOT_HERE", player)) ||
|
||||
Punishment.isPunished(SteamwarUser.byId(BauServerInfo.getOwnerId()), Punishment.PunishmentType.NoSchemReceiving, punishment ->
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_NOT_HERE_ALL", player)))) {
|
||||
return;
|
||||
}
|
||||
if (node.isDir()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_DIR", player);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
new SchematicData(node, revision).loadToPlayer(player);
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_DONE", player, node.getName());
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} has loaded Schematic {1} {2}", new Object[]{player.getName(), node.getId(), node.getName()});
|
||||
} catch (NoClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_NO_DATA", player);
|
||||
} catch (IllegalArgumentException e) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_ILLEGAL_REVISION", player, revision);
|
||||
} catch (Exception e) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_ERROR", player);
|
||||
Bukkit.getLogger().log(Level.INFO, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void download(Player player, SchematicNode node) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if (Punishment.isPunished(user, Punishment.PunishmentType.NoSchemSharing, punishment -> {
|
||||
SchematicSystem.MESSAGE.send("UTIL_DOWNLOAD_PUNISHED", player, punishment.getReason());
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
if (node.getOwner() != user.getId()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_DOWNLOAD_NOT_OWN", player);
|
||||
return;
|
||||
}
|
||||
|
||||
SchematicSystem.MESSAGE.send("UTIL_DOWNLOAD_LINK", player);
|
||||
player.sendMessage(NodeDownload.getLink(node));
|
||||
}
|
||||
|
||||
public static void changeType(Player player, SchematicNode node, SchematicType type, SchematicCommand.Extend extend) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if (node.getOwner() != user.getId()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_NOT_OWN", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.isDir()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_DIR", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!type.isAssignable()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_NOT_ASSIGNABLE", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.getSchemtype().equals(type)) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_ALREADY", player);
|
||||
return;
|
||||
}
|
||||
|
||||
node.setPrepared(false);
|
||||
|
||||
if (type.writeable()) {
|
||||
node.setSchemtype(type);
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_DONE", player);
|
||||
} else if (type.fightType()) {
|
||||
if (Punishment.isPunished(user,
|
||||
Punishment.PunishmentType.NoSchemSubmitting,
|
||||
punishment -> SchematicSystem.MESSAGE.send(punishment.isPerma() ? "UTIL_TYPE_PUNISHED_PERMA" : "UTIL_TYPE_PUNISHED", player, punishment.getReason(), punishment.getEndTime()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.getSchemtype().check()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_FIGHT_ALREADY", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SchematicType.values().stream().filter(SchematicType::check)
|
||||
.map(schematicType -> SchematicNode.getAllSchematicsOfType(user.getId(), schematicType.toDB()))
|
||||
.map(List::size)
|
||||
.reduce(Integer::sum)
|
||||
.orElse(0) >= 3) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_TOO_MANY", player);
|
||||
return;
|
||||
}
|
||||
|
||||
GameModeConfig<Material, String> checkSchemType = SchematicSystem.getGameModeConfig(type);
|
||||
if (checkSchemType.isAfterDeadline()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_AFTER_DEADLINE", player, checkSchemType.Deadline);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoCheckerResult result = null;
|
||||
try {
|
||||
result = AutoChecker.impl.check(new SchematicData(node).load(), checkSchemType);
|
||||
} catch (IOException e) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_ERROR", player);
|
||||
SchematicSystem.getInstance().getLogger().throwing(SchematicCommandUtils.class.getName(), "changeType", e);
|
||||
return;
|
||||
}
|
||||
if (!result.isOk()) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_ERROR", player);
|
||||
result.sendErrorMessage(player, node.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (extend == null) {
|
||||
submitSchemGUI(player, node, type);
|
||||
} else if (extend == SchematicCommand.Extend.AUSFAHREN) {
|
||||
NetworkSender.send(new PrepareSchemPacket(SteamwarUser.get(player.getUniqueId()).getId(), node.getId(), type.toDB()));
|
||||
SchematicSystem.MESSAGE.send("UTIL_TYPE_EXTEND", player);
|
||||
} else {
|
||||
node.setSchemtype(type.checkType());
|
||||
SchematicSystem.MESSAGE.send(type.getManualCheck() ? "UTIL_SUBMIT_DIRECT_DONE" : "UTIL_SUBMIT_DIRECT_PLAYABLE", player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void submitSchemGUI(Player player, SchematicNode node, SchematicType type) {
|
||||
SWInventory inv = new SWInventory(player, 9, SchematicSystem.MESSAGE.parse("UTIL_SUBMIT_TITLE", player));
|
||||
inv.setItem(0, SWItem.getMaterial("SIGN"), SchematicSystem.MESSAGE.parse(node.allowReplay()?"UTIL_SUBMIT_REPLAY_ON":"UTIL_SUBMIT_REPLAY_OFF", player), click -> {
|
||||
node.setAllowReplay(!node.allowReplay());
|
||||
submitSchemGUI(player, node, type);
|
||||
});
|
||||
inv.setItem(1, SWItem.getMaterial(node.replaceColor() ? "PINK_WOOL" : "LIGHT_GRAY_WOOL"), SchematicSystem.MESSAGE.parse(node.replaceColor()?"UTIL_SUBMIT_COLOR_ON":"UTIL_SUBMIT_COLOR_OFF", player), click -> {
|
||||
node.setReplaceColor(!node.replaceColor());
|
||||
submitSchemGUI(player, node, type);
|
||||
});
|
||||
inv.setItem(7, SWItem.getDye(7), (byte) 7, SchematicSystem.MESSAGE.parse("UTIL_SUBMIT_DIRECT", player), click -> {
|
||||
node.setSchemtype(type.checkType());
|
||||
SchematicSystem.MESSAGE.send(type.getManualCheck() ? "UTIL_SUBMIT_DIRECT_DONE" : "UTIL_SUBMIT_DIRECT_PLAYABLE", player);
|
||||
player.closeInventory();
|
||||
});
|
||||
inv.setItem(8, SWItem.getDye(10), (byte) 10, SchematicSystem.MESSAGE.parse("UTIL_SUBMIT_EXTEND", player), click -> {
|
||||
NetworkSender.send(new PrepareSchemPacket(SteamwarUser.get(player.getUniqueId()).getId(), node.getId(), type.toDB()));
|
||||
SchematicSystem.MESSAGE.send("UTIL_SUBMIT_EXTEND_DONE", player);
|
||||
player.closeInventory();
|
||||
});
|
||||
inv.setCallback(-999, click -> player.closeInventory());
|
||||
inv.open();
|
||||
}
|
||||
|
||||
public static void quitPlayer(Player player) {
|
||||
CACHED_LISTS.remove(player);
|
||||
PUBLIC_TOGGLED.remove(player);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@With
|
||||
static class CachedSchematicList {
|
||||
private List<SchematicNode> nodes;
|
||||
private int page;
|
||||
private int maxPage;
|
||||
private SchematicNode parent;
|
||||
private SchematicListBehavior behavior;
|
||||
}
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import de.steamwar.command.TypeMapper;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.getUser;
|
||||
|
||||
public class SchematicMapper {
|
||||
|
||||
private static final TypeMapper<SchematicNode> publicCommandTypeMapper = publicNodeTypeMapper();
|
||||
|
||||
public static TypeMapper<SchematicNode> publicNodeTypeMapper() {
|
||||
return new TypeMapper<SchematicNode>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
return SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<NodeMember> nodeMemberTypeMapper() {
|
||||
return new TypeMapper<NodeMember>() {
|
||||
@Override
|
||||
public NodeMember map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(getUser((Player) commandSender), previousArguments[previousArguments.length - 1]);
|
||||
SteamwarUser user = SteamwarUser.get(s);
|
||||
return NodeMember.getNodeMember(node.getId(), user.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
return Optional.ofNullable(SchematicNode.getNodeFromPath(getUser((Player) commandSender), strings[strings.length - 1]))
|
||||
.map(SchematicNode::getMembers)
|
||||
.map(nodeMembers -> nodeMembers.stream().map(NodeMember::getMember).map(SteamwarUser::byId).map(SteamwarUser::getUserName).collect(Collectors.toList()))
|
||||
.orElse(Collections.emptyList());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<SchematicNode> dirNodeTypeMapper() {
|
||||
return new TypeMapper<SchematicNode>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
List<String> list = SchematicNode.getNodeTabcomplete(getUser((Player) commandSender), s);
|
||||
list.removeIf(s1 -> !s1.endsWith("/"));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(getUser((Player) commandSender), s);
|
||||
if(node.isDir()) {
|
||||
return node;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<SchematicNode> publicDirNodeTypeMapper() {
|
||||
return new TypeMapper<SchematicNode>() {
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
Collection<String> list = publicCommandTypeMapper.tabCompletes(commandSender, strings, s);
|
||||
list.removeIf(s1 -> !s1.endsWith("/"));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
SchematicNode node = publicCommandTypeMapper.map(commandSender, previousArguments, s);
|
||||
if(node.isDir()) {
|
||||
return node;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<String> stringTabMapper() {
|
||||
return new TypeMapper<String>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
List<String> list = SchematicNode.getNodeTabcomplete(getUser((Player) commandSender), s);
|
||||
list.removeIf(s1 -> !s1.endsWith("/"));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<String> stringMapper() {
|
||||
return new TypeMapper<String>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
List<String> list = SchematicNode.getNodeTabcomplete(getUser((Player) commandSender), s);
|
||||
list.add(s);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<SchematicType> typeTypeMapper() {
|
||||
return new TypeMapper<SchematicType>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
return SchematicType.values().stream().filter(SchematicType::isAssignable).map(SchematicType::name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicType map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return SchematicType.values().stream().filter(type -> type.name().equals(s)).collect(Collectors.toList()).get(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<SchematicNode> nodeTypeMapper() {
|
||||
return new TypeMapper<SchematicNode>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
return SchematicNode.getNodeTabcomplete(getUser((Player) commandSender), s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return SchematicNode.getNodeFromPath(getUser((Player) commandSender), s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeMapper<GameModeConfig<Material, String>> gameModeConfigTypeMapper() {
|
||||
return new TypeMapper<GameModeConfig<Material, String>>() {
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
return SchematicType.values().stream().filter(type -> SchematicSystem.getGameModeConfig(type) != null).map(SchematicType::name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameModeConfig<Material, String> map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return SchematicType.values().stream().filter(type -> type.name().equalsIgnoreCase(s)).map(SchematicSystem::getGameModeConfig).findAny().orElse(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand;
|
||||
|
||||
import de.steamwar.command.AbstractValidator;
|
||||
import de.steamwar.command.TypeValidator;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@UtilityClass
|
||||
public class SchematicValidator {
|
||||
|
||||
private static boolean nodeNullCheck(AbstractValidator.MessageSender messageSender, SchematicNode node) {
|
||||
if (node == null) {
|
||||
messageSender.send("COMMAND_INVALID_NODE");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static TypeValidator<SchematicNode> isSchemValidator() {
|
||||
return (commandSender, schematicNode, messageSender) -> {
|
||||
if(!nodeNullCheck(messageSender, schematicNode)) {
|
||||
return false;
|
||||
}
|
||||
if(schematicNode.isDir()) {
|
||||
messageSender.send("COMMAND_MUST_SCHEM");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeValidator<SchematicNode> isDirValidator() {
|
||||
return (commandSender, schematicNode, messageSender) -> {
|
||||
if(!nodeNullCheck(messageSender, schematicNode)) {
|
||||
return false;
|
||||
}
|
||||
if(!schematicNode.isDir()) {
|
||||
messageSender.send("COMMAND_MUST_DIR");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeValidator<SchematicNode> isOwnerValidator() {
|
||||
return (commandSender, schematicNode, messageSender) -> {
|
||||
if(!nodeNullCheck(messageSender, schematicNode)) {
|
||||
return false;
|
||||
}
|
||||
if(schematicNode.getOwner() != SteamwarUser.get(((Player) commandSender).getUniqueId()).getId()) {
|
||||
messageSender.send("COMMAND_NOT_OWN");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public static TypeValidator<SchematicNode> isOwnerSchematicValidator() {
|
||||
return (commandSender, schematicNode, messageSender) -> {
|
||||
if(!nodeNullCheck(messageSender, schematicNode)) {
|
||||
return false;
|
||||
}
|
||||
if(schematicNode.getOwner() != SchematicCommandUtils.getUser((Player) commandSender).getId()) {
|
||||
messageSender.send("COMMAND_NOT_OWN");
|
||||
return false;
|
||||
}
|
||||
if(schematicNode.isDir()) {
|
||||
messageSender.send("COMMAND_MUST_SCHEM");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.bukkit.BukkitPlayer;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoChecker;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoCheckerResult;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.sql.GameModeConfig;
|
||||
import de.steamwar.sql.SchematicData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.check;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class CheckPart extends SWCommand {
|
||||
public CheckPart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Register("check")
|
||||
public void checkCommand(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node, GameModeConfig<Material, String> type) {
|
||||
try {
|
||||
check(player, new SchematicData(node).load(), type, node.getName(), false);
|
||||
} catch (IOException e) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_ERROR", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Register(value = {"check", "clipboard"})
|
||||
public void checkClipboardCommand(Player player, @ErrorMessage("UTIL_CHECK_TYPE_NOT_FOUND") GameModeConfig<Material, String> type) {
|
||||
try {
|
||||
check(player, WorldEdit.getInstance().getSessionManager().findByName(player.getName()).getClipboard().getClipboard(), type, "clipboard", false);
|
||||
} catch (EmptyClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_CHECK_CLIPBOARD_EMPTY", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Register(value = {"check", "selection"})
|
||||
public void checkSelectionCommand(Player player, @ErrorMessage("UTIL_CHECK_TYPE_NOT_FOUND") GameModeConfig<Material, String> type) {
|
||||
try {
|
||||
Clipboard clipboard = new BlockArrayClipboard(WorldEdit.getInstance().getSessionManager().findByName(player.getName()).getSelection(new BukkitWorld(player.getWorld())));
|
||||
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(player.getWorld()), -1);
|
||||
|
||||
SchematicCommand.createCopy(editSession, clipboard);
|
||||
|
||||
check(player, clipboard, type, "selection", false);
|
||||
} catch (IncompleteRegionException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_CHECK_SELECTION_INCOMPLETE", player);
|
||||
} catch (WorldEditException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_ERROR", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Register("fix")
|
||||
public void fixSchematicCommand(Player player, @ErrorMessage("UTIL_CHECK_TYPE_NOT_FOUND") GameModeConfig<Material, String> type) {
|
||||
if(Core.getVersion() < 15) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_FIX_WRONG_VERSION", player);
|
||||
return;
|
||||
}
|
||||
Clipboard clipboard;
|
||||
try {
|
||||
clipboard = WorldEdit.getInstance().getSessionManager().findByName(player.getName()).getClipboard().getClipboard();
|
||||
} catch (EmptyClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_CHECK_CLIPBOARD_EMPTY", player);
|
||||
return;
|
||||
}
|
||||
AutoCheckerResult result = AutoChecker.impl.check(clipboard, type);
|
||||
if(result.isOk()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_FIX_OK", player);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
clipboard = SchematicCommand.fixClipboard(clipboard, result, type);
|
||||
WorldEdit.getInstance().getSessionManager().get(new BukkitPlayer(player)).setClipboard(new ClipboardHolder(clipboard));
|
||||
AutoCheckerResult after = AutoChecker.impl.check(clipboard, type);
|
||||
if(after.isOk()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_FIX_DONE", player);
|
||||
} else {
|
||||
after.sendErrorMessage(player, SchematicSystem.MESSAGE.parse("COMMAND_FIX_MANUAL", player));
|
||||
SchematicSystem.MESSAGE.send("COMMAND_FIX_COULD_NOT_FIX", player);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_FIX_ERROR", player);
|
||||
SchematicSystem.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.getUser;
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.mkdirs;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class MemberPart extends SWCommand {
|
||||
public MemberPart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Register("addmember")
|
||||
public void addMember(Player player, @Validator("isOwnerValidator") SchematicNode node, SteamwarUser... targets) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if(Punishment.isPunished(user, Punishment.PunishmentType.NoSchemSharing, punishment -> SchematicSystem.MESSAGE.send("COMMAND_ADD_PUNISH", player, punishment.getReason()))) {
|
||||
return;
|
||||
}
|
||||
List<SteamwarUser> added = new ArrayList<>();
|
||||
for (SteamwarUser target: targets) {
|
||||
if(Punishment.isPunished(target,
|
||||
Punishment.PunishmentType.NoSchemReceiving,
|
||||
punishment -> SchematicSystem.MESSAGE.send("COMMAND_ADD_USER_PUNISHED", player, target.getUserName()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (user.getId() == target.getId()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_OWN", player);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target.getId() == 0) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_PUBLIC", player);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NodeMember.getNodeMember(node.getId(), target.getId()) != null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_ALREADY", player, target.getUserName());
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeMember.createNodeMember(node.getId(), target.getId());
|
||||
added.add(target);
|
||||
|
||||
Player t = Bukkit.getPlayer(target.getUUID());
|
||||
if (t != null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_ADDED", t, node.generateBreadcrumbs(user), player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Optional<String> reduced = added.stream().map(SteamwarUser::getUserName).reduce((s, s2) -> s + ", " + s2);
|
||||
if (reduced.isPresent()) {
|
||||
SchematicSystem.MESSAGE.send(added.size()>1?"COMMAND_ADD_MANY":"COMMAND_ADD_ONE", player, reduced.get());
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_NONE", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Register("delmember")
|
||||
public void delMember(Player player, @Validator("isOwnerValidator") SchematicNode node, @Mapper("memberMapper") NodeMember member) {
|
||||
SteamwarUser user = getUser(player);
|
||||
SteamwarUser target = SteamwarUser.byId(member.getMember());
|
||||
|
||||
List<SchematicNode> nodes = SchematicNode.deepGet(node.getId(), node1 -> node1.getOwner() != user.getId());
|
||||
if (!nodes.isEmpty()) {
|
||||
for (SchematicNode schematicNode : nodes) {
|
||||
SchematicNode newNode = mkdirs(schematicNode.generateBreadcrumbs(user).split("/"), target, 1);
|
||||
if(SchematicNode.getSchematicNode(schematicNode.getName(), newNode == null ? 0 : newNode.getId()) != null) {
|
||||
schematicNode.setName(schematicNode.getName() + "-" + Instant.now().getEpochSecond() % 1000);
|
||||
}
|
||||
schematicNode.setParent(newNode == null ? null : newNode.getId());
|
||||
}
|
||||
}
|
||||
|
||||
member.delete();
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELMEM_DONE", player, target.getUserName(), node.generateBreadcrumbs(user));
|
||||
|
||||
Player t = Bukkit.getPlayer(target.getUUID());
|
||||
if (t != null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELMEM_DELETED", t, node.getName(), player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Register("addteam")
|
||||
public void addTeam(Player player, @Validator("isOwnerValidator") SchematicNode node) {
|
||||
SteamwarUser user = getUser(player);
|
||||
Team team = Team.byId(user.getTeam());
|
||||
if (team == null || team.getTeamId() == 0) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_ADD_TEAM_NOT_IN_TEAM", player);
|
||||
return;
|
||||
}
|
||||
|
||||
addMember(player, node, team.getMembers().stream().map(SteamwarUser::byId).filter(steamwarUser -> steamwarUser.getId() != user.getId()).toArray(SteamwarUser[]::new));
|
||||
}
|
||||
|
||||
@Register("delteam")
|
||||
public void remTeam(Player player, @Validator("isOwnerValidator") SchematicNode node) {
|
||||
SteamwarUser user = getUser(player);
|
||||
Team team = Team.byId(user.getTeam());
|
||||
if (team == null || team.getTeamId() == 0) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DEL_TEAM_NOT_IN_TEAM", player);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> removed = new ArrayList<>();
|
||||
for (Integer member : team.getMembers()) {
|
||||
if (user.getId() == member) continue;
|
||||
NodeMember nodeMember = NodeMember.getNodeMember(node.getId(), member);
|
||||
if (nodeMember != null) {
|
||||
nodeMember.delete();
|
||||
removed.add(SteamwarUser.byId(member).getUserName());
|
||||
}
|
||||
}
|
||||
|
||||
Optional<String> reduced = removed.stream().reduce((s, s2) -> s + ", " + s2);
|
||||
if (reduced.isPresent()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DEL_TEAM_DONE", player, reduced.get());
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DEL_TEAM_NONE", player);
|
||||
}
|
||||
}
|
||||
|
||||
@Register("clearmember")
|
||||
public void clearMember(Player player, @Validator("isOwnerValidator") SchematicNode node) {
|
||||
node.getMembers().forEach(NodeMember::delete);
|
||||
SchematicSystem.MESSAGE.send("COMMAND_CLEAR_MEMBER_DONE", player);
|
||||
}
|
||||
|
||||
@Register("delallmember")
|
||||
public void delAllMember(Player player, SteamwarUser target) {
|
||||
SteamwarUser user = getUser(player);
|
||||
int i = 0;
|
||||
for (NodeMember nodeMember : NodeMember.getSchematics(target.getId())) {
|
||||
SchematicNode node = SchematicNode.getSchematicNode(nodeMember.getNode());
|
||||
if (node.getOwner() == user.getId()) {
|
||||
nodeMember.delete();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DEL_ALL_MEMBER", player, target.getUserName(), i);
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SafeSchematicNode;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.autocheck.AutoChecker;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils;
|
||||
import de.steamwar.sql.*;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.*;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class ModifyPart extends SWCommand {
|
||||
public ModifyPart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Register("changetype")
|
||||
@Register("submit")
|
||||
public void changeType(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node) {
|
||||
TextComponent base = new TextComponent();
|
||||
|
||||
Clipboard clipboard;
|
||||
try {
|
||||
clipboard = new SchematicData(node).load();
|
||||
} catch (IOException ignored) {
|
||||
SchematicSystem.MESSAGE.send("UTIL_LOAD_ERROR", player);
|
||||
return;
|
||||
}
|
||||
|
||||
String breadcrumb = node.generateBreadcrumbs(SteamwarUser.get(player.getUniqueId()));
|
||||
|
||||
SchematicType.values().parallelStream()
|
||||
.filter(SchematicType::isAssignable)
|
||||
.filter(type -> SchematicSystem.getGameModeConfig(type) == null || AutoChecker.impl.sizeCheck(clipboard, SchematicSystem.getGameModeConfig(type)).fastOk())
|
||||
.forEach(type -> {
|
||||
TextComponent component = new TextComponent(type.name() + " ");
|
||||
component.setColor(ChatColor.GRAY);
|
||||
component.setBold(true);
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(SchematicSystem.MESSAGE.parse("COMMAND_CHANGE_TYPE_SELECT", player))));
|
||||
component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem changetype " + breadcrumb + " " + type.name()));
|
||||
base.addExtra(component);
|
||||
});
|
||||
|
||||
player.spigot().sendMessage(base);
|
||||
}
|
||||
|
||||
@Register("changetype")
|
||||
@Register("submit")
|
||||
public void changeType(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node, SchematicType type) {
|
||||
changeType(player, node, type, null);
|
||||
}
|
||||
|
||||
@Register("changetype")
|
||||
@Register("submit")
|
||||
public void changeType(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node, SchematicType type, SchematicCommand.Extend extend) {
|
||||
SchematicCommandUtils.changeType(player, node, type, extend);
|
||||
}
|
||||
|
||||
@Register("move")
|
||||
public void moveToNull(Player player, @ErrorMessage("COMMAND_INVALID_NODE") SchematicNode node) {
|
||||
move(player, node, "/");
|
||||
}
|
||||
|
||||
@Register("move")
|
||||
public void move(Player player, @ErrorMessage("COMMAND_INVALID_NODE") SchematicNode node, @Mapper("dirStringMapper") String name) {
|
||||
SteamwarUser user = getUser(player);
|
||||
|
||||
if (name.equals("/")) {
|
||||
if(node.getOwner() == user.getId()) {
|
||||
node.setParent(null);
|
||||
} else if(NodeMember.getNodeMember(node.getId(), user.getId()) != null) {
|
||||
NodeMember member = NodeMember.getNodeMember(node.getId(), user.getId());
|
||||
member.setParentId(null);
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_NOT_OWN", player);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (name.startsWith("/")) name = name.substring(1);
|
||||
if (name.endsWith("/")) name = name.substring(0, name.length() - 1);
|
||||
String[] layers = name.split("/");
|
||||
if (invalidSchemName(player, layers)) return;
|
||||
SchematicNode newNode = mkdirs(layers, user, 0);
|
||||
if(SchematicNode.parentsOfNode(user, newNode.getId()).stream().anyMatch(n -> n.getId() == node.getId())) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_MOVE_RECURSIVE", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if(node.getOwner() == user.getId()) {
|
||||
SafeSchematicNode.Result result = SafeSchematicNode.setParent(user, node, newNode);
|
||||
if(!result.isSuccessful()) {
|
||||
result.sendError(player);
|
||||
return;
|
||||
}
|
||||
} else if(NodeMember.getNodeMember(node.getId(), user.getId()) != null) {
|
||||
NodeMember member = NodeMember.getNodeMember(node.getId(), user.getId());
|
||||
member.setParentId(newNode.getId());
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_NOT_OWN", player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SchematicSystem.MESSAGE.send("COMMAND_MOVE_DONE", player, SchematicNode.byIdAndUser(user, node.getId()).generateBreadcrumbs(user));
|
||||
}
|
||||
|
||||
@Register("rename")
|
||||
public void rename(Player player, @Validator("isOwnerValidator") SchematicNode node, String name) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if (invalidSchemName(player, new String[]{name})) {
|
||||
return;
|
||||
}
|
||||
SafeSchematicNode.Result result = SafeSchematicNode.setName(user, node, name);
|
||||
if (!result.isSuccessful()) {
|
||||
result.sendError(player);
|
||||
return;
|
||||
}
|
||||
SchematicSystem.MESSAGE.send("COMMAND_RENAME_DONE", player, node.generateBreadcrumbs(user));
|
||||
}
|
||||
|
||||
@Register("delete")
|
||||
public void deleteSchem(Player player, SchematicNode node) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
if (node.getOwner() != user.getId()) {
|
||||
NodeMember member = NodeMember.getNodeMember(node.getId(), user.getId());
|
||||
if (member == null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELETE_NOT_OWN", player);
|
||||
return;
|
||||
}
|
||||
member.delete();
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELETE_MEMBER", player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.isDir()) {
|
||||
if (SchematicNode.getSchematicNodeInNode(node).isEmpty()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELETE_DIR", player, node.generateBreadcrumbs(user));
|
||||
node.delete();
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELETE_DIR_FULL", player);
|
||||
}
|
||||
} else {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DELETE_SCHEM", player, node.generateBreadcrumbs(user));
|
||||
node.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Register("replacecolor")
|
||||
public void replacecolor(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node) {
|
||||
boolean state = !node.replaceColor();
|
||||
node.setReplaceColor(state);
|
||||
SchematicSystem.MESSAGE.send(state?"COMMAND_REPLACE_COLOR_ON":"COMMAND_REPLACE_COLOR_OFF", player, node.getName());
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.inventory.SWAnvilInv;
|
||||
import de.steamwar.inventory.SchematicSelector;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.providers.BauServerInfo;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.sql.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.*;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class SavePart extends SWCommand {
|
||||
|
||||
public SavePart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Register("save")
|
||||
public void saveSchem(Player player) {
|
||||
SchematicSelector selector = new SchematicSelector(player, SchematicSelector.selectSchematicNode(), schematicNode -> {
|
||||
if(schematicNode == null || schematicNode.isDir()) {
|
||||
SWAnvilInv anvilInv = new SWAnvilInv(player, SchematicSystem.MESSAGE.parse("COMMAND_ENTER_NAME", player));
|
||||
anvilInv.setCallback(s -> saveSchem(player, schematicNode==null?s:(schematicNode.generateBreadcrumbs(getUser(player)) + s)));
|
||||
anvilInv.setItem(Material.CAULDRON);
|
||||
anvilInv.open();
|
||||
} else {
|
||||
saveSchem(player, schematicNode.generateBreadcrumbs(getUser(player)));
|
||||
}
|
||||
});
|
||||
selector.setSingleDirOpen(false);
|
||||
selector.open();
|
||||
}
|
||||
|
||||
@Register("save")
|
||||
public void saveSchem(Player player, @AbstractSWCommand.Mapper("stringMapper") String name) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if(BauServerInfo.isBauServer() && BauServerInfo.getOwnerId() != user.getId() &&
|
||||
(Punishment.isPunished(user, Punishment.PunishmentType.NoSchemReceiving, punishment ->
|
||||
SchematicSystem.MESSAGE.send("COMMAND_PUNISHMENT_NO_SAVE_EXTERNAL", player)) ||
|
||||
Punishment.isPunished(SteamwarUser.byId(BauServerInfo.getOwnerId()), Punishment.PunishmentType.NoSchemSharing, punishment ->
|
||||
SchematicSystem.MESSAGE.send("COMMAND_PUNISHMENT_NO_SAVE", player)))) {
|
||||
return;
|
||||
}
|
||||
if (name.endsWith("/")) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_NO_NAME", player);
|
||||
return;
|
||||
}
|
||||
if (name.startsWith("/")) name = name.substring(1);
|
||||
String[] layers = name.split("/");
|
||||
if (invalidSchemName(player, layers)) return;
|
||||
SchematicNode currentNode = mkdirs(layers, user, 1);
|
||||
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(user, String.join("/", layers));
|
||||
if (node != null) {
|
||||
if(node.isDir()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_FOLDER", player);
|
||||
return;
|
||||
} else if (!node.getSchemtype().writeable() || node.getOwner() != user.getId()) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_NO_OVERWRITE", player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
boolean newSchem = false;
|
||||
if (node == null) {
|
||||
newSchem = true;
|
||||
node = SchematicNode.createSchematic(user.getId(), layers[layers.length - 1], currentNode == null ? 0 : currentNode.getId());
|
||||
}
|
||||
|
||||
try {
|
||||
SchematicData.saveFromPlayer(player, node);
|
||||
} catch (NoClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_CLIPBOARD_EMPTY", player);
|
||||
if (newSchem)
|
||||
node.delete();
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not save schematic", ex);
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_ERROR", player);
|
||||
if (newSchem)
|
||||
node.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
SchematicSystem.MESSAGE.send(newSchem?"COMMAND_SAVE_DONE":"COMMAND_SAVE_OVERWRITE", player, node.generateBreadcrumbs(user));
|
||||
}
|
||||
|
||||
@Register("dir")
|
||||
@Register("ordner")
|
||||
@Register("mkdir")
|
||||
public void mkdir(Player player, @Mapper("dirStringMapper") String name) {
|
||||
SteamwarUser user = getUser(player);
|
||||
if (name.startsWith("/")) name = name.substring(1);
|
||||
if (name.endsWith("/")) name = name.substring(0, name.length() - 1);
|
||||
String[] layers = name.split("/");
|
||||
if (invalidSchemName(player, layers)) return;
|
||||
SchematicNode node = mkdirs(layers, user, 0);
|
||||
SchematicSystem.MESSAGE.send("COMMAND_DIR_DONE", player, node.generateBreadcrumbs(user));
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import de.steamwar.command.*;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SchematicType;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.createCachedSchemList;
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.getUser;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class SearchPart extends SWCommand {
|
||||
|
||||
private static final Map<String, AbstractTypeMapper<CommandSender, ?>> searchMapper = new HashMap<>();
|
||||
|
||||
|
||||
static {
|
||||
searchMapper.put("-type", SWCommandUtils.createMapper(SchematicType.values().stream().map(SchematicType::name).toArray(String[]::new)));
|
||||
searchMapper.put("-owner", SWCommandUtils.createMapper(Function.identity(), (commandSender, s) -> Collections.singletonList(s)));
|
||||
Class<?> clazz = Material.class;
|
||||
searchMapper.put("-item", SWCommandUtils.createEnumMapper((Class<Enum<?>>) clazz));
|
||||
searchMapper.put("-public", null);
|
||||
searchMapper.put("-ignoreCase", null);
|
||||
searchMapper.put("-exclude", SWCommandUtils.createMapper(Function.identity(), (commandSender, s) -> Collections.singletonList(s)));
|
||||
searchMapper.put("-excludeType", SWCommandUtils.createMapper(SchematicType.values().stream().map(SchematicType::name).toArray(String[]::new)));
|
||||
searchMapper.put("-excludeOwner", SWCommandUtils.createMapper(Function.identity(), (commandSender, s) -> Collections.singletonList(s)));
|
||||
}
|
||||
|
||||
public SearchPart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
public boolean containsCheckCase(String s, String s2, AtomicBoolean isIgnoreCase) {
|
||||
if (isIgnoreCase.get()) {
|
||||
return s.toLowerCase().contains(s2.toLowerCase());
|
||||
}
|
||||
return s.contains(s2);
|
||||
}
|
||||
|
||||
@Register("search")
|
||||
public void schemSearch(Player player, @OptionalValue("1") int page, @Mapper("searchMapper") String... query) {
|
||||
SteamwarUser user = getUser(player);
|
||||
int userId = user.getId();
|
||||
List<Predicate<SchematicNode>> predicates = new ArrayList<>();
|
||||
List<String> nameList = new ArrayList<>();
|
||||
int i = 0;
|
||||
AtomicBoolean isIgnoreCase = new AtomicBoolean(false);
|
||||
while (i < query.length) {
|
||||
String current = query[i];
|
||||
if (searchMapper.containsKey(current)) {
|
||||
if (searchMapper.get(current) == null) {
|
||||
switch (current) {
|
||||
case "-public":
|
||||
userId = 0;
|
||||
break;
|
||||
case "-ignoreCase":
|
||||
isIgnoreCase.set(true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + current);
|
||||
}
|
||||
} else if (i + 1 < query.length) {
|
||||
int finalI = i;
|
||||
switch (current) {
|
||||
case "-type":
|
||||
predicates.add(node -> !node.isDir() && node.getSchemtype().name().equalsIgnoreCase(query[finalI + 1]));
|
||||
break;
|
||||
case "-item":
|
||||
predicates.add(node -> node.getItem().equalsIgnoreCase(query[finalI + 1]));
|
||||
break;
|
||||
case "-owner":
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(query[finalI + 1]);
|
||||
if (steamwarUser == null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SEARCH_NOT_A_PLAYER", player, query[finalI + 1]);
|
||||
return;
|
||||
}
|
||||
predicates.add(node -> node.getOwner() == steamwarUser.getId());
|
||||
break;
|
||||
case "-exclude":
|
||||
predicates.add(node -> !node.getName().contains(query[finalI + 1]));
|
||||
break;
|
||||
case "-excludeType":
|
||||
predicates.add(node -> !node.isDir() && !node.getSchemtype().name().equalsIgnoreCase(query[finalI + 1]));
|
||||
break;
|
||||
case "-excludeOwner":
|
||||
SteamwarUser steamwarUser1 = SteamwarUser.get(query[finalI + 1]);
|
||||
if (steamwarUser1 == null) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SEARCH_NOT_A_PLAYER", player, query[finalI + 1]);
|
||||
return;
|
||||
}
|
||||
predicates.add(node -> node.getOwner() != steamwarUser1.getId());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + current);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
predicates.add(node -> containsCheckCase(node.getName(), current, isIgnoreCase));
|
||||
nameList.add(current);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
List<SchematicNode> nodes = SchematicNode.getAll(SteamwarUser.byId(userId)).stream().filter(node -> {
|
||||
for (Predicate<SchematicNode> predicate : predicates) {
|
||||
if (!predicate.test(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}).collect(Collectors.toList());
|
||||
createCachedSchemList(player, nodes, Math.max(page - 1, 0), null, SchematicCommandUtils.SchematicListBehavior.builder().setPublics(userId == 0).setShowPath(false).setRenderHook(s -> {
|
||||
for (String ss : nameList) {
|
||||
s = s.replace(ss, "§e§l" + ss + "§7");
|
||||
}
|
||||
return "§7" + s;
|
||||
}).setNonCachedBreadcrumbs(true).build());
|
||||
}
|
||||
|
||||
@Mapper(value = "searchMapper", local = true)
|
||||
public TypeMapper<String> searchTypeMapper() {
|
||||
return new TypeMapper<String>() {
|
||||
@Override
|
||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
|
||||
if (strings.length == 0) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(s);
|
||||
list.addAll(searchMapper.keySet());
|
||||
return list;
|
||||
}
|
||||
String last = strings[strings.length - 1];
|
||||
if (searchMapper.containsKey(last)) {
|
||||
AbstractTypeMapper<CommandSender, ?> mapper = searchMapper.get(last);
|
||||
if (mapper == null) {
|
||||
List<String> list = new ArrayList<>(searchMapper.keySet());
|
||||
list.add(s);
|
||||
return list;
|
||||
}
|
||||
return mapper.tabCompletes(commandSender, strings, s);
|
||||
}
|
||||
List<String> list = new ArrayList<>(searchMapper.keySet());
|
||||
list.add(s);
|
||||
return list;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.commands.schematiccommand.parts;
|
||||
|
||||
import de.steamwar.command.AbstractSWCommand;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.SchematicSystem;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.GUI;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils;
|
||||
import de.steamwar.sql.NodeData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.*;
|
||||
|
||||
@AbstractSWCommand.PartOf(SchematicCommand.class)
|
||||
@Linked
|
||||
public class ViewPart extends SWCommand {
|
||||
public ViewPart() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Register("list")
|
||||
@Register({"list", "/"})
|
||||
public void schemList(Player player, @OptionalValue(value = "1", onlyUINIG = true) int page) {
|
||||
createCachedSchemList(player, SchematicNode.list(getUser(player), null), Math.max(page - 1, 0), null, SchematicCommandUtils.SchematicListBehavior.DEFAULT);
|
||||
}
|
||||
|
||||
@Register({"list", "public"})
|
||||
public void schemListPublic(Player player, @Validator("isDirValidator") @Mapper("publicDirMapper") SchematicNode node, @OptionalValue("1") int page) {
|
||||
schemList(player, node, page);
|
||||
}
|
||||
|
||||
@Register({"list", "public"})
|
||||
@Register({"list", "public", "/"})
|
||||
public void schemListPublic(Player player, @OptionalValue(value = "1", onlyUINIG = true) int page) {
|
||||
createCachedSchemList(player, SchematicNode.list(SteamwarUser.byId(0), null), Math.max(page - 1, 0), null, SchematicCommandUtils.SchematicListBehavior.builder().setPublics(true).setPageCommandGen(integer -> "/schem list public " + integer).build());
|
||||
}
|
||||
|
||||
@Register("list")
|
||||
public void schemList(Player player, @Validator("isDirValidator") @Mapper("dirMapper") SchematicNode node, @OptionalValue("1") int page) {
|
||||
SteamwarUser user = getUser(player);
|
||||
createCachedSchemList(player, SchematicNode.list(user, node.getId()), Math.max(page - 1, 0), node, SchematicCommandUtils.SchematicListBehavior.builder().setPublics(node.getOwner() == 0).setPageCommandGen(value -> "/schem list " + (node.getOwner()==0?"public ":"") + node.generateBreadcrumbs(user) + " " + value).build());
|
||||
}
|
||||
|
||||
@Register({"info", "public"})
|
||||
public void schemInfoPublic(Player player, @Mapper("publicMapper") SchematicNode node) {
|
||||
schemInfo(player, SchematicNode.getSchematicNode(node.getId()));
|
||||
}
|
||||
|
||||
@Register("info")
|
||||
public void schemInfo(Player player, @ErrorMessage("COMMAND_INVALID_NODE") SchematicNode node) {
|
||||
printSchemInfo(player, node);
|
||||
}
|
||||
|
||||
@Register("revisions")
|
||||
public void revisions(Player player, @Validator("isSchemValidator") SchematicNode node) {
|
||||
List<NodeData> revisions = NodeData.get(node);
|
||||
if(revisions.isEmpty()) {
|
||||
SchematicSystem.MESSAGE.send("REVISIONS_EMPTY", player);
|
||||
return;
|
||||
}
|
||||
|
||||
SchematicSystem.MESSAGE.send("REVISIONS_TITLE", player);
|
||||
for (int j = Math.max(0, revisions.size() - 10); j < revisions.size(); j++) {
|
||||
player.spigot().sendMessage(
|
||||
new ComponentBuilder(SchematicSystem.MESSAGE.parseToComponent("REVISIONS_REVISION_NUMBER", false, player, j + 1, revisions.get(j).getCreatedAt()))
|
||||
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem load " + (node.getOwner() == 0 ? "public " : "") + node.generateBreadcrumbs(getUser(player)) + " " + (j + 1)))
|
||||
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{SchematicSystem.MESSAGE.parseToComponent("UTIL_INFO_ACTION_LOAD_HOVER", false, player)}))
|
||||
.create()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Register(value = "page", noTabComplete = true)
|
||||
public void pageCommand(Player player, int page) {
|
||||
cachedSchemList(player, page);
|
||||
}
|
||||
|
||||
@Register({"l", "public"})
|
||||
@Register({"load", "public"})
|
||||
public void loadSchemPublic(Player player, @Validator("isSchemValidator") @Mapper("publicMapper") SchematicNode node, @OptionalValue("-1") int revision) {
|
||||
loadSchem(player, node, revision);
|
||||
}
|
||||
|
||||
@Register("l")
|
||||
@Register("load")
|
||||
public void loadSchem(Player player, @Validator("isSchemValidator") SchematicNode node, @OptionalValue("-1") int revision) {
|
||||
SchematicCommandUtils.loadSchem(player, node, revision);
|
||||
}
|
||||
|
||||
@Register("gui")
|
||||
public void gui(Player player) {
|
||||
GUI.list(player);
|
||||
}
|
||||
|
||||
@Register("download")
|
||||
public void download(Player player, @Validator("isSchemValidator") SchematicNode node) {
|
||||
SchematicCommandUtils.download(player, node);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
CheckPart:
|
||||
- fix
|
||||
- check
|
||||
MemberPart:
|
||||
- addmember
|
||||
- delmember
|
||||
- addteam
|
||||
- delteam
|
||||
- clearmember
|
||||
- delallmember
|
||||
ModifyPart:
|
||||
- changetype
|
||||
- move
|
||||
- rename
|
||||
- delete
|
||||
- lockreplay
|
||||
- replacecolor
|
||||
SavePart:
|
||||
- save
|
||||
- ordner
|
||||
SearchPart:
|
||||
- search
|
||||
ViewPart:
|
||||
- list
|
||||
- info
|
||||
- load
|
||||
- gui
|
||||
- download
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
@Linked
|
||||
public class PlayerEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
SchematicCommandUtils.quitPlayer(event.getPlayer());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user