📄 dhttrackerplugin.java
字号:
/*
* Created on 31-Jan-2005
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* 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, or (at your option) any later version.
* 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.
* 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.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.plugins.tracker.dht;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.peer.PEPeerSource;
import org.gudy.azureus2.core3.tracker.protocol.PRHelpers;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.AENetworkClassifier;
import org.gudy.azureus2.core3.util.AESemaphore;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.core3.util.ByteFormatter;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.core3.util.TorrentUtils;
import org.gudy.azureus2.plugins.Plugin;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.PluginListener;
import org.gudy.azureus2.plugins.download.Download;
import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
import org.gudy.azureus2.plugins.download.DownloadAnnounceResultPeer;
import org.gudy.azureus2.plugins.download.DownloadListener;
import org.gudy.azureus2.plugins.download.DownloadManagerListener;
import org.gudy.azureus2.plugins.download.DownloadPropertyEvent;
import org.gudy.azureus2.plugins.download.DownloadPropertyListener;
import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
import org.gudy.azureus2.plugins.download.DownloadTrackerListener;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
import org.gudy.azureus2.plugins.peers.Peer;
import org.gudy.azureus2.plugins.peers.PeerManager;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
import org.gudy.azureus2.plugins.ui.UIManager;
import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
import org.gudy.azureus2.plugins.ui.config.ConfigSection;
import org.gudy.azureus2.plugins.ui.config.Parameter;
import org.gudy.azureus2.plugins.ui.config.ParameterListener;
import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
import org.gudy.azureus2.plugins.utils.UTTimerEvent;
import org.gudy.azureus2.plugins.utils.UTTimerEventPerformer;
import com.aelitis.azureus.core.networkmanager.NetworkManager;
import com.aelitis.azureus.plugins.dht.*;
/**
* @author parg
*
*/
public class
DHTTrackerPlugin
implements Plugin, DownloadListener, DownloadPropertyListener, DownloadTrackerListener
{
private static final String PLUGIN_NAME = "Distributed Tracker";
private static final String PLUGIN_CONFIGSECTION_ID = "plugins.dhttracker";
private static final int ANNOUNCE_TIMEOUT = 2*60*1000;
private static final int SCRAPE_TIMEOUT = 30*1000;
private static final int ANNOUNCE_MIN_DEFAULT = 2*60*1000;
private static final int ANNOUNCE_MAX = 60*60*1000;
private static final boolean TRACK_NORMAL_DEFAULT = true;
private static final int NUM_WANT = 30; // Limit to ensure replies fit in 1 packet
private static URL DEFAULT_URL;
static{
try{
DEFAULT_URL = new URL( "dht:" );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
private PluginInterface plugin_interface;
private DHTPlugin dht;
private TorrentAttribute ta_networks;
private TorrentAttribute ta_peer_sources;
private Set running_downloads = new HashSet();
private Map registered_downloads = new HashMap();
private Map query_map = new HashMap();
private Map in_progress = new HashMap();
private BooleanParameter track_normal_when_offline;
private LoggerChannel log;
private Map scrape_injection_map = new WeakHashMap();
private AEMonitor this_mon = new AEMonitor( "DHTTrackerPlugin" );
public void
initialize(
PluginInterface _plugin_interface )
{
plugin_interface = _plugin_interface;
plugin_interface.getPluginProperties().setProperty( "plugin.version", "1.0" );
plugin_interface.getPluginProperties().setProperty( "plugin.name", PLUGIN_NAME );
log = plugin_interface.getLogger().getTimeStampedChannel(PLUGIN_NAME);
ta_networks = plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_NETWORKS );
ta_peer_sources = plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_PEER_SOURCES );
UIManager ui_manager = plugin_interface.getUIManager();
final BasicPluginViewModel model =
ui_manager.createBasicPluginViewModel( PLUGIN_NAME);
model.setConfigSectionID(PLUGIN_CONFIGSECTION_ID);
BasicPluginConfigModel config =
ui_manager.createBasicPluginConfigModel( ConfigSection.SECTION_PLUGINS,
PLUGIN_CONFIGSECTION_ID);
track_normal_when_offline = config.addBooleanParameter2( "dhttracker.tracknormalwhenoffline", "dhttracker.tracknormalwhenoffline", TRACK_NORMAL_DEFAULT );
track_normal_when_offline.addListener(
new ParameterListener()
{
public void
parameterChanged(
Parameter param )
{
configChanged();
}
});
if ( !TRACK_NORMAL_DEFAULT ){
// should be TRUE by default
System.out.println( "**** DHT Tracker default set for testing purposes ****" );
}
model.getActivity().setVisible( false );
model.getProgress().setVisible( false );
model.getLogArea().setMaximumSize( 80000 );
log.addListener(
new LoggerChannelListener()
{
public void
messageLogged(
int type,
String message )
{
model.getLogArea().appendText( message+"\n");
}
public void
messageLogged(
String str,
Throwable error )
{
model.getLogArea().appendText( error.toString()+"\n");
}
});
model.getStatus().setText( "Initialising" );
log.log( "Waiting for Distributed Database initialisation" );
plugin_interface.addListener(
new PluginListener()
{
public void
initializationComplete()
{
final PluginInterface dht_pi =
plugin_interface.getPluginManager().getPluginInterfaceByClass(
DHTPlugin.class );
if ( dht_pi != null ){
dht = (DHTPlugin)dht_pi.getPlugin();
Thread t =
new AEThread( "DHTTrackerPlugin:init" )
{
public void
runSupport()
{
try{
if ( dht.isEnabled()){
log.log( "DDB Available" );
model.getStatus().setText( "Running" );
initialise();
}else{
log.log( "DDB Disabled" );
model.getStatus().setText( "Disabled, Distributed database not available" );
notRunning();
}
}catch( Throwable e ){
log.log( "DDB Failed", e );
model.getStatus().setText( "Failed" );
notRunning();
}
}
};
t.setDaemon( true );
t.start();
}else{
log.log( "DDB Plugin missing" );
model.getStatus().setText( "Failed" );
notRunning();
}
}
public void
closedownInitiated()
{
}
public void
closedownComplete()
{
}
});
}
protected void
notRunning()
{
plugin_interface.getDownloadManager().addListener(
new DownloadManagerListener()
{
public void
downloadAdded(
final Download download )
{
Torrent torrent = download.getTorrent();
if ( torrent != null && torrent.isDecentralised()){
download.addListener(
new DownloadListener()
{
public void
stateChanged(
final Download download,
int old_state,
int new_state )
{
int state = download.getState();
if ( state == Download.ST_DOWNLOADING ||
state == Download.ST_SEEDING ){
download.setAnnounceResult(
new DownloadAnnounceResult()
{
public Download
getDownload()
{
return( download );
}
public int
getResponseType()
{
return( DownloadAnnounceResult.RT_ERROR );
}
public int
getReportedPeerCount()
{
return( 0 );
}
public int
getSeedCount()
{
return( 0 );
}
public int
getNonSeedCount()
{
return( 0 );
}
public String
getError()
{
return( "Distributed Database Offline" );
}
public URL
getURL()
{
return( download.getTorrent().getAnnounceURL());
}
public DownloadAnnounceResultPeer[]
getPeers()
{
return( new DownloadAnnounceResultPeer[0] );
}
public long
getTimeToWait()
{
return( 0 );
}
public Map
getExtensions()
{
return( null );
}
});
}
}
public void
positionChanged(
Download download,
int oldPosition,
int newPosition )
{
}
});
download.setScrapeResult(
new DownloadScrapeResult()
{
public Download
getDownload()
{
return( download );
}
public int
getResponseType()
{
return( RT_ERROR );
}
public int
getSeedCount()
{
return( -1 );
}
public int
getNonSeedCount()
{
return( -1 );
}
public long
getScrapeStartTime()
{
return( SystemTime.getCurrentTime());
}
public void
setNextScrapeStartTime(
long nextScrapeStartTime)
{
}
public long
getNextScrapeStartTime()
{
return( -1 );
}
public String
getStatus()
{
return( "Distributed Database Offline" );
}
public URL
getURL()
{
return( download.getTorrent().getAnnounceURL());
}
});
}
}
public void
downloadRemoved(
Download download )
{
}
});
}
protected void
initialise()
{
plugin_interface.getDownloadManager().addListener(
new DownloadManagerListener()
{
public void
downloadAdded(
Download download )
{
download.addPropertyListener( DHTTrackerPlugin.this );
download.addTrackerListener( DHTTrackerPlugin.this );
download.addListener( DHTTrackerPlugin.this );
checkDownloadForRegistration( download, true );
}
public void
downloadRemoved(
Download download )
{
download.removePropertyListener( DHTTrackerPlugin.this );
download.removeTrackerListener( DHTTrackerPlugin.this );
download.removeListener( DHTTrackerPlugin.this );
try{
this_mon.enter();
running_downloads.remove( download );
}finally{
this_mon.exit();
}
}
});
plugin_interface.getUtilities().createTimer("DHT Tracker").addPeriodicEvent(
15000,
new UTTimerEventPerformer()
{
public void
perform(
UTTimerEvent event)
{
processRegistrations();
}
});
}
public void
propertyChanged(
Download download,
DownloadPropertyEvent event )
{
if ( event.getType() == DownloadPropertyEvent.PT_TORRENT_ATTRIBUTE_WRITTEN ){
if ( event.getData() == ta_networks ||
event.getData() == ta_peer_sources ){
checkDownloadForRegistration( download, false );
}
}
}
public void
scrapeResult(
DownloadScrapeResult result )
{
checkDownloadForRegistration( result.getDownload(), false );
}
public void
announceResult(
DownloadAnnounceResult result )
{
checkDownloadForRegistration( result.getDownload(), false );
}
protected void
checkDownloadForRegistration(
Download download,
boolean first_time )
{
int state = download.getState();
boolean register_it = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -