package de.fanta.challengesjoinentities.commands.AdventureCommand;
import de.fanta.challengesjoinentities.ChallengesJoinEntities;
import de.fanta.challengesjoinentities.ChatUtil;
import de.iani.cubesideutils.bukkit.commands.SubCommand;
import de.iani.cubesideutils.commands.ArgsParser;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class AdventureConvertMapCommand extends SubCommand {
private static FileConfiguration ServerConfig;
private static File ServerConfigFile;
private static ChallengesJoinEntities plugin;
public AdventureConvertMapCommand(ChallengesJoinEntities plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String s, String s1, ArgsParser args) {
String urlString;
String versioString;
if (!(sender instanceof Player player)) {
ChatUtil.sendErrorMessage(sender, "You are not a Player");
return true;
}
if (!player.hasPermission("adventure.convertmap")) {
ChatUtil.sendErrorMessage(player, "Keine Rechte!");
return true;
}
if (args.hasNext()) {
urlString = args.getNext();
if (args.hasNext()) {
versioString = args.getNext();
} else {
ChatUtil.sendErrorMessage(player, "/convertmap <URL> <Server-Version>");
return true;
}
File folder = new File(Bukkit.getPluginsFolder().getPath() + "/Challenges/MapConverter");
if (!folder.exists()) {
folder.mkdir();
}
String finalUrlString = urlString;
String finalVersioString = versioString;
plugin.getScheduler().runAsync(() -> downloadMap(finalUrlString, finalVersioString, folder, player));
} else {
ChatUtil.sendErrorMessage(sender, "/convertmap <URL> <Server-Version>");
return true;
}
return true;
}
private static void downloadMap(String finalUrlString, String versioString, File folder, Player player) {
Path zipPath = Path.of(folder + "/world.zip");
try {
InputStream in = new URL(finalUrlString).openStream();
Files.copy(in, zipPath, StandardCopyOption.REPLACE_EXISTING);
ChatUtil.sendNormalMessage(player, "Map heruntergeladen.");
} catch (IOException e) {
throw new RuntimeException(e);
}
unZip(folder, zipPath, versioString, player);
}
private static void unZip(File folder, Path zipPath, String versioString, Player player) {
File worldFolder = new File(folder.getPath() + "/" + UUID.randomUUID());
try {
unzipFolder(zipPath, worldFolder.toPath());
ChatUtil.sendNormalMessage(player, "UnZip Done " + worldFolder.getName());
} catch (IOException e) {
throw new RuntimeException(e);
}
searchRegionFile(worldFolder, versioString, player);
}
private static void searchRegionFile(File file, String versioString, Player player) {
File[] files;
files = file.listFiles();
if (files != null) {
for (File filefile : files) {
if (filefile.getName().equals("region")) {
ChatUtil.sendNormalMessage(player, "region folder found");
convertToSpigotMap(filefile.getAbsoluteFile(), versioString, player);
return;
}
if (filefile.isDirectory()) {
searchRegionFile(filefile, versioString, player);
}
}
}
}
private static void convertToSpigotMap(File file, String versioString, Player player) {
if (file != null) {
File mapFolder = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 7));
File worldFolder = new File(mapFolder.getAbsoluteFile() + "/world");
File netherFolder = new File(mapFolder.getAbsoluteFile() + "/world_nether");
File endFolder = new File(mapFolder.getAbsoluteFile() + "/world_the_end");
try {
FileUtils.forceMkdir(worldFolder);
FileUtils.forceMkdir(netherFolder);
FileUtils.forceMkdir(endFolder);
} catch (IOException e) {
throw new RuntimeException(e);
}
File[] files;
files = mapFolder.listFiles();
if (files != null) {
for (File tempFiles : files) {
try {
if (!tempFiles.getName().equals("DIM1") && !tempFiles.getName().equals("DIM-1") && !tempFiles.getName().equals("world") && !tempFiles.getName().equals("world_nether") && !tempFiles.getName().equals("world_the_end")) {
if (tempFiles.isDirectory()) {
FileUtils.moveDirectory(tempFiles, new File(worldFolder + "/" + tempFiles.getName()));
} else {
FileUtils.moveFile(tempFiles, new File(worldFolder + "/" + tempFiles.getName()));
}
}
if (tempFiles.getName().equals("DIM1")) {
FileUtils.moveDirectory(tempFiles, new File(endFolder + "/" + tempFiles.getName()));
}
if (tempFiles.getName().equals("DIM-1")) {
FileUtils.moveDirectory(tempFiles, new File(netherFolder + "/" + tempFiles.getName()));
}
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Can't Copy File", e);
}
}
File challengesFolder = new File(mapFolder.getAbsoluteFile() + "/Challenges");
try {
FileUtils.forceMkdir(challengesFolder);
} catch (IOException e) {
throw new RuntimeException(e);
}
createServerConfig(challengesFolder);
try {
getServerConfig().set("servertype", "ADVENTURE");
ServerConfig.save(ServerConfigFile);
getServerConfig().set("serverversion", versioString);
ServerConfig.save(ServerConfigFile);
} catch (IOException e) {
Bukkit.getLogger().log(Level.SEVERE, "Can't Save Config", e);
}
String oldFolderName = mapFolder.getName();
String newFolderName = mapFolder.getName().replace(" ", "_");
File newFolderFile = new File(mapFolder.getPath().replace(oldFolderName, newFolderName));
mapFolder.renameTo(newFolderFile);
ChatUtil.sendNormalMessage(player, "Konvertierung fertig.");
File destFolder = new File("/home/minecraft/Adventure-Maps/test/" + newFolderName);
try {
FileUtils.moveDirectory(newFolderFile, destFolder);
} catch (IOException e) {
throw new RuntimeException(e);
}
ChatUtil.sendNormalMessage(player, "Map wurde zum testen in das test Verzeichnis verschoben.");
TextComponent component = new TextComponent(TextComponent.fromLegacyText(ChallengesJoinEntities.PREFIX + ChatUtil.GREEN + " Klicke hier um die Map zu testen."));
component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/a testmap test " + newFolderName));
player.sendMessage(component);
} else {
ChatUtil.sendErrorMessage(player, "Keine datei gefunden.");
}
} else {
ChatUtil.sendErrorMessage(player, "Keine datei gefunden.");
}
}
public static FileConfiguration getServerConfig() {
return ServerConfig;
}
private static void createServerConfig(File folder) {
ServerConfigFile = new File(folder.getPath() + "/serverconfig.yml");
if (!ServerConfigFile.exists()) {
try {
FileUtils.forceMkdirParent(ServerConfigFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ServerConfig = new YamlConfiguration();
}
public static void unzipFolder(Path source, Path target) throws IOException {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source.toFile()))) {
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
boolean isDirectory = zipEntry.getName().endsWith(File.separator);
Path newPath = zipSlipProtect(zipEntry, target);
if (isDirectory) {
Files.createDirectories(newPath);
} else {
if (newPath.getParent() != null) {
if (Files.notExists(newPath.getParent())) {
Files.createDirectories(newPath.getParent());
}
}
Files.copy(zis, newPath, StandardCopyOption.REPLACE_EXISTING);
}
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
}
}
public static Path zipSlipProtect(ZipEntry zipEntry, Path targetDir) throws IOException {
Path targetDirResolved = targetDir.resolve(zipEntry.getName());
Path normalizePath = targetDirResolved.normalize();
if (!normalizePath.startsWith(targetDir)) {
throw new IOException("Bad zip entry: " + zipEntry.getName());
}
return normalizePath;
}
}