diff --git a/src/main/java/de/viper/survivalplus/util/LockSystem.java b/src/main/java/de/viper/survivalplus/util/LockSystem.java new file mode 100644 index 0000000..5f0d24a --- /dev/null +++ b/src/main/java/de/viper/survivalplus/util/LockSystem.java @@ -0,0 +1,276 @@ +package de.viper.survivalplus.util; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class LockSystem implements Listener, CommandExecutor { + + private final SurvivalPlus plugin; + private final Map lockedBlocks = new HashMap<>(); + private final Set lockMode = new HashSet<>(); + private final Map lockTimeoutTasks = new HashMap<>(); + + private final File lockFile; + private FileConfiguration lockConfig; + + public LockSystem(SurvivalPlus plugin) { + this.plugin = plugin; + this.lockFile = new File(plugin.getDataFolder(), "locks.yml"); + this.lockConfig = YamlConfiguration.loadConfiguration(lockFile); + loadLocks(); + } + + public static class LockData { + private final String ownerUUID; + private final Set friendsUUID; + + public LockData(String ownerUUID) { + this.ownerUUID = ownerUUID; + this.friendsUUID = new HashSet<>(); + } + + public String getOwnerUUID() { + return ownerUUID; + } + + public Set getFriendsUUID() { + return friendsUUID; + } + + public void addFriend(String friendUUID) { + friendsUUID.add(friendUUID); + } + + public void removeFriend(String friendUUID) { + friendsUUID.remove(friendUUID); + } + + public boolean isFriend(String uuid) { + return friendsUUID.contains(uuid); + } + } + + private void loadLocks() { + lockedBlocks.clear(); + if (!lockFile.exists()) return; + + for (String key : lockConfig.getKeys(false)) { + String path = key + "."; + String owner = lockConfig.getString(path + "owner"); + List friends = lockConfig.getStringList(path + "friends"); + + String[] parts = key.split("_"); + if (parts.length != 4) continue; + + String worldName = parts[0]; + double x = Double.parseDouble(parts[1]); + double y = Double.parseDouble(parts[2]); + double z = Double.parseDouble(parts[3]); + + Location loc = new Location(plugin.getServer().getWorld(worldName), x, y, z); + LockData lock = new LockData(owner); + lock.getFriendsUUID().addAll(friends); + + lockedBlocks.put(loc, lock); + } + } + + private void saveLocks() { + lockConfig = new YamlConfiguration(); + + for (Map.Entry entry : lockedBlocks.entrySet()) { + Location loc = entry.getKey(); + LockData lock = entry.getValue(); + String key = loc.getWorld().getName() + "_" + loc.getBlockX() + "_" + loc.getBlockY() + "_" + loc.getBlockZ(); + + lockConfig.set(key + ".owner", lock.getOwnerUUID()); + lockConfig.set(key + ".friends", new ArrayList<>(lock.getFriendsUUID())); + } + + try { + lockConfig.save(lockFile); + } catch (IOException e) { + plugin.getLogger().severe("Konnte locks.yml nicht speichern!"); + e.printStackTrace(); + } + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + + Block block = event.getClickedBlock(); + if (block == null) return; + + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + Location loc = block.getLocation(); + boolean isLockable = block.getState() instanceof InventoryHolder || block.getType().name().contains("DOOR"); + + if (lockMode.contains(uuid)) { + lockMode.remove(uuid); + + BukkitRunnable timeout = lockTimeoutTasks.remove(uuid); + if (timeout != null) timeout.cancel(); + + if (!isLockable) { + player.sendMessage(plugin.getMessage("lock.not-lockable")); + return; + } + + if (lockedBlocks.containsKey(loc)) { + player.sendMessage(plugin.getMessage("lock.already-locked")); + } else { + lockedBlocks.put(loc, new LockData(uuid.toString())); + saveLocks(); + player.sendMessage(plugin.getMessage("lock.locked")); + } + + event.setCancelled(true); + return; + } + + if (!isLockable) return; + if (!lockedBlocks.containsKey(loc)) return; + + LockData lock = lockedBlocks.get(loc); + String playerUUID = uuid.toString(); + + if (lock.getOwnerUUID().equals(playerUUID) || lock.isFriend(playerUUID) || player.isOp()) { + return; + } + + player.sendMessage(plugin.getMessage("lock.block-denied")); + event.setCancelled(true); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getMessage("lock.only-players")); + return true; + } + + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + + if (args.length == 0) { + if (lockMode.contains(uuid)) { + player.sendMessage(plugin.getMessage("lock.mode-already")); + return true; + } + + lockMode.add(uuid); + player.sendMessage(plugin.getMessage("lock.mode-start")); + + BukkitRunnable timeout = new BukkitRunnable() { + @Override + public void run() { + if (lockMode.remove(uuid)) { + player.sendMessage(plugin.getMessage("lock.mode-timeout")); + lockTimeoutTasks.remove(uuid); + } + } + }; + timeout.runTaskLater(plugin, 20 * 30); // 30 Sekunden + lockTimeoutTasks.put(uuid, timeout); + return true; + } + + if (args.length < 1) { + player.sendMessage(plugin.getMessage("lock.usage")); + return true; + } + + String sub = args[0].toLowerCase(); + Block targetBlock = player.getTargetBlockExact(5); + if (targetBlock == null) { + player.sendMessage(plugin.getMessage("lock.no-target-block")); + return true; + } + + Location loc = targetBlock.getLocation(); + + switch (sub) { + case "unlock": + LockData lock = lockedBlocks.get(loc); + if (lock == null) { + player.sendMessage(plugin.getMessage("lock.not-locked")); + } else if (!lock.getOwnerUUID().equals(uuid.toString()) && !player.isOp()) { + player.sendMessage(plugin.getMessage("lock.no-permission-unlock")); + } else { + lockedBlocks.remove(loc); + saveLocks(); + player.sendMessage(plugin.getMessage("lock.unlocked")); + } + break; + + case "friendadd": + if (args.length < 2) { + player.sendMessage(plugin.getMessage("lock.friendadd.usage")); + return true; + } + lock = lockedBlocks.get(loc); + if (lock == null) { + player.sendMessage(plugin.getMessage("lock.not-locked")); + } else if (!lock.getOwnerUUID().equals(uuid.toString()) && !player.isOp()) { + player.sendMessage(plugin.getMessage("lock.no-permission-friends")); + } else { + Player friend = player.getServer().getPlayer(args[1]); + if (friend == null) { + player.sendMessage(plugin.getMessage("lock.friendadd.not-found")); + } else { + lock.addFriend(friend.getUniqueId().toString()); + saveLocks(); + player.sendMessage(plugin.getMessage("lock.friendadd.success").replace("{player}", friend.getName())); + } + } + break; + + case "friendremove": + if (args.length < 2) { + player.sendMessage(plugin.getMessage("lock.friendremove.usage")); + return true; + } + lock = lockedBlocks.get(loc); + if (lock == null) { + player.sendMessage(plugin.getMessage("lock.not-locked")); + } else if (!lock.getOwnerUUID().equals(uuid.toString()) && !player.isOp()) { + player.sendMessage(plugin.getMessage("lock.no-permission-friends")); + } else { + Player friend = player.getServer().getPlayer(args[1]); + if (friend == null) { + player.sendMessage(plugin.getMessage("lock.friendremove.not-found")); + } else { + lock.removeFriend(friend.getUniqueId().toString()); + saveLocks(); + player.sendMessage(plugin.getMessage("lock.friendremove.success").replace("{player}", friend.getName())); + } + } + break; + + default: + player.sendMessage(plugin.getMessage("lock.unknown-subcommand")); + break; + } + + return true; + } +}