// $Id$ /* * WorldEdit * Copyright (C) 2010 sk89q * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.sk89q.worldedit.commands; import java.io.File; import java.io.IOException; import com.sk89q.util.commands.Command; import com.sk89q.util.commands.CommandContext; import com.sk89q.worldedit.*; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.data.DataException; import com.sk89q.worldedit.regions.Region; /** * Clipboard commands. * * @author sk89q */ public class ClipboardCommands { @Command( aliases = {"/copy"}, usage = "", desc = "Copy the selection to the clipboard", min = 0, max = 0 ) @CommandPermissions({"worldedit.clipboard.copy"}) public static void copy(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { Region region = session.getRegion(); Vector min = region.getMinimumPoint(); Vector max = region.getMaximumPoint(); Vector pos = player.getBlockIn(); CuboidClipboard clipboard = new CuboidClipboard( max.subtract(min).add(new Vector(1, 1, 1)), min, min.subtract(pos)); clipboard.copy(editSession); session.setClipboard(clipboard); player.print("Block(s) copied."); } @Command( aliases = {"/cut"}, usage = "[leave-id]", desc = "Cut the selection to the clipboard", min = 0, max = 1 ) @CommandPermissions({"worldedit.clipboard.cut"}) public static void cut(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { BaseBlock block = new BaseBlock(0); if (args.argsLength() > 0) { block = we.getBlock(player, args.getString(0)); } Region region = session.getRegion(); Vector min = region.getMinimumPoint(); Vector max = region.getMaximumPoint(); Vector pos = player.getBlockIn(); CuboidClipboard clipboard = new CuboidClipboard( max.subtract(min).add(new Vector(1, 1, 1)), min, min.subtract(pos)); clipboard.copy(editSession); session.setClipboard(clipboard); editSession.setBlocks(session.getRegion(), block); player.print("Block(s) cut."); } @Command( aliases = {"/paste"}, usage = "[at-origin?]", desc = "Paste the clipboard's contents", min = 0, max = 1 ) @CommandPermissions({"worldedit.clipboard.paste"}) public static void paste(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { boolean atOrigin = args.argsLength() > 0 ? (args.getString(0).equalsIgnoreCase("true") || args.getString(0).equalsIgnoreCase("yes")) : false; if (atOrigin) { Vector pos = session.getClipboard().getOrigin(); session.getClipboard().place(editSession, pos, false); player.findFreePosition(); player.print("Pasted to copy origin. Undo with //undo"); } else { Vector pos = session.getPlacementPosition(player); session.getClipboard().paste(editSession, pos, false); player.findFreePosition(); player.print("Pasted relative to you. Undo with //undo"); } } @Command( aliases = {"/rotate"}, usage = "", desc = "Rotate the contents of the clipboard", min = 1, max = 1 ) @CommandPermissions({"worldedit.clipboard.rotate"}) public static void rotate(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { int angle = args.getInteger(0); if (angle % 90 == 0) { CuboidClipboard clipboard = session.getClipboard(); clipboard.rotate2D(angle); player.print("Clipboard rotated by " + angle + " degrees."); } else { player.printError("Angles must be divisible by 90 degrees."); } } @Command( aliases = {"/flip"}, usage = "[dir]", desc = "Flip the contents of the clipboard", min = 0, max = 1 ) @CommandPermissions({"worldedit.clipboard.flip"}) public static void flip(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { CuboidClipboard.FlipDirection dir = we.getFlipDirection(player, args.argsLength() > 0 ? args.getString(0).toLowerCase() : "me"); CuboidClipboard clipboard = session.getClipboard(); clipboard.flip(dir); player.print("Clipboard flipped."); } @Command( aliases = {"/load"}, usage = "", desc = "Load a schematic into your clipboard", min = 1, max = 1 ) @CommandPermissions({"worldedit.clipboard.load"}) public static void load(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { LocalConfiguration config = we.getConfiguration(); String filename = args.getString(0).replace("\0", "") + ".schematic"; File dir = we.getWorkingDirectoryFile(config.saveDir); File f = new File(dir, filename); if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) { player.printError("Valid characters: A-Z, a-z, 0-9, spaces, " + "./\'$@~!%^*()[]+{},?"); return; } try { String filePath = f.getCanonicalPath(); String dirPath = dir.getCanonicalPath(); if (!filePath.substring(0, dirPath.length()).equals(dirPath)) { player.printError("Schematic could not read or it does not exist."); } else { session.setClipboard(CuboidClipboard.loadSchematic(f)); WorldEdit.logger.info(player.getName() + " loaded " + filePath); player.print(filename + " loaded. Paste it with //paste"); } } catch (DataException e) { player.printError("Load error: " + e.getMessage()); } catch (IOException e) { player.printError("Schematic could not read or it does not exist: " + e.getMessage()); } } @Command( aliases = {"/save"}, usage = "", desc = "Save a schematic into your clipboard", min = 1, max = 1 ) @CommandPermissions({"worldedit.clipboard.save"}) public static void save(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { LocalConfiguration config = we.getConfiguration(); String filename = args.getString(0).replace("\0", "") + ".schematic"; if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) { player.printError("Valid characters: A-Z, a-z, 0-9, spaces, " + "./\'$@~!%^*()[]+{},?"); return; } File dir = we.getWorkingDirectoryFile(config.saveDir); File f = new File(dir, filename); if (!dir.exists()) { if (!dir.mkdir()) { player.printError("A schematics/ folder could not be created."); return; } } try { String filePath = f.getCanonicalPath(); String dirPath = dir.getCanonicalPath(); if (!filePath.substring(0, dirPath.length()).equals(dirPath)) { player.printError("Invalid path for Schematic."); } else { // Create parent directories File parent = f.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } session.getClipboard().saveSchematic(f); WorldEdit.logger.info(player.getName() + " saved " + filePath); player.print(filename + " saved."); } } catch (DataException se) { player.printError("Save error: " + se.getMessage()); } catch (IOException e) { player.printError("Schematic could not written: " + e.getMessage()); } } @Command( aliases = {"clearclipboard"}, usage = "", desc = "Clear your clipboard", min = 0, max = 0 ) @CommandPermissions({"worldedit.clipboard.clear"}) public static void clearClipboard(CommandContext args, WorldEdit we, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { session.setClipboard(null); player.print("Clipboard cleared."); } }