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 class ChunkWriterManager implements Runnable, SecureSingleThreadNotifiabl 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 class ChunkWriterManager implements Runnable, SecureSingleThreadNotifiabl } } + 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 class ChunkWriterManager implements Runnable, SecureSingleThreadNotifiabl 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(); - - _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; - } - - byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; - - 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()); - } - - _bytes_written += chunk_file.length(); - - _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()}); - - chunk_file.delete(); - - chunk_file = new File(getChunks_dir() + "/" + new File(_download.getFile_name()).getName() + ".chunk" + String.valueOf(_last_chunk_id_written + 1)); + if (!download_finished && _download.getProgress() == _file_size) { + finishDownload(); + download_finished = true; } - } catch (IOException ex) { - chunk_io_error = true; - LOG.log(Level.WARNING, ex.getMessage()); - MiscTools.pausar(1000); + + byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; + + 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()); + } + + _bytes_written += chunk_file.length(); + + _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()}); + + chunk_file.delete(); + + 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); } + } 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 @@ import javax.swing.UIManager; */ 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.HashMap; 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 final class SmartMegaProxyManager { 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 final class SmartMegaProxyManager { _proxy_list_url = null; } - refreshProxyList(); + THREAD_POOL.execute(() -> { + refreshProxyList(); + }); } - public void refreshProxyList() { + public synchronized void refreshProxyList() { - THREAD_POOL.execute(() -> { + String data; - synchronized (this) { + HttpURLConnection con = null; - String data; + try { - HttpURLConnection con = null; + String custom_proxy_list = (_proxy_list_url == null ? DBTools.selectSettingValue("custom_proxy_list") : null); - try { + LinkedHashMap custom_clean_list = new LinkedHashMap<>(); - String custom_proxy_list = (_proxy_list_url == null ? DBTools.selectSettingValue("custom_proxy_list") : null); + HashMap custom_clean_list_auth = new HashMap<>(); - LinkedHashMap custom_clean_list = new LinkedHashMap<>(); + if (custom_proxy_list != null) { - HashMap custom_clean_list_auth = new HashMap<>(); + ArrayList custom_list = new ArrayList<>(Arrays.asList(custom_proxy_list.split("\\r?\\n"))); - if (custom_proxy_list != null) { + if (!custom_list.isEmpty()) { - ArrayList custom_list = new ArrayList<>(Arrays.asList(custom_proxy_list.split("\\r?\\n"))); + Long current_time = System.currentTimeMillis(); - if (!custom_list.isEmpty()) { + for (String proxy : custom_list) { - Long current_time = System.currentTimeMillis(); + boolean socks = false; - for (String proxy : custom_list) { + if (proxy.trim().startsWith("*")) { + socks = true; - boolean socks = false; - - if (proxy.trim().startsWith("*")) { - socks = true; - - proxy = proxy.trim().substring(1); - } - - if (proxy.trim().contains("@")) { - - String[] proxy_parts = proxy.trim().split("@"); - - custom_clean_list_auth.put(proxy_parts[0], proxy_parts[1]); - - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - - custom_clean_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}; - - custom_clean_list.put(proxy, proxy_data); - } - } + proxy = proxy.trim().substring(1); } - if (!custom_clean_list.isEmpty()) { + if (proxy.trim().contains("@")) { - _proxy_list.clear(); + String[] proxy_parts = proxy.trim().split("@"); - _proxy_list.putAll(custom_clean_list); + custom_clean_list_auth.put(proxy_parts[0], proxy_parts[1]); + + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + + custom_clean_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}; + + custom_clean_list.put(proxy, proxy_data); } - - if (!custom_clean_list_auth.isEmpty()) { - - 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); - - con = (HttpURLConnection) url.openConnection(); - - con.setUseCaches(false); - - con.setRequestProperty("User-Agent", MainPanel.DEFAULT_USER_AGENT); - - try (InputStream is = con.getInputStream(); ByteArrayOutputStream byte_res = new ByteArrayOutputStream()) { - - byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; - - int reads; - - while ((reads = is.read(buffer)) != -1) { - - byte_res.write(buffer, 0, reads); - } - - data = new String(byte_res.toByteArray(), "UTF-8"); - } - - String[] proxy_list = data.split("\n"); - - if (proxy_list.length > 0) { - - _proxy_list.clear(); - - PROXY_LIST_AUTH.clear(); - - Long current_time = System.currentTimeMillis(); - - for (String proxy : proxy_list) { - - boolean socks = false; - - if (proxy.trim().startsWith("*")) { - socks = true; - - proxy = proxy.trim().substring(1); - } - - if (proxy.trim().contains("@")) { - - String[] proxy_parts = proxy.trim().split("@"); - - PROXY_LIST_AUTH.put(proxy_parts[0], proxy_parts[1]); - - Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; - - _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()}); - - } else if (!custom_clean_list.isEmpty()) { - - _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()}); - } 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(); - } - } + + if (!custom_clean_list.isEmpty()) { + + _proxy_list.clear(); + + _proxy_list.putAll(custom_clean_list); + } + + if (!custom_clean_list_auth.isEmpty()) { + + 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); + + con = (HttpURLConnection) url.openConnection(); + + con.setUseCaches(false); + + con.setRequestProperty("User-Agent", MainPanel.DEFAULT_USER_AGENT); + + try (InputStream is = con.getInputStream(); ByteArrayOutputStream byte_res = new ByteArrayOutputStream()) { + + byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE]; + + int reads; + + while ((reads = is.read(buffer)) != -1) { + + byte_res.write(buffer, 0, reads); + } + + data = new String(byte_res.toByteArray(), "UTF-8"); + } + + String[] proxy_list = data.split("\n"); + + if (proxy_list.length > 0) { + + _proxy_list.clear(); + + PROXY_LIST_AUTH.clear(); + + Long current_time = System.currentTimeMillis(); + + for (String proxy : proxy_list) { + + boolean socks = false; + + if (proxy.trim().startsWith("*")) { + socks = true; + + proxy = proxy.trim().substring(1); + } + + if (proxy.trim().contains("@")) { + + String[] proxy_parts = proxy.trim().split("@"); + + PROXY_LIST_AUTH.put(proxy_parts[0], proxy_parts[1]); + + Long[] proxy_data = new Long[]{current_time, socks ? 1L : -1L}; + + _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()}); + + } else if (!custom_clean_list.isEmpty()) { + + _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()}); + } 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