use of com.biglybt.net.magneturi.MagnetURIHandlerException in project BiglyBT by BiglySoftware.
the class MagnetPlugin method initialize.
@Override
public void initialize(PluginInterface _plugin_interface) {
plugin_interface = _plugin_interface;
MagnetURIHandler uri_handler = MagnetURIHandler.getSingleton();
final LocaleUtilities lu = plugin_interface.getUtilities().getLocaleUtilities();
lu.addListener(new LocaleListener() {
@Override
public void localeChanged(Locale l) {
updateLocale(lu);
}
});
updateLocale(lu);
BasicPluginConfigModel config = plugin_interface.getUIManager().createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, PLUGIN_CONFIGSECTION_ID);
config.addInfoParameter2("MagnetPlugin.current.port", String.valueOf(uri_handler.getPort()));
secondary_lookup = config.addBooleanParameter2("MagnetPlugin.use.lookup.service", "MagnetPlugin.use.lookup.service", true);
md_lookup = config.addBooleanParameter2("MagnetPlugin.use.md.download", "MagnetPlugin.use.md.download", true);
md_lookup_delay = config.addIntParameter2("MagnetPlugin.use.md.download.delay", "MagnetPlugin.use.md.download.delay", MD_LOOKUP_DELAY_SECS_DEFAULT);
md_lookup.addEnabledOnSelection(md_lookup_delay);
timeout_param = config.addIntParameter2("MagnetPlugin.timeout.secs", "MagnetPlugin.timeout.secs", PLUGIN_DOWNLOAD_TIMEOUT_SECS_DEFAULT);
sources_param = config.addStringListParameter2("MagnetPlugin.add.sources", "MagnetPlugin.add.sources", SOURCE_VALUES, SOURCE_STRINGS, SOURCE_VALUES[1]);
sources_extra_param = config.addIntParameter2("MagnetPlugin.add.sources.extra", "MagnetPlugin.add.sources.extra", 0);
magnet_recovery = config.addBooleanParameter2("MagnetPlugin.recover.magnets", "MagnetPlugin.recover.magnets", true);
Parameter[] nps = new Parameter[AENetworkClassifier.AT_NETWORKS.length];
for (int i = 0; i < nps.length; i++) {
String nn = AENetworkClassifier.AT_NETWORKS[i];
String config_name = "Network Selection Default." + nn;
String msg_text = "ConfigView.section.connection.networks." + nn;
final BooleanParameter param = config.addBooleanParameter2(config_name, msg_text, COConfigurationManager.getBooleanParameter(config_name));
COConfigurationManager.addParameterListener(config_name, new com.biglybt.core.config.ParameterListener() {
@Override
public void parameterChanged(String name) {
param.setDefaultValue(COConfigurationManager.getBooleanParameter(name));
}
});
nps[i] = param;
net_params.put(nn, param);
}
config.createGroup("label.default.nets", nps);
MenuItemListener listener = new MenuItemListener() {
@Override
public void selected(MenuItem _menu, Object _target) {
TableRow[] rows = (TableRow[]) _target;
String cb_all_data = "";
for (TableRow row : rows) {
Torrent torrent;
String name;
Object ds = row.getDataSource();
Download download = null;
ShareResource share = null;
if (ds instanceof ShareResourceFile) {
ShareResourceFile sf = (ShareResourceFile) ds;
try {
torrent = sf.getItem().getTorrent();
} catch (ShareException e) {
continue;
}
name = sf.getName();
share = sf;
} else if (ds instanceof ShareResourceDir) {
ShareResourceDir sd = (ShareResourceDir) ds;
try {
torrent = sd.getItem().getTorrent();
} catch (ShareException e) {
continue;
}
name = sd.getName();
share = sd;
} else if (ds instanceof Download) {
download = (Download) ds;
torrent = download.getTorrent();
name = download.getName();
} else {
continue;
}
boolean is_share = false;
Set<String> networks = new HashSet<>();
if (share != null) {
is_share = true;
Map<String, String> properties = share.getProperties();
if (properties != null) {
String nets = properties.get(ShareManager.PR_NETWORKS);
if (nets != null) {
String[] bits = nets.split(",");
for (String bit : bits) {
bit = AENetworkClassifier.internalise(bit.trim());
if (bit != null) {
networks.add(bit);
}
}
}
}
}
if (download != null) {
TorrentAttribute ta = plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_NETWORKS);
String[] nets = download.getListAttribute(ta);
networks.addAll(Arrays.asList(nets));
try {
byte[] hash = download.getTorrentHash();
if (plugin_interface.getShareManager().lookupShare(hash) != null) {
is_share = true;
}
} catch (Throwable e) {
}
}
String cb_data = download == null ? UrlUtils.getMagnetURI(name, torrent) : UrlUtils.getMagnetURI(download);
if (download != null) {
List<Tag> tags = TagManagerFactory.getTagManager().getTagsForTaggable(TagType.TT_DOWNLOAD_MANUAL, PluginCoreUtils.unwrap(download));
for (Tag tag : tags) {
if (tag.isPublic()) {
cb_data += "&tag=" + UrlUtils.encode(tag.getTagName(true));
}
}
}
String sources = sources_param.getValue();
boolean add_sources = sources.equals("2") || (sources.equals("1") && is_share);
if (add_sources) {
if (networks.isEmpty()) {
for (String net : AENetworkClassifier.AT_NETWORKS) {
if (isNetworkEnabled(net)) {
networks.add(net);
}
}
}
if (networks.contains(AENetworkClassifier.AT_PUBLIC) && !cb_data.contains("xsource=")) {
InetAddress ip = NetworkAdmin.getSingleton().getDefaultPublicAddress();
InetAddress ip_v6 = NetworkAdmin.getSingleton().getDefaultPublicAddressV6();
int port = TCPNetworkManager.getSingleton().getTCPListeningPortNumber();
if (ip != null && port > 0) {
cb_data += "&xsource=" + UrlUtils.encode(ip.getHostAddress() + ":" + port);
}
if (ip_v6 != null && port > 0) {
cb_data += "&xsource=" + UrlUtils.encode(ip_v6.getHostAddress() + ":" + port);
}
int extra = sources_extra_param.getValue();
if (extra > 0) {
if (download == null) {
if (torrent != null) {
download = plugin_interface.getDownloadManager().getDownload(torrent);
}
}
if (download != null) {
Set<String> added = new HashSet<>();
DownloadManager dm = PluginCoreUtils.unwrap(download);
PEPeerManager pm = dm.getPeerManager();
if (pm != null) {
List<PEPeer> peers = pm.getPeers();
for (PEPeer peer : peers) {
String peer_ip = peer.getIp();
if (AENetworkClassifier.categoriseAddress(peer_ip) == AENetworkClassifier.AT_PUBLIC) {
int peer_port = peer.getTCPListenPort();
if (peer_port > 0) {
cb_data += "&xsource=" + UrlUtils.encode(peer_ip + ":" + peer_port);
added.add(peer_ip);
extra--;
if (extra == 0) {
break;
}
}
}
}
}
if (extra > 0) {
Map response_cache = dm.getDownloadState().getTrackerResponseCache();
if (response_cache != null) {
List<TRTrackerAnnouncerResponsePeer> peers = TRTrackerAnnouncerFactory.getCachedPeers(response_cache);
for (TRTrackerAnnouncerResponsePeer peer : peers) {
String peer_ip = peer.getAddress();
if (AENetworkClassifier.categoriseAddress(peer_ip) == AENetworkClassifier.AT_PUBLIC) {
if (!added.contains(peer_ip)) {
int peer_port = peer.getPort();
if (peer_port > 0) {
cb_data += "&xsource=" + UrlUtils.encode(peer_ip + ":" + peer_port);
added.add(peer_ip);
extra--;
if (extra == 0) {
break;
}
}
}
}
}
}
}
}
}
}
}
// removed this as well - nothing wrong with allowing magnet copy
// for private torrents - they still can't be tracked if you don't
// have permission
/*if ( torrent.isPrivate()){
cb_data = getMessageText( "private_torrent" );
}else if ( torrent.isDecentralised()){
*/
// ok
/* relaxed this as we allow such torrents to be downloaded via magnet links
* (as opposed to tracked in the DHT)
}else if ( torrent.isDecentralisedBackupEnabled()){
TorrentAttribute ta_peer_sources = plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_PEER_SOURCES );
String[] sources = download.getListAttribute( ta_peer_sources );
boolean ok = false;
for (int i=0;i<sources.length;i++){
if ( sources[i].equalsIgnoreCase( "DHT")){
ok = true;
break;
}
}
if ( !ok ){
cb_data = getMessageText( "decentral_disabled" );
}
}else{
cb_data = getMessageText( "decentral_backup_disabled" );
*/
// }
// System.out.println( "MagnetPlugin: export = " + url );
cb_all_data += (cb_all_data.length() == 0 ? "" : "\n") + cb_data;
}
try {
plugin_interface.getUIManager().copyToClipBoard(cb_all_data);
} catch (Throwable e) {
e.printStackTrace();
}
}
};
List<TableContextMenuItem> menus = new ArrayList<>();
for (String table : TableManager.TABLE_MYTORRENTS_ALL) {
TableContextMenuItem menu = plugin_interface.getUIManager().getTableManager().addContextMenuItem(table, "MagnetPlugin.contextmenu.exporturi");
menu.addMultiListener(listener);
menu.setHeaderCategory(MenuItem.HEADER_SOCIAL);
menus.add(menu);
}
uri_handler.addListener(new MagnetURIHandlerListener() {
@Override
public byte[] badge() {
InputStream is = getClass().getClassLoader().getResourceAsStream("com/biglybt/plugin/magnet/Magnet.gif");
if (is == null) {
return (null);
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[8192];
while (true) {
int len = is.read(buffer);
if (len <= 0) {
break;
}
baos.write(buffer, 0, len);
}
} finally {
is.close();
}
return (baos.toByteArray());
} catch (Throwable e) {
Debug.printStackTrace(e);
return (null);
}
}
@Override
public byte[] download(MagnetURIHandlerProgressListener muh_listener, byte[] hash, String args, InetSocketAddress[] sources, long timeout) throws MagnetURIHandlerException {
try {
Download dl = plugin_interface.getDownloadManager().getDownload(hash);
if (dl != null) {
Torrent torrent = dl.getTorrent();
if (torrent != null) {
byte[] torrent_data = torrent.writeToBEncodedData();
torrent_data = addTrackersAndWebSeedsEtc(torrent_data, args, new HashSet<String>());
return (torrent_data);
}
}
} catch (Throwable e) {
Debug.printStackTrace(e);
}
return (recoverableDownload(muh_listener, hash, args, sources, timeout, false));
}
@Override
public boolean download(URL url) throws MagnetURIHandlerException {
try {
plugin_interface.getDownloadManager().addDownload(url, false);
return (true);
} catch (DownloadException e) {
throw (new MagnetURIHandlerException("Operation failed", e));
}
}
@Override
public boolean set(String name, Map values) {
List l = listeners.getList();
for (int i = 0; i < l.size(); i++) {
if (((MagnetPluginListener) l.get(i)).set(name, values)) {
return (true);
}
}
return (false);
}
@Override
public int get(String name, Map values) {
List l = listeners.getList();
for (int i = 0; i < l.size(); i++) {
int res = ((MagnetPluginListener) l.get(i)).get(name, values);
if (res != Integer.MIN_VALUE) {
return (res);
}
}
return (Integer.MIN_VALUE);
}
});
plugin_interface.getUIManager().addUIListener(new UIManagerListener() {
@Override
public void UIAttached(UIInstance instance) {
if (instance.getUIType().equals(UIInstance.UIT_SWT)) {
try {
Class.forName("com.biglybt.plugin.magnet.swt.MagnetPluginUISWT").getConstructor(new Class[] { UIInstance.class, TableContextMenuItem[].class }).newInstance(new Object[] { instance, menus.toArray(new TableContextMenuItem[menus.size()]) });
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
public void UIDetached(UIInstance instance) {
}
});
final List<Download> to_delete = new ArrayList<>();
Download[] downloads = plugin_interface.getDownloadManager().getDownloads();
for (Download download : downloads) {
if (download.getFlag(Download.FLAG_METADATA_DOWNLOAD)) {
to_delete.add(download);
}
}
final AESemaphore delete_done = new AESemaphore("delete waiter");
if (to_delete.size() > 0) {
AEThread2 t = new AEThread2("MagnetPlugin:delmds", true) {
@Override
public void run() {
try {
for (Download download : to_delete) {
try {
download.stop();
} catch (Throwable e) {
}
try {
download.remove(true, true);
} catch (Throwable e) {
Debug.out(e);
}
}
} finally {
delete_done.release();
}
}
};
t.start();
} else {
delete_done.release();
}
plugin_interface.addListener(new PluginListener() {
@Override
public void initializationComplete() {
// make sure DDB is initialised as we need it to register its
// transfer types
AEThread2 t = new AEThread2("MagnetPlugin:init", true) {
@Override
public void run() {
delete_done.reserve();
recoverDownloads();
plugin_interface.getDistributedDatabase();
}
};
t.start();
}
@Override
public void closedownInitiated() {
}
@Override
public void closedownComplete() {
}
});
}
use of com.biglybt.net.magneturi.MagnetURIHandlerException in project BiglyBT by BiglySoftware.
the class MagnetPlugin method _downloadSupport.
private DownloadResult _downloadSupport(final MagnetPluginProgressListener listener, final byte[] hash, final String args, final InetSocketAddress[] sources, long _timeout, int flags) throws MagnetURIHandlerException {
final long timeout;
if (_timeout < 0) {
// use plugin defined value
int secs = timeout_param.getValue();
if (secs <= 0) {
timeout = Integer.MAX_VALUE;
} else {
timeout = secs * 1000L;
}
} else {
timeout = _timeout;
}
boolean md_enabled;
final boolean dummy_hash = Arrays.equals(hash, new byte[20]);
if ((flags & FL_DISABLE_MD_LOOKUP) != 0) {
md_enabled = false;
} else {
md_enabled = md_lookup.getValue() && FeatureAvailability.isMagnetMDEnabled();
}
final byte[][] result_holder = { null };
final Throwable[] result_error = { null };
final boolean[] manually_cancelled = { false };
TimerEvent md_delay_event = null;
final MagnetPluginMDDownloader[] md_downloader = { null };
boolean net_pub_default = isNetworkEnabled(AENetworkClassifier.AT_PUBLIC);
final Set<String> networks_enabled;
final Set<String> additional_networks = new HashSet<>();
if (args != null) {
String[] bits = args.split("&");
List<URL> fl_args = new ArrayList<>();
Set<String> tr_networks = new HashSet<>();
Set<String> explicit_networks = new HashSet<>();
for (String bit : bits) {
if (bit.startsWith("maggot_sha1")) {
tr_networks.clear();
explicit_networks.clear();
fl_args.clear();
explicit_networks.add(AENetworkClassifier.AT_I2P);
break;
}
String[] x = bit.split("=");
if (x.length == 2) {
String lhs = x[0].toLowerCase();
if (lhs.equals("fl") || lhs.equals("xs") || lhs.equals("as")) {
try {
URL url = new URL(UrlUtils.decode(x[1]));
fl_args.add(url);
tr_networks.add(AENetworkClassifier.categoriseAddress(url.getHost()));
} catch (Throwable e) {
}
} else if (lhs.equals("tr")) {
try {
tr_networks.add(AENetworkClassifier.categoriseAddress(new URL(UrlUtils.decode(x[1])).getHost()));
} catch (Throwable e) {
}
} else if (lhs.equals("net")) {
String network = AENetworkClassifier.internalise(x[1]);
if (network != null) {
explicit_networks.add(network);
}
}
}
}
if (explicit_networks.size() > 0) {
networks_enabled = explicit_networks;
} else {
networks_enabled = tr_networks;
if (net_pub_default) {
if (networks_enabled.size() == 0) {
networks_enabled.add(AENetworkClassifier.AT_PUBLIC);
}
} else {
networks_enabled.remove(AENetworkClassifier.AT_PUBLIC);
}
}
if (fl_args.size() > 0) {
final AESemaphore fl_sem = new AESemaphore("fl_sem");
int fl_run = 0;
for (int i = 0; i < fl_args.size() && i < 3; i++) {
final URL fl_url = fl_args.get(i);
String url_net = AENetworkClassifier.categoriseAddress(fl_url.getHost());
if (networks_enabled.contains(url_net)) {
new AEThread2("Magnet:fldl", true) {
@Override
public void run() {
try {
TOTorrent torrent = TorrentUtils.download(fl_url, timeout);
if (torrent != null) {
if (dummy_hash || Arrays.equals(torrent.getHash(), hash)) {
synchronized (result_holder) {
result_holder[0] = BEncoder.encode(torrent.serialiseToMap());
}
}
}
} catch (Throwable e) {
Debug.out(e);
} finally {
fl_sem.release();
}
}
}.start();
fl_run++;
}
}
if (dummy_hash) {
long remaining = timeout;
for (int i = 0; i < fl_run && remaining > 0; i++) {
long start = SystemTime.getMonotonousTime();
if (!fl_sem.reserve(remaining)) {
break;
}
remaining -= (SystemTime.getMonotonousTime() - start);
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
}
}
}
}
} else {
networks_enabled = new HashSet<>();
if (net_pub_default) {
networks_enabled.add(AENetworkClassifier.AT_PUBLIC);
}
}
if (dummy_hash) {
return (null);
}
if (md_enabled) {
int delay_millis;
if ((flags & FL_NO_MD_LOOKUP_DELAY) != 0) {
delay_millis = 0;
} else {
delay_millis = md_lookup_delay.getValue() * 1000;
}
md_delay_event = SimpleTimer.addEvent("MagnetPlugin:md_delay", delay_millis <= 0 ? 0 : (SystemTime.getCurrentTime() + delay_millis), new TimerEventPerformer() {
@Override
public void perform(TimerEvent event) {
MagnetPluginMDDownloader mdd;
synchronized (md_downloader) {
if (event.isCancelled()) {
return;
}
md_downloader[0] = mdd = new MagnetPluginMDDownloader(MagnetPlugin.this, plugin_interface, hash, networks_enabled, sources, args);
}
if (listener != null) {
listener.reportActivity(getMessageText("report.md.starts"));
}
mdd.start(new MagnetPluginMDDownloader.DownloadListener() {
@Override
public void reportProgress(int downloaded, int total_size) {
if (listener != null) {
listener.reportActivity(getMessageText("report.md.progress", String.valueOf(downloaded + "/" + total_size)));
listener.reportCompleteness(100 * downloaded / total_size);
}
}
@Override
public void complete(TOTorrent torrent, Set<String> peer_networks) {
if (listener != null) {
listener.reportActivity(getMessageText("report.md.done"));
}
synchronized (result_holder) {
additional_networks.addAll(peer_networks);
try {
result_holder[0] = BEncoder.encode(torrent.serialiseToMap());
} catch (Throwable e) {
Debug.out(e);
}
}
}
@Override
public void failed(boolean mc, Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
synchronized (result_holder) {
manually_cancelled[0] = mc;
result_error[0] = e;
}
}
});
}
});
}
try {
try {
long remaining = timeout;
boolean sl_enabled = secondary_lookup.getValue() && FeatureAvailability.isMagnetSLEnabled();
boolean sl_failed = false;
long secondary_lookup_time = -1;
final Object[] secondary_result = { null };
if (networks_enabled.contains(AENetworkClassifier.AT_PUBLIC)) {
boolean is_first_download = first_download;
if (is_first_download) {
if (listener != null) {
listener.reportActivity(getMessageText("report.waiting_ddb"));
}
first_download = false;
}
final DistributedDatabase db = plugin_interface.getDistributedDatabase();
if (db.isAvailable()) {
final List potential_contacts = new ArrayList();
final AESemaphore potential_contacts_sem = new AESemaphore("MagnetPlugin:liveones");
final AEMonitor potential_contacts_mon = new AEMonitor("MagnetPlugin:liveones");
final int[] outstanding = { 0 };
final boolean[] lookup_complete = { false };
if (listener != null) {
listener.reportActivity(getMessageText("report.searching"));
}
DistributedDatabaseListener ddb_listener = new DistributedDatabaseListener() {
private Set found_set = new HashSet();
@Override
public void event(DistributedDatabaseEvent event) {
int type = event.getType();
if (type == DistributedDatabaseEvent.ET_OPERATION_STARTS) {
if (sources.length > 0) {
new DelayedEvent("MP:sourceAdd", 10 * 1000, new AERunnable() {
@Override
public void runSupport() {
addExplicitSources();
}
});
}
} else if (type == DistributedDatabaseEvent.ET_VALUE_READ) {
contactFound(event.getValue().getContact());
} else if (type == DistributedDatabaseEvent.ET_OPERATION_COMPLETE || type == DistributedDatabaseEvent.ET_OPERATION_TIMEOUT) {
if (listener != null) {
listener.reportActivity(getMessageText("report.found", String.valueOf(found_set.size())));
}
// now inject any explicit sources
addExplicitSources();
try {
potential_contacts_mon.enter();
lookup_complete[0] = true;
} finally {
potential_contacts_mon.exit();
}
potential_contacts_sem.release();
}
}
protected void addExplicitSources() {
for (int i = 0; i < sources.length; i++) {
try {
InetSocketAddress source = sources[i];
if (AENetworkClassifier.categoriseAddress(source) == AENetworkClassifier.AT_PUBLIC) {
contactFound(db.importContact(sources[i]));
}
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
}
public void contactFound(final DistributedDatabaseContact contact) {
String key = contact.getAddress().toString();
synchronized (found_set) {
if (found_set.contains(key)) {
return;
}
found_set.add(key);
}
if (listener != null && listener.verbose()) {
listener.reportActivity(getMessageText("report.found", contact.getName()));
}
try {
potential_contacts_mon.enter();
outstanding[0]++;
} finally {
potential_contacts_mon.exit();
}
contact.isAlive(20 * 1000, new DistributedDatabaseListener() {
@Override
public void event(DistributedDatabaseEvent event) {
try {
boolean alive = event.getType() == DistributedDatabaseEvent.ET_OPERATION_COMPLETE;
if (listener != null && listener.verbose()) {
listener.reportActivity(getMessageText(alive ? "report.alive" : "report.dead", contact.getName()));
}
try {
potential_contacts_mon.enter();
Object[] entry = new Object[] { Boolean.valueOf(alive), contact };
boolean added = false;
if (alive) {
for (int i = 0; i < potential_contacts.size(); i++) {
if (!((Boolean) ((Object[]) potential_contacts.get(i))[0]).booleanValue()) {
potential_contacts.add(i, entry);
added = true;
break;
}
}
}
if (!added) {
// dead at end
potential_contacts.add(entry);
}
} finally {
potential_contacts_mon.exit();
}
} finally {
try {
potential_contacts_mon.enter();
outstanding[0]--;
} finally {
potential_contacts_mon.exit();
}
potential_contacts_sem.release();
}
}
});
}
};
db.read(ddb_listener, db.createKey(hash, "Torrent download lookup for '" + ByteFormatter.encodeString(hash) + "'"), timeout, DistributedDatabase.OP_EXHAUSTIVE_READ | DistributedDatabase.OP_PRIORITY_HIGH);
long overall_start = SystemTime.getMonotonousTime();
long last_found = -1;
AsyncDispatcher dispatcher = new AsyncDispatcher();
while (remaining > 0) {
try {
potential_contacts_mon.enter();
if (lookup_complete[0] && potential_contacts.size() == 0 && outstanding[0] == 0) {
break;
}
} finally {
potential_contacts_mon.exit();
}
while (remaining > 0) {
if (listener != null && listener.cancelled()) {
return (null);
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
long wait_start = SystemTime.getMonotonousTime();
boolean got_sem = potential_contacts_sem.reserve(1000);
long now = SystemTime.getMonotonousTime();
remaining -= (now - wait_start);
if (got_sem) {
last_found = now;
break;
} else {
if (sl_enabled) {
if (secondary_lookup_time == -1) {
long base_time;
if (last_found == -1 || now - overall_start > 60 * 1000) {
base_time = overall_start;
} else {
base_time = last_found;
}
long time_so_far = now - base_time;
if (time_so_far > SECONDARY_LOOKUP_DELAY) {
secondary_lookup_time = SystemTime.getMonotonousTime();
doSecondaryLookup(listener, secondary_result, hash, networks_enabled, args);
}
} else {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
sl_failed = true;
// ignore, we just continue processing
}
}
}
continue;
}
}
if (sl_enabled) {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
sl_failed = true;
}
}
final DistributedDatabaseContact contact;
final boolean live_contact;
try {
potential_contacts_mon.enter();
if (potential_contacts.size() == 0) {
if (outstanding[0] == 0) {
break;
} else {
continue;
}
} else {
Object[] entry = (Object[]) potential_contacts.remove(0);
live_contact = ((Boolean) entry[0]).booleanValue();
contact = (DistributedDatabaseContact) entry[1];
}
} finally {
potential_contacts_mon.exit();
}
// System.out.println( "magnetDownload: " + contact.getName() + ", live = " + live_contact );
final AESemaphore contact_sem = new AESemaphore("MD:contact");
dispatcher.dispatch(new AERunnable() {
@Override
public void runSupport() {
try {
if (!live_contact) {
if (listener != null) {
listener.reportActivity(getMessageText("report.tunnel", contact.getName()));
}
contact.openTunnel();
}
try {
if (listener != null) {
listener.reportActivity(getMessageText("report.downloading", contact.getName()));
}
DistributedDatabaseValue value = contact.read(listener == null ? null : new DistributedDatabaseProgressListener() {
@Override
public void reportSize(long size) {
listener.reportSize(size);
}
@Override
public void reportActivity(String str) {
listener.reportActivity(str);
}
@Override
public void reportCompleteness(int percent) {
listener.reportCompleteness(percent);
}
}, db.getStandardTransferType(DistributedDatabaseTransferType.ST_TORRENT), db.createKey(hash, "Torrent download content for '" + ByteFormatter.encodeString(hash) + "'"), timeout);
if (value != null) {
// let's verify the torrent
byte[] data = (byte[]) value.getValue(byte[].class);
try {
TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray(data);
if (Arrays.equals(hash, torrent.getHash())) {
if (listener != null) {
listener.reportContributor(contact.getAddress());
}
synchronized (result_holder) {
result_holder[0] = data;
}
} else {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", "torrent invalid (hash mismatch)"));
}
}
} catch (Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", "torrent invalid (decode failed)"));
}
}
}
} catch (Throwable e) {
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
Debug.printStackTrace(e);
}
} finally {
contact_sem.release();
}
}
});
while (true) {
if (listener != null && listener.cancelled()) {
return (null);
}
boolean got_sem = contact_sem.reserve(500);
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
if (got_sem) {
break;
}
}
}
} else {
if (is_first_download) {
if (listener != null) {
listener.reportActivity(getMessageText("report.ddb_disabled"));
}
}
}
}
if (sl_enabled && !sl_failed) {
if (secondary_lookup_time == -1) {
secondary_lookup_time = SystemTime.getMonotonousTime();
doSecondaryLookup(listener, secondary_result, hash, networks_enabled, args);
}
while (SystemTime.getMonotonousTime() - secondary_lookup_time < SECONDARY_LOOKUP_MAX_TIME) {
if (listener != null && listener.cancelled()) {
return (null);
}
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (manually_cancelled[0]) {
throw (new Exception("Manually cancelled"));
}
}
Thread.sleep(500);
} catch (ResourceDownloaderException e) {
// get here when secondary lookup completes with fail
sl_failed = true;
break;
}
}
}
if (md_enabled) {
while (remaining > 0) {
if (listener != null && listener.cancelled()) {
return (null);
}
Thread.sleep(500);
remaining -= 500;
if (!sl_failed) {
try {
byte[] torrent = getSecondaryLookupResult(secondary_result);
if (torrent != null) {
return (new DownloadResult(torrent, networks_enabled, additional_networks));
}
} catch (ResourceDownloaderException e) {
// get here when secondary lookup completes with fail
sl_failed = true;
}
}
synchronized (result_holder) {
if (result_holder[0] != null) {
return (new DownloadResult(result_holder[0], networks_enabled, additional_networks));
}
if (result_error[0] != null) {
break;
}
}
}
}
// nothing found
return (null);
} catch (Throwable e) {
Debug.printStackTrace(e);
if (listener != null) {
listener.reportActivity(getMessageText("report.error", Debug.getNestedExceptionMessage(e)));
}
throw (new MagnetURIHandlerException("MagnetURIHandler failed", e));
}
} finally {
synchronized (md_downloader) {
if (md_delay_event != null) {
md_delay_event.cancel();
if (md_downloader[0] != null) {
md_downloader[0].cancel();
}
}
}
}
}
use of com.biglybt.net.magneturi.MagnetURIHandlerException in project BiglyBT by BiglySoftware.
the class MagnetPlugin method recoverableDownload.
private byte[] recoverableDownload(final MagnetURIHandlerProgressListener muh_listener, final byte[] hash, final String args, final InetSocketAddress[] sources, final long timeout, boolean is_recovering) throws MagnetURIHandlerException {
boolean recover = magnet_recovery.getValue();
String hash_str = Base32.encode(hash);
try {
if (recover) {
Map map = new HashMap();
map.put("hash", hash);
map.put("args", args);
List<Map> l_sources = new ArrayList<>();
map.put("sources", l_sources);
if (sources != null && sources.length > 0) {
for (InetSocketAddress isa : sources) {
try {
Map m = new HashMap();
m.put("port", isa.getPort());
if (isa.isUnresolved()) {
map.put("host", isa.getHostName());
} else {
InetAddress ia = isa.getAddress();
map.put("address", ia.getAddress());
}
l_sources.add(m);
} catch (Throwable e) {
Debug.out(e);
}
}
}
map.put("timeout", timeout);
synchronized (download_activities) {
Map active = COConfigurationManager.getMapParameter("MagnetPlugin.active.magnets", new HashMap());
active.put(hash_str, map);
COConfigurationManager.setParameter("MagnetPlugin.active.magnets", active);
}
COConfigurationManager.setDirty();
}
byte[] result = download(muh_listener == null ? null : new MagnetPluginProgressListener() {
@Override
public void reportSize(long size) {
muh_listener.reportSize(size);
}
@Override
public void reportActivity(String str) {
muh_listener.reportActivity(str);
}
@Override
public void reportCompleteness(int percent) {
muh_listener.reportCompleteness(percent);
}
@Override
public void reportContributor(InetSocketAddress address) {
}
@Override
public boolean cancelled() {
return (muh_listener.cancelled());
}
@Override
public boolean verbose() {
return (muh_listener.verbose());
}
}, hash, args, sources, timeout, is_recovering ? MagnetPlugin.FL_NO_MD_LOOKUP_DELAY : MagnetPlugin.FL_NONE);
return (result);
} catch (Throwable e) {
if (e instanceof MagnetURIHandlerException) {
throw ((MagnetURIHandlerException) e);
} else {
throw (new MagnetURIHandlerException("Magnet download failed", e));
}
} finally {
if (recover) {
synchronized (download_activities) {
Map active = COConfigurationManager.getMapParameter("MagnetPlugin.active.magnets", new HashMap());
active.remove(hash_str);
}
COConfigurationManager.setDirty();
}
}
}
Aggregations