public static boolean isPlatformTracker(TOTorrent torrent) { try { if (torrent == null) { return false; } Object oCache = mapPlatformTrackerTorrents.get(torrent); if (oCache instanceof Boolean) { return ((Boolean) oCache).booleanValue(); } // check them all incase someone includes one of our trackers in a multi-tracker // torrent URL announceURL = torrent.getAnnounceURL(); if (announceURL != null) { if (!isPlatformHost(announceURL.getHost())) { mapPlatformTrackerTorrents.put(torrent, new Boolean(false)); return (false); } } TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets(); for (int i = 0; i < sets.length; i++) { URL[] urls = sets[i].getAnnounceURLs(); for (int j = 0; j < urls.length; j++) { if (!isPlatformHost(urls[j].getHost())) { mapPlatformTrackerTorrents.put(torrent, new Boolean(false)); return (false); } } } boolean b = announceURL != null; mapPlatformTrackerTorrents.put(torrent, new Boolean(b)); return b; } catch (Throwable e) { Debug.printStackTrace(e); mapPlatformTrackerTorrents.put(torrent, new Boolean(false)); return (false); } }
public static boolean canProgressiveOrIsComplete(TOTorrent torrent) { if (torrent == null) { return false; } try { DownloadManagerEnhancer enhancer = DownloadManagerEnhancer.getSingleton(); EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload(torrent.getHash()); if (edm == null) { return enhancer.isProgressiveAvailable() && PlatformTorrentUtils.isContentProgressive(torrent); } boolean complete = edm.getDownloadManager().isDownloadComplete(false); if (complete) { return true; } // not complete if (!edm.supportsProgressiveMode()) { return false; } } catch (TOTorrentException e) { return false; } return true; }
protected TRTrackerAnnouncerMuxer( TOTorrent _torrent, TRTrackerAnnouncerFactory.DataProvider _f_provider, boolean _manual) throws TRTrackerAnnouncerException { super(_torrent); try { last_response_informed = new TRTrackerAnnouncerResponseImpl( null, _torrent.getHashWrapper(), TRTrackerAnnouncerResponse.ST_OFFLINE, TRTrackerAnnouncer.REFRESH_MINIMUM_SECS, "Initialising"); } catch (TOTorrentException e) { Logger.log(new LogEvent(_torrent, LOGID, "Torrent hash retrieval fails", e)); throw (new TRTrackerAnnouncerException("TRTrackerAnnouncer: URL encode fails")); } is_manual = _manual; f_provider = _f_provider; split(); }
private TRTrackerAnnouncerHelper create( TOTorrent torrent, String[] networks, TOTorrentAnnounceURLSet[] sets) throws TRTrackerAnnouncerException { TRTrackerAnnouncerHelper announcer; boolean decentralised; if (sets.length == 0) { decentralised = TorrentUtils.isDecentralised(torrent.getAnnounceURL()); } else { decentralised = TorrentUtils.isDecentralised(sets[0].getAnnounceURLs()[0]); } if (decentralised) { announcer = new TRTrackerDHTAnnouncerImpl(torrent, networks, is_manual, getHelper()); } else { announcer = new TRTrackerBTAnnouncerImpl(torrent, sets, networks, is_manual, getHelper()); } for (TOTorrentAnnounceURLSet set : sets) { URL[] urls = set.getAnnounceURLs(); for (URL u : urls) { String key = u.toExternalForm(); StatusSummary summary = recent_responses.get(key); if (summary == null) { summary = new StatusSummary(announcer, u); recent_responses.put(key, summary); } else { summary.setHelper(announcer); } } } if (provider != null) { announcer.setAnnounceDataProvider(provider); } if (ip_override != null) { announcer.setIPOverride(ip_override); } return (announcer); }
/** * @param torrent * @param string * @since 3.0.1.5 */ public static void log(TOTorrent torrent, String string) { String hash = ""; try { hash = torrent.getHashWrapper().toBase32String(); } catch (Exception e) { } log(hash + "] " + string); }
public static void generate_preview_for_torrent(TOTorrent created, File file) throws TOTorrentException { logger.finer("generating preview..2."); try { File largestFile = null; long largest = 0; for (TOTorrentFile f : created.getFiles()) { if (f == null) { continue; } if (InOrderType.getType(f.getRelativePath()) == null) { continue; } if (f.getLength() > largest) { largest = f.getLength(); if (file.isDirectory() == false) { largestFile = new File(file.getParent(), f.getRelativePath()); } else { largestFile = new File(file, f.getRelativePath()); } } } if (largestFile != null) { logger.finer("largest is: " + largestFile.getAbsolutePath()); } try { FFMpegAsyncOperationManager.getInstance() .getPreviewImage(created.getHash(), largestFile, 10, TimeUnit.SECONDS); } catch (TorrentException e) { // this should never happen... e.printStackTrace(); } catch (DataNotAvailableException e) { logger.finest("unable to create preview for file: " + largest); } } catch (NullPointerException e) { logger.warning("Preview generation null pointer: " + e.toString()); e.printStackTrace(); } }
public long getHashFailCount() { TOTorrent t = download_manager.getTorrent(); if (t == null) { return (0); } long total = getHashFailBytes(); long res = total / t.getPieceLength(); if (res == 0 && total > 0) { res = 1; } return (res); }
public CachePeer[] lookup(TOTorrent torrent) { try { InetAddress[] addresses = findCache(torrent.getAnnounceURL(), torrent.getHash()); CachePeer[] result = new CachePeer[addresses.length]; for (int i = 0; i < addresses.length; i++) { result[i] = new CacheDiscovery.CachePeerImpl(CachePeer.PT_CACHE_LOGIC, addresses[i], 6881); } return (result); } catch (TOTorrentException e) { Debug.printStackTrace(e); return (new CachePeer[0]); } }
public static boolean isUpdateDM(DownloadManager dm) { Boolean oisUpdate = (Boolean) dm.getUserData("isUpdate"); if (oisUpdate != null) { return oisUpdate.booleanValue(); } boolean isUpdate = true; TOTorrent torrent = dm.getTorrent(); if (torrent == null) { isUpdate = false; } else { URL announceURL = torrent.getAnnounceURL(); if (announceURL != null) { if (announceURL.getHost().indexOf(AELITIS_HOST_CORE) == -1) { isUpdate = false; } } if (isUpdate) { TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets(); for (int i = 0; i < sets.length; i++) { URL[] urls = sets[i].getAnnounceURLs(); for (int j = 0; j < urls.length; j++) { if (urls[j].getHost().indexOf(AELITIS_HOST_CORE) == -1) { isUpdate = false; break; } } } } } dm.setUserData("isUpdate", new Boolean(isUpdate)); return isUpdate; }
protected void setControlFile() { TOTorrentFile tf = owner.getOwner().getTorrentFile(); if (tf == null) { controlFileName = null; control_dir = null; } else { TOTorrent torrent = tf.getTorrent(); TOTorrentFile[] files = torrent.getFiles(); int file_index = -1; for (int i = 0; i < files.length; i++) { if (files[i] == tf) { file_index = i; break; } } if (file_index == -1) { Debug.out("File '" + owner.getName() + "' not found in torrent!"); controlFileName = null; control_dir = null; } else { control_dir = owner.getOwner().getControlFileDir(); controlFileName = StringInterner.intern("fmfile" + file_index + ".dat"); } } }
public boolean hasSameHashAs(TOTorrent other) { try { byte[] other_hash = other.getHash(); return (Arrays.equals(getHash(), other_hash)); } catch (TOTorrentException e) { Debug.printStackTrace(e); return (false); } }
static Map getTempContentMap(TOTorrent torrent) { if (torrent == null) { return new HashMap(); } Map mapAZProps = torrent.getAdditionalMapProperty("attributes"); if (mapAZProps == null) { mapAZProps = new HashMap(); torrent.setAdditionalMapProperty("attributes", mapAZProps); } Object objExistingContentMap = mapAZProps.get(TOR_AZ_PROP_MAP); Map mapContent; if (objExistingContentMap instanceof Map) { mapContent = (Map) objExistingContentMap; } else { mapContent = new HashMap(); mapAZProps.put(TOR_AZ_PROP_MAP, mapContent); } return mapContent; }
public static Map getContentMap(TOTorrent torrent) { if (torrent == null) { return Collections.EMPTY_MAP; } Map mapAZProps = torrent.getAdditionalMapProperty(TOTorrent.AZUREUS_PROPERTIES); if (mapAZProps == null) { mapAZProps = new HashMap(); torrent.setAdditionalMapProperty(TOTorrent.AZUREUS_PROPERTIES, mapAZProps); } Object objExistingContentMap = mapAZProps.get(TOR_AZ_PROP_MAP); Map mapContent; if (objExistingContentMap instanceof Map) { mapContent = (Map) objExistingContentMap; } else { mapContent = new HashMap(); mapAZProps.put(TOR_AZ_PROP_MAP, mapContent); } return mapContent; }
/** * @param torrent * @param maxDelayMS TODO */ public static void updateMetaData(final TOTorrent torrent, long maxDelayMS) { if (!isContent(torrent, true)) { log(torrent, "torrent " + new String(torrent.getName()) + " not az content"); return; } log(torrent, "updateMD"); PlatformTorrentMessenger.getMetaData( new TOTorrent[] {torrent}, maxDelayMS, new PlatformTorrentMessenger.GetMetaDataReplyListener() { public void messageSent() {} public void replyReceived(String replyType, Map mapHashes) { updateMetaData_handleReply(torrent, null, replyType, mapHashes); } }); }
public static boolean isExternallyPlayable( TOTorrent torrent, int file_index, boolean complete_only) { if (torrent == null) { return false; } try { Download download = AzureusCoreFactory.getSingleton() .getPluginManager() .getDefaultPluginInterface() .getDownloadManager() .getDownload(torrent.getHash()); if (download != null) { return isExternallyPlayable(download, file_index, complete_only); } } catch (Exception e) { e.printStackTrace(); } return false; }
private void _openView(int viewID, Object data) { switch (viewID) { case VIEW_CONSOLE: openView(SideBar.SIDEBAR_HEADER_PLUGINS, LoggerView.class, null, data, true); break; case VIEW_ALLPEERS: openView(SideBar.SIDEBAR_HEADER_TRANSFERS, PeersSuperView.class, null, data, true); break; case VIEW_PEERS_STATS: openView(SideBar.SIDEBAR_HEADER_PLUGINS, ClientStatsView.class, null, data, true); break; case VIEW_CONFIG: showConfig((data instanceof String) ? (String) data : null); break; case VIEW_DM_DETAILS: { String id = SideBar.SIDEBAR_TORRENT_DETAILS_PREFIX; if (data instanceof DownloadManager) { DownloadManager dm = (DownloadManager) data; TOTorrent torrent = dm.getTorrent(); if (torrent != null) { try { id += torrent.getHashWrapper().toBase32String(); } catch (TOTorrentException e) { e.printStackTrace(); } } } MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI(); if (mdi != null) { mdi.loadEntryByID(id, true, false, data); } } break; case VIEW_DM_MULTI_OPTIONS: openView(SideBar.SIDEBAR_HEADER_TRANSFERS, TorrentOptionsView.class, null, data, true); break; case VIEW_MYSHARES: openView(SideBar.SIDEBAR_HEADER_TRANSFERS, MySharesView.class, null, data, true); break; case VIEW_MYTORRENTS: { MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI(); if (mdi != null) { mdi.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY); } } break; case VIEW_MYTRACKER: openView(SideBar.SIDEBAR_HEADER_TRANSFERS, MyTrackerView.class, null, data, true); break; case VIEW_TAGS_OVERVIEW: { MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI(); if (mdi != null) { mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_TAGS); } break; } case VIEW_TAG: { if (data instanceof Tag) { Tag tag = (Tag) data; String id = "Tag." + tag.getTagType().getTagType() + "." + tag.getTagID(); MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI(); if (mdi != null) { mdi.loadEntryByID(id, true, false, data); } } break; } default: break; } }
private void create_swarm_synchronously(final File file, String[] tags) throws Exception { /** Trying to create these causes a TOTorrentException */ if (file.isDirectory() == false) { if (file.length() == 0) { return; } } TOTorrentCreator currentCreator = null; cancelled = false; try { currentCreator = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength( file, new URL("http://tracker.invalid/announce"), true); } catch (java.net.MalformedURLException e) { throw new TOTorrentException("malformed tracker url (should _never_ happen)", 0); } final TOTorrentCreator creator_shadow = currentCreator; final BackendTaskManager tasks = BackendTaskManager.get(); final int task_id = tasks.createTask( "Hashing...", new CancellationListener() { public void cancelled(int inID) { mExclusions.add(file.getAbsolutePath()); creator_shadow.cancel(); } }); tasks.getTask(task_id).setSummary("Watch directory hash: " + file.getName()); currentCreator.addListener( new TOTorrentProgressListener() { public void reportCurrentTask(String task_description) { System.out.println("creating: " + task_description); } public void reportProgress(int percent_complete) { if ((percent_complete % 10) == 0) { logger.fine("progress: " + percent_complete); } if (tasks.getTask(task_id) != null) { tasks.getTask(task_id).setProgress(percent_complete + "%"); } if (stopping && !cancelled) { creator_shadow.cancel(); cancelled = true; } } }); TOTorrent created = null; try { created = currentCreator.create(); } catch (TOTorrentException e) { if (e.getReason() == TOTorrentException.RT_ZERO_LENGTH) { logger.warning("Skipping creation of zero-length swarm: " + file.getAbsolutePath()); return; } throw e; } logger.finer("create finished, removing task_id: " + task_id); tasks.removeTask(task_id); if (created == null || cancelled) { System.err.println("created == null, canceled?"); return; } String configSavePath = COConfigurationManager.getStringParameter("General_sDefaultTorrent_Directory"); File outTorrent = null; if (configSavePath == null) { outTorrent = new File(file.getParentFile().getAbsolutePath(), file.getName() + ".torrent"); } else { outTorrent = new File(configSavePath, file.getName() + ".torrent"); } logger.finer("saving to: " + outTorrent.getAbsolutePath()); try { LocaleTorrentUtil.setDefaultTorrentEncoding(created); } catch (LocaleUtilEncodingException e1) { e1.printStackTrace(); } logger.finer("setdefaultencoding, serializing..."); created.serialiseToBEncodedFile(outTorrent); logger.finest("done that"); /** * very small chance of this happening -- most of the time the quit will come during the hashing * (which will cancel it, which will result in null and immediate return) */ if (!stopping) { generate_preview_for_torrent(created, file); logger.finer("settings perms"); ArrayList<GroupBean> typed = new ArrayList<GroupBean>(); typed.add(GroupBean.ALL_FRIENDS); PermissionsDAO.get() .setGroupsForHash(ByteFormatter.encodeString(created.getHash()), typed, true); /** Finally add that swarm and make sure the permissions are f2f only */ GlobalManager gm = AzureusCoreImpl.getSingleton().getGlobalManager(); logger.finer( "calling add download manager, file: " + file.getAbsolutePath() + " save: " + file.getParentFile().getAbsolutePath()); try { final DownloadManager dm = gm.addDownloadManager( outTorrent.getAbsolutePath(), created.getHash(), file.getAbsolutePath(), org.gudy.azureus2.core3.download.DownloadManager.STATE_WAITING, true, true, null); if (tags != null) { DownloadManagerState dmState = dm.getDownloadState(); if (dmState != null) { dm.getDownloadState().setListAttribute(FileCollection.ONESWARM_TAGS_ATTRIBUTE, tags); logger.finer("set tags: " + tags.length + " first: " + tags[0]); } } dm.addListener( new DownloadManagerListener() { public void completionChanged(DownloadManager manager, boolean completed) {} public void downloadComplete(DownloadManager manager) {} public void filePriorityChanged(DownloadManager download, DiskManagerFileInfo file) {} public void positionChanged( DownloadManager download, int oldPosition, int newPosition) {} public void stateChanged(DownloadManager manager, int state) { if (state == org.gudy.azureus2.core3.download.DownloadManager.STATE_SEEDING) { logger.fine("binding audio data for: " + dm.getDisplayName()); MagicDirectoryManager.bind_audio_xml(dm); dm.stopIt( org.gudy.azureus2.core3.download.DownloadManager.STATE_STOPPED, false, false); dm.removeListener(this); } } }); dm.setForceStart(true); } catch (Exception e) { logger.warning(e.toString()); e.printStackTrace(); throw e; } // logger.finest("force start"); // dm.setForceStart(true); } else { logger.finer("was stopping"); } // coreInterface.getF2FInterface().setTorrentPrivacy(dm.getTorrent().getHash(), // false, true); // start doesn't matter here, f2f should start it automatically if // there's a request }
public static boolean generate_audio_info_xml( File saveLocation, TOTorrent inTorrent, File metaFile) { Map<String, Properties> audio_file_properties = new HashMap<String, Properties>(); if (inTorrent.isSimpleTorrent()) { Properties p = new Properties(); InOrderType type = InOrderType.getType(saveLocation.getName()); if (type != null) { if (type.getFileTypeFilter().equals(FileTypeFilter.Audio)) { try { AudioFile f = AudioFileIO.read(saveLocation); Tag tag = f.getTag(); if (tag != null) { AudioHeader audioHeader = f.getAudioHeader(); setPropsFromTagAndHeader(p, audioHeader, tag); } if (p.size() > 0) { audio_file_properties.put(saveLocation.getName(), p); } } catch (Exception e) { System.err.println("audio tag parse error: " + e.toString()); } } } } else { for (TOTorrentFile torrent_file : inTorrent.getFiles()) { Properties p = new Properties(); audio_file_properties.put(torrent_file.getRelativePath(), p); InOrderType type = InOrderType.getType(torrent_file.getRelativePath()); if (type != null) { if (type.getFileTypeFilter().equals(FileTypeFilter.Audio)) { try { File file = new File(saveLocation, torrent_file.getRelativePath()); AudioFile f = AudioFileIO.read(file); Tag tag = f.getTag(); if (tag != null) { AudioHeader audioHeader = f.getAudioHeader(); setPropsFromTagAndHeader(p, audioHeader, tag); if (p.size() > 0) { audio_file_properties.put(saveLocation.getName(), p); } } } catch (Exception e) { System.err.println("audio tag parse error: " + e.toString()); } } // if it's an audio type } // if this file has a recognizable type } // for over torrent files } if (audio_file_properties.size() > 0) { try { XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(metaFile))); encoder.writeObject(audio_file_properties); encoder.close(); logger.fine( "wrote audio properties xml for: " + (new String(inTorrent.getName(), "UTF-8"))); } catch (Exception e) { try { logger.warning( "error writing audio properties for: " + new String(inTorrent.getName(), "UTF-8") + " / " + e.toString()); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } e.printStackTrace(); return false; } return true; } return false; }
private static void updateMetaData_handleReply( TOTorrent torrent, String hash, String replyType, Map mapHashes) { if (hash == null && torrent != null) { try { hash = torrent.getHashWrapper().toBase32String(); } catch (Exception e) { } } GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager(); DownloadManager dm = gm.getDownloadManager(new HashWrapper(Base32.decode(hash))); if (torrent == null && dm != null) { torrent = dm.getTorrent(); } Map contentMap = PlatformTorrentUtils.getContentMap(torrent); final TOTorrent torrentFinal = torrent; if (replyType.equals(PlatformMessenger.REPLY_EXCEPTION)) { if (torrent != null) { // try again in a bit log(torrent, "Exception, retrying later"); SimpleTimer.addEvent( "Update MD Retry", SystemTime.getCurrentTime() + RETRY_METADATA, new TimerEventPerformer() { public void perform(TimerEvent event) { log(torrentFinal, "retry time"); PlatformTorrentUtils.updateMetaData(torrentFinal, 15000); } }); } } else { Map jsonMapMetaData = hash == null ? null : (Map) mapHashes.get(hash); if (jsonMapMetaData != null) { long oldLastUpdated = getContentLastUpdated(torrent); long expireyMins = 0; for (Iterator iter = jsonMapMetaData.keySet().iterator(); iter.hasNext(); ) { String key = (String) iter.next(); Object value = jsonMapMetaData.get(key); if (value == null || value.equals(null)) { contentMap.remove(key); } else if ((key.equals("Thumbnail") || key.endsWith(".B64")) && value instanceof String) { contentMap.put(key, Base64.decode((String) value)); } else if (key.equals("expires-in-mins") && value instanceof Long) { expireyMins = ((Long) value).longValue(); } else { contentMap.put(key, value); } writeTorrentIfExists(torrent); } // crappy way of updating the display name if (dm != null) { String title = PlatformTorrentUtils.getContentTitle(torrent); if (title != null && title.length() > 0 && dm.getDownloadState().getDisplayName() == null) { dm.getDownloadState().setDisplayName(title); } } triggerMetaDataUpdateListeners(torrent); if (torrent != null) { // setup next refresh long refreshOn; if (expireyMins > 0) { refreshOn = SystemTime.getCurrentTime() + (expireyMins * 60 * 1000L); } else { long newLastUpdated = getContentLastUpdated(torrent); long diff = newLastUpdated - oldLastUpdated; log( torrent, "Last Updated: new " + new Date(newLastUpdated) + ";old " + new Date(oldLastUpdated) + ";diff=" + diff); if (diff > 0 && oldLastUpdated != 0) { diff *= 2; if (diff < MIN_MD_REFRESH_MS) { diff = MIN_MD_REFRESH_MS; } else if (diff > MAX_MD_REFRESH_MS) { diff = MAX_MD_REFRESH_MS; } refreshOn = SystemTime.getOffsetTime(diff); } else { refreshOn = SystemTime.getCurrentTime() + (7 * 24 * 60 * 60 * 1000L); } } log(torrent, "got MD. Next refresh in " + (refreshOn - SystemTime.getCurrentTime())); setMetaDataRefreshOn(torrent, refreshOn); SimpleTimer.addEvent( "Update MD", refreshOn, new TimerEventPerformer() { public void perform(TimerEvent event) { PlatformTorrentUtils.updateMetaData(torrentFinal, 15000); } }); } } else if (torrent != null) { long refreshOn = SystemTime.getCurrentTime() + (30 * 24 * 60 * 60 * 1000L); setMetaDataRefreshOn(torrent, refreshOn); log(torrent, "no hash in reply. Next refresh on " + new Date(refreshOn)); } } }
protected void split() throws TRTrackerAnnouncerException { String[] networks = f_provider == null ? null : f_provider.getNetworks(); TRTrackerAnnouncerHelper to_activate = null; synchronized (this) { if (stopped || destroyed) { return; } TOTorrent torrent = getTorrent(); TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets(); // sanitise dht entries if (sets.length == 0) { sets = new TOTorrentAnnounceURLSet[] { torrent .getAnnounceURLGroup() .createAnnounceURLSet(new URL[] {torrent.getAnnounceURL()}) }; } else { boolean found_decentralised = false; boolean modified = false; for (int i = 0; i < sets.length; i++) { TOTorrentAnnounceURLSet set = sets[i]; URL[] urls = set.getAnnounceURLs().clone(); for (int j = 0; j < urls.length; j++) { URL u = urls[j]; if (u != null && TorrentUtils.isDecentralised(u)) { if (found_decentralised) { modified = true; urls[j] = null; } else { found_decentralised = true; } } } } if (modified) { List<TOTorrentAnnounceURLSet> s_list = new ArrayList<TOTorrentAnnounceURLSet>(); for (TOTorrentAnnounceURLSet set : sets) { URL[] urls = set.getAnnounceURLs(); List<URL> u_list = new ArrayList<URL>(urls.length); for (URL u : urls) { if (u != null) { u_list.add(u); } } if (u_list.size() > 0) { s_list.add( torrent .getAnnounceURLGroup() .createAnnounceURLSet(u_list.toArray(new URL[u_list.size()]))); } } sets = s_list.toArray(new TOTorrentAnnounceURLSet[s_list.size()]); } } List<TOTorrentAnnounceURLSet[]> new_sets = new ArrayList<TOTorrentAnnounceURLSet[]>(); if (is_manual || sets.length < 2) { new_sets.add(sets); } else { List<TOTorrentAnnounceURLSet> list = new ArrayList<TOTorrentAnnounceURLSet>(Arrays.asList(sets)); // often we have http:/xxxx/ and udp:/xxxx/ as separate groups - keep these together while (list.size() > 0) { TOTorrentAnnounceURLSet set1 = list.remove(0); boolean done = false; URL[] urls1 = set1.getAnnounceURLs(); if (urls1.length == 1) { URL url1 = urls1[0]; String prot1 = url1.getProtocol().toLowerCase(); String host1 = url1.getHost(); for (int i = 0; i < list.size(); i++) { TOTorrentAnnounceURLSet set2 = list.get(i); URL[] urls2 = set2.getAnnounceURLs(); if (urls2.length == 1) { URL url2 = urls2[0]; String prot2 = url2.getProtocol().toLowerCase(); String host2 = url2.getHost(); if (host1.equals(host2)) { if ((prot1.equals("udp") && prot2.startsWith("http")) || (prot2.equals("udp") && prot1.startsWith("http"))) { list.remove(i); new_sets.add(new TOTorrentAnnounceURLSet[] {set1, set2}); done = true; } } } } } if (!done) { new_sets.add(new TOTorrentAnnounceURLSet[] {set1}); } } } // work out the difference Iterator<TOTorrentAnnounceURLSet[]> ns_it = new_sets.iterator(); // need to copy list as we modify it and returned list ain't thread safe List<TRTrackerAnnouncerHelper> existing_announcers = new ArrayList<TRTrackerAnnouncerHelper>(announcers.getList()); List<TRTrackerAnnouncerHelper> new_announcers = new ArrayList<TRTrackerAnnouncerHelper>(); // first look for unchanged sets while (ns_it.hasNext()) { TOTorrentAnnounceURLSet[] ns = ns_it.next(); Iterator<TRTrackerAnnouncerHelper> a_it = existing_announcers.iterator(); while (a_it.hasNext()) { TRTrackerAnnouncerHelper a = a_it.next(); TOTorrentAnnounceURLSet[] os = a.getAnnounceSets(); if (same(ns, os)) { ns_it.remove(); a_it.remove(); new_announcers.add(a); break; } } } // reuse existing announcers // first remove dht ones from the equation TRTrackerAnnouncerHelper existing_dht_announcer = null; TOTorrentAnnounceURLSet[] new_dht_set = null; ns_it = new_sets.iterator(); while (ns_it.hasNext()) { TOTorrentAnnounceURLSet[] x = ns_it.next(); if (TorrentUtils.isDecentralised(x[0].getAnnounceURLs()[0])) { new_dht_set = x; ns_it.remove(); break; } } Iterator<TRTrackerAnnouncerHelper> an_it = existing_announcers.iterator(); while (an_it.hasNext()) { TRTrackerAnnouncerHelper a = an_it.next(); TOTorrentAnnounceURLSet[] x = a.getAnnounceSets(); if (TorrentUtils.isDecentralised(x[0].getAnnounceURLs()[0])) { existing_dht_announcer = a; an_it.remove(); break; } } if (existing_dht_announcer != null && new_dht_set != null) { new_announcers.add(existing_dht_announcer); } else if (existing_dht_announcer != null) { activated.remove(existing_dht_announcer); existing_dht_announcer.destroy(); } else if (new_dht_set != null) { TRTrackerAnnouncerHelper a = create(torrent, networks, new_dht_set); new_announcers.add(a); } // now do the non-dht ones ns_it = new_sets.iterator(); while (ns_it.hasNext() && existing_announcers.size() > 0) { TRTrackerAnnouncerHelper a = existing_announcers.remove(0); TOTorrentAnnounceURLSet[] s = ns_it.next(); ns_it.remove(); if (activated.contains(a) && torrent.getPrivate() && a instanceof TRTrackerBTAnnouncerImpl) { URL url = a.getTrackerURL(); if (url != null) { forceStop((TRTrackerBTAnnouncerImpl) a, networks, url); } } a.setAnnounceSets(s, networks); new_announcers.add(a); } // create any new ones required ns_it = new_sets.iterator(); while (ns_it.hasNext()) { TOTorrentAnnounceURLSet[] s = ns_it.next(); TRTrackerAnnouncerHelper a = create(torrent, networks, s); new_announcers.add(a); } // finally fix up the announcer list to represent the new state Iterator<TRTrackerAnnouncerHelper> a_it = announcers.iterator(); while (a_it.hasNext()) { TRTrackerAnnouncerHelper a = a_it.next(); if (!new_announcers.contains(a)) { a_it.remove(); try { if (activated.contains(a) && torrent.getPrivate() && a instanceof TRTrackerBTAnnouncerImpl) { URL url = a.getTrackerURL(); if (url != null) { forceStop((TRTrackerBTAnnouncerImpl) a, networks, url); } } } finally { if (Logger.isEnabled()) { Logger.log( new LogEvent( getTorrent(), LOGID, "Deactivating " + getString(a.getAnnounceSets()))); } activated.remove(a); a.destroy(); } } } a_it = new_announcers.iterator(); while (a_it.hasNext()) { TRTrackerAnnouncerHelper a = a_it.next(); if (!announcers.contains(a)) { announcers.add(a); } } if (!is_manual && announcers.size() > 0) { if (activated.size() == 0) { TRTrackerAnnouncerHelper a = announcers.get(0); if (Logger.isEnabled()) { Logger.log( new LogEvent(getTorrent(), LOGID, "Activating " + getString(a.getAnnounceSets()))); } activated.add(a); last_activation_time = SystemTime.getMonotonousTime(); if (provider != null) { to_activate = a; } } setupActivationCheck(ACT_CHECK_INIT_DELAY); } } if (to_activate != null) { if (complete) { to_activate.complete(true); } else { to_activate.update(false); } } }