📄 trtrackerservertorrentimpl.java
字号:
peer_list_compaction_suspended = true;
for (int i=0;i<peer_list.size();i++){
TRTrackerServerPeerImpl peer = (TRTrackerServerPeerImpl)peer_list.get(i);
if ( peer == null ){
continue;
}
if ( now > peer.getTimeout()){
removePeer( peer, i, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null );
}else{
if ( peer.isNATStatusBad()){
new_bad_NAT_count++;
}
}
}
}finally{
peer_list_compaction_suspended = false;
}
bad_NAT_count = new_bad_NAT_count;
if ( removed_count > 1000 ){
removed_count = 0;
checkForPeerListCompaction( true );
// rehash
HashMap new_peer_map = new HashMap(peer_map);
HashMap new_peer_reuse_map = new HashMap(peer_reuse_map);
peer_map = new_peer_map;
peer_reuse_map = new_peer_reuse_map;
}else{
checkForPeerListCompaction( false );
}
Iterator it = lightweight_seed_map.values().iterator();
while( it.hasNext()){
lightweightSeed lws = (lightweightSeed)it.next();
if ( now > lws.getTimeout()){
it.remove();
}
}
}finally{
this_mon.exit();
}
}
protected void
checkForPeerListCompaction(
boolean force )
{
if ( peer_list_hole_count > 0 && !peer_list_compaction_suspended ){
if ( force || peer_list_hole_count > peer_map.size()/10 ){
ArrayList new_peer_list = new ArrayList( peer_list.size() - (peer_list_hole_count/2));
int holes_found = 0;
for (int i=0;i<peer_list.size();i++){
Object obj = peer_list.get(i);
if ( obj == null ){
holes_found++;
}else{
new_peer_list.add( obj );
}
}
if( holes_found != peer_list_hole_count ){
Debug.out( "TRTrackerTorrent:compactHoles: count mismatch" );
}
peer_list = new_peer_list;
peer_list_hole_count = 0;
}
}
}
protected void
updateXferStats(
int bytes_in,
int bytes_out )
{
stats.addXferStats( bytes_in, bytes_out );
}
public TRTrackerServerTorrentStats
getStats()
{
return( stats );
}
public int
getPeerCount()
{
return( peer_map.size() + lightweight_seed_map.size());
}
public int
getSeedCount()
{
if ( seed_count < 0 ){
Debug.out( "seed count negative" );
}
return( seed_count + lightweight_seed_map.size());
}
public int
getLeecherCount()
{
// this isn't synchronised so could possible end up negative
int res = peer_map.size() - seed_count;
return( res<0?0:res );
}
public TRTrackerServerPeer[]
getPeers()
{
try{
this_mon.enter();
TRTrackerServerPeer[] res = new TRTrackerServerPeer[peer_map.size()];
peer_map.values().toArray( res );
return( res );
}finally{
this_mon.exit();
}
}
public HashWrapper
getHash()
{
return( hash );
}
public void
setRedirects(
URL[] urls )
{
try{
this_mon.enter();
redirects = urls;
}finally{
this_mon.exit();
}
}
public URL[]
getRedirects()
{
return( redirects );
}
protected void
handleRedirects(
String url_parameters,
String real_ip_address,
boolean scrape )
throws TRTrackerServerException
{
if ( redirects != null ){
if ( url_parameters.indexOf("permredirect") != -1 ){
Debug.out( "redirect recursion" );
throw( new TRTrackerServerException( "redirection recursion not supported" ));
}
URL redirect = redirects[real_ip_address.hashCode()%redirects.length];
Map headers = new HashMap();
String redirect_str = redirect.toString();
if ( scrape ){
int pos = redirect_str.indexOf( "/announce" );
if ( pos == -1 ){
return;
}
redirect_str = redirect_str.substring( 0, pos ) + "/scrape" + redirect_str.substring( pos + 9 );
}
if ( redirect_str.indexOf('?' ) == -1 ){
redirect_str += "?";
}else{
redirect_str += "&";
}
redirect_str += "permredirect=1";
if ( url_parameters.length() > 0 ){
redirect_str += "&" + url_parameters;
}
System.out.println( "redirect -> " + redirect_str );
headers.put( "Location", redirect_str);
throw( new TRTrackerServerException(301, "Moved Permanently", headers ));
}
}
public void
addListener(
TRTrackerServerTorrentListener l )
{
listeners.add(l);
if ( deleted ){
l.deleted(this);
}
}
public void
removeListener(
TRTrackerServerTorrentListener l )
{
listeners.remove(l);
}
protected void
peerEvent(
TRTrackerServerPeer peer,
int event,
String url_parameters )
throws TRTrackerServerException
{
if ( peer_listeners != null ){
for (int i=0;i<peer_listeners.size();i++){
try{
((TRTrackerServerTorrentPeerListener)peer_listeners.get(i)).eventOccurred( this, peer, event, url_parameters );
}catch( TRTrackerServerException e ){
throw( e );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
}
public void
addPeerListener(
TRTrackerServerTorrentPeerListener l )
{
if ( peer_listeners == null ){
peer_listeners = new ArrayList();
}
peer_listeners.add( l );
}
public void
removePeerListener(
TRTrackerServerTorrentPeerListener l )
{
if ( peer_listeners != null ){
peer_listeners.remove(l);
}
}
public void
disableCaching()
{
caching_enabled = false;
}
public boolean
isCachingEnabled()
{
return( caching_enabled );
}
public int
getBadNATPeerCount()
{
return( bad_NAT_count );
}
protected void
delete()
{
deleted = true;
for (int i=0;i<listeners.size();i++){
((TRTrackerServerTorrentListener)listeners.get(i)).deleted(this);
}
}
static class
announceCacheEntry
{
protected Map data;
protected boolean send_peer_ids;
protected byte compact_mode;
protected long time;
protected
announceCacheEntry(
Map _data,
boolean _send_peer_ids,
byte _compact_mode )
{
data = _data;
send_peer_ids = _send_peer_ids;
compact_mode = _compact_mode;
time = SystemTime.getCurrentTime();
}
protected boolean
getSendPeerIds()
{
return( send_peer_ids );
}
protected byte
getCompactMode()
{
return( compact_mode );
}
protected long
getTime()
{
return( time );
}
protected Map
getData()
{
return( data );
}
}
protected static class
lightweightSeed
{
long timeout;
long last_contact_time;
long uploaded;
byte nat_status;
protected
lightweightSeed(
long _now,
long _timeout,
long _uploaded,
byte _nat_status )
{
last_contact_time = _now;
timeout = _timeout;
uploaded = _uploaded;
nat_status = _nat_status;
}
protected long
getTimeout()
{
return( timeout );
}
protected long
getLastContactTime()
{
return( last_contact_time );
}
protected long
getUploaded()
{
return( uploaded );
}
protected byte
getNATStatus()
{
return( nat_status );
}
}
protected static class
QueuedPeer
{
private short tcp_port;
private short udp_port;
private short http_port;
private byte[] ip;
private byte crypto_level;
private byte az_ver;
private int create_time_secs;
private int timeout_secs;
private boolean seed;
protected
QueuedPeer(
String ip_str,
int _tcp_port,
int _udp_port,
int _http_port,
byte _crypto_level,
byte _az_ver,
int _timeout_secs,
boolean _seed )
{
try{
ip = ip_str.getBytes( Constants.BYTE_ENCODING );
}catch( UnsupportedEncodingException e ){
Debug.printStackTrace(e);
}
tcp_port = (short)_tcp_port;
udp_port = (short)_udp_port;
http_port = (short)_http_port;
crypto_level = _crypto_level;
az_ver = _az_ver;
seed = _seed;
create_time_secs = (int)SystemTime.getCurrentTime()/1000;
timeout_secs = _timeout_secs * TRTrackerServerImpl.CLIENT_TIMEOUT_MULTIPLIER;
}
protected boolean
sameAs(
TRTrackerServerPeerImpl peer )
{
return( tcp_port == peer.getTCPPort() &&
Arrays.equals( ip, peer.getIPAsRead()));
}
protected boolean
sameAs(
QueuedPeer other )
{
return( tcp_port == other.tcp_port &&
Arrays.equals( ip,other.ip ));
}
protected byte[]
getIP()
{
return( ip );
}
protected boolean
isSeed()
{
return( seed );
}
protected byte[]
getIPBytes()
{
try{
return( HostNameToIPResolver.hostAddressToBytes( new String( ip, Constants.BYTE_ENCODING )));
}catch( UnsupportedEncodingException e ){
Debug.printStackTrace(e);
return( null );
}
}
protected int
getTCPPort()
{
return( tcp_port & 0xffff );
}
protected int
getUDPPort()
{
return( udp_port & 0xffff );
}
protected int
getHTTPPort()
{
return( http_port & 0xffff );
}
protected byte
getCryptoLevel()
{
return( crypto_level );
}
protected byte
getAZVer()
{
return( az_ver );
}
protected int
getCreateTime()
{
return( create_time_secs );
}
protected boolean
isTimedOut(
long now_millis )
{
int now_secs = (int)(now_millis/1000);
if ( now_secs < create_time_secs ){
create_time_secs = now_secs;
}
return( create_time_secs + timeout_secs > now_secs );
}
protected String
getString()
{
return( new String(ip) + ":" + getTCPPort() + "/" + getUDPPort() + "/" + getCryptoLevel());
}
}
public String
getString()
{
String redirect;
if ( redirects == null ){
redirect = "none";
}else{
redirect = "";
for (int i=0;i<redirects.length;i++){
redirect += (i==0?"":",") + redirects[i];
}
}
return( "seeds=" + getSeedCount() + ",leechers=" + getLeecherCount() + ", redirect=" + redirect );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -