📄 downloadmanagerimpl.java
字号:
public int
getNbPeers()
{
PEPeerManager peerManager = controller.getPeerManager();
if (peerManager != null){
return peerManager.getNbPeers();
}
return 0;
}
public String
getTrackerStatus()
{
TRTrackerAnnouncer tc = getTrackerClient();
if (tc != null){
return tc.getStatusString();
}
// no tracker, return scrape
if (torrent != null ) {
TRTrackerScraperResponse response = getTrackerScrapeResponse();
if (response != null) {
return response.getStatusString();
}
}
return "";
}
// this is called asynchronously when a response is received
public void
setTrackerScrapeResponse(
TRTrackerScraperResponse response )
{
tracker_listeners.dispatch( LDT_TL_SCRAPERESULT, response );
}
public TRTrackerAnnouncer
getTrackerClient()
{
return( tracker_client );
}
public void
setAnnounceResult(
DownloadAnnounceResult result )
{
TRTrackerAnnouncer cl = getTrackerClient();
if ( cl == null ){
Debug.out( "setAnnounceResult called when download not running" );
return;
}
cl.setAnnounceResult( result );
}
public void
setScrapeResult(
DownloadScrapeResult result )
{
if ( torrent != null && result != null ){
TRTrackerScraper scraper = globalManager.getTrackerScraper();
TRTrackerScraperResponse current_resp = getTrackerScrapeResponse();
URL target_url;
if ( current_resp != null ){
target_url = current_resp.getURL();
}else{
target_url = torrent.getAnnounceURL();
}
scraper.setScrape( torrent, target_url, result );
}
}
public int
getNbPieces()
{
if ( torrent == null ){
return(0);
}
return( torrent.getNumberOfPieces());
}
public int
getTrackerTime()
{
TRTrackerAnnouncer tc = getTrackerClient();
if ( tc != null){
return( tc.getTimeUntilNextUpdate());
}
// no tracker, return scrape
if ( torrent != null ) {
TRTrackerScraperResponse response = getTrackerScrapeResponse();
if (response != null) {
if (response.getStatus() == TRTrackerScraperResponse.ST_SCRAPING){
return( -1 );
}
return (int)((response.getNextScrapeStartTime() - SystemTime.getCurrentTime()) / 1000);
}
}
return( TRTrackerAnnouncer.REFRESH_MINIMUM_SECS );
}
public TOTorrent
getTorrent()
{
return( torrent );
}
private File cached_save_location;
private File cached_save_location_result;
public File
getSaveLocation()
{
// this can be called quite often - cache results for perf reasons
File save_location = torrent_save_location;
if ( save_location == cached_save_location ){
return( cached_save_location_result );
}
File res = download_manager_state.getFileLink( save_location );
if ( res == null ){
res = save_location;
}else{
try{
res = res.getCanonicalFile();
}catch( Throwable e ){
res = res.getAbsoluteFile();
}
}
cached_save_location = save_location;
cached_save_location_result = res;
return( res );
}
public File
getAbsoluteSaveLocation()
{
return( torrent_save_location );
}
public void
setTorrentSaveDir(
String new_dir )
{
File old_location = torrent_save_location;
String old_dir = old_location.getParent();
if ( new_dir.equals( old_dir )){
return;
}
// assumption here is that the caller really knows what they are doing. You can't
// just change this willy nilly, it must be synchronised with reality. For example,
// the disk-manager calls it after moving files on completing
// The UI can call it as long as the torrent is stopped.
// Calling it while a download is active will in general result in unpredictable behaviour!
updateFileLinks( old_dir, new_dir, torrent.isSimpleTorrent()?old_location.getParentFile():old_location );
torrent_save_location = new File( new_dir, old_location.getName());
try{
torrent_save_location = torrent_save_location.getCanonicalFile();
}catch( Throwable e ){
torrent_save_location = torrent_save_location.getAbsoluteFile();
}
controller.fileInfoChanged();
}
public String
getPieceLength()
{
if ( torrent != null ){
return( DisplayFormatters.formatByteCountToKiBEtc(torrent.getPieceLength()));
}
return( "" );
}
public String
getTorrentFileName()
{
return torrentFileName;
}
public void
setTorrentFileName(
String string)
{
torrentFileName = string;
}
public TRTrackerScraperResponse
getTrackerScrapeResponse()
{
TRTrackerScraperResponse r = null;
TRTrackerScraper scraper = globalManager.getTrackerScraper();
TRTrackerAnnouncer tc = getTrackerClient();
if ( tc != null ){
r = scraper.scrape( tc );
}
if ( r == null && torrent != null){
// torrent not running. For multi-tracker torrents we need to behave sensibly
// here
TRTrackerScraperResponse non_null_response = null;
TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
if ( sets.length == 0 ){
r = scraper.scrape(torrent);
}else{
// we use a fixed seed so that subsequent scrapes will randomise
// in the same order, as required by the spec. Note that if the
// torrent's announce sets are edited this all works fine (if we
// cached the randomised URL set this wouldn't work)
Random scrape_random = new Random(scrape_random_seed);
for (int i=0;r==null && i<sets.length;i++){
TOTorrentAnnounceURLSet set = sets[i];
URL[] urls = set.getAnnounceURLs();
List rand_urls = new ArrayList();
for (int j=0;j<urls.length;j++ ){
URL url = urls[j];
int pos = (int)(scrape_random.nextDouble() * (rand_urls.size()+1));
rand_urls.add(pos,url);
}
for (int j=0;r==null && j<rand_urls.size();j++){
URL url = (URL)rand_urls.get(j);
r = scraper.scrape(torrent, url);
if ( r!= null ){
int status = r.getStatus();
// Exit if online
if (status == TRTrackerScraperResponse.ST_ONLINE) {
// trigger listeners of new scrape
if (torrent.setAnnounceURL(url))
setTrackerScrapeResponse(r);
break;
}
// Scrape 1 at a time to save on outgoing connections
if (status == TRTrackerScraperResponse.ST_INITIALIZING ||
status == TRTrackerScraperResponse.ST_SCRAPING) {
break;
}
// treat bad scrapes as missing so we go on to
// the next tracker
if ( (!r.isValid()) || status == TRTrackerScraperResponse.ST_ERROR ){
if ( non_null_response == null ){
non_null_response = r;
}
r = null;
}
}
}
}
if ( r == null ){
r = non_null_response;
}
}
}
return( r );
}
public void
checkTracker(
boolean force )
{
TRTrackerAnnouncer tc = getTrackerClient();
if ( tc != null)
tc.update( force );
}
public void
scrapeTracker(
boolean force )
{
if ( torrent != null ){
TRTrackerScraper scraper = globalManager.getTrackerScraper();
scraper.scrape( torrent, force );
}
}
protected void
setTrackerRefreshDelayOverrides(
int percent )
{
TRTrackerAnnouncer tc = getTrackerClient();
if ( tc != null ){
tc.setRefreshDelayOverrides( percent );
}
}
public String
getTorrentComment()
{
return torrent_comment;
}
public String
getTorrentCreatedBy()
{
return torrent_created_by;
}
public long
getTorrentCreationDate()
{
if (torrent==null){
return(0);
}
return( torrent.getCreationDate());
}
public GlobalManager
getGlobalManager()
{
return( globalManager );
}
public DiskManager
getDiskManager()
{
return( controller.getDiskManager());
}
public DiskManagerFileInfo[]
getDiskManagerFileInfo()
{
return( controller.getDiskManagerFileInfo());
}
public PEPeerManager
getPeerManager()
{
return( controller.getPeerManager());
}
public boolean
isDownloadComplete()
{
return( onlySeeding );
}
public void
addListener(
DownloadManagerListener listener )
{
try{
listeners_mon.enter();
listeners.addListener(listener);
listener.stateChanged( this, getState());
// we DON'T dispatch a downloadComplete event here as this event is used to mark the
// transition between downloading and seeding, NOT purely to inform of seeding status
}finally{
listeners_mon.exit();
}
}
public void
removeListener(
DownloadManagerListener listener )
{
try{
listeners_mon.enter();
listeners.removeListener(listener);
}finally{
listeners_mon.exit();
}
}
protected void
informStateChanged()
{
// whenever the state changes we'll get called
try{
listeners_mon.enter();
int new_state = controller.getState();
boolean new_force_start = controller.isForceStart();
if ( new_state != last_informed_state ||
new_force_start != latest_informed_force_start ){
last_informed_state = new_state;
latest_informed_force_start = new_force_start;
listeners.dispatch( LDT_STATECHANGED, new Object[]{ this, new Integer( new_state )});
}
}finally{
listeners_mon.exit();
}
}
protected void
informDownloadEnded()
{
try{
listeners_mon.enter();
listeners.dispatch( LDT_DOWNLOADCOMPLETE, new Object[]{ this });
}finally{
listeners_mon.exit();
}
}
protected void
informPositionChanged(
int new_position )
{
try{
listeners_mon.enter();
int old_position = position;
if ( new_position != old_position ){
position = new_position;
listeners.dispatch(
LDT_POSITIONCHANGED,
new Object[]{ this, new Integer( old_position ), new Integer( new_position )});
}
}finally{
listeners_mon.exit();
}
}
public void
addPeerListener(
DownloadManagerPeerListener listener )
{
addPeerListener(listener, true);
}
public void
addPeerListener(
DownloadManagerPeerListener listener,
boolean bDispatchForExisting )
{
try{
peer_listeners_mon.enter();
peer_listeners.addListener( listener );
if (!bDispatchForExisting)
return; // finally will call
for (int i=0;i<current_peers.size();i++){
peer_listeners.dispatch( listener, LDT_PE_PEER_ADDED, current_peers.get(i));
}
for (int i=0;i<current_pieces.size();i++){
peer_listeners.dispatch( listener, LDT_PE_PIECE_ADDED, current_pieces.get(i));
}
PEPeerManager temp = controller.getPeerManager();
if ( temp != null ){
peer_listeners.dispatch( listener, LDT_PE_PM_ADDED, temp );
}
}finally{
peer_listeners_mon.exit();
}
}
public void
removePeerListener(
DownloadManagerPeerListener listener )
{
peer_listeners.removeListener( listener );
}
public void
addPeer(
PEPeer peer )
{
try{
peer_listeners_mon.enter();
current_peers.add( peer );
peer_listeners.dispatch( LDT_PE_PEER_ADDED, peer );
}finally{
peer_listeners_mon.exit();
}
}
public void
removePeer(
PEPeer peer )
{
try{
peer_listeners_mon.enter();
current_peers.remove( peer );
peer_listeners.dispatch( LDT_PE_PEER_REMOVED, peer );
}finally{
peer_listeners_mon.exit();
}
}
public PEPeer[]
getCurrentPeers()
{
try{
peer_listeners_mon.enter();
return (PEPeer[])current_peers.toArray(new PEPeer[current_peers.size()]);
}finally{
peer_listeners_mon.exit();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -