package co.forsaken.projectindigo.utils.atlauncher; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NodeList; import co.forsaken.api.json.JsonWebCall; import co.forsaken.projectindigo.data.Mod; import co.forsaken.projectindigo.data.Mod.ModType; import co.forsaken.projectindigo.data.Server; import co.forsaken.projectindigo.log.LogManager; import co.forsaken.projectindigo.utils.DirectoryLocations; import co.forsaken.projectindigo.utils.FileUtils; import co.forsaken.projectindigo.utils.ServerLoader; import co.forsaken.projectindigo.utils.atlauncher.tokens.ModpackToken; import co.forsaken.projectindigo.utils.atlauncher.tokens.PacksToken; import co.forsaken.projectindigo.utils.atlauncher.tokens.VersionToken; public class AtLauncherServerLoader extends ServerLoader { private static final String API_BASE = "http://download.nodecdn.net/containers/atl/"; public static final String API_BASE_PACKS = "launcher/json/packs.json"; private static final String API_BASE_PACK_INFO = "packs/%s/versions/%s/Configs.xml"; private static final String API_BASE_PACK_CONFIG = "packs/%s/versions/%s/Configs.zip"; private static final String type = "atlauncher"; private static PacksToken token; private static HashMap<String, Document> modpackInfo = new HashMap<String, Document>(); public AtLauncherServerLoader(Server _server) { super(_server, false); } private static Document getModpack(String name, String version) { String url = String.format(API_BASE + API_BASE_PACK_INFO, name.replaceAll(" ", ""), version); String nme = (name + "-" + version).replaceAll(".", "_").replaceAll(" ", ""); if (!modpackInfo.containsKey(nme)) { File baseModTypeFile = new File(DirectoryLocations.BACKEND_DATA_DIR.format(type + "/")); if (!baseModTypeFile.exists()) baseModTypeFile.mkdirs(); File modpackFile = new File(baseModTypeFile, nme); try { if (!modpackFile.exists()) modpackFile.createNewFile(); FileUtils.writeStreamToFile(new URL(url).openStream(), modpackFile); } catch (IOException e) { e.printStackTrace(); LogManager.warn("Failed to load modpacks, loading from backup"); } InputStream modPackStream = null; try { modPackStream = new FileInputStream(modpackFile); } catch (IOException e) { LogManager.warn("Failed to read modpack file - falling back to direct download"); } if (modPackStream == null) { try { modPackStream = new URL(url).openStream(); } catch (IOException e) { LogManager.error("Completely unable to download the modpack file - check your connection"); } } if (modPackStream != null) { try { modpackInfo.put(nme, FileUtils.getXML(modPackStream)); } catch (Exception e) { LogManager.error("Exception reading modpack file"); return null; } if (modpackInfo == null) { LogManager.error("Error: could not load modpack data!"); return null; } } } return modpackInfo.get(nme); } private static PacksToken getModpackInfo() { if (token == null) { try { token = new JsonWebCall(API_BASE + API_BASE_PACKS).executeGet(PacksToken.class, true); } catch (Exception e) { LogManager.error(API_BASE + API_BASE_PACKS + " could not be retrieved... its most likely down, try again in a few seconds"); return null; } } return token; } @Override public boolean load(Server server) { return loadPack(server); } private boolean loadPack(Server server) { PacksToken token = getModpackInfo(); if (token == null) { return false; } boolean found = true; for (ModpackToken t : token.data) { if (!t.name.equalsIgnoreCase(server.getToken().modpackRefName)) { continue; } server.setDesc(t.description); server.setModList(new HashMap<String, Mod>()); for (VersionToken vt : t.versions) { if (!vt.version.equalsIgnoreCase(server.getToken().version)) { continue; } Document doc = getModpack(t.name, vt.version); NodeList mods = doc.getElementsByTagName("mod"); for (int i = 0; i < mods.getLength(); i++) { NamedNodeMap mod = mods.item(i).getAttributes(); String name = mod.getNamedItem("name") != null ? mod.getNamedItem("name").getTextContent() : ""; List<String> authors = mod.getNamedItem("authors") != null ? Arrays.asList(mod.getNamedItem("authors").getTextContent().split(",")) : new ArrayList<String>(); String url = mod.getNamedItem("url") != null ? mod.getNamedItem("url").getTextContent() : ""; String website = mod.getNamedItem("website") != null ? mod.getNamedItem("website").getTextContent() : ""; String type = mod.getNamedItem("type") != null ? mod.getNamedItem("type").getTextContent() : ""; ModType ty = ModType.mod; if (type.equalsIgnoreCase("resourcepack")) { ty = ModType.resourcePack; } else if (type.equalsIgnoreCase("forge")) { ty = ModType.forge; } type = mod.getNamedItem("optional") != null ? mod.getNamedItem("optional").getTextContent() : ""; if (!type.isEmpty()) { if (type.equalsIgnoreCase("yes")) { ty = ModType.optionalMod; } } if (ty == ModType.optionalMod) { if (!server.hasOptionalMod(name)) { continue; } } Mod m = new Mod(name, authors, API_BASE + url, website, ty); server.getModList().put(name, m); } for (Mod m : getMojangLibraries(server, vt.minecraft)) { server.getModList().put(m.getName(), m); } NodeList libraries = doc.getElementsByTagName("library"); outer: for (int i = 0; i < libraries.getLength(); i++) { NamedNodeMap library = libraries.item(i).getAttributes(); String name = library.getNamedItem("file") != null ? library.getNamedItem("file").getTextContent() : ""; List<String> replace = new ArrayList<String>(); for (String s : server.getModList().keySet()) { String sTotal = s; if (s.contains("-")) { if (s.contains("/")) { s = s.substring(s.lastIndexOf("/") + 1); } if (name.substring(0, name.lastIndexOf('-')).equalsIgnoreCase(s.substring(0, s.lastIndexOf('-')))) { if (parseVersion(s.substring(s.lastIndexOf('-') + 1, s.lastIndexOf("."))) < parseVersion(name.substring(name.lastIndexOf('-') + 1, name.lastIndexOf(".")))) { replace.add(sTotal); break; } continue outer; } } } for (String s : replace) { LogManager.info("Removing " + s + " to make way for " + name); server.getModList().remove(s); } List<String> authors = new ArrayList<String>(); String url = library.getNamedItem("url") != null ? library.getNamedItem("url").getTextContent() : ""; String website = ""; ModType ty = ModType.library; Mod m = new Mod(name, authors, API_BASE + url, website, ty); server.getModList().put(name, m); } server.getModList().put("forge_config", new Mod("forge_config", new ArrayList<String>(), String.format(API_BASE + API_BASE_PACK_CONFIG, t.name.replaceAll(" ", ""), vt.version), "", ModType.config)); server.getModList().put("server_download", new Mod("server_download", new ArrayList<String>(), MOJANG_DOWNLOAD_BASE + "versions/" + vt.minecraft + "/" + vt.minecraft + ".jar", "", ModType.minecraft)); break; } } return found; } public String getDownloadUrl(Server server) { return null; } public String getDownloadUrl(Server server, String modname) { return API_BASE + server.getModList().get(modname).getDownloadUrl(); } }