package com.atlauncher.obj; import com.atlauncher.ATLauncher; import com.atlauncher.Settings; import com.atlauncher.utils.Digester; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.EnumSet; import java.util.zip.GZIPInputStream; public final class Downloadable implements Runnable{ public final String endpoint; public final String hash; public final Path output; public final boolean md5; private HttpURLConnection conn; public Downloadable(String endpoint, Path output, String hash, boolean md5){ this.endpoint = endpoint; this.hash = hash; this.md5 = md5; this.output = output.resolve(endpoint.substring(endpoint.lastIndexOf('/') + 1)); try{ if(!Files.exists(output.getParent())){ Files.createDirectories(output.getParent()); } } catch(IOException e){ e.printStackTrace(System.out); } } private boolean isGzip(){ return (this.getConnection().getContentEncoding() != null && this.getConnection().getContentEncoding().equalsIgnoreCase("gzip")); } private HttpURLConnection getConnection(){ if(this.conn == null){ try{ this.conn = (HttpURLConnection) new URL(Settings.SERVERS[0].getFileURL(this.endpoint)).openConnection(); this.conn.setUseCaches(false); this.conn.setDefaultUseCaches(false); this.conn.setRequestProperty("Accept-Encoding", "gzip"); this.conn.setRequestProperty("User-Agent", Settings.USER_AGENT); this.conn.setRequestProperty("Cache-Control", "no-store,max-age=0,no-cache"); this.conn.setRequestProperty("Expires", "0"); this.conn.setRequestProperty("Pragma", "no-cache"); this.conn.connect(); } catch(Exception ex){ ex.printStackTrace(System.err); } } return this.conn; } public boolean needsUpdate(){ if(this.hash == null){ return true; } if(Files.exists(this.output)){ if(this.md5){ return !Digester.getMD5(this.output).equalsIgnoreCase(this.hash); } else{ return !Digester.getSHA1(this.output).equalsIgnoreCase(this.hash); } } return true; } @Override public void run(){ if(Files.exists(this.output)){ if(this.needsUpdate()){ ATLauncher.LOGGER.info("Updating File " + this.output); try{ Files.delete(this.output); } catch(IOException e){ e.printStackTrace(); } } else{ return; } } try(InputStream stream = this.getStream(); FileChannel channel = this.getChannel(); ReadableByteChannel rbc = Channels.newChannel(stream)){ channel.transferFrom(rbc, 0, Long.MAX_VALUE); } catch(Exception ex){ ex.printStackTrace(System.out); } } private FileChannel getChannel() throws IOException{ return FileChannel.open(this.output, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE)); } private InputStream getStream(){ try{ return (this.isGzip() ? new GZIPInputStream(this.getConnection().getInputStream()) : this.getConnection().getInputStream()); } catch(Exception ex){ ex.printStackTrace(System.err); return this.getConnection().getErrorStream(); } } }