@Override public void run() { Asset asset; while ((asset = filesLeft.poll()) != null) { for (int i = 1; i < MAX_TRIES + 1; i++) { try { File file = new File(getAssetsDir(), "objects/" + asset.path); // does exist? create if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } File localMc = new File(minecraftDir, asset.path); BufferedInputStream stream; // check for local copy if (localMc.exists() && Constants.hash(localMc, "SHA1").equals(asset.hash)) // if so, copy stream = new BufferedInputStream(Files.newInputStreamSupplier(localMc).getInput()); else // otherwise download stream = new BufferedInputStream( new URL(Constants.ASSETS_URL + "/" + asset.path).openStream()); Files.write(ByteStreams.toByteArray(stream), file); stream.close(); // check hash... String hash = Constants.hash(file, "SHA1"); if (asset.hash.equals(hash)) break; // hashes are fine; else { file.delete(); getLogger() .error("download attempt " + i + " failed! : " + asset.hash + " != " + hash); } } catch (Exception e) { getLogger().error("Error downloading asset: " + asset.path); e.printStackTrace(); if (!errored) errored = true; } } } }