package in.twizmwaz.cardinal.repository.repositories; import com.google.common.collect.Lists; import in.twizmwaz.cardinal.repository.LoadedMap; import in.twizmwaz.cardinal.repository.exception.RotationLoadException; import in.twizmwaz.cardinal.util.CollectionUtils; import in.twizmwaz.cardinal.util.Config; import in.twizmwaz.cardinal.util.Contributor; import in.twizmwaz.cardinal.util.DomUtil; import in.twizmwaz.cardinal.util.Numbers; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.jdom2.Document; import org.jdom2.Element; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.logging.Level; import java.util.stream.Collectors; public abstract class Repository { private static final List<String> requirements = Arrays.asList("map.xml", "region", "level.dat"); private List<LoadedMap> loaded = Lists.newArrayList(); private Map<String, File> includes = new HashMap<>(); private String path; private File root; private int id = -1; private static int maxId = 0; public int getId() { return id; } public String getSource(boolean show) { return show ? path : null; } protected String getPath() { return path; } public File getRoot() { return root; } public String toChatMessage(boolean op) { String source = getSource(op); return ChatColor.YELLOW + "#" + getId() + " " + ChatColor.GOLD + (source == null ? ChatColor.STRIKETHROUGH + "Hidden" : source); } public File getInclude(String name) { return includes.containsKey(name) ? includes.get(name) : null; } Repository(String path) throws RotationLoadException, IOException { this.path = path; this.root = new File(path); } public void refreshRepo() throws RotationLoadException, IOException { if (id == -1) id = maxId++; includes.clear(); root = new File(path); if (!root.exists()) root.mkdirs(); loadIncludes(root); loaded = CollectionUtils.updateAndRun(loaded, loadMapsIn(root), LoadedMap::update) .peek(LoadedMap::load).collect(Collectors.toList()); } private void loadIncludes(File file) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { if (child.isFile()) { if (child.getName().endsWith(".xml") && !child.getName().equals("map.xml")) { includes.put(child.getName(), child); } } else loadIncludes(child); } } } private List<LoadedMap> loadMapsIn(File file) { List<LoadedMap> result = new LinkedList<>(); if (file == null || file.listFiles() == null) { return result; } for (File map : file.listFiles()) { if (map.isFile() || map.list() == null) continue; if (Arrays.asList(map.list()).containsAll(requirements)) { try { result.add(loadMap(map)); } catch (Exception e) { Bukkit.getLogger().log(Level.WARNING, "Failed to load map at " + map.getAbsolutePath()); if (Config.debug_displayMapLoadErrors) { Bukkit.getLogger().log(Level.INFO, "Showing error, this can be disabled in the config: "); e.printStackTrace(); } } } else { result.addAll(loadMapsIn(map)); } } return result; } private LoadedMap loadMap(File map) throws Exception { Document xml = DomUtil.parseMap(this, new File(map.getPath() + "/map.xml")); String name = xml.getRootElement().getChild("name").getTextNormalize(); String version = xml.getRootElement().getChild("version").getTextNormalize(); String objective = xml.getRootElement().getChild("objective").getTextNormalize(); List<Contributor> authors = new ArrayList<>(); for (Element authorsElement : xml.getRootElement().getChildren("authors")) { for (Element author : authorsElement.getChildren()) { authors.add(parseContributor(author)); } } List<Contributor> contributors = new ArrayList<>(); for (Element contributorsElement : xml.getRootElement().getChildren("contributors")) { for (Element contributor : contributorsElement.getChildren()) { contributors.add(parseContributor(contributor)); } } List<String> rules = new ArrayList<>(); for (Element rulesElement : xml.getRootElement().getChildren("rules")) { for (Element rule : rulesElement.getChildren()) { rules.add(rule.getTextNormalize()); } } int maxPlayers = 0; for (Element teams : xml.getRootElement().getChildren("teams")) { for (Element team : teams.getChildren()) { maxPlayers = maxPlayers + Numbers.parseInt(team.getAttributeValue("max")); } } return new LoadedMap(name, version, objective, authors, contributors, rules, maxPlayers, map); } /** * @return Returns all loaded maps */ public List<LoadedMap> getLoaded() { return loaded; } private static Contributor parseContributor(Element element) { if (element.getAttributeValue("uuid") != null) { return new Contributor(UUID.fromString(element.getAttributeValue("uuid")), element.getAttributeValue("contribution")); } else return new Contributor(element.getText(), element.getAttributeValue("contribution")); } @Override public String toString() { return this.getClass().getSimpleName() + " id:" + id + ", Path:" + path; } @Override public boolean equals(Object other) { return other.getClass().equals(this.getClass()) && ((Repository) other).path.equals(this.path); } }