package com.intellectualcrafters.plot.commands; import com.intellectualcrafters.configuration.ConfigurationSection; import com.intellectualcrafters.configuration.InvalidConfigurationException; import com.intellectualcrafters.configuration.file.YamlConfiguration; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.ConfigurationNode; import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.object.FileBytes; import com.intellectualcrafters.plot.object.PlotArea; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.object.SetupObject; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.SetupUtils; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.WorldUtil; import com.intellectualcrafters.plot.util.block.GlobalBlockQueue; import com.plotsquared.general.commands.CommandDeclaration; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @CommandDeclaration( command = "template", permission = "plots.admin", description = "Create or use a world template", usage = "/plot template [import|export] <world> <template>", category = CommandCategory.ADMINISTRATION) public class Template extends SubCommand { public static boolean extractAllFiles(String world, String template) { try { File folder = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.Paths.TEMPLATES); if (!folder.exists()) { return false; } File input = new File(folder + File.separator + template + ".template"); File output = PS.get().IMP.getDirectory(); if (!output.exists()) { output.mkdirs(); } try (ZipInputStream zis = new ZipInputStream(new FileInputStream(input))) { ZipEntry ze = zis.getNextEntry(); byte[] buffer = new byte[2048]; while (ze != null) { if (!ze.isDirectory()) { String name = ze.getName().replace('\\', File.separatorChar).replace('/', File.separatorChar); File newFile = new File((output + File.separator + name).replaceAll("__TEMP_DIR__", world)); File parent = newFile.getParentFile(); if (parent != null) { parent.mkdirs(); } try (FileOutputStream fos = new FileOutputStream(newFile)) { int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } } } ze = zis.getNextEntry(); } zis.closeEntry(); } return true; } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } public static byte[] getBytes(PlotArea plotArea) { ConfigurationSection section = PS.get().worlds.getConfigurationSection("worlds." + plotArea.worldname); YamlConfiguration config = new YamlConfiguration(); String generator = SetupUtils.manager.getGenerator(plotArea); if (generator != null) { config.set("generator.plugin", generator); } for (String key : section.getKeys(true)) { config.set(key, section.get(key)); } return config.saveToString().getBytes(); } public static void zipAll(String world, Set<FileBytes> files) throws IOException { File output = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.Paths.TEMPLATES); output.mkdirs(); try (FileOutputStream fos = new FileOutputStream(output + File.separator + world + ".template"); ZipOutputStream zos = new ZipOutputStream(fos)) { for (FileBytes file : files) { ZipEntry ze = new ZipEntry(file.path); zos.putNextEntry(ze); zos.write(file.data); } zos.closeEntry(); } } @Override public boolean onCommand(final PlotPlayer player, String[] args) { if (args.length != 2 && args.length != 3) { if (args.length == 1) { if (args[0].equalsIgnoreCase("export")) { MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot template export <world>"); return true; } else if (args[0].equalsIgnoreCase("import")) { MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot template import <world> <template>"); return true; } } MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot template <import|export> <world> [template]"); return true; } final String world = args[1]; switch (args[0].toLowerCase()) { case "import": { if (args.length != 3) { MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot template import <world> <template>"); return false; } if (PS.get().hasPlotArea(world)) { MainUtil.sendMessage(player, C.SETUP_WORLD_TAKEN, world); return false; } boolean result = extractAllFiles(world, args[2]); if (!result) { MainUtil.sendMessage(player, "&cInvalid template file: " + args[2] + ".template"); return false; } File worldFile = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.Paths.TEMPLATES + File.separator + "tmp-data.yml"); YamlConfiguration worldConfig = YamlConfiguration.loadConfiguration(worldFile); PS.get().worlds.set("worlds." + world, worldConfig.get("")); try { PS.get().worlds.save(PS.get().worldsFile); PS.get().worlds.load(PS.get().worldsFile); } catch (InvalidConfigurationException | IOException e) { e.printStackTrace(); } String manager = worldConfig.getString("generator.plugin", PS.imp().getPluginName()); String generator = worldConfig.getString("generator.init", manager); int type = worldConfig.getInt("generator.type"); int terrain = worldConfig.getInt("generator.terrain"); SetupObject setup = new SetupObject(); setup.plotManager = manager; setup.setupGenerator = generator; setup.type = type; setup.terrain = terrain; setup.step = new ConfigurationNode[0]; setup.world = world; SetupUtils.manager.setupWorld(setup); GlobalBlockQueue.IMP.addTask(new Runnable() { @Override public void run() { MainUtil.sendMessage(player, "Done!"); player.teleport(WorldUtil.IMP.getSpawn(world)); } }); return true; } case "export": if (args.length != 2) { MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot template export <world>"); return false; } final PlotArea area = PS.get().getPlotAreaByString(world); if (area == null) { MainUtil.sendMessage(player, C.NOT_VALID_PLOT_WORLD); return false; } final PlotManager manager = area.getPlotManager(); TaskManager.runTaskAsync(new Runnable() { @Override public void run() { try { manager.exportTemplate(area); } catch (Exception e) { // Must recover from any exception thrown a third party template manager e.printStackTrace(); MainUtil.sendMessage(player, "Failed: " + e.getMessage()); return; } MainUtil.sendMessage(player, "Done!"); } }); return true; default: C.COMMAND_SYNTAX.send(player, getUsage()); } return false; } }