diff --git a/src/main/java/com/tonikelope/megabasterd/KissVideoStreamServer.java b/src/main/java/com/tonikelope/megabasterd/KissVideoStreamServer.java index 26a3c0c4e..b66c20162 100644 --- a/src/main/java/com/tonikelope/megabasterd/KissVideoStreamServer.java +++ b/src/main/java/com/tonikelope/megabasterd/KissVideoStreamServer.java @@ -37,6 +37,7 @@ public final class KissVideoStreamServer implements HttpHandler, SecureSingleThr public static final int THREAD_START = 0x01; public static final int THREAD_STOP = 0x02; + public static final int DEFAULT_WORKERS = 10; private final MainPanel _main_panel; private final ConcurrentHashMap> _link_cache; @@ -436,7 +437,7 @@ public final class KissVideoStreamServer implements HttpHandler, SecureSingleThr THREAD_POOL.execute(chunkwriter); - for (int i = 0; i < StreamChunkWriter.BUFFER_CHUNKS_SIZE; i++) { + for (int i = 0; i < DEFAULT_WORKERS; i++) { StreamChunkDownloader worker = new StreamChunkDownloader(i + 1, chunkwriter); diff --git a/src/main/java/com/tonikelope/megabasterd/MainPanel.java b/src/main/java/com/tonikelope/megabasterd/MainPanel.java index a35b7d321..7edd0eeff 100644 --- a/src/main/java/com/tonikelope/megabasterd/MainPanel.java +++ b/src/main/java/com/tonikelope/megabasterd/MainPanel.java @@ -48,7 +48,7 @@ import org.apache.http.auth.UsernamePasswordCredentials; */ public final class MainPanel { - public static final String VERSION = "3.9"; + public static final String VERSION = "3.91"; public static final int THROTTLE_SLICE_SIZE = 16 * 1024; public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024; public static final int STREAMER_PORT = 1337; diff --git a/src/main/java/com/tonikelope/megabasterd/MainPanelView.java b/src/main/java/com/tonikelope/megabasterd/MainPanelView.java index 6f23a2fe6..c79ae4e59 100644 --- a/src/main/java/com/tonikelope/megabasterd/MainPanelView.java +++ b/src/main/java/com/tonikelope/megabasterd/MainPanelView.java @@ -854,8 +854,8 @@ public final class MainPanelView extends javax.swing.JFrame { MainPanel.getProxy_manager().setExit(true); - synchronized (MainPanel.getProxy_manager().getRefresh_lock()) { - MainPanel.getProxy_manager().getRefresh_lock().notify(); + synchronized (MainPanel.getProxy_manager()) { + MainPanel.getProxy_manager().notify(); } this.getMain_panel().setProxy_manager(null); diff --git a/src/main/java/com/tonikelope/megabasterd/MegaAPI.java b/src/main/java/com/tonikelope/megabasterd/MegaAPI.java index 009cec1e3..cb56eec78 100644 --- a/src/main/java/com/tonikelope/megabasterd/MegaAPI.java +++ b/src/main/java/com/tonikelope/megabasterd/MegaAPI.java @@ -202,9 +202,9 @@ public final class MegaAPI { url_api = new URL(API_URL + "/cs?id=" + String.valueOf(_seqno) + (_sid != null ? "&sid=" + _sid : "") + (API_KEY != null ? "&ak=" + API_KEY : "")); String res = _rawRequest(request, url_api); - - if(res!=null) { - + + if (res != null) { + ObjectMapper objectMapper = new ObjectMapper(); HashMap[] res_map = objectMapper.readValue(res, HashMap[].class); @@ -229,7 +229,7 @@ public final class MegaAPI { quota[1] = (Long) res_map[0].get("mstrg"); } } - + } catch (Exception ex) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); diff --git a/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java b/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java index 9eea4a8fb..27fe4ba95 100644 --- a/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java +++ b/src/main/java/com/tonikelope/megabasterd/SmartMegaProxyManager.java @@ -6,12 +6,13 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.util.Random; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Level; import java.util.logging.Logger; import static com.tonikelope.megabasterd.MainPanel.THREAD_POOL; import static com.tonikelope.megabasterd.MiscTools.getApacheKissHttpClient; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; @@ -23,19 +24,20 @@ import org.apache.http.impl.client.CloseableHttpClient; public class SmartMegaProxyManager implements Runnable { public static final int PROXY_TIMEOUT = 30; - public static final int REFRESH_PROXY_LIST_TIMEOUT = 1800; + public static final int PROXY_MAX_EXCLUDE_COUNTER = 5; + public static final int PROXY_EXCLUDE_SECS = 10; private volatile String _proxy_list_url; private final ConcurrentLinkedQueue _proxy_list; + private final ConcurrentHashMap _proxy_info; private final MainPanel _main_panel; private volatile boolean _exit; - private final Object _refresh_lock; public SmartMegaProxyManager(MainPanel main_panel, String proxy_list_url) { _main_panel = main_panel; _proxy_list_url = proxy_list_url; _proxy_list = new ConcurrentLinkedQueue<>(); + _proxy_info = new ConcurrentHashMap<>(); _exit = false; - _refresh_lock = new Object(); } public String getProxy_list_url() { @@ -54,53 +56,64 @@ public class SmartMegaProxyManager implements Runnable { @Override public void run() { - synchronized (_refresh_lock) { - - _refreshProxyList(); - } + _refreshProxyList(); } }); } - public Object getRefresh_lock() { - return _refresh_lock; - } - public String getFastestProxy() { - return _proxy_list.peek(); - } + for (String proxy : _proxy_list) { - public String getRandomProxy() { + HashMap proxy_info = (HashMap) _proxy_info.get(proxy); - synchronized (_refresh_lock) { - return _proxy_list.toArray(new String[_proxy_list.size()])[(new Random()).nextInt(_proxy_list.size())]; + Long extimestamp = (Long) proxy_info.get("extimestamp"); + + if (extimestamp == null || extimestamp + PROXY_EXCLUDE_SECS * 1000 < System.currentTimeMillis()) { + + return proxy; + + } else { + Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Smart Proxy Manager: proxy is temporary excluded -> {1}", new Object[]{Thread.currentThread().getName(), proxy}); + } } + + return null; } public void excludeProxy(String proxy) { - if (_proxy_list.contains(proxy)) { + if (_proxy_info.containsKey(proxy)) { - synchronized (_refresh_lock) { + HashMap proxy_info = (HashMap) _proxy_info.get(proxy); + + int excount = (int) proxy_info.get("excount") + 1; + + if (excount < PROXY_MAX_EXCLUDE_COUNTER) { + + proxy_info.put("excount", excount); + + proxy_info.put("extimestamp", System.currentTimeMillis()); + + } else { + + Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Smart Proxy Manager: proxy removed -> {1}", new Object[]{Thread.currentThread().getName(), proxy}); _proxy_list.remove(proxy); - } + _proxy_info.remove(proxy); - _main_panel.getView().updateSmartProxyStatus("SmartProxy: " + _proxy_list.size()); + _main_panel.getView().updateSmartProxyStatus("SmartProxy: " + _proxy_list.size()); - if (_proxy_list.isEmpty()) { + if (_proxy_list.isEmpty()) { - THREAD_POOL.execute(new Runnable() { - @Override - public void run() { - - synchronized (_refresh_lock) { + THREAD_POOL.execute(new Runnable() { + @Override + public void run() { _refreshProxyList(); } - } - }); + }); + } } } } @@ -139,11 +152,16 @@ public class SmartMegaProxyManager implements Runnable { if (proxy_list.length > 0) { _proxy_list.clear(); + _proxy_info.clear(); for (String proxy : proxy_list) { if (proxy.trim().matches(".+?:[0-9]{1,5}")) { - this._proxy_list.add(proxy); + _proxy_list.add(proxy); + HashMap proxy_info = new HashMap<>(); + proxy_info.put("extimestamp", null); + proxy_info.put("excount", 0); + _proxy_info.put(proxy.trim(), proxy_info); } } } @@ -167,17 +185,18 @@ public class SmartMegaProxyManager implements Runnable { _main_panel.getView().updateSmartProxyStatus(""); + this._refreshProxyList(); + while (!_exit) { - synchronized (_refresh_lock) { + this._refreshProxyList(); - this._refreshProxyList(); - - try { - _refresh_lock.wait(1000 * REFRESH_PROXY_LIST_TIMEOUT); - } catch (InterruptedException ex) { - Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); + try { + synchronized (this) { + wait(); } + } catch (InterruptedException ex) { + Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } } diff --git a/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java b/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java index 2f33a8d56..1e9675a3a 100644 --- a/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java +++ b/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java @@ -16,8 +16,8 @@ import static com.tonikelope.megabasterd.MiscTools.*; */ public class StreamChunkWriter implements Runnable, SecureMultiThreadNotifiable { - public static final int CHUNK_SIZE = 10485760; //10 MB - public static final int BUFFER_CHUNKS_SIZE = 4; + public static final int CHUNK_SIZE = 1048576; + public static final int BUFFER_CHUNKS_SIZE = 20; private long _next_offset_required; private long _bytes_written; private final long _start_offset;