diff --git a/pom.xml b/pom.xml index 5d1e38240..016d004c1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.tonikelope MegaBasterd - 7.95 + 7.96 jar diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkWriterManager.java b/src/main/java/com/tonikelope/megabasterd/ChunkWriterManager.java index dc29bc555..ec9d2120e 100644 --- a/src/main/java/com/tonikelope/megabasterd/ChunkWriterManager.java +++ b/src/main/java/com/tonikelope/megabasterd/ChunkWriterManager.java @@ -143,7 +143,7 @@ public long getLast_chunk_id_written() { private String _create_chunks_temp_dir() { - File chunks_temp_dir = new File((_download.getCustom_chunks_dir() != null ? _download.getCustom_chunks_dir() : _download.getDownload_path()) + "/.mb_chunks_" + _download.getFile_key()); + File chunks_temp_dir = new File((_download.getCustom_chunks_dir() != null ? _download.getCustom_chunks_dir() : _download.getDownload_path()) + "/.MEGABASTERD_CHUNKS_" + MiscTools.HashString("sha1", _download.getUrl())); chunks_temp_dir.mkdirs(); @@ -159,6 +159,19 @@ public void delete_chunks_temp_dir() { } } + private void finishDownload() { + _download.getMain_panel().getDownload_manager().getTransference_running_list().remove(_download); + _download.getMain_panel().getDownload_manager().secureNotify(); + _download.getView().printStatusNormal("Download finished. Joining file chunks, please wait..."); + _download.getView().getPause_button().setVisible(false); + _download.getMain_panel().getGlobal_dl_speed().detachTransference(_download); + _download.getView().getSpeed_label().setVisible(false); + _download.getView().getSlots_label().setVisible(false); + _download.getView().getSlot_status_label().setVisible(false); + _download.getView().getSlots_spinner().setVisible(false); + + } + @Override public void run() { @@ -170,82 +183,70 @@ public void run() { if (!download_finished && _download.getProgress() == _file_size) { - _download.getMain_panel().getDownload_manager().getTransference_running_list().remove(_download); - _download.getMain_panel().getDownload_manager().secureNotify(); - - _download.getView().printStatusNormal("Download finished. Joining file chunks, please wait..."); - _download.getView().getPause_button().setVisible(false); - _download.getMain_panel().getGlobal_dl_speed().detachTransference(_download); - _download.getView().getSpeed_label().setVisible(false); - _download.getView().getSlots_label().setVisible(false); - _download.getView().getSlot_status_label().setVisible(false); - _download.getView().getSlots_spinner().setVisible(false); + finishDownload(); download_finished = true; } boolean chunk_io_error; do { - synchronized (ChunkWriterManager.class) { - chunk_io_error = false; - try { + chunk_io_error = false; - File chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1)); + try { - while (chunk_file.exists() && chunk_file.canRead() && chunk_file.canWrite() && chunk_file.length() > 0) { + File chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1)); - if (!download_finished && _download.getProgress() == _file_size) { + while (chunk_file.exists() && chunk_file.canRead() && chunk_file.canWrite() && chunk_file.length() > 0) { - _download.getMain_panel().getDownload_manager().getTransference_running_list().remove(_download); - _download.getMain_panel().getDownload_manager().secureNotify(); + if (!download_finished && _download.getProgress() == _file_size) { - _download.getView().printStatusNormal("Download finished. Joining file chunks, please wait..."); - _download.getView().getPause_button().setVisible(false); - _download.getMain_panel().getGlobal_dl_speed().detachTransference(_download); - _download.getView().getSpeed_label().setVisible(false); - _download.getView().getSlots_label().setVisible(false); - _download.getView().getSlot_status_label().setVisible(false); - _download.getView().getSlots_spinner().setVisible(false); - download_finished = true; - } + finishDownload(); + download_finished = true; + } - byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; + byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; - int reads; + int reads; - try (CipherInputStream cis = new CipherInputStream(new BufferedInputStream(new FileInputStream(chunk_file)), genDecrypter("AES", "AES/CTR/NoPadding", _byte_file_key, forwardMEGALinkKeyIV(_byte_iv, _bytes_written)))) { - while ((reads = cis.read(buffer)) != -1) { - _download.getOutput_stream().write(buffer, 0, reads); - } - } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException ex) { - LOG.log(Level.SEVERE, ex.getMessage()); + try (CipherInputStream cis = new CipherInputStream(new BufferedInputStream(new FileInputStream(chunk_file)), genDecrypter("AES", "AES/CTR/NoPadding", _byte_file_key, forwardMEGALinkKeyIV(_byte_iv, _bytes_written)))) { + while ((reads = cis.read(buffer)) != -1) { + _download.getOutput_stream().write(buffer, 0, reads); } + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException ex) { + LOG.log(Level.SEVERE, ex.getMessage()); + } - _bytes_written += chunk_file.length(); + _bytes_written += chunk_file.length(); - _last_chunk_id_written++; + _last_chunk_id_written++; - LOG.log(Level.INFO, "{0} ChunkWriterManager has written to disk chunk [{1}] {2} {3} {4}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.calculateLastWrittenChunk(_bytes_written), _download.getFile_name()}); + LOG.log(Level.INFO, "{0} ChunkWriterManager has written to disk chunk [{1}] {2} {3} {4}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.calculateLastWrittenChunk(_bytes_written), _download.getFile_name()}); - chunk_file.delete(); + chunk_file.delete(); - chunk_file = new File(getChunks_dir() + "/" + new File(_download.getFile_name()).getName() + ".chunk" + String.valueOf(_last_chunk_id_written + 1)); + chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1)); - } - } catch (IOException ex) { - chunk_io_error = true; - LOG.log(Level.WARNING, ex.getMessage()); - MiscTools.pausar(1000); } + } catch (IOException ex) { + chunk_io_error = true; + LOG.log(Level.WARNING, ex.getMessage()); + MiscTools.pausar(1000); } + } while (chunk_io_error); if (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) { LOG.log(Level.INFO, "{0} ChunkWriterManager waiting for chunk [{1}] {2}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written + 1, _download.getFile_name()}); - secureWait(); + try { + synchronized (_secure_notify_lock) { + _secure_notify_lock.wait(1000); + } + } catch (InterruptedException ex) { + Logger.getLogger(ChunkWriterManager.class.getName()).log(Level.SEVERE, null, ex); + } } diff --git a/src/main/java/com/tonikelope/megabasterd/MainPanel.java b/src/main/java/com/tonikelope/megabasterd/MainPanel.java index 5f125912c..09e9569c4 100644 --- a/src/main/java/com/tonikelope/megabasterd/MainPanel.java +++ b/src/main/java/com/tonikelope/megabasterd/MainPanel.java @@ -70,7 +70,7 @@ */ public final class MainPanel { - public static final String VERSION = "7.95"; + public static final String VERSION = "7.96"; public static final boolean FORCE_SMART_PROXY = false; //TRUE FOR DEBUGING SMART PROXY public static final int THROTTLE_SLICE_SIZE = 16 * 1024; public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024; diff --git a/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java b/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java index fd81cec19..a2ad972d9 100644 --- a/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java +++ b/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java @@ -27,6 +27,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,7 +43,7 @@ public final class SmartMegaProxyManager { private static final Logger LOG = Logger.getLogger(SmartMegaProxyManager.class.getName()); private volatile String _proxy_list_url; - private final LinkedHashMap _proxy_list; + private final ConcurrentHashMap _proxy_list; private static final HashMap PROXY_LIST_AUTH = new HashMap<>(); private final MainPanel _main_panel; private volatile int _ban_time; @@ -63,12 +64,14 @@ public boolean isForce_smart_proxy() { public SmartMegaProxyManager(String proxy_list_url, MainPanel main_panel) { _proxy_list_url = (proxy_list_url != null && !"".equals(proxy_list_url)) ? proxy_list_url : DEFAULT_SMART_PROXY_URL; - _proxy_list = new LinkedHashMap<>(); + _proxy_list = new ConcurrentHashMap<>(); _main_panel = main_panel; refreshSmartProxySettings(); - refreshProxyList(); + THREAD_POOL.execute(() -> { + refreshProxyList(); + }); } private synchronized int countBlockedProxies() { @@ -191,168 +194,164 @@ public synchronized void refreshProxyList(String url_list) { _proxy_list_url = null; } - refreshProxyList(); - } - - public void refreshProxyList() { - THREAD_POOL.execute(() -> { + refreshProxyList(); + }); + } - synchronized (this) { + public synchronized void refreshProxyList() { - String data; + String data; - HttpURLConnection con = null; + HttpURLConnection con = null; - try { + try { - String custom_proxy_list = (_proxy_list_url == null ? DBTools.selectSettingValue("custom_proxy_list") : null); + String custom_proxy_list = (_proxy_list_url == null ? DBTools.selectSettingValue("custom_proxy_list") : null); - LinkedHashMap custom_clean_list = new LinkedHashMap<>(); + LinkedHashMap custom_clean_list = new LinkedHashMap<>(); - HashMap custom_clean_list_auth = new HashMap<>(); + HashMap custom_clean_list_auth = new HashMap<>(); - if (custom_proxy_list != null) { + if (custom_proxy_list != null) { - ArrayList custom_list = new ArrayList<>(Arrays.asList(custom_proxy_list.split("\\r?\\n"))); + ArrayList custom_list = new ArrayList<>(Arrays.asList(custom_proxy_list.split("\\r?\\n"))); - if (!custom_list.isEmpty()) { + if (!custom_list.isEmpty()) { - Long current_time = System.currentTimeMillis(); + Long current_time = System.currentTimeMillis(); - for (String proxy : custom_list) { + for (String proxy : custom_list) { - boolean socks = false; + boolean socks = false; - if (proxy.trim().startsWith("*")) { - socks = true; + if (proxy.trim().startsWith("*")) { + socks = true; - proxy = proxy.trim().substring(1); - } + proxy = proxy.trim().substring(1); + } - if (proxy.trim().contains("@")) { + if (proxy.trim().contains("@")) { - String[] proxy_parts = proxy.trim().split("@"); + String[] proxy_parts = proxy.trim().split("@"); - custom_clean_list_auth.put(proxy_parts[0], proxy_parts[1]); + custom_clean_list_auth.put(proxy_parts[0], proxy_parts[1]); - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - custom_clean_list.put(proxy_parts[0], proxy_data); + custom_clean_list.put(proxy_parts[0], proxy_data); - } else if (proxy.trim().matches(".+?:[0-9]{1,5}")) { + } else if (proxy.trim().matches(".+?:[0-9]{1,5}")) { - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - custom_clean_list.put(proxy, proxy_data); - } - } + custom_clean_list.put(proxy, proxy_data); } + } + } - if (!custom_clean_list.isEmpty()) { - - _proxy_list.clear(); + if (!custom_clean_list.isEmpty()) { - _proxy_list.putAll(custom_clean_list); - } + _proxy_list.clear(); - if (!custom_clean_list_auth.isEmpty()) { + _proxy_list.putAll(custom_clean_list); + } - PROXY_LIST_AUTH.clear(); + if (!custom_clean_list_auth.isEmpty()) { - PROXY_LIST_AUTH.putAll(custom_clean_list_auth); - } + PROXY_LIST_AUTH.clear(); - } + PROXY_LIST_AUTH.putAll(custom_clean_list_auth); + } - if (custom_clean_list.isEmpty() && _proxy_list_url != null && !"".equals(_proxy_list_url)) { + } - URL url = new URL(this._proxy_list_url); + if (custom_clean_list.isEmpty() && _proxy_list_url != null && !"".equals(_proxy_list_url)) { - con = (HttpURLConnection) url.openConnection(); + URL url = new URL(this._proxy_list_url); - con.setUseCaches(false); + con = (HttpURLConnection) url.openConnection(); - con.setRequestProperty("User-Agent", MainPanel.DEFAULT_USER_AGENT); + con.setUseCaches(false); - try (InputStream is = con.getInputStream(); ByteArrayOutputStream byte_res = new ByteArrayOutputStream()) { + con.setRequestProperty("User-Agent", MainPanel.DEFAULT_USER_AGENT); - byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; + try (InputStream is = con.getInputStream(); ByteArrayOutputStream byte_res = new ByteArrayOutputStream()) { - int reads; + byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; - while ((reads = is.read(buffer)) != -1) { + int reads; - byte_res.write(buffer, 0, reads); - } + while ((reads = is.read(buffer)) != -1) { - data = new String(byte_res.toByteArray(), "UTF-8"); - } + byte_res.write(buffer, 0, reads); + } - String[] proxy_list = data.split("\n"); + data = new String(byte_res.toByteArray(), "UTF-8"); + } - if (proxy_list.length > 0) { + String[] proxy_list = data.split("\n"); - _proxy_list.clear(); + if (proxy_list.length > 0) { - PROXY_LIST_AUTH.clear(); + _proxy_list.clear(); - Long current_time = System.currentTimeMillis(); + PROXY_LIST_AUTH.clear(); - for (String proxy : proxy_list) { + Long current_time = System.currentTimeMillis(); - boolean socks = false; + for (String proxy : proxy_list) { - if (proxy.trim().startsWith("*")) { - socks = true; + boolean socks = false; - proxy = proxy.trim().substring(1); - } + if (proxy.trim().startsWith("*")) { + socks = true; - if (proxy.trim().contains("@")) { + proxy = proxy.trim().substring(1); + } - String[] proxy_parts = proxy.trim().split("@"); + if (proxy.trim().contains("@")) { - PROXY_LIST_AUTH.put(proxy_parts[0], proxy_parts[1]); + String[] proxy_parts = proxy.trim().split("@"); - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + PROXY_LIST_AUTH.put(proxy_parts[0], proxy_parts[1]); - _proxy_list.put(proxy_parts[0], proxy_data); + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - } else if (proxy.trim().matches(".+?:[0-9]{1,5}")) { - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - _proxy_list.put(proxy, proxy_data); - } + _proxy_list.put(proxy_parts[0], proxy_data); - } + } else if (proxy.trim().matches(".+?:[0-9]{1,5}")) { + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + _proxy_list.put(proxy, proxy_data); } - _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (" + String.valueOf(getProxyCount()) + ")" + (this.isForce_smart_proxy() ? " F!" : "")); + } + } - LOG.log(Level.INFO, "{0} Smart Proxy Manager: proxy list refreshed ({1})", new Object[]{Thread.currentThread().getName(), _proxy_list.size()}); + _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (" + String.valueOf(getProxyCount()) + ")" + (this.isForce_smart_proxy() ? " F!" : "")); - } else if (!custom_clean_list.isEmpty()) { + LOG.log(Level.INFO, "{0} Smart Proxy Manager: proxy list refreshed ({1})", new Object[]{Thread.currentThread().getName(), _proxy_list.size()}); - _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (" + String.valueOf(getProxyCount()) + ")" + (this.isForce_smart_proxy() ? " F!" : "")); + } else if (!custom_clean_list.isEmpty()) { - LOG.log(Level.INFO, "{0} Smart Proxy Manager: proxy list refreshed ({1})", new Object[]{Thread.currentThread().getName(), _proxy_list.size()}); - } else { - _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (0 proxies!)" + (this.isForce_smart_proxy() ? " F!" : "")); - LOG.log(Level.INFO, "{0} Smart Proxy Manager: NO PROXYS"); - } + _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (" + String.valueOf(getProxyCount()) + ")" + (this.isForce_smart_proxy() ? " F!" : "")); - } catch (MalformedURLException ex) { - LOG.log(Level.SEVERE, ex.getMessage()); - } catch (IOException ex) { - LOG.log(Level.SEVERE, ex.getMessage()); - } finally { - if (con != null) { - con.disconnect(); - } + LOG.log(Level.INFO, "{0} Smart Proxy Manager: proxy list refreshed ({1})", new Object[]{Thread.currentThread().getName(), _proxy_list.size()}); + } else { + _main_panel.getView().updateSmartProxyStatus("SmartProxy: ON (0 proxies!)" + (this.isForce_smart_proxy() ? " F!" : "")); + LOG.log(Level.INFO, "{0} Smart Proxy Manager: NO PROXYS"); + } - } + } catch (MalformedURLException ex) { + LOG.log(Level.SEVERE, ex.getMessage()); + } catch (IOException ex) { + LOG.log(Level.SEVERE, ex.getMessage()); + } finally { + if (con != null) { + con.disconnect(); } - }); + + } } diff --git a/src/main/resources/images/mbasterd_screen.png b/src/main/resources/images/mbasterd_screen.png index 8d34ae35a..2f9c39fcb 100644 Binary files a/src/main/resources/images/mbasterd_screen.png and b/src/main/resources/images/mbasterd_screen.png differ