⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 globalmanagerimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 * File    : GlobalManagerImpl.java
 * Created : 21-Oct-2003
 * By      : stuff
 * 
 * Azureus - a Java Bittorrent client
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details ( see the LICENSE file ).
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.gudy.azureus2.core3.global.impl;

/*
 * Created on 30 juin 2003
 *
 */

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.*;

import org.gudy.azureus2.core3.category.Category;
import org.gudy.azureus2.core3.category.CategoryManager;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.download.*;
import org.gudy.azureus2.core3.download.impl.DownloadManagerAdapter;
import org.gudy.azureus2.core3.global.*;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.LogEvent;
import org.gudy.azureus2.core3.logging.LogIDs;
import org.gudy.azureus2.core3.logging.Logger;
import org.gudy.azureus2.core3.peer.PEPeerManager;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentException;
import org.gudy.azureus2.core3.tracker.client.*;
import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
import org.gudy.azureus2.core3.tracker.util.TRTrackerUtilsListener;
import org.gudy.azureus2.core3.util.*;

import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.helpers.TorrentFolderWatcher;
import com.aelitis.azureus.core.util.CopyOnWriteList;

import org.gudy.azureus2.plugins.network.ConnectionManager;


/**
 * @author Olivier
 * 
 */
public class GlobalManagerImpl 
	extends DownloadManagerAdapter
	implements 	GlobalManager, AEDiagnosticsEvidenceGenerator
{
	private static final LogIDs LOGID = LogIDs.CORE;
	
		// GlobalManagerListener support
		// Must be an async listener to support the non-synchronised invocation of
		// listeners when a new listener is added and existing downloads need to be
		// reported
	
	private static final int LDT_MANAGER_ADDED			= 1;
	private static final int LDT_MANAGER_REMOVED		= 2;
	private static final int LDT_DESTROY_INITIATED		= 3;
	private static final int LDT_DESTROYED				= 4;
    private static final int LDT_SEEDING_ONLY           = 5;
	
	private ListenerManager	listeners 	= ListenerManager.createAsyncManager(
		"GM:ListenDispatcher",
		new ListenerManagerDispatcher()
		{
			public void
			dispatch(
				Object		_listener,
				int			type,
				Object		value )
			{
				GlobalManagerListener	target = (GlobalManagerListener)_listener;
		
				if ( type == LDT_MANAGER_ADDED ){
					
					target.downloadManagerAdded((DownloadManager)value);
					
				}else if ( type == LDT_MANAGER_REMOVED ){
					
					target.downloadManagerRemoved((DownloadManager)value);
					
				}else if ( type == LDT_DESTROY_INITIATED ){
					
					target.destroyInitiated();
					
				}else if ( type == LDT_DESTROYED ){
					
					target.destroyed();
                    
				}else if ( type == LDT_SEEDING_ONLY ){
                    
                    target.seedingStatusChanged( ((Boolean)value).booleanValue() );
                }
			}
		});
	
		// GlobalManagerDownloadWillBeRemovedListener support
		// Not async (doesn't need to be and can't be anyway coz it has an exception)
	
	private static final int LDT_MANAGER_WBR			= 1;
	
	private ListenerManager	removal_listeners 	= ListenerManager.createManager(
			"GM:DLWBRMListenDispatcher",
			new ListenerManagerDispatcherWithException()
			{
				public void
				dispatchWithException(
					Object		_listener,
					int			type,
					Object		value )
				
					throws GlobalManagerDownloadRemovalVetoException
				{					
					GlobalManagerDownloadWillBeRemovedListener	target = (GlobalManagerDownloadWillBeRemovedListener)_listener;
					
					target.downloadWillBeRemoved((DownloadManager)value);
				}
			});
	
	private List 		managers_cow	= new ArrayList();
	private AEMonitor	managers_mon	= new AEMonitor( "GM:Managers" );
	
	private Map		manager_map			= new HashMap();
		
	private Checker checker;
	private GlobalManagerStatsImpl		stats;
    private long last_swarm_stats_calc_time		= 0;
    private long last_swarm_stats				= 0;
	    

	private TRTrackerScraper 			trackerScraper;
	private GlobalManagerStatsWriter 	stats_writer;
	private GlobalManagerHostSupport	host_support;
  
	private Map							saved_download_manager_state	= new HashMap();
	
	private int							next_seed_piece_recheck_index;
	
	private TorrentFolderWatcher torrent_folder_watcher;
  
	private ArrayList paused_list = new ArrayList();
	private final AEMonitor paused_list_mon = new AEMonitor( "GlobalManager:PL" );
  
  
  
	/* Whether the GlobalManager is active (false) or stopped (true) */
  
	private volatile boolean 	isStopping;
	private volatile boolean	destroyed;
	private volatile boolean 	needsSaving = false;
  
	private boolean seeding_only_mode = false;
	private FrequencyLimitedDispatcher	check_seeding_only_state_dispatcher = 
		new FrequencyLimitedDispatcher(
			new AERunnable(){ public void runSupport(){ checkSeedingOnlyStateSupport(); }}, 5000 );
	
	
	private int 	nat_status				= ConnectionManager.NAT_UNKNOWN;
	private boolean	nat_status_probably_ok;
	
	private Set		old_network_interfaces;
	private long	last_network_change;
	
   private CopyOnWriteList	dm_adapters = new CopyOnWriteList();

   /** delay loading of torrents */
   DelayedEvent loadTorrentsDelay = null;
   /** Whether loading of existing torrents is done */
   boolean loadingComplete = false;
   /** Monitor to block adding torrents while loading existing torrent list */
   AESemaphore loadingSem = new AESemaphore("Loading Torrents");

	
	
   public class Checker extends AEThread {
    int loopFactor;
    private static final int waitTime = 10*1000;
    // 5 minutes save resume data interval (default)
    private int saveResumeLoopCount = 5*60*1000 / waitTime;
    private int netCheckLoopCount	= 60*1000 / waitTime;
    private int natCheckLoopCount	= 30*1000 / waitTime;
    private int seedPieceCheckCount	= 30*1000 / waitTime;
           
    private AESemaphore	run_sem = new AESemaphore( "GM:Checker:run");
    

     public Checker() {
      super("Global Status Checker");
      loopFactor = 0;
      setPriority(Thread.MIN_PRIORITY);
      //determineSaveResumeDataInterval();
    }

    private void determineSaveResumeDataInterval() {
      int saveResumeInterval = COConfigurationManager.getIntParameter("Save Resume Interval", 5);
      if (saveResumeInterval >= 1 && saveResumeInterval <= 90)
        saveResumeLoopCount = saveResumeInterval * 60000 / waitTime;
    }

    public void 
	runSupport() 
    {    	
      while ( true ){

      	try{
	        loopFactor++;
	        
	        determineSaveResumeDataInterval();
	        
	        if ((loopFactor % saveResumeLoopCount == 0) || needsSaving) {
	          	
	        	saveDownloads( true );
	        }
	        
	        if ((loopFactor % netCheckLoopCount == 0)) {
          	
	        	checkNetwork();
	        }
	        
	        if ((loopFactor % natCheckLoopCount == 0)) {
	          	
	        	computeNATStatus();
	        	
	        		// we need this periodic check to pick up on DND file state changes (someone changes
	        		// a file from DND to normal and consequentially changes to a non-seeding mode). 
	        		// Doing this via listeners is too much effort
	        	
		        checkSeedingOnlyState();
	        }
	        	
	        if ((loopFactor % seedPieceCheckCount == 0)) {

	        	seedPieceRecheck();
	        }
	        
	        for (Iterator it=managers_cow.iterator();it.hasNext();) {
          	
	        	DownloadManager manager = (DownloadManager)it.next();
            
	        	if ( loopFactor % saveResumeLoopCount == 0 ) {
	        		
	        		manager.saveResumeData();
	        	}
	        	
		            /*
		             * seeding rules have been moved to StartStopRulesDefaultPlugin
		             */
	              
	         		// Handle forced starts here
         	
	        	if (	manager.getState() == DownloadManager.STATE_READY &&
	        			manager.isForceStart()) {
            	
	        		manager.startDownload();
	           }
	        }        

      	}catch( Throwable e ){
      		
      		Debug.printStackTrace( e );
      	}
      	
        try {
        	run_sem.reserve(waitTime);
        	
        	if ( run_sem.isReleasedForever()){
        		
        		break;
        	}
        }
        catch (Exception e) {
        	Debug.printStackTrace( e );
        }
      }
    }

    public void stopIt() {
      run_sem.releaseForever();
    }
  }

  public 
  GlobalManagerImpl(
	AzureusCore		core,
	final	GlobalMangerProgressListener listener,
  	long existingTorrentLoadDelay)
  {
    //Debug.dumpThreadsLoop("Active threads");
  	
  	AEDiagnostics.addEvidenceGenerator( this );
	
    stats = new GlobalManagerStatsImpl( this );
       
    try{
    	stats_writer = new GlobalManagerStatsWriter( core );
    	
    }catch( Throwable e ){
    	
    	Logger.log(new LogEvent(LOGID, "Stats unavailable", e ));
    }

    // Wait at least a few seconds before loading existing torrents.
    // typically the UI will call loadExistingTorrents before this runs
    // This is here in case the UI is stupid or forgets
    if (existingTorrentLoadDelay > 0) {
			loadTorrentsDelay = new DelayedEvent("GM:tld", existingTorrentLoadDelay,
					new AERunnable() {
						public void runSupport() {
							loadExistingTorrentsNow(listener, false); // already async
						}
					});
		} else {
			// run sync
			loadDownloads(listener);
		}

    if (listener != null)
      listener.reportCurrentTask(MessageText.getString("splash.initializeGM"));

    // Initialize scraper after loadDownloads so that we can merge scrapes
    // into one request per tracker
    trackerScraper = TRTrackerScraperFactory.getSingleton();
    
    trackerScraper.setClientResolver(
    	new TRTrackerScraperClientResolver()
		{
    		public int
			getStatus(
				HashWrapper	torrent_hash )
    		{
       			DownloadManager	dm = getDownloadManager(torrent_hash);
    			
    			if ( dm == null ){

    				return( TRTrackerScraperClientResolver.ST_NOT_FOUND );
    			}
    			    			
    			int	dm_state = dm.getState();
    			
    			if ( 	dm_state == DownloadManager.STATE_QUEUED ){
    				
    				return( TRTrackerScraperClientResolver.ST_QUEUED );
    				
    			}else if ( 	dm_state == DownloadManager.STATE_DOWNLOADING ||
    						dm_state == DownloadManager.STATE_SEEDING ){
    				
    				return( TRTrackerScraperClientResolver.ST_RUNNING );
    			}
    			
    			return( TRTrackerScraperClientResolver.ST_OTHER );
    		}
    		
    		public boolean
			isNetworkEnabled(
				HashWrapper	hash,
				URL			url )
    		{
       			DownloadManager	dm = getDownloadManager(hash);
    			
    			if ( dm == null ){
    				
    				return( false );
    			}
    			
    			String	nw = AENetworkClassifier.categoriseAddress( url.getHost());
    			
    			String[]	networks = dm.getDownloadState().getNetworks();
    			
    			for (int i=0;i<networks.length;i++){
    				
    				if ( networks[i] ==  nw ){
    					
    					return( true );
    				}
    			}
    			
    			return( false );
    		}
    		
    		public Object[]
    		getExtensions(
    			HashWrapper	hash )
    		{
     			DownloadManager	dm = getDownloadManager(hash);
    			
     			Character	state;
     			String		ext;
     			
    			if ( dm == null ){
    				
    				ext		= "";
    	   			state	= TRTrackerScraperClientResolver.FL_NONE;
    	   		  
    			}else{
    			
    				ext = dm.getDownloadState().getTrackerClientExtensions();
    			
    				if ( ext == null ){
    					
    					ext = "";
    				}
    				
    				boolean	comp = dm.isDownloadComplete( false );
    					   				
    				int	dm_state = dm.getState();
    				
    					// treat anything not stopped or running as queued as we need to be "optimistic"
    					// for torrents at the start-of-day
    				
    				if ( 	dm_state == DownloadManager.STATE_ERROR ||
    						dm_state == DownloadManager.STATE_STOPPED ||
    						( dm_state == DownloadManager.STATE_STOPPING && dm.getSubState() != DownloadManager.STATE_QUEUED )){
    					
       					state	= comp?TRTrackerScraperClientResolver.FL_COMPLETE_STOPPED:TRTrackerScraperClientResolver.FL_INCOMPLETE_STOPPED;
       				 
    				}else if (  dm_state == DownloadManager.STATE_DOWNLOADING ||
    							dm_state == DownloadManager.STATE_SEEDING ){
    					  
      					state	= comp?TRTrackerScraperClientResolver.FL_COMPLETE_RUNNING:TRTrackerScraperClientResolver.FL_INCOMPLETE_RUNNING;
      					    						
    				}else{
    				
    					state	= comp?TRTrackerScraperClientResolver.FL_COMPLETE_QUEUED:TRTrackerScraperClientResolver.FL_INCOMPLETE_QUEUED;
    				}
    			}
    			
    			return( new Object[]{ ext, state });
    		}
    		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -