diff --git a/SchematicSystem/SchematicSystem_15/build.gradle.kts b/SchematicSystem/SchematicSystem_15/build.gradle.kts new file mode 100644 index 00000000..261c40bd --- /dev/null +++ b/SchematicSystem/SchematicSystem_15/build.gradle.kts @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id("java") + id("base") +} + +group = "de.steamwar" +version = "" + +tasks.compileJava { + options.encoding = "UTF-8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +sourceSets { + main { + java { + srcDirs("src/") + } + resources { + srcDirs("src/") + exclude("**/*.java", "**/*.kt") + } + } +} + +dependencies { + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + compileOnly(project(":SchematicSystem:SchematicSystem_Core")) + compileOnly(project(":SpigotCore")) + + compileOnly("de.steamwar:spigot:1.15") + compileOnly("de.steamwar:worldedit:1.15") +} diff --git a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java new file mode 100644 index 00000000..e0823263 --- /dev/null +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java @@ -0,0 +1,185 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.schematicsystem.CheckSchemType; +import org.bukkit.Material; + +import java.util.*; +import java.util.stream.Collectors; + +public class AutoChecker15 implements AutoChecker.IAutoChecker { + private static final Set 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 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.HONEY_BOTTLE); + + public AutoChecker.BlockScanResult scan(Clipboard clipboard) { + 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(INVENTORY.contains(material)) { + checkInventory(result, block, material, new BlockPos(x, y, z)); + } + + if(x == 0 || x == max.getBlockX() - 1 || y == max.getBlockY() - 1 || z == 0 || z == max.getBlockZ() - 1) { + result.getDesignBlocks().computeIfAbsent(material, m -> new ArrayList<>()).add(new BlockPos(x, y, z)); + } + } + } + } + return result; + } + + private static final Map> itemsInInv = new EnumMap<>(Material.class); + + static { + itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.TNT, EnumSet.of(Material.CHEST, Material.BARREL)); + itemsInInv.put(Material.FIRE_CHARGE, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); + FLOWERS.forEach(material -> itemsInInv.put(material, INVENTORY)); + } + + private void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { + 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 items = nbt.getList("Items", CompoundTag.class); + if(items.isEmpty()) + return; //Leeres Inventar + + int counter = 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 (!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 += item.getByte("Count"); + } + if (item.containsKey("tag")) { + result.getForbiddenNbt().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); + } + } + result.getDispenserItems().put(pos, counter); + } + + @Override + public AutoCheckerResult check(Clipboard clipboard, CheckSchemType type) { + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .blockScanResult(scan(clipboard)) + .entities(clipboard.getEntities().stream().map(Entity::getLocation).map(blockVector3 -> new BlockPos(blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ())).collect(Collectors.toList())) + .build(); + } + + @Override + public AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type) { + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .build(); + } +} diff --git a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand15.java b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand15.java new file mode 100644 index 00000000..47f58a58 --- /dev/null +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand15.java @@ -0,0 +1,148 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.autocheck.AutoCheckerResult; +import de.steamwar.schematicsystem.autocheck.BlockPos; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +import org.bukkit.Material; + +import java.util.*; +import java.util.stream.Collectors; + +public class SchematicCommand15 implements SchematicCommand.ISchematicCommand { + @Override + public Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, CheckSchemType 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> toBeCheckedInvs = new HashMap<>(); + + toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenItems()); + toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenNbt()); + + for (Map.Entry> entry: toBeCheckedInvs.entrySet()) { + BlockPos pos = entry.getKey(); + Set 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 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.getMaxDispenserItems() > 0 ) { + for (Map.Entry entry : result.getBlockScanResult().getDispenserItems().entrySet()) { + if(entry.getValue() <= type.getMaxDispenserItems()) { + 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 items = tag.getList("Items", CompoundTag.class); + Collections.reverse(items); // To let the first item be in the Dispenser + List list = new ArrayList<>(); + int diff = entry.getValue() - type.getMaxDispenserItems(); + for (CompoundTag item : items) { + if(item == null) { + continue; + } + + if(diff == 0) { + list.add(item); + continue; + } + + if(diff > item.getByte("Count")) { + diff -= item.getByte("Count"); + continue; + } + + item = item.createBuilder().putByte("Count", (byte) (item.getByte("Count") - diff)).build(); + diff = 0; + list.add(item); + } + + builder.put("Items", new ListTag(CompoundTag.class, list)); + clipboard.setBlock(vector, block.toBaseBlock(builder.build())); + } + } + + if(!result.isLimitedBlocksOK()) { + Set toReplace = type.getLimits().entrySet().stream() + .filter(setIntegerEntry -> setIntegerEntry.getValue() == 0) + .flatMap(setIntegerEntry -> setIntegerEntry.getKey().stream()) + .map(Material::matchMaterial) + .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; + } + + @Override + public void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException { + Operations.complete(new ForwardExtentCopy(editSession, clipboard.getRegion(), clipboard, clipboard.getMinimumPoint())); + } +} diff --git a/SchematicSystem/SchematicSystem_8/build.gradle.kts b/SchematicSystem/SchematicSystem_8/build.gradle.kts new file mode 100644 index 00000000..14652dc6 --- /dev/null +++ b/SchematicSystem/SchematicSystem_8/build.gradle.kts @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id("java") + id("base") +} + +group = "de.steamwar" +version = "" + +tasks.compileJava { + options.encoding = "UTF-8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +sourceSets { + main { + java { + srcDirs("src/") + } + resources { + srcDirs("src/") + exclude("**/*.java", "**/*.kt") + } + } +} + +dependencies { + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + compileOnly(project(":SchematicSystem:SchematicSystem_Core")) + compileOnly(project(":SpigotCore")) + + compileOnly("de.steamwar:spigot:1.8") + compileOnly("de.steamwar:worldedit:1.12") +} diff --git a/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/autocheck/AutoChecker8.java b/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/autocheck/AutoChecker8.java new file mode 100644 index 00000000..1dbc8e44 --- /dev/null +++ b/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/autocheck/AutoChecker8.java @@ -0,0 +1,174 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.autocheck; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.regions.Region; +import de.steamwar.schematicsystem.CheckSchemType; +import org.bukkit.Material; + +import java.util.*; +import java.util.stream.Collectors; + +@SuppressWarnings("deprecation") +public class AutoChecker8 implements AutoChecker.IAutoChecker { + private static final int DISPENSER = Material.DISPENSER.getId(); + private static final int JUKEBOX = Material.JUKEBOX.getId(); + private static final int CHEST = Material.CHEST.getId(); + private static final Set INVENTORY = new HashSet<>(); + private static final Set FLOWERS; + + static{ + INVENTORY.add(CHEST); + INVENTORY.add(Material.TRAPPED_CHEST.getId()); + INVENTORY.add(Material.HOPPER.getId()); + INVENTORY.add(Material.FURNACE.getId()); + INVENTORY.add(Material.BURNING_FURNACE.getId()); + INVENTORY.add(JUKEBOX); //RecordItem + INVENTORY.add(DISPENSER); + INVENTORY.add(Material.DROPPER.getId()); + INVENTORY.add(Material.ANVIL.getId()); + INVENTORY.add(Material.BREWING_STAND.getId()); + for(int i = 219; i <= 234; i++) { + INVENTORY.add(i); // ShulkerBoxes + } + + Set flowers = new HashSet<>(); + flowers.add(Material.YELLOW_FLOWER); + flowers.add(Material.RED_ROSE); + flowers.add(Material.DOUBLE_PLANT); + flowers.add(Material.DIAMOND_BARDING); + flowers.add(Material.IRON_BARDING); + flowers.add(Material.GOLD_BARDING); + FLOWERS = flowers; + } + + public void scan(AutoChecker.BlockScanResult result, Clipboard clipboard) { + Region region = clipboard.getRegion(); + Vector min = region.getMinimumPoint(); + Vector max = region.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.getBlock(new Vector(x, y, z)); + final int blockId = block.getId(); + final Material material = Material.getMaterial(blockId); + + result.getBlockCounts().merge(material, 1, Integer::sum); + + if(INVENTORY.contains(blockId)){ + checkInventory(result, block, blockId, new BlockPos(x, y, z)); + } + + if(x == 0 || x == max.getBlockX() - 1 || y == max.getBlockY() - 1 || z == 0 || z == max.getBlockZ() - 1) { + result.getDesignBlocks().computeIfAbsent(material, m -> new ArrayList<>()).add(new BlockPos(x, y, z)); + } + } + } + } + } + + private static final Map> itemsInInv = new EnumMap<>(Material.class); + + static { + itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.TNT, EnumSet.of(Material.CHEST)); + itemsInInv.put(Material.FIREBALL, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); + FLOWERS.forEach(material -> itemsInInv.put(material, INVENTORY.stream().map(Material::getMaterial).collect(Collectors.toCollection(() -> EnumSet.noneOf(Material.class))))); + } + + private static void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, int blockId, BlockPos pos) { + CompoundTag nbt = block.getNbtData(); + if(nbt == null){ + result.getDefunctNbt().add(pos); + return; + } + + if(blockId == JUKEBOX && nbt.getValue().containsKey("RecordItem")){ + result.getRecords().add(pos); + return; + } + + List items = nbt.getList("Items", CompoundTag.class); + if(items.isEmpty()) + return; //Leeres Inventar + + int counter = 0; + for(CompoundTag item : items){ + if(!item.containsKey("id")){ + result.getDefunctNbt().add(pos); + continue; + } + + String materialName = item.getString("id"); + if(materialName.contains(":")) + materialName = materialName.split(":")[1]; + materialName = materialName.toUpperCase().replace("SHOVEL", "SPADE"); + Material itemType = Material.getMaterial(materialName); + if(itemType == null && item.getString("id").equals("minecraft:fire_charge")) + itemType = Material.FIREBALL; + if(itemType == null) //Leere Slots + continue; + + + if(!itemsInInv.getOrDefault(itemType, EnumSet.noneOf(Material.class)).contains(Material.getMaterial(blockId))) { + result.getForbiddenItems().computeIfAbsent(pos, blockPos -> new HashSet<>()).add(Material.getMaterial(blockId)); + } else if(blockId == DISPENSER && (itemType.equals(Material.FIREBALL) || itemType.equals(Material.ARROW))) { + counter += item.getByte("Count"); + } + if(item.containsKey("tag")) { + result.getForbiddenNbt().computeIfAbsent(pos, blockPos -> new HashSet<>()).add(Material.getMaterial(blockId)); + } + } + + result.getDispenserItems().put(pos, counter); + } + + @Override + public AutoCheckerResult check(Clipboard clipboard, CheckSchemType type) { + AutoChecker.BlockScanResult blockScanResult = new AutoChecker.BlockScanResult(); + scan(blockScanResult, clipboard); + + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .blockScanResult(blockScanResult) + .entities(clipboard.getEntities().stream().map(Entity::getLocation).map(blockVector3 -> new BlockPos(blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ())).collect(Collectors.toList())) + .build(); + } + + @Override + public AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type) { + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .build(); + } +} diff --git a/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand8.java b/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand8.java new file mode 100644 index 00000000..ad38643a --- /dev/null +++ b/SchematicSystem/SchematicSystem_8/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand8.java @@ -0,0 +1,42 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +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 de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.autocheck.AutoCheckerResult; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; + +public class SchematicCommand8 implements SchematicCommand.ISchematicCommand { + + @Override + public Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, CheckSchemType type) throws Exception { + return null; + } + + @Override + public void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException { + Operations.complete(new ForwardExtentCopy(editSession, clipboard.getRegion(), clipboard, clipboard.getMinimumPoint())); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/build.gradle.kts b/SchematicSystem/SchematicSystem_Core/build.gradle.kts new file mode 100644 index 00000000..f833cb0f --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/build.gradle.kts @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id("java") + id("base") +} + +group = "de.steamwar" +version = "" + +tasks.compileJava { + options.encoding = "UTF-8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +sourceSets { + main { + java { + srcDirs("src/") + } + resources { + srcDirs("src/") + exclude("**/*.java", "**/*.kt") + } + } +} + +dependencies { + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + compileOnly(project(":SpigotCore")) + + compileOnly("de.steamwar:spigot:1.15") + compileOnly("de.steamwar:worldedit:1.15") +} diff --git a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties new file mode 100644 index 00000000..b5e1c15f --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem.properties @@ -0,0 +1,264 @@ +# +# This file is a part of the SteamWar software. +# +# Copyright (C) 2023 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 . +# + +PREFIX=§eSchematic§8» §7 +ON=§aon +OFF=§coff +CHANGE=§7To change +CLICK=§7Click +CLICK_DRAG_ITEM=§7Click or drag item here +CURRENT=§7Current: {0} +CONFIRM=§aConfirm +CANCEL=§cCancel + +UTIL_NAME_REQUIRED=§cFolder name required +UTIL_NAME_TOO_LONG=§cSchematic name too long +UTIL_NAME_INVALID_CHAR=§cThe specified schema name contains forbidden characters +UTIL_NAME_FORBIDDEN=§cThe path must not contain \"§l{0}§c\" +UTIL_LIST_HEAD=§eSchematics §8(§e{0}§8) +UTIL_LIST_PATH=§7Current path: §e{0} +UTIL_LIST_BACK=§e../ +UTIL_LIST_BACK_HOVER=§eBack {0} +UTIL_LIST_DIR=§7§lDIR +UTIL_LIST_TYPE=§8§l{0} +UTIL_LIST_BASE=§e +UTIL_LIST_FROM=§8from §7{0} +UTIL_LIST_OPEN_DIR=§eShow directory +UTIL_LIST_OPEN_SCHEM=§eManage schematics +UTIL_LIST_REMOVE=[Remove] +UTIL_LIST_REMOVE_HOVER=§7Remove yourself from the directory +UTIL_LIST_BACK_ARROW=«« +UTIL_LIST_BACK_ARROW_HOVER=§ePrevious page +UTIL_LIST_NEXT=Page ({0}/{1}) »» +UTIL_LIST_NEXT_HOVER=§eNext page +UTIL_INFO_SCHEM=§7Schematic: §e{0} +UTIL_INFO_NAME=§7Name: §e{0} +UTIL_INFO_OWNER=§7Owner: §e{0} +UTIL_INFO_PARENT=§7Directory: §e{0} +UTIL_INFO_UPDATED=§7Last update: §e{0} +UTIL_INFO_TYPE=§7Type: §e{0} +UTIL_INFO_TYPE_DIR=§eDIR +UTIL_INFO_RANK=§7Rank: §e{0} +UTIL_INFO_COLOR=§7Color translation: {0} +UTIL_INFO_REPLAY=§7Replay playback: {0} +UTIL_INFO_ELO=§7Elo: §e{0} +UTIL_INFO_FORMAT=§7Format: §e{0} +UTIL_INFO_STATUS=§cState: §c{0}: {1} +UTIL_INFO_MEMBER=§7Members: §e{0} +UTIL_INFO_MEMBER_STRING=Members: +UTIL_INFO_ACTION_LOAD=(Load) +UTIL_INFO_ACTION_LOAD_HOVER=§eLoad schematic +UTIL_INFO_ACTION_DOWNLOAD=(Download) +UTIL_INFO_ACTION_DOWNLOAD_HOVER=§eDownload schematic +UTIL_INFO_ACTION_TYPE_HOVER=§eChange schematic type +UTIL_INFO_ACTION_ADD_HOVER=§eAdd member +UTIL_INFO_ACTION_REMOVE_HOVER=§eRemove {0} +UTIL_INFO_ACTION_MOVE_HOVER=§eMove schematic +UTIL_INFO_ACTION_RENAME_HOVER=§eRename schematic +UTIL_INFO_ACTION_DELETE=(Delete) +UTIL_INFO_ACTION_DELETE_HOVER=§eDelete schematic +UTIL_LOAD_NOT_HERE=§cYou cannot load schematics here +UTIL_LOAD_NOT_HERE_ALL=§cSchematics cannot be loaded on this build +UTIL_LOAD_DIR=§cYou cannot load folders +UTIL_LOAD_DONE=§7Schematic §e{0} loaded +UTIL_LOAD_NO_DATA=§cNo data could be found in the Schematic +UTIL_LOAD_ERROR=§cThe schematic could not be loaded +UTIL_DOWNLOAD_PUNISHED=§cYou are not allowed to download schematics: §f§l{0} +UTIL_DOWNLOAD_NOT_OWN=§cYou may download only your own schematics +UTIL_DOWNLOAD_LINK=Your download link: +UTIL_TYPE_PUNISHED=§cYou are not allowed to submit schematics: §f§l{0} +UTIL_TYPE_NOT_OWN=§cYou can only submit your own schematics +UTIL_TYPE_DIR=§cYou cannot submit folders +UTIL_TYPE_NOT_ASSIGNABLE=§cSchematics cannot be changed for this type +UTIL_TYPE_ALREADY=§cThe Schematic already has this type +UTIL_TYPE_DONE=§aChange schematic type +UTIL_TYPE_FIGHT_ALREADY=§cYou have already submitted this schematic +UTIL_TYPE_AFTER_DEADLINE=§cSchematics of this type can no longer be submitted. Deadline was: {0} +UTIL_TYPE_ERROR=§cThe Schematic is not compliant with the rules +UTIL_TYPE_EXTEND=§aThe preparation server is starting +UTIL_SUBMIT_TITLE=Extend Schematic +UTIL_SUBMIT_REPLAY_ON=§aReplay allowed +UTIL_SUBMIT_REPLAY_OFF=§cReplay locked +UTIL_SUBMIT_COLOR_ON=§aReplace pink to team color +UTIL_SUBMIT_COLOR_OFF=§cDo not replace pink +UTIL_SUBMIT_DIRECT=§eSubmit directly +UTIL_SUBMIT_DIRECT_DONE=§aThe Schematic will be reviewed in a timely manner +UTIL_SUBMIT_EXTEND=§eExtend Schematic +UTIL_SUBMIT_EXTEND_DONE=§aThe preparation server is starting +UTIL_CHECK_TYPE_NOT_FOUND=§cThe type {0} was not found +UTIL_CHECK_SUCCESS=§aThe schematic was checked successfully + +COMMAND_INVALID_NODE=§cInvalid Schematic +COMMAND_NOT_OWN=§cYou can only use this command on your own Schematic +COMMAND_MUST_DIR=§cYou can only use this command on a directory +COMMAND_MUST_SCHEM=§cYou can only use this command on a Schematic +COMMAND_ENTER_NAME=Insert name +COMMAND_PUNISHMENT_NO_SAVE_EXTERNAL=§cYou can not make schematics on other build server +COMMAND_PUNISHMENT_NO_SAVE=§cSchematics cannot be made on this build +COMMAND_SAVE_NO_NAME=§cYou must also specify a name for the schematic after the folder +COMMAND_SAVE_FOLDER=§cSchematic is a folder +COMMAND_SAVE_NO_OVERWRITE=§cYou must not overwrite this Schematic +COMMAND_SAVE_CLIPBOARD_EMPTY=§cYour clipboard is empty +COMMAND_SAVE_ERROR=§cError while saving the Schematic +COMMAND_SAVE_DONE=Schematic §e{0} §7stored +COMMAND_SAVE_OVERWRITE=Schematic §e{0} §7overwritten +COMMAND_SAVE_OVERWRITE_CONFIRM=§cThe Schematic §e{0} §calready exists. Do you want to overwrite it? §e*click* +COMMAND_SAVE_OVERWRITE_CONFIRM_HOVER=§eOverwrite Schematic +COMMAND_ADD_PUNISH=§cYou may not add anyone to your schematics: §f§l{0} +COMMAND_ADD_USER_PUNISHED=§c{0} must not be added to schematics +COMMAND_ADD_OWN=§cSo please: This is your own Schematic! +COMMAND_ADD_PUBLIC=§cFor public requests please contact the moderator +COMMAND_ADD_ALREADY=§c{0} is already added to this schematic +COMMAND_ADD_ADDED=You now have access to the Schematic §e{0} §7of §e{1} +COMMAND_ADD_NONE=§cNo player has been added +COMMAND_ADD_ONE=§7The player §e{0} was added to the schematic +COMMAND_ADD_MANY=§7The players §e{0} were added to the schematic +COMMAND_DELMEM_DONE=The player §e{0} §7no longer has access to the Schematic §e{1} +COMMAND_DELMEM_DELETED=§cYou now no longer have access to the Schematic §e{0} §7of §e{1} +COMMAND_SEARCH_NOT_A_PLAYER=§cThe player §e{0} §cdoes not exists +COMMAND_LOCKREPLAY=Replays of fights with {0} can no longer be viewed from now on +COMMAND_REPLACE_COLOR_OFF=In fights {0} pink blocks are not replaced +COMMAND_REPLACE_COLOR_ON=In fights {0} pink blocks are replaced +COMMAND_DIR_DONE=§7Directory §e{0} §7created +COMMAND_CHANGE_TYPE_SELECT=§eSelect type +COMMAND_MOVE_RECURSIVE=§cThis only gives mistakes, trust me +COMMAND_MOVE_DONE=§7The schematic can now be found under §e{0} +COMMAND_RENAME_DONE=§7The schematic is now called §e{0} +COMMAND_ADD_TEAM_NOT_IN_TEAM=§cYou are not in any team +COMMAND_DEL_TEAM_NOT_IN_TEAM=§cYou are not in any team +COMMAND_DEL_TEAM_NONE=§7No player was removed +COMMAND_DEL_TEAM_DONE=§7The player §e{0} §7were removed from the Schematic +COMMAND_CLEAR_MEMBER_DONE=§7All players were removed from the Schematic +COMMAND_DEL_ALL_MEMBER=§e{0} §7has been removed from §e{1} §7Schematics +COMMAND_PUBLIC_ON=§aYou are now the public user +COMMAND_PUBLIC_OFF=§cYou are no longer the public user +COMMAND_DELETE_NOT_OWN=§cThe schematic is not yours +COMMAND_DELETE_MEMBER=§aYou have removed yourself from the Schematic +COMMAND_DELETE_DIR=§aThe folder §e{0}§a is deleted... +COMMAND_DELETE_DIR_FULL=§cThe folder must be empty to delete it +COMMAND_DELETE_SCHEM=§aThe Schematic §e{0}§a is deleted... +COMMAND_CHECK_SELECTION_INCOMPLETE=§cThe selection is incomplete +COMMAND_CHECK_CLIPBOARD_EMPTY=§cThe clipboard is empty +COMMAND_FIX_OK=§aThe schematic is already fixed +COMMAND_FIX_DONE=§aThe schematic has been fixed +COMMAND_FIX_COULD_NOT_FIX=§cCould not fix this in the schematic +COMMAND_FIX_MANUAL=manually fix +COMMAND_FIX_ERROR=§cError while fixing the schematic, please contact a developer +COMMAND_FIX_WRONG_VERSION=§cThis feature is only available for version 1.15 and greater + +HELP_HEADER=§e§lSchematicSystem §8§lHelp +HELP_VIEW=Find & Load +HELP_VIEW_HOVER=Search or download schematics +HELP_VIEW_1=§8/§7schem §einfo §8[§7schematic§8] - §7Shows information about the schematic +HELP_VIEW_2=§8/§7schem §elist §8- §7Shows you your schematics +HELP_VIEW_3=§8/§7schem §elist public §8- §7Shows all public schematics +HELP_VIEW_4=§8/§7schem §esearch §8[§7keyword§8] - §7Searches for matching schematics +HELP_VIEW_5=§8/§7schem §eload §8[§7schematic§8] - §7Loads a schematic +HELP_VIEW_6=§8/§7schem §edownload §8[§7schematic§8] - §7Gives you a download link (valid for 1 min) +HELP_VIEW_7=§8/§7download §8- §7Gives you a download link for your current clipboard (valid for 1 min) +HELP_VIEW_8=§8/§7schem §echeck §8[§7schematic§8|§7selection§8|§7clipboard§8] [§7schematictype§8] - §7Checks the schematic for errors +HELP_EDIT=Save & Edit +HELP_EDIT_HOVER=Modification of schematics and folders +HELP_EDIT_1=§8/§7schem §esave §8[§7schematic§8] - §7Saves your clipboard as a schematic +HELP_EDIT_2=§8/§7schem §eordner §8[§7directory§8] - §7Create an empty folder +HELP_EDIT_3=§8/§7schem §emove §8[§7schematic§8] [§7new path§8] - §7Move a schematic +HELP_EDIT_4=§8/§7schem §erename §8[§7schematic§8] [§7new path§8] - §7Give the schematic a new name +HELP_EDIT_5=§8/§7schem §echangetype §8[§7schematic§8] - §7Changes the type of your schematic +HELP_EDIT_6=§8/§7schem §elockreplay §8[§7schematic§8] - §7Locks replays of the schematic +HELP_EDIT_7=§8/§7schem §ereplacecolor §8[§7schematic§8] - §7Changes color substitution in the arena +HELP_EDIT_8=§8/§7schem §edelete §8[§7schematic§8] - §7Deletes a schematic +HELP_EDIT_9=§8/§7schem §efix §8[§7schematictype§8] - §7Tries to fix the schematic in your clipboard +HELP_SHARE=Ownership +HELP_SHARE_HOVER=Share Schematics with others +HELP_SHARE_1=§8/§7schem §eaddmember §8[§7schematic§8] §8[§7Spieler§8] - §7Adds a player to a schematic +HELP_SHARE_2=§8/§7schem §edelmember §8[§7schematic§8] §8[§7Spieler§8] - §7Removes a player from a schematic +HELP_SHARE_3=§8/§7schem §eclearmember §8[§7schematic§8] - §7Removes all players from the schematic +HELP_SHARE_4=§8/§7schem §edelallmember §8[§7player§8] - §7Removes a player from all your schematics +HELP_SHARE_5=§8/§7schem §eaddteam §8[§7schematic§8] - §7Add everyone from your team to the schematic +HELP_SHARE_6=§8/§7schem §edelteam §8[§7schematic§8] - §7Remove everyone from your team from the Schematic + +GUI_TITLE=Schematics \{1\} +GUI_FOLDER_PROPERTIES=§7Directory properties +GUI_INFO_LOAD=§eLoading +GUI_INFO_BACK=§eBack +GUI_INFO_STATUS=§eState {0} +GUI_INFO_STATUS_LORE=§7{0} +GUI_INFO_MAT=§e{0} +GUI_INFO_TYPE=§e{0} +GUI_INFO_DOWNLOAD=§eDownload +GUI_INFO_COLOR=Color translation +GUI_INFO_REPLAY=Replay playback +GUI_INFO_REPLAY_OFF=§7§lTurn off +GUI_INFO_REPLAY_TITLE=Lock playback permanently +GUI_INFO_MEMBER=§eMembers +GUI_INFO_MOVE=§eMove +GUI_INFO_RENAME=§eRename +GUI_INFO_RENAME_TITLE={0} rename +GUI_INFO_DELETE=§cDelete +GUI_INFO_MEMBER_FROM=§7Owner §e{0} +GUI_INFO_MEMBER_REMOVE=§cRemove access +GUI_CHANGE_TYPE=Change type +GUI_CHANGE_TYPE_NOT_POSSIBLE=§cThe Schematic is too big +GUI_CHANGE_TYPE_NOT_POSSIBLE_COLOR=§7{0} +GUI_DELETE_OWN_DELETED=Schematic §e{0} §7deleted +GUI_DELETE_OWN_TITLE=Delete {0} +GUI_DELETE_MEMBER_TITLE=Remove {0} +GUI_DELETE_MEMBER_DONE=Access to Schematic §e{0} §7removed +GUI_DELETE_MEMBERS_TITLE=Remove members +GUI_CHANGE_ITEM=Change item + +AUTO_CHECK_RESULT_NOT_LOAD=The schematic could not be loaded +AUTO_CHECK_RESULT_TOO_WIDE=The schematic is too wide ({0} > {1}) +AUTO_CHECK_RESULT_TOO_LONG=The schematic is too long ({0} > {1}) +AUTO_CHECK_RESULT_TOO_HIGH=The schematic is too high ({0} > {1}) +AUTO_CHECK_RESULT_TOO_MANY_BLOCK=The block {0} was used {1} times too often +AUTO_CHECK_RESULT_TOO_MANY_BLOCKS=The block combination {0} was used {1} times too often +AUTO_CHECK_RESULT_TOO_MANY_ALL_BLOCKS=Too many blocks ({0} > {1}) +AUTO_CHECK_RESULT_TOO_MANY_RECORDS=No records allowed ({0} found) +AUTO_CHECK_RESULT_FORBIDDEN_ITEM=In {0}s the forbidden item {1} {2} times was found +AUTO_CHECK_RESULT_FORBIDDEN_ITEM_NBT=In {0}s the forbidden item {1} {2} times was found with custom tag +AUTO_CHECK_RESULT_TOO_MANY_DISPENSER_ITEMS=One launcher contains more than {0} arrows and fireballs +AUTO_CHECK_RESULT_TOO_MANY_DISPENSERS_ITEMS={0} launchers contains more than {1} arrows and fireballs +AUTO_CHECK_RESULT_NBTS_WARNING={0} {1}s contain no or incorrect NBT data +AUTO_CHECK_RESULT_NBT_WARNING=One {0} contains no or incorrect NBT data. + +SAFE_NODE_NOT_A_DIR=§cThe selected Schematic is not a folder +SAFE_NODE_ALREADY_IN_DIRECTORY=§cThe schematic is already available in this folder +SAFE_NODE_INVALID_NAME=§cThis name is illegal +SAFE_NODE_NOT_OWNER=§cYou are not the owner of this schematic + +DOWNLOAD_ERROR=§cAn error occurred while uploading the schematic + +AUTO_CHECKER_RESULT_HEADER=§7---=== (§eAuto-Check: {0}§7) ===--- +AUTO_CHECKER_RESULT_WIDTH =§7Width: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_LENGTH=§7Length: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_HEIGHT=§7Height: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_BLOCKS=§7Blocks: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_UNKNOWN_MATERIAL=§7Unknown block: §c{0} +AUTO_CHECKER_RESULT_TOO_MANY_BLOCK=§7{0}: §c{1}§7, Max: §e{2} +AUTO_CHECKER_RESULT_FORBIDDEN_BLOCK=§7Forbidden block: §c{0} +AUTO_CHECKER_RESULT_FORBIDDEN_ITEM=§7Forbidden Item: [{0}, {1}, {2}] -> §c{3} +AUTO_CHECKER_RESULT_DEFUNCT_NBT=§7Defunct NBT: §7[{0}, {1}, {2}] +AUTO_CHECKER_RESULT_DESIGN_BLOCK=§7{0} in Design: [{1}, {2}, {3}] +AUTO_CHECKER_RESULT_ENTITY=§7Entity: §7[{0}, {1}, {2}] +AUTO_CHECKER_RESULT_RECORD=§7Record: §c[{0}, {1}, {2}] +AUTO_CHECKER_RESULT_TOO_MANY_DISPENSER_ITEMS=§7Dispenser: §c[{0}, {1}, {2}]§7, §c{3} §7items, Max: §e{4} +AUTO_CHECKER_RESULT_FORBIDDEN_ITEM_NBT=§7Forbidden Item NBT: [{0}, {1}, {2}] -> §c{3} +AUTO_CHECKER_RESULT_TELEPORT_HERE=§7Teleport to block +AUTO_CHECKER_RESULT_AFTER_DEADLINE=§cThe deadline has expired: {0} \ No newline at end of file diff --git a/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties new file mode 100644 index 00000000..cf370bcb --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/SchematicSystem_de.properties @@ -0,0 +1,243 @@ +# +# This file is a part of the SteamWar software. +# +# Copyright (C) 2023 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 . +# + +ON=§aAn +OFF=§cAus +CHANGE=§7Zum Ändern +CLICK=§7anklicken +CLICK_DRAG_ITEM=§7anklicken oder hier Item hineinlegen +CURRENT=§7Aktuell: {0} +CONFIRM=§aBestätigen +CANCEL=§cAbbrechen + +UTIL_NAME_REQUIRED=§cDeine Ordner brauchen schon einen Namen +UTIL_NAME_TOO_LONG=§cDer Name der Schematic ist zu lang +UTIL_NAME_INVALID_CHAR=§cDer angegebene Schematicname enthält verbotene Zeichen +UTIL_NAME_FORBIDDEN=§cDer Pfad darf nicht \"§l{0}§c\" enthalten +UTIL_LIST_PATH=§7Aktueller Pfad: §e{0} +UTIL_LIST_BACK_HOVER=§eZurück gehen {0} +UTIL_LIST_FROM=§8von §7{0} +UTIL_LIST_OPEN_DIR=§eOrdner anzeigen +UTIL_LIST_OPEN_SCHEM=§eSchematic verwalten +UTIL_LIST_REMOVE=[Entfernen] +UTIL_LIST_REMOVE_HOVER=§7Entferne dich von dem Ordner +UTIL_LIST_BACK_ARROW_HOVER=§eVorherige Seite +UTIL_LIST_NEXT=Seite ({0}/{1}) »» +UTIL_LIST_NEXT_HOVER=§eNächste Seite +UTIL_INFO_OWNER=§7Besitzer: §e{0} +UTIL_INFO_PARENT=§7Ordner: §e{0} +UTIL_INFO_UPDATED=§7Letzes Update: §e{0} +UTIL_INFO_TYPE=§7Typ: §e{0} +UTIL_INFO_RANK=§7Rang: §e{0} +UTIL_INFO_COLOR=§7Farbersetzung: {0} +UTIL_INFO_REPLAY=§7Replaywiedergabe: {0} +UTIL_INFO_STATUS=§cStatus: §c{0}: {1} +UTIL_INFO_MEMBER=§7Mitglieder: §e{0} +UTIL_INFO_MEMBER_STRING=Mitglieder: +UTIL_INFO_ACTION_LOAD=(Laden) +UTIL_INFO_ACTION_LOAD_HOVER=§eSchematic laden +UTIL_INFO_ACTION_DOWNLOAD_HOVER=§eSchematic downloaden +UTIL_INFO_ACTION_TYPE_HOVER=§eSchematic Typ ändern +UTIL_INFO_ACTION_ADD_HOVER=§eMember hinzufügen +UTIL_INFO_ACTION_REMOVE_HOVER=§e{0} entfernen +UTIL_INFO_ACTION_MOVE_HOVER=§eSchematic verschieben +UTIL_INFO_ACTION_RENAME_HOVER=§eSchematic umbenennen +UTIL_INFO_ACTION_DELETE=(Löschen) +UTIL_INFO_ACTION_DELETE_HOVER=§eSchematic löschen +UTIL_LOAD_NOT_HERE=§cDu kannst hier keine Schematics laden +UTIL_LOAD_NOT_HERE_ALL=§cAuf diesem Bau können keine Schematics geladen werden +UTIL_LOAD_DIR=§cDu kannst keine Ordner Laden +UTIL_LOAD_DONE=§7Schematic §e{0} geladen +UTIL_LOAD_NO_DATA=§cEs konnte keine Daten in der Schematic gefunden werden +UTIL_LOAD_ERROR=§cDie Schematic konnte nicht geladen werden +UTIL_DOWNLOAD_PUNISHED=§cDu darf keine Schematics Downloaden: §f§l{0} +UTIL_DOWNLOAD_NOT_OWN=§cDu darfst nur deine eigenen Schematics herunterladen +UTIL_DOWNLOAD_LINK=Dein Download Link: +UTIL_TYPE_PUNISHED=§cDu darf keine Schematics einsenden: §f§l{0} +UTIL_TYPE_NOT_OWN=§cDu kannst nur deine eigenen Schematics einsenden +UTIL_TYPE_DIR=§cDu kannst keine Ordner einsenden +UTIL_TYPE_NOT_ASSIGNABLE=§cZu diesem Typen können keine Schematics geändert werden +UTIL_TYPE_ALREADY=§cDie Schematic hat schon diesen Typen +UTIL_TYPE_DONE=§aSchematictyp geändert +UTIL_TYPE_FIGHT_ALREADY=§cDu hast diese Schematic bereits eingesendet +UTIL_TYPE_AFTER_DEADLINE=§cVon diesem Typen können keine Schematics mehr eingesendet werden. Einsendeschluss war: {0} +UTIL_TYPE_ERROR=§cDie Schematic ist nicht regelkonform +UTIL_TYPE_EXTEND=§aDer Vorbereitungsserver wird gestartet +UTIL_SUBMIT_TITLE=Schematic ausfahren +UTIL_SUBMIT_REPLAY_ON=§aReplay erlaubt +UTIL_SUBMIT_REPLAY_OFF=§cReplay gesperrt +UTIL_SUBMIT_COLOR_ON=§aPink zu Teamfarbe ersetzen +UTIL_SUBMIT_COLOR_OFF=§cPink nicht ersetzen +UTIL_SUBMIT_DIRECT=§eDirekt einsenden +UTIL_SUBMIT_DIRECT_DONE=§aDie Schematic wird zeitnah überprüft +UTIL_SUBMIT_EXTEND=§eSchematic ausfahren +UTIL_SUBMIT_EXTEND_DONE=§aDer Vorbereitungsserver wird gestartet + +COMMAND_INVALID_NODE=§cDie Schematic konnte nicht gefunden werden +COMMAND_NOT_OWN=§cDas darfst du nur bei deinen eigenen Schematics machen +COMMAND_MUST_DIR=§cDu musst einen Ordner angeben +COMMAND_MUST_SCHEM=§cDu musst eine Schematic angeben +COMMAND_ENTER_NAME=Namen eingeben +COMMAND_PUNISHMENT_NO_SAVE_EXTERNAL=§cDu kannst nicht auf anderen Baus Schematics machen +COMMAND_PUNISHMENT_NO_SAVE=§cAuf diesem Bau können keine Schematics gemacht werden +COMMAND_SAVE_NO_NAME=§cDu must auch einen Namen für die Schematic nach dem Ordner angeben +COMMAND_SAVE_FOLDER=§cDie Schematic ist ein Ordner +COMMAND_SAVE_NO_OVERWRITE=§cDu darfst diese Schematic nicht überschreiben +COMMAND_SAVE_CLIPBOARD_EMPTY=§cDein Clipboard ist leer +COMMAND_SAVE_ERROR=§cFehler beim Speichern der Schematic +COMMAND_SAVE_DONE=Schematic §e{0} §7gespeichert +COMMAND_SAVE_OVERWRITE=Schematic §e{0} §7überschrieben +COMMAND_SAVE_OVERWRITE_CONFIRM=§cDie Schematic §e{0} §7existiert bereits. Möchtest du sie überschreiben? §e*klick* +COMMAND_SAVE_OVERWRITE_CONFIRM_HOVER=§eSchematic überschreiben +COMMAND_ADD_PUNISH=§cDu darfst niemanden auf deine Schematics hinzufügen: §f§l{0} +COMMAND_ADD_USER_PUNISHED=§c{0} darf nicht auf Schematics hinzugefügt werden +COMMAND_ADD_OWN=§cAlso bitte: Das ist deine eigene Schematic! +COMMAND_ADD_PUBLIC=§cFür Public-Anträge bitte bei der Moderation melden +COMMAND_ADD_ALREADY=§c{0} ist bereits auf diese Schematic geaddet +COMMAND_ADD_ADDED=Du hast nun Zugriff auf die Schematic §e{0} §7von §e{1} +COMMAND_ADD_NONE=§cEs wurde kein Spieler hinzugefügt +COMMAND_ADD_ONE=§7Der Spieler §e{0} wurde auf die Schematic hinzugefügt +COMMAND_ADD_MANY=§7Die Spieler §e{0} wurden auf die Schematic hinzugefügt +COMMAND_DELMEM_DONE=Der Spieler §e{0} §7hat nun keinen Zugriff mehr auf die Schematic §e{1} +COMMAND_DELMEM_DELETED=§cDu hast nun keinen Zugriff mehr auf die Schematic §e{0} §7von §e{1} +COMMAND_SEARCH_NOT_A_PLAYER=§cDer Spieler §e{0} §cexistiert nicht +COMMAND_LOCKREPLAY=Replays von Kämpfen mit {0} können ab sofort nicht mehr betrachtet werden +COMMAND_REPLACE_COLOR_OFF=In Kämpfen {0} werden pinke Blöcke nicht ersetzt +COMMAND_REPLACE_COLOR_ON=In Kämpfen {0} werden pinke Blöcke ersetzt +COMMAND_DIR_DONE=§7Ordner §e{0} §7erstellt +COMMAND_CHANGE_TYPE_SELECT=§eTyp auswählen +COMMAND_MOVE_RECURSIVE=§cDas gibt nur Fehler, vertrau mir +COMMAND_MOVE_DONE=§7Die Schematic ist nun unter §e{0} §7zu finden +COMMAND_RENAME_DONE=§7Die Schematic heißt nun §e{0} +COMMAND_ADD_TEAM_NOT_IN_TEAM=§cDu bist in keinem Team +COMMAND_DEL_TEAM_NOT_IN_TEAM=§cDu bist in keinem Team +COMMAND_DEL_TEAM_NONE=§7Es wurde kein Spieler entfernt +COMMAND_DEL_TEAM_DONE=§7Der Spieler §e{0} §7wurden von der Schematic entfernt +COMMAND_CLEAR_MEMBER_DONE=§7Alle Spieler wurden von der Schematic entfernt +COMMAND_DEL_ALL_MEMBER=§e{0} §7wurde von §e{1} §7Schematics entfernt +COMMAND_PUBLIC_ON=§aDu bist nun der Public User +COMMAND_PUBLIC_OFF=§cDu bist nun nicht mehr der Public User +COMMAND_DELETE_NOT_OWN=§cDie Schematic gehört dir nicht +COMMAND_DELETE_MEMBER=§aDu hast dich von der Schematic entfernt +COMMAND_DELETE_DIR=§aDer Ordner §e{0}§a wird gelöscht... +COMMAND_DELETE_DIR_FULL=§cDer Ordner muss leer sein, um ihn zu löschen +COMMAND_DELETE_SCHEM=§aDie Schematic §e{0}§a wird gelöscht... +COMMAND_CHECK_SELECTION_INCOMPLETE=§cDeine Auswahl ist unvollständig +COMMAND_CHECK_CLIPBOARD_EMPTY=§cDein Clipboard ist leer +COMMAND_FIX_OK=§aDie Schematic ist bereits gefixt +COMMAND_FIX_DONE=§aDie Schematic wurde repariert +COMMAND_FIX_COULD_NOT_FIX=§cKonnte diese nicht sachen in der Schematic reparieren +COMMAND_FIX_MANUAL=Manuel Fixen +COMMAND_FIX_ERROR=§cFehler beim Fixen der Schematic, bitte kontaktiere einen Developer +COMMAND_FIX_WRONG_VERSION=§cDiese Funktion ist nur für Version 1.15 und höher verfügbar + +HELP_HEADER=§e§lSchematicSystem §8§lHilfe +HELP_VIEW=Finden & Laden +HELP_VIEW_HOVER=Suche oder lade Schematics +HELP_VIEW_1=§8/§7schem §einfo §8[§7Schematic§8] - §7Zeigt dir Informationen zur Schematic +HELP_VIEW_2=§8/§7schem §elist §8- §7Zeigt dir deine Schematics an +HELP_VIEW_3=§8/§7schem §elist public §8- §7Zeigt alle Public-Schematics +HELP_VIEW_4=§8/§7schem §esearch §8[§7Stichwort§8] - §7Sucht nach passenden Schematics +HELP_VIEW_5=§8/§7schem §eload §8[§7Schematic§8] - §7Lädt eine Schematic +HELP_VIEW_6=§8/§7schem §edownload §8[§7Schematic§8] - §7Gibt dir einen Downloadlink (1 min gültig) +HELP_VIEW_7=§8/§7download §8- §7Gibt dir einen Downloadlink von deinem Clipboard (1 min gültig) +HELP_VIEW_8=§8/§7schem §echeck §8[§7Schematic§8|§7selection§8|§7clipboard§8] [§7SchematicTyp§8] - §7Überprüft deine Schematic +HELP_EDIT=Speichern & Bearbeiten +HELP_EDIT_HOVER=Modifizierung von Schematics und Ordnern +HELP_EDIT_1=§8/§7schem §esave §8[§7Schematic§8] - §7Speichert dein Clipboard als Schematic +HELP_EDIT_2=§8/§7schem §eordner §8[§7Ordner§8] - §7Erstelle einen leeren Ordner +HELP_EDIT_3=§8/§7schem §emove §8[§7Schematic§8] [§7Neuer Pfad§8] - §7Verschiebe eine Schematic +HELP_EDIT_4=§8/§7schem §erename §8[§7Schematic§8] [§7Neuer Name§8] - §7Gib der Schematic einen neuen Namen +HELP_EDIT_5=§8/§7schem §echangetype §8[§7Schematic§8] - §7Ändert die Art deiner Schematic +HELP_EDIT_6=§8/§7schem §elockreplay §8[§7Schematic§8] - §7Sperrt Replays mit der Schematic +HELP_EDIT_7=§8/§7schem §ereplacecolor §8[§7Schematic§8] - §7Ändert Farbersetzung in der Arena +HELP_EDIT_8=§8/§7schem §edelete §8[§7Schematic§8] - §7Löscht eine Schematic +HELP_EDIT_9=§8/§7schem §efix §8[§7SchematicTyp§8] - §7Versucht die Schematic in deinem Clipboard konform zu machen +HELP_SHARE=Besitzrechte +HELP_SHARE_HOVER=Schematics mit anderen teilen +HELP_SHARE_1=§8/§7schem §eaddmember §8[§7Schematic§8] §8[§7Spieler§8] - §7Fügt einen Spieler zu einer Schematic hinzu +HELP_SHARE_2=§8/§7schem §edelmember §8[§7Schematic§8] §8[§7Spieler§8] - §7Entfernt einen Spieler von einer Schematic +HELP_SHARE_3=§8/§7schem §eclearmember §8[§7Schematic§8] - §7Entfernt alle Spieler von der Schematic +HELP_SHARE_4=§8/§7schem §edelallmember §8[§7Spieler§8] - §7Entfernt einen Spieler von allen deinen Schematics +HELP_SHARE_5=§8/§7schem §eaddteam §8[§7Schematic§8] - §7Füge jeden aus deinem Team auf die Schematic hinzu +HELP_SHARE_6=§8/§7schem §edelteam §8[§7Schematic§8] - §7Entferne jeden aus deinem Team von der Schematic + +GUI_TITLE=Schematics \{1\} +GUI_FOLDER_PROPERTIES=§7Ordnereigenschaften +GUI_INFO_LOAD=§eLaden +GUI_INFO_BACK=§eZurück +GUI_INFO_STATUS=§eStatus {0} +GUI_INFO_COLOR=Farbersetzung +GUI_INFO_REPLAY=Replay Wiedergabe +GUI_INFO_REPLAY_OFF=§7Zum §lAusschalten +GUI_INFO_REPLAY_TITLE=Wiedergabe dauerhaft sperren +GUI_INFO_MEMBER=§eMitglieder +GUI_INFO_MOVE=§eVerschieben +GUI_INFO_RENAME=§eUmbenennen +GUI_INFO_RENAME_TITLE={0} umbenennen +GUI_INFO_DELETE=§cLöschen +GUI_INFO_MEMBER_FROM=§7von §e{0} +GUI_INFO_MEMBER_REMOVE=§cZugriff entfernen +GUI_CHANGE_TYPE=Typ ändern +GUI_CHANGE_TYPE_NOT_POSSIBLE=§cDie Schematic ist zu groß +GUI_DELETE_OWN_DELETED=Schematic §e{0} §7gelöscht +GUI_DELETE_OWN_TITLE={0} löschen +GUI_DELETE_MEMBER_TITLE={0} entfernen +GUI_DELETE_MEMBER_DONE=Zugriff zu Schematic §e{0} §7entfernt +GUI_DELETE_MEMBERS_TITLE=Mitglieder entfernen +GUI_CHANGE_ITEM=Item ändern + +AUTO_CHECK_RESULT_NOT_LOAD=Die Schematic konnte nicht geladen werden +AUTO_CHECK_RESULT_TOO_WIDE=Die Schematic ist zu breit ({0} > {1}) +AUTO_CHECK_RESULT_TOO_LONG=Die Schematic ist zu lang ({0} > {1}) +AUTO_CHECK_RESULT_TOO_HIGH=Die Schematic ist zu hoch ({0} > {1}) +AUTO_CHECK_RESULT_TOO_MANY_BLOCK=Der Block {0} wurde {1} mal zu häufig verbaut +AUTO_CHECK_RESULT_TOO_MANY_BLOCKS=Die Blockkombination {0} wurde {1} mal zu häufig verbaut +AUTO_CHECK_RESULT_TOO_MANY_ALL_BLOCKS=Zu viele Blöcke ({0} > {1}) +AUTO_CHECK_RESULT_TOO_MANY_RECORDS=Keine Schallplatten erlaubt ({0} gefunden) +AUTO_CHECK_RESULT_FORBIDDEN_ITEM=In {0}s wurde das verbotene Item {1} {2} mal gefunden +AUTO_CHECK_RESULT_FORBIDDEN_ITEM_NBT=In {0}s wurde das verbotene Item {1} {2} mal mit Custom-Tag gefunden +AUTO_CHECK_RESULT_TOO_MANY_DISPENSER_ITEMS=Ein Werfer enthält mehr als {0} Pfeile und Feuerbälle +AUTO_CHECK_RESULT_TOO_MANY_DISPENSERS_ITEMS={0} Werfer enthält mehr als {1} Pfeile und Feuerbälle +AUTO_CHECK_RESULT_NBTS_WARNING={0} {1}s enthalten keine oder inkorrekte NBT-Daten +AUTO_CHECK_RESULT_NBT_WARNING=Ein(e) {0} enthält keine oder inkorrekte NBT-Daten + +SAFE_NODE_NOT_A_DIR=§cDie ausgewählte Schematic ist kein Ordner +SAFE_NODE_ALREADY_IN_DIRECTORY=§cDie Schematic gibt es bereits in diesem Ordner +SAFE_NODE_INVALID_NAME=§cDieser Name ist unzulässig +SAFE_NODE_NOT_OWNER=§cDu bist nicht der Besitzer dieser Schematic + +DOWNLOAD_ERROR=§cFehler beim Hochladen deines Clipboards + +AUTO_CHECKER_RESULT_HEADER=§7---=== (§eAutoPrüfer: {0}§7) ===--- +AUTO_CHECKER_RESULT_WIDTH=§7Breite: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_LENGTH=§7Länge: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_HEIGHT=§7Höhe: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_BLOCKS=§7Blöcke: §c{0}§7, Max: §e{1} +AUTO_CHECKER_RESULT_UNKNOWN_MATERIAL=§7Unbekannter Block: §c{0} +AUTO_CHECKER_RESULT_TOO_MANY_BLOCK=§7{0}: §c{1}§7, Max: §e{2} +AUTO_CHECKER_RESULT_FORBIDDEN_BLOCK=§7Verbotener Block: §c{0} +AUTO_CHECKER_RESULT_FORBIDDEN_ITEM=§7Verbotener gegenstand: [{0}, {1}, {2}] -> §c{3} +AUTO_CHECKER_RESULT_DEFUNCT_NBT=§7Keine NBT-Daten: §c[{0}, {1}, {2}] +AUTO_CHECKER_RESULT_DESIGN_BLOCK=§7{0} im Design: [{1}, {2}, {3}] +AUTO_CHECKER_RESULT_RECORD=§7Schallplatte: §c[{0}, {1}, {2}] +AUTO_CHECKER_RESULT_TOO_MANY_DISPENSER_ITEMS=§7Dispenser: §c[{0}, {1}, {2}]§7, §c{3} §7gegenstände, Max: §e{4} +AUTO_CHECKER_RESULT_FORBIDDEN_ITEM_NBT=§7Verbotene NBT-Daten: [{0}, {1}, {2}] -> §c{3} +AUTO_CHECKER_RESULT_TELEPORT_HERE=§7Zum block teleportieren +AUTO_CHECKER_RESULT_AFTER_DEADLINE=§cDer einsendeschluss ist bereits vorbei: {0} \ No newline at end of file diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/CheckSchemType.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/CheckSchemType.java new file mode 100644 index 00000000..fead2a47 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/CheckSchemType.java @@ -0,0 +1,113 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 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 . +*/ + +package de.steamwar.schematicsystem; + +import de.steamwar.sql.SchematicType; +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.*; + +@Getter +public class CheckSchemType { + + private static final Map types = new HashMap<>(); + + private final int width; + private final int height; + private final int depth; + private final int maxDispenserItems; + + private final Map, Integer> limits; + private final int maxBlocks; + + private final Date deadline; + private final float maxBlastResistance; + + private CheckSchemType(ConfigurationSection section) { + String name = section.getString("Schematic.Type"); + width = section.getInt("Schematic.Size.x"); + height = section.getInt("Schematic.Size.y"); + depth = section.getInt("Schematic.Size.z"); + + maxDispenserItems = section.getInt("Schematic.MaxDispenserItems", 128); + maxBlocks = section.getInt("Schematic.MaxBlocks", 0); + + maxBlastResistance = (float) section.getDouble("Schematic.MaxDesignBlastResistance", Double.MAX_VALUE); + + limits = new HashMap<>(); + for(Map entry : section.getMapList("Schematic.Limited")) { + int amount = (Integer) entry.get("Amount"); + Set materials = new HashSet<>((List) entry.get("Materials")); + if(amount == 0) { + materials.forEach(material -> limits.put(Collections.singleton(material), 0)); + } else { + limits.put(materials, amount); + } + } + + String deadlineString = section.getString("deadline", null); + if (deadlineString != null) { + try { + SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); + deadline = dateFormat.parse(deadlineString); + } catch (ParseException e) { + throw new SecurityException(e.getMessage(), e); + } + } else { + deadline = null; + } + + types.put(SchematicType.fromDB(name.toLowerCase()), this); + types.put(SchematicType.fromDB("c" + name.toLowerCase()), this); + } + + static { + File folder = new File(SchematicSystem.getInstance().getDataFolder().getParentFile(), "FightSystem"); + + if(folder.exists()) { + for(File configFile : folder.listFiles((file, name) -> name.endsWith(".yml") && !name.endsWith(".kits.yml"))) { + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + if (!config.isList("CheckQuestions") && config.getBoolean("Schematic.ManualCheck", true)) + continue; + + new CheckSchemType(config); + } + } + } + + public static CheckSchemType get(SchematicType type){ + return types.get(type); + } + + public Map, Integer> getLimits() { + return new HashMap<>(limits); + } + + public boolean isAfterDeadline() { + return deadline != null && deadline.before(Date.from(Instant.now())); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java new file mode 100644 index 00000000..449d59d8 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java @@ -0,0 +1,89 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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; + } + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SchematicSystem.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SchematicSystem.java new file mode 100644 index 00000000..d6b94807 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/SchematicSystem.java @@ -0,0 +1,48 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem; + +import de.steamwar.message.Message; +import de.steamwar.schematicsystem.commands.DownloadCommand; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandInitializer; +import de.steamwar.schematicsystem.listener.PlayerEventListener; +import org.bukkit.Bukkit; +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; + + @Override + public void onEnable() { + instance = this; + + SchematicCommandInitializer.init(); + new DownloadCommand(); + + Bukkit.getPluginManager().registerEvents(new PlayerEventListener(), this); + } + + public static SchematicSystem getInstance() { + return instance; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java new file mode 100644 index 00000000..ef4d9bea --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoChecker.java @@ -0,0 +1,60 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.autocheck; + +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.core.VersionDependent; +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.SchematicSystem; +import lombok.Getter; +import lombok.ToString; +import org.bukkit.Material; + +import java.util.*; + +public class AutoChecker { + + public static AutoCheckerResult check(Clipboard clipboard, CheckSchemType type) { + return impl.check(clipboard, type); + } + + public static AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type) { + return impl.sizeCheck(clipboard, type); + } + + private static final IAutoChecker impl = VersionDependent.getVersionImpl(SchematicSystem.getInstance()); + + public interface IAutoChecker { + AutoCheckerResult check(Clipboard clipboard, CheckSchemType type); + AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type); + } + + @Getter + @ToString + public static class BlockScanResult { + private final Map blockCounts = new EnumMap<>(Material.class); + private final List defunctNbt = new ArrayList<>(); + private final List records = new ArrayList<>(); + private final Map> designBlocks = new EnumMap<>(Material.class); + private final Map dispenserItems = new HashMap<>(); + private final Map> forbiddenItems = new HashMap<>(); + private final Map> forbiddenNbt = new HashMap<>(); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerResult.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerResult.java new file mode 100644 index 00000000..6a708bdf --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerResult.java @@ -0,0 +1,168 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.autocheck; + +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.SchematicSystem; +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.*; + +@Builder +@Getter +@ToString +public class AutoCheckerResult { + private final CheckSchemType type; + private final int width; + private final int height; + private final int depth; + private final AutoChecker.BlockScanResult blockScanResult; + private final List entities; + + public boolean isOk() { + return blockScanResult.getRecords().isEmpty() && + blockScanResult.getForbiddenItems().isEmpty() && + blockScanResult.getForbiddenNbt().isEmpty() && + isSizeOk() && + isBlockCountOk() && + isLimitedBlocksOK() && + isDispenserItemsOK() && + !type.isAfterDeadline() && + entities.isEmpty() && + isDesignBlastResistanceOK(); + } + + public boolean fastOk() { + return isSizeOk() && + !type.isAfterDeadline(); + } + + public boolean isDispenserItemsOK() { + return blockScanResult.getDispenserItems().values().stream().allMatch(i -> i <= type.getMaxDispenserItems()); + } + + public boolean hasWarnings() { + return blockScanResult.getDefunctNbt().isEmpty(); + } + + public boolean isSizeOk() { + return !isTooWide() && !isTooHigh() && !isTooDeep(); + } + + public boolean isTooWide() { + return width > type.getWidth(); + } + + public boolean isTooHigh() { + return height > type.getHeight(); + } + + public boolean isTooDeep() { + return depth > type.getDepth(); + } + + public boolean isBlockCountOk() { + return type.getMaxBlocks() == 0 || blockScanResult.getBlockCounts().entrySet().stream().filter(entry -> entry.getKey() != Material.AIR).map(Map.Entry::getValue).reduce(Integer::sum).map(i -> i <= type.getMaxBlocks()).orElse(false); + } + + public boolean isLimitedBlocksOK() { + try { + return type.getLimits().entrySet().stream() + .map(setIntegerEntry -> setIntegerEntry.getKey().stream().map(Material::getMaterial).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().map(Material::getBlastResistance).noneMatch(i -> i > type.getMaxBlastResistance()); + } + + 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.getWidth()); + if(isTooHigh()) SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_HEIGHT", p, height, type.getHeight()); + if(isTooDeep()) SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_LENGTH", p, depth, type.getDepth()); + if(type.getMaxBlocks() != 0 && !isBlockCountOk()) { + SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_BLOCKS", p, blockScanResult.getBlockCounts().values().stream().reduce(Integer::sum).orElse(0), type.getMaxBlocks()); + } + if(!isLimitedBlocksOK()) { + type.getLimits().forEach((strings, integer) -> { + for (String string : strings) { + Material mat = Material.matchMaterial(string); + 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); + } + } + } + }); + } + blockScanResult.getDispenserItems().entrySet().stream().filter(blockVector3IntegerEntry -> blockVector3IntegerEntry.getValue() > type.getMaxDispenserItems()).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.getMaxDispenserItems()); + }); + blockScanResult.getRecords().forEach(blockVector3 -> { + SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_RECORD", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ()); + }); + blockScanResult.getForbiddenItems().forEach((blockVector3, materials) -> { + SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_ITEM", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ(), setToString(materials)); + }); + blockScanResult.getForbiddenNbt().forEach((blockVector3, materials) -> { + SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_FORBIDDEN_ITEM_NBT", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ(), setToString(materials)); + }); + blockScanResult.getDefunctNbt().forEach(blockVector3 -> { + SchematicSystem.MESSAGE.sendPrefixless("AUTO_CHECKER_RESULT_DEFUNCT_NBT", p, SchematicSystem.MESSAGE.parse("AUTO_CHECKER_RESULT_TELEPORT_HERE", p), tpCommandTo(blockVector3), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()); + }); + blockScanResult.getDesignBlocks().forEach((material, poss) -> { + if(material.getBlastResistance() > type.getMaxBlastResistance()) { + 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.getDeadline()); + } + } + + 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 set) { + return set.stream().map(material -> material.getKey().getKey()).reduce((s, s2) -> s + "§7, §c" + s2).orElse(""); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/BlockPos.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/BlockPos.java new file mode 100644 index 00000000..7dff0dbe --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/BlockPos.java @@ -0,0 +1,50 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2022 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 . +*/ + +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; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java new file mode 100644 index 00000000..ff797b67 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java @@ -0,0 +1,63 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands; + +import de.steamwar.command.SWCommand; +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; + +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", 0); + boolean newSchem = false; + if(copyNode == null) { + copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", 0, SchematicType.Normal.toDB(), ""); + newSchem = true; + } + + try { + new SchematicData(copyNode).saveFromPlayer(player); + } 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); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/GUI.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/GUI.java new file mode 100644 index 00000000..cd953ed7 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/GUI.java @@ -0,0 +1,321 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.core.Core; +import de.steamwar.inventory.*; +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.SafeSchematicNode; +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.autocheck.AutoChecker; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils; +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.*; + +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 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()); + if(!node.isDir()) { + inv.setItem(0, SWItem.getMaterial("WOOD_AXE"), SchematicSystem.MESSAGE.parse("GUI_INFO_LOAD", player), click -> { + player.closeInventory(); + SchematicCommandUtils.loadSchem(player, node); + }); + } + + inv.setItem(9, SWItem.getMaterial("LEASH"), SchematicSystem.MESSAGE.parse("GUI_INFO_BACK", player), clickType -> { + back.reOpen(); + }); + + 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.get(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 types = SchematicType.values().parallelStream() + .filter(SchematicType::isAssignable) + .filter(type -> finalClipboard == null || CheckSchemType.get(type) == null || AutoChecker.sizeCheck(finalClipboard, CheckSchemType.get(type)).fastOk()) + .collect(Collectors.toList()); + + List> 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 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())); + inv.setItem(0, SWItem.getDye(1), (byte) 1, SchematicSystem.MESSAGE.parse("CONFIRM", p), click -> { + p.performCommand("schematic delete " + schem.generateBreadcrumbs()); + + 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())); + 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()); + 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> members = new LinkedList<>(); + for(NodeMember member : schem.getMembers()){ + SteamwarUser user = SteamwarUser.get(member.getMember()); + members.add(new SWListInv.SWListEntry<>(SWItem.getPlayerSkull(user.getUserName()), member)); + } + + SWListInv 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); + }); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand.java new file mode 100644 index 00000000..b3ecf374 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand.java @@ -0,0 +1,149 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.command.*; +import de.steamwar.core.VersionDependent; +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.autocheck.AutoCheckerResult; +import de.steamwar.sql.*; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandHelp.*; +import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.*; + +@SuppressWarnings("unused") +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 publicNodeTypeMapper() { + return SchematicMapper.publicNodeTypeMapper(); + } + + @Mapper("memberMapper") + public static TypeMapper nodeMemberTypeMapper() { + return SchematicMapper.nodeMemberTypeMapper(); + } + + @Mapper("dirMapper") + public static TypeMapper dirNodeTypeMapper() { + return SchematicMapper.dirNodeTypeMapper(); + } + + @Mapper("publicDirMapper") + public static TypeMapper publicDirNodeTypeMapper() { + return SchematicMapper.publicDirNodeTypeMapper(); + } + + @Mapper("dirStringMapper") + public static TypeMapper stringTabMapper() { + return SchematicMapper.stringTabMapper(); + } + + @Mapper("stringMapper") + public static TypeMapper stringMapper() { + return SchematicMapper.stringMapper(); + } + + @ClassMapper(SchematicType.class) + public static TypeMapper typeTypeMapper() { + return SchematicMapper.typeTypeMapper(); + } + + @AbstractSWCommand.ClassMapper(value = SchematicNode.class, local = true) + public static TypeMapper nodeTypeMapper() { + return SchematicMapper.nodeTypeMapper(); + } + + @ClassMapper(value = CheckSchemType.class, local = true) + public static TypeMapper checkSchemTypeTypeMapper() { + return SchematicMapper.checkSchemTypeTypeMapper(); + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + SchematicSystem.MESSAGE.send(message, sender, args); + } + + @Validator(value = "isSchemValidator", local = true) + public static TypeValidator isSchemValidator() { + return SchematicValidator.isSchemValidator(); + } + + @Validator(value = "isDirValidator", local = true) + public static TypeValidator isDirValidator() { + return SchematicValidator.isDirValidator(); + } + + @Validator(value = "isOwnerValidator", local = true) + public static TypeValidator isOwnerValidator() { + return SchematicValidator.isOwnerValidator(); + } + + @Validator(value = "isOwnerSchematicValidator", local = true) + public static TypeValidator isOwnerSchematicValidator() { + return SchematicValidator.isOwnerSchematicValidator(); + } + + public enum Extend { + AUSFAHREN, + NORMAL + } + + public static final ISchematicCommand impl = VersionDependent.getVersionImpl(SchematicSystem.getInstance()); + + public interface ISchematicCommand { + Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, CheckSchemType type) throws Exception; + void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandHelp.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandHelp.java new file mode 100644 index 00000000..1cb0ebd8 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandHelp.java @@ -0,0 +1,92 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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; + } + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandInitializer.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandInitializer.java new file mode 100644 index 00000000..7245ead6 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandInitializer.java @@ -0,0 +1,36 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.commands.schematiccommand.parts.*; + +public class SchematicCommandInitializer { + + public static void init() { + new SchematicCommand().setMessage(SchematicSystem.MESSAGE); + new CheckPart().setMessage(SchematicSystem.MESSAGE); + new MemberPart().setMessage(SchematicSystem.MESSAGE); + new ModifyPart().setMessage(SchematicSystem.MESSAGE); + new SavePart().setMessage(SchematicSystem.MESSAGE); + new SearchPart().setMessage(SchematicSystem.MESSAGE); + new ViewPart().setMessage(SchematicSystem.MESSAGE); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java new file mode 100644 index 00000000..753cd3b9 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommandUtils.java @@ -0,0 +1,505 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.CheckSchemType; +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.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 PUBLIC_TOGGLED = new ArrayList<>(); + private static final List FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public")); + private static final Map 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 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 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(); + 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.get(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() : 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() : 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())); + 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 renderHook = s -> s; + @Builder.Default private IntFunction 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()); + 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() + " ")) + .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.get(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())) + .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() + " " + node.generateBreadcrumbs().replace("/" + node.getName(), ""))) + .create() + ); + } else { + SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_PARENT", player, node.getParent() == null ? "/" : node.getParentNode().generateBreadcrumbs()); + } + 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())) + .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_ELO", player, node.getElo(Season.getSeason())); + } + + SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getSchemFormat() ? ".schem" : ".schematic"); + 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.get(nodeMember.getMember()); + memberBuilder.append(member.getUserName()) + .color(ChatColor.YELLOW) + .event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/schem delmember " + node.generateBreadcrumbs() + " " + 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() + " ")); + player.spigot().sendMessage(memberBuilder.create()); + } else { + List schematicMembers = new ArrayList<>(); + NodeMember.getNodeMembers(node.getId()).forEach(nodeMember -> schematicMembers.add(SteamwarUser.get(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())); + 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())); + 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())); + base.addExtra(delete); + } + + if (!base.getExtra().isEmpty()) { + player.spigot().sendMessage(base); + } + } + + public static void check(Player player, Clipboard clipboard, CheckSchemType type, String schemName, boolean gui) { + AutoCheckerResult result = AutoChecker.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 currentNode = Optional.empty(); + for (int i = 0; i < layers.length - minus; i++) { + int finalI = i; + List 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.get(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) { + 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.get(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).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 (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 (Punishment.isPunished(user, + Punishment.PunishmentType.NoSchemSubmitting, + punishment -> SchematicSystem.MESSAGE.send("UTIL_TYPE_PUNISHED", player, punishment.getReason()))) { + return; + } + 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; + } + + if (type.writeable()) { + node.setSchemtype(type); + SchematicSystem.MESSAGE.send("UTIL_TYPE_DONE", player); + } else if (type.fightType()) { + if (node.getSchemtype().check()) { + SchematicSystem.MESSAGE.send("UTIL_TYPE_FIGHT_ALREADY", player); + return; + } + + CheckSchemType checkSchemType = CheckSchemType.get(type); + if (checkSchemType.isAfterDeadline()) { + SchematicSystem.MESSAGE.send("UTIL_TYPE_AFTER_DEADLINE", player, checkSchemType.getDeadline()); + return; + } + + AutoCheckerResult result = null; + try { + result = AutoChecker.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); + } + } + } + + 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.allowReplay()?"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("UTIL_SUBMIT_DIRECT_DONE", 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 nodes; + private int page; + private int maxPage; + private SchematicNode parent; + private SchematicListBehavior behavior; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicMapper.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicMapper.java new file mode 100644 index 00000000..bcf60e63 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicMapper.java @@ -0,0 +1,191 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import de.steamwar.command.TypeMapper; +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.sql.NodeMember; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SchematicType; +import de.steamwar.sql.SteamwarUser; +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 publicCommandTypeMapper = publicNodeTypeMapper(); + + public static TypeMapper publicNodeTypeMapper() { + return new TypeMapper() { + @Override + public List tabCompletes(CommandSender commandSender, String[] strings, String s) { + return SchematicNode.getNodeTabcomplete(SteamwarUser.get(0), s); + } + + @Override + public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) { + return SchematicNode.getNodeFromPath(SteamwarUser.get(0), s); + } + }; + } + + public static TypeMapper nodeMemberTypeMapper() { + return new TypeMapper() { + @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 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::get).map(SteamwarUser::getUserName).collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + }; + } + + public static TypeMapper dirNodeTypeMapper() { + return new TypeMapper() { + @Override + public List tabCompletes(CommandSender commandSender, String[] strings, String s) { + List 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 publicDirNodeTypeMapper() { + return new TypeMapper() { + @Override + public Collection tabCompletes(CommandSender commandSender, String[] strings, String s) { + Collection 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 stringTabMapper() { + return new TypeMapper() { + @Override + public List tabCompletes(CommandSender commandSender, String[] strings, String s) { + List 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 stringMapper() { + return new TypeMapper() { + @Override + public List tabCompletes(CommandSender commandSender, String[] strings, String s) { + List 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 typeTypeMapper() { + return new TypeMapper() { + @Override + public List 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 nodeTypeMapper() { + return new TypeMapper() { + @Override + public List 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 checkSchemTypeTypeMapper() { + return new TypeMapper() { + @Override + public Collection tabCompletes(CommandSender commandSender, String[] strings, String s) { + return SchematicType.values().stream().filter(type -> CheckSchemType.get(type) != null).map(SchematicType::name).collect(Collectors.toList()); + } + + @Override + public CheckSchemType map(CommandSender commandSender, String[] previousArguments, String s) { + return SchematicType.values().stream().filter(type -> type.name().equalsIgnoreCase(s)).map(CheckSchemType::get).findAny().orElse(null); + } + }; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicValidator.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicValidator.java new file mode 100644 index 00000000..e6bff1dd --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicValidator.java @@ -0,0 +1,94 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import de.steamwar.command.AbstractSWCommand; +import de.steamwar.command.AbstractValidator; +import de.steamwar.command.TypeValidator; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.entity.Player; + +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 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 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 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 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; + }; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/CheckPart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/CheckPart.java new file mode 100644 index 00000000..9f23a795 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/CheckPart.java @@ -0,0 +1,119 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.schematicsystem.CheckSchemType; +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.SchematicData; +import de.steamwar.sql.SchematicNode; +import org.bukkit.entity.Player; + +import java.io.IOException; +import java.util.logging.Level; + +import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.check; +import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand.impl; + +@AbstractSWCommand.PartOf(SchematicCommand.class) +public class CheckPart extends SWCommand { + public CheckPart() { + super(null); + } + + @Register("check") + public void checkCommand(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node, CheckSchemType 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") CheckSchemType 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") CheckSchemType 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); + + impl.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") CheckSchemType 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.check(clipboard, type); + if(result.isOk()) { + SchematicSystem.MESSAGE.send("COMMAND_FIX_OK", player); + return; + } + try { + clipboard = impl.fixClipboard(clipboard, result, type); + WorldEdit.getInstance().getSessionManager().get(new BukkitPlayer(player)).setClipboard(new ClipboardHolder(clipboard)); + AutoCheckerResult after = AutoChecker.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); + } + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/MemberPart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/MemberPart.java new file mode 100644 index 00000000..f7f09ac3 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/MemberPart.java @@ -0,0 +1,173 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand.parts; + +import de.steamwar.command.AbstractSWCommand; +import de.steamwar.command.SWCommand; +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) +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 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(), player.getName()); + } + } + + Optional 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.get(member.getMember()); + + List nodes = SchematicNode.deepGet(node.getId(), node1 -> node1.getOwner() != user.getId()); + if (!nodes.isEmpty()) { + for (SchematicNode schematicNode : nodes) { + SchematicNode newNode = mkdirs(schematicNode.generateBreadcrumbs().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()); + + 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.get(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::get).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.get(user.getTeam()); + if (team == null || team.getTeamId() == 0) { + SchematicSystem.MESSAGE.send("COMMAND_DEL_TEAM_NOT_IN_TEAM", player); + return; + } + + List 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.get(member).getUserName()); + } + } + + Optional 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); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ModifyPart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ModifyPart.java new file mode 100644 index 00000000..cee2cbc3 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ModifyPart.java @@ -0,0 +1,186 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.SafeSchematicNode; +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.autocheck.AutoChecker; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +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) +public class ModifyPart extends SWCommand { + public ModifyPart() { + super(null); + } + + @Register("changetype") + public void changeType(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node) { + TextComponent base = new TextComponent(); + + Clipboard clipboard = null; + try { + clipboard = new SchematicData(node).load(); + } catch (IOException ignored) { } + + Clipboard finalClipboard = clipboard; + + String breadcrumb = node.generateBreadcrumbs(); + + SchematicType.values().parallelStream() + .filter(SchematicType::isAssignable) + .filter(type -> finalClipboard == null || CheckSchemType.get(type) == null || AutoChecker.sizeCheck(finalClipboard, CheckSchemType.get(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") + public void changeType(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node, SchematicType type) { + changeType(player, node, type, null); + } + + @Register("changetype") + 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()); + } + + @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()); + } + + @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()); + node.delete(); + } else { + SchematicSystem.MESSAGE.send("COMMAND_DELETE_DIR_FULL", player); + } + } else { + SchematicSystem.MESSAGE.send("COMMAND_DELETE_SCHEM", player, node.generateBreadcrumbs()); + node.delete(); + } + } + + @Register("lockreplay") + public void lockreplay(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node) { + node.setAllowReplay(false); + SchematicSystem.MESSAGE.send("COMMAND_LOCKREPLAY", player, node.getName()); + } + + @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()); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SavePart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SavePart.java new file mode 100644 index 00000000..31695f73 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SavePart.java @@ -0,0 +1,133 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +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.providers.BauServerInfo; +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +import de.steamwar.sql.*; +import net.md_5.bungee.api.chat.ClickEvent; +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) +public class SavePart extends SWCommand { + + public SavePart() { + super(null); + } + + @Register("save") + @Register("s") + 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() + s), true)); + anvilInv.setItem(Material.CAULDRON); + anvilInv.open(); + } else { + saveSchem(player, schematicNode.generateBreadcrumbs(), true); + } + }); + selector.setSingleDirOpen(false); + selector.open(); + } + + @Register("save") + @Register("s") + public void saveSchem(Player player, @AbstractSWCommand.Mapper("stringMapper") String name, @AbstractSWCommand.StaticValue(value = {"", "-f"}, allowISE=true) @AbstractSWCommand.OptionalValue("") boolean overwrite) { + 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.get(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; + } else if(!overwrite) { + SchematicSystem.MESSAGE.send("COMMAND_SAVE_OVERWRITE_CONFIRM", player, SchematicSystem.MESSAGE.parse("COMMAND_SAVE_OVERWRITE_CONFIRM_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/schem s " + name + " -f"), node.generateBreadcrumbs()); + return; + } + } + + boolean newSchem = false; + if (node == null) { + newSchem = true; + node = SchematicNode.createSchematic(user.getId(), layers[layers.length - 1], currentNode == null ? 0 : currentNode.getId()); + } + + try { + new SchematicData(node).saveFromPlayer(player); + } 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()); + } + + @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()); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SearchPart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SearchPart.java new file mode 100644 index 00000000..00dfd850 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/SearchPart.java @@ -0,0 +1,184 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand.parts; + +import de.steamwar.command.*; +import de.steamwar.schematicsystem.SchematicSystem; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +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) +public class SearchPart extends SWCommand { + + private static final Map> 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>) 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> predicates = new ArrayList<>(); + List 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 nodes = SchematicNode.getAll(SteamwarUser.get(userId)).stream().filter(node -> { + for (Predicate 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 searchTypeMapper() { + return new TypeMapper() { + @Override + public String map(CommandSender commandSender, String[] previousArguments, String s) { + return s; + } + + @Override + public Collection tabCompletes(CommandSender commandSender, String[] strings, String s) { + if (strings.length == 0) { + List list = new ArrayList<>(); + list.add(s); + list.addAll(searchMapper.keySet()); + return list; + } + String last = strings[strings.length - 1]; + if (searchMapper.containsKey(last)) { + AbstractTypeMapper mapper = searchMapper.get(last); + if (mapper == null) { + List list = new ArrayList<>(searchMapper.keySet()); + list.add(s); + return list; + } + return mapper.tabCompletes(commandSender, strings, s); + } + List list = new ArrayList<>(searchMapper.keySet()); + list.add(s); + return list; + } + }; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ViewPart.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ViewPart.java new file mode 100644 index 00000000..60146d4e --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/ViewPart.java @@ -0,0 +1,98 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand.parts; + +import de.steamwar.command.AbstractSWCommand; +import de.steamwar.command.SWCommand; +import de.steamwar.schematicsystem.commands.schematiccommand.GUI; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils; +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommand; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.entity.Player; + +import static de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils.*; + +@AbstractSWCommand.PartOf(SchematicCommand.class) +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.get(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() + " " + 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(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) { + loadSchem(player, node); + } + + @Register("l") + @Register("load") + public void loadSchem(Player player, @Validator("isSchemValidator") SchematicNode node) { + SchematicCommandUtils.loadSchem(player, node); + } + + @Register("gui") + public void gui(Player player) { + GUI.list(player); + } + + @Register("download") + public void download(Player player, @Validator("isOwnerSchematicValidator") SchematicNode node) { + SchematicCommandUtils.download(player, node); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/parts.info b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/parts.info new file mode 100644 index 00000000..7dcd251a --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/schematiccommand/parts/parts.info @@ -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 diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/listener/PlayerEventListener.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/listener/PlayerEventListener.java new file mode 100644 index 00000000..3afb8ddd --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/listener/PlayerEventListener.java @@ -0,0 +1,33 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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 . + */ + +package de.steamwar.schematicsystem.listener; + +import de.steamwar.schematicsystem.commands.schematiccommand.SchematicCommandUtils; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +public class PlayerEventListener implements Listener { + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + SchematicCommandUtils.quitPlayer(event.getPlayer()); + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/plugin.yml b/SchematicSystem/SchematicSystem_Core/src/plugin.yml new file mode 100644 index 00000000..40e41e64 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/plugin.yml @@ -0,0 +1,8 @@ +name: SchematicSystem +version: "2.1.0" +authors: [Yaruma3341, Lixfel, Chaoscaot] +depend: [SpigotCore, WorldEdit] +main: de.steamwar.schematicsystem.SchematicSystem +website: steamwar.de +api-version: "1.13" +description: Schematic-Frontend diff --git a/SchematicSystem/build.gradle.kts b/SchematicSystem/build.gradle.kts new file mode 100644 index 00000000..0c2b5ae6 --- /dev/null +++ b/SchematicSystem/build.gradle.kts @@ -0,0 +1,50 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id("java") + id("base") + + id("com.github.johnrengelman.shadow") +} + +group = "de.steamwar" +version = "" + +tasks.compileJava { + options.encoding = "UTF-8" +} + +tasks.build { + finalizedBy(tasks.shadowJar) +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") + + implementation(project(":SchematicSystem:SchematicSystem_Core")) + implementation(project(":SchematicSystem:SchematicSystem_8")) + implementation(project(":SchematicSystem:SchematicSystem_15")) +} diff --git a/settings.gradle.kts b/settings.gradle.kts index cc7e386b..c143edd1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,6 +44,11 @@ include("MissileWars") include("Realtime") +include("SchematicSystem") +include("SchematicSystem:SchematicSystem_8") +include("SchematicSystem:SchematicSystem_15") +include("SchematicSystem:SchematicSystem_Core") + include("SpigotCore") include("SpigotCore:CRIUDummy") include("SpigotCore:SpigotCore_8")