diff --git a/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java b/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java new file mode 100644 index 0000000..25a5711 --- /dev/null +++ b/SchematicSystem_Core/src/de/steamwar/schematicsystem/SafeSchematicNode.java @@ -0,0 +1,117 @@ +/* + 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.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import lombok.AllArgsConstructor; +import lombok.NonNull; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SafeSchematicNode { + + public static Result setParent(@NonNull SteamwarUser user, @NonNull SchematicNode node, SchematicNode newParent) { + if(user.getId() != node.getId()) { + return Result.NOT_OWNER; + } + if(newParent == null) { + if(SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0) + .stream().map(SchematicNode::getName).anyMatch(s -> s.equalsIgnoreCase(node.getName()))) { + return Result.ALREADY_IN_DIRECTORY; + } + + node.setParent(0); + } else { + if(!newParent.isDir()) { + return Result.NOT_A_DIR; + } + + if(SchematicNode.getSchematicsAccessibleByUser(user.getId(), newParent.getParent()) + .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.getId()) { + return Result.NOT_OWNER; + } + + if(invalidSchemName(name)) { + return Result.INVALID_NAME; + } + + if(SchematicNode.getSchematicsAccessibleByUser(user.getId(), node.getParent()).stream().map(SchematicNode::getName).anyMatch(s -> s.equalsIgnoreCase(name))) { + return Result.ALREADY_IN_DIRECTORY; + } + + node.setName(name); + return Result.DONE; + } + + private static final List FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public")); + public static boolean invalidSchemName(String name) { + if (name.isEmpty()) { + return true; + } + if(name.length() > 64) { + return true; + } + if (name.contains("/") || + name.contains("\\") || + name.contains("<") || + name.contains(">") || + name.contains("^") || + name.contains("°") || + name.contains("'") || + name.contains("\"") || + name.contains(" ")) { + return true; + } + return FORBIDDEN_NAMES.contains(name.toLowerCase()); + } + + @AllArgsConstructor + public enum Result { + DONE("No"), + NOT_A_DIR(SchematicSystem.PREFIX + "§cDie ausgewählte Schematic ist kein Ordner"), + ALREADY_IN_DIRECTORY(SchematicSystem.PREFIX + "§cDie Schematic gibt es bereits in diesem Ordner"), + INVALID_NAME(SchematicSystem.PREFIX + "§cDieser Name ist unzulässig"), + NOT_OWNER(SchematicSystem.PREFIX + "§cDu bist nicht der Besitzer dieser Schematic"); + + private String errorMessage; + + public void sendError(Player player) { + player.sendMessage(errorMessage); + } + + public boolean isSuccessful() { + return this == DONE; + } + } +} diff --git a/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/GUI.java b/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/GUI.java index ea47d1b..fbabed5 100644 --- a/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/GUI.java +++ b/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/GUI.java @@ -20,6 +20,7 @@ package de.steamwar.schematicsystem.commands; import de.steamwar.inventory.*; +import de.steamwar.schematicsystem.SafeSchematicNode; import de.steamwar.schematicsystem.SchematicSystem; import de.steamwar.sql.*; import org.bukkit.Material; @@ -102,8 +103,12 @@ public class GUI { inv.setItem(5, skull); inv.setItem(6, Material.ARROW, "§eVerschieben", clickType -> { SchematicSelector selector = new SchematicSelector(player, SchematicSelector.selectDirectory(), npar -> { - node.setParent(npar==null?null:npar.getId()); - info(player, SchematicNode.getSchematicNode(node.getId())); + SafeSchematicNode.Result result = SafeSchematicNode.setParent(user, node, npar); + if(result.isSuccessful()) { + info(player, SchematicNode.getSchematicNode(node.getId())); + } else { + result.sendError(player); + } }); selector.open(); }); @@ -112,10 +117,12 @@ public class GUI { SWAnvilInv anvilInv = new SWAnvilInv(player, node.getName() + " umbenennen", node.getName()); anvilInv.setItem(finalMat); anvilInv.setCallback(s -> { - if (!invalidSchemName(player, new String[]{s})) { - node.setName(s); + SafeSchematicNode.Result result = SafeSchematicNode.setName(user, node, s); + if(result.isSuccessful()) { + info(player, node); + } else { + result.sendError(player); } - info(player, node); }); anvilInv.open(); }); diff --git a/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/SchematicCommand.java b/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/SchematicCommand.java index 14578b4..d7350ae 100644 --- a/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/SchematicCommand.java +++ b/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/SchematicCommand.java @@ -24,6 +24,7 @@ import de.steamwar.command.SWCommandUtils; import de.steamwar.command.TypeMapper; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SchematicSelector; +import de.steamwar.schematicsystem.SafeSchematicNode; import de.steamwar.providers.BauServerInfo; import de.steamwar.schematicsystem.SchematicSystem; import de.steamwar.sql.*; @@ -424,7 +425,11 @@ public class SchematicCommand extends SWCommand { player.sendMessage(SchematicSystem.PREFIX + "§cDas gibt nur Fehler, vertrau mir."); return; } - node.setParent(newNode.getId()); + SafeSchematicNode.Result result = SafeSchematicNode.setParent(user, node, newNode); + if(!result.isSuccessful()) { + result.sendError(player); + return; + } } player.sendMessage(SchematicSystem.PREFIX + "§7Die Schematic ist nun unter §e" + node.generateBreadcrumbs(user) + " §7zu finden"); } @@ -439,7 +444,11 @@ public class SchematicCommand extends SWCommand { if (invalidSchemName(player, new String[]{name})) { return; } - node.setName(name); + SafeSchematicNode.Result result = SafeSchematicNode.setName(user, node, name); + if(!result.isSuccessful()) { + result.sendError(player); + return; + } player.sendMessage(SchematicSystem.PREFIX + "§7Die Schematic heist nun §e" + node.generateBreadcrumbs(user)); } diff --git a/pom.xml b/pom.xml index b1a8c5c..cc39eaa 100644 --- a/pom.xml +++ b/pom.xml @@ -45,5 +45,10 @@ system ${main.basedir}/lib/SpigotCore.jar + + org.projectlombok + lombok + 1.18.22 + \ No newline at end of file