/* Copyright (c) 2014-2015 Jesper Öqvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky 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. * * Chunky 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 Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import javax.net.ssl.HttpsURLConnection; import se.llbit.chunky.PersistentSettings; import se.llbit.json.JsonArray; import se.llbit.json.JsonObject; import se.llbit.json.JsonParser; import se.llbit.json.JsonValue; import se.llbit.json.PrettyPrinter; /** * Utility class to download Minecraft Jars and player data. * * @author Jesper Öqvist <jesper@llbit.se> */ public class MCDownloader { /** * Download a Minecraft Jar by version name. */ public static void downloadMC(String version, File destDir) throws IOException { String theUrl = String .format("https://s3.amazonaws.com/Minecraft.Download/versions/%s/%s.jar", version, version); File destination = new File(destDir, "minecraft.jar"); System.out.println("url: " + theUrl); System.out.println("destination: " + destination.getAbsolutePath()); URL url = new URL(theUrl); ReadableByteChannel inChannel = Channels.newChannel(url.openStream()); FileOutputStream out = new FileOutputStream(destination); out.getChannel().transferFrom(inChannel, 0, Long.MAX_VALUE); out.close(); } /** * Download a player skin by player name. */ public static void downloadSkin(String name, File destDir) throws IOException { String theUrl = String.format("http://s3.amazonaws.com/MinecraftSkins/%s.png", name); File destination = new File(destDir, name + ".skin.png"); URL url = new URL(theUrl); ReadableByteChannel inChannel = Channels.newChannel(url.openStream()); FileOutputStream out = new FileOutputStream(destination); out.getChannel().transferFrom(inChannel, 0, Long.MAX_VALUE); out.close(); } /** * Download a Minecraft player profile. * * @param uuid UUID of player * @throws IOException */ public static JsonObject fetchProfile(String uuid) throws IOException { String key = uuid + ":profile"; File cacheFile = new File(PersistentSettings.cacheDirectory(), Util.cacheEncode(key.hashCode())); JsonArray cache; if (cacheFile.exists()) { FileInputStream in = new FileInputStream(cacheFile); JsonParser cacheParse = new JsonParser(in); try { cache = cacheParse.parse().array(); in.close(); for (JsonValue entry : cache) { if (entry.array().get(0).stringValue("").equals(key)) { return entry.array().get(1).object(); } } } catch (JsonParser.SyntaxError e) { cache = new JsonArray(); } } else { cache = new JsonArray(); } String url = "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid; HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection(); int responseCode = conn.getResponseCode(); JsonObject profile; if (responseCode == 200) { try { JsonParser parser = new JsonParser(conn.getInputStream()); profile = parser.parse().object(); // TODO unparse base64 data. } catch (JsonParser.SyntaxError e) { e.printStackTrace(System.err); profile = new JsonObject(); } } else { profile = new JsonObject(); } JsonArray newEntry = new JsonArray(); newEntry.add(key); newEntry.add(profile); cache.add(newEntry); if (!PersistentSettings.cacheDirectory().isDirectory()) { PersistentSettings.cacheDirectory().mkdirs(); } FileOutputStream out = new FileOutputStream(cacheFile); PrettyPrinter jsonOut = new PrettyPrinter("", new PrintStream(out)); cache.prettyPrint(jsonOut); out.close(); return profile; } }