📄 trtrackerclientclassicimpl.java
字号:
int p_pos = url_str.indexOf("?");
url_str = url_str.substring(p_pos+1);
String event_str = getURLParam( url_str, "event" );
int event = PRUDPPacketRequestAnnounce.EV_UPDATE;
if ( event_str != null ){
if ( event_str.equals( "started" )){
event = PRUDPPacketRequestAnnounce.EV_STARTED;
}else if ( event_str.equals( "stopped" )){
event = PRUDPPacketRequestAnnounce.EV_STOPPED;
}else if ( event_str.equals( "completed" )){
event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
}
}
String ip_str = getURLParam( url_str, "ip" );
int ip = 0;
if ( ip_str != null ){
ip = PRHelpers.addressToInt( ip_str);
}
announce_request.setDetails(
torrent_hash,
tracker_peer_id,
getLongURLParam( url_str, "downloaded" ),
event,
ip,
key_udp,
(int)getLongURLParam( url_str, "numwant" ),
getLongURLParam( url_str, "left" ),
(short)getLongURLParam( url_str, "port" ),
getLongURLParam( url_str, "uploaded" ));
}
reply = handler.sendAndReceive( auth, request, destination );
if ( reply.getAction() == PRUDPPacket.ACT_REPLY_ANNOUNCE ){
if ( auth != null ){
SESecurityManager.setPasswordAuthenticationOutcome( UDP_REALM, reqUrl, true );
}
if ( PRUDPPacket.VERSION == 1 ){
PRUDPPacketReplyAnnounce announce_reply = (PRUDPPacketReplyAnnounce)reply;
Map map = new HashMap();
map.put( "interval", new Long( announce_reply.getInterval()));
int[] addresses = announce_reply.getAddresses();
short[] ports = announce_reply.getPorts();
List peers = new ArrayList();
map.put( "peers", peers );
for (int i=0;i<addresses.length;i++){
Map peer = new HashMap();
peers.add( peer );
peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
peer.put( "port", new Long( ports[i]));
}
byte[] data = BEncoder.encode( map );
message.write( data );
return( null );
}else{
PRUDPPacketReplyAnnounce2 announce_reply = (PRUDPPacketReplyAnnounce2)reply;
Map map = new HashMap();
map.put( "interval", new Long( announce_reply.getInterval()));
int[] addresses = announce_reply.getAddresses();
short[] ports = announce_reply.getPorts();
map.put( "complete", new Long(announce_reply.getSeeders()));
map.put( "incomplete", new Long(announce_reply.getLeechers()));
List peers = new ArrayList();
map.put( "peers", peers );
for (int i=0;i<addresses.length;i++){
Map peer = new HashMap();
peers.add( peer );
peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
peer.put( "port", new Long( ports[i]));
}
byte[] data = BEncoder.encode( map );
message.write( data );
return( null );
}
}else{
failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
}
}else{
failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
}
}catch( PRUDPPacketHandlerException e ){
if ( e.getMessage() == null || e.getMessage().indexOf("timed out") == -1 ){
throw( e );
}
}
}
}catch( Throwable e ){
failure_reason = exceptionToString(e);
}
if ( auth != null ){
SESecurityManager.setPasswordAuthenticationOutcome( UDP_REALM, reqUrl, false );
}
return( failure_reason );
}
protected long
getLongURLParam(
String url,
String param )
{
String val = getURLParam( url, param );
if( val == null ){
return(0);
}
return( Long.parseLong( val ));
}
protected String
getURLParam(
String url,
String param )
{
int p1 = url.indexOf( param + "=" );
if ( p1 == -1 ){
return( null );
}
int p2 = url.indexOf( "&", p1 );
if ( p2 == -1 ){
return( url.substring(p1+param.length()+1));
}
return( url.substring(p1+param.length()+1,p2));
}
protected String
exceptionToString(
Throwable e )
{
String class_name = e.getClass().getName();
int pos = class_name.lastIndexOf( '.' );
if ( pos != -1 ){
class_name = class_name.substring(pos+1);
}
String str = class_name + ":" + e.getMessage();
if ( str.indexOf( "timed out") != -1 ){
str = "timeout";
}
return( str );
}
public URL
constructUrl(
String evt,
URL _url)
throws MalformedURLException
{
String url = _url.toString();
StringBuffer request = new StringBuffer(url);
// if url already has a query component then just append our parameters on the end
if ( url.indexOf('?') != -1 ){
request.append('&');
}else{
request.append('?');
}
request.append(info_hash);
request.append(tracker_peer_id_str);
request.append(port);
request.append("&uploaded=").append(announce_data_provider.getTotalSent());
request.append("&downloaded=").append(announce_data_provider.getTotalReceived());
request.append("&left=").append(announce_data_provider.getRemaining());
if (evt.length() != 0) {
request.append("&event=").append(evt);
}
if (evt.equals("stopped")){
request.append("&numwant=0");
}else {
//calculate how many peers we should ask for
int numwant = calculateNumWant() * 2; //send 2X as usually 50% of peers are firewalled
request.append("&numwant=" + numwant);
//no_peer_id has been made obsolete by 'compact'
//remove this 2.0.9.0 or beyond
//request.append("&no_peer_id=1");
// latest space saving measure, a compact return type where peers are returned
// as 6 byte entries in a single byte[] (4 bytes ip, 2 byte port)
request.append( "&compact=1" );
}
// any explicit override takes precedence over any implicit override added
// when hosting torrents
String explicit_ip = COConfigurationManager.getStringParameter("Override Ip", "");
String ip = explicit_ip.length()>0?explicit_ip:(ip_override==null?"":ip_override);
if (ip.length() != 0) {
// gotta try and use the non-dns version
String ip2;
try{
ip2 = PRHelpers.DNSToIPAddress( ip );
}catch( UnknownHostException e){
LGLogger.log( LGLogger.ERROR, "IP Override host resolution of '" + ip + "' fails, using unresolved address" );
ip2 = ip;
}
request.append("&ip=").append(ip2);
}
if ( COConfigurationManager.getBooleanParameter("Tracker Key Enable Client", true )){
request.append( "&key=" + key_id);
}
return new URL( request.toString());
}
protected int
calculateNumWant()
{
int MAX_PEERS = 100;
int maxAllowed = PeerUtils.numNewConnectionsAllowed( peer_data_id );
if ( maxAllowed < 0 || maxAllowed > MAX_PEERS ) {
maxAllowed = MAX_PEERS;
}
return maxAllowed;
}
public byte[]
getPeerId()
{
return( data_peer_id );
}
public void
setAnnounceDataProvider(
TrackerClientAnnounceDataProvider _provider)
{
announce_data_provider = _provider;
}
public TOTorrent
getTorrent()
{
return( torrent );
}
public URL
getTrackerUrl()
{
return( lastUsedUrl );
}
public void
setTrackerUrl(
URL new_url )
{
try{
new_url = new URL( new_url.toString().replaceAll(" ", ""));
List list = new ArrayList(1);
list.add( new_url );
trackerUrlLists.clear();
trackerUrlLists.add( list );
informURLChange( new_url, true );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
public void
resetTrackerUrl(
boolean shuffle )
{
constructTrackerUrlLists(shuffle);
if ( trackerUrlLists.size() == 0 ){
return;
}
URL first_url = (URL)((List)trackerUrlLists.get(0)).get(0);
informURLChange( first_url, true );
}
public void
refreshListeners()
{
informURLRefresh();
}
public void
setIPOverride(
String override )
{
ip_override = override;
}
public void
clearIPOverride()
{
ip_override = null;
}
private void
constructTrackerUrlLists(
boolean shuffle )
{
try{
trackerUrlLists = new ArrayList();
//This entry is present on multi-tracker torrents
TOTorrentAnnounceURLSet[] announce_sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
if ( announce_sets.length == 0 ){
//If not present, we use the default specification
URL url = torrent.getAnnounceURL();
//We then contruct a list of one element, containing this url, and put this list
//into the list of lists of urls.
List list = new ArrayList();
list.add(url);
trackerUrlLists.add(list);
}else{
//Ok we have a multi-tracker torrent
for(int i = 0 ; i < announce_sets.length ; i++){
//Each list contains a list of urls
URL[] urls = announce_sets[i].getAnnounceURLs();
List random_urls = new ArrayList();
for(int j = 0 ; j < urls.length; j++){
//System.out.println(urls.get(j).getClass());
URL url = urls[j];
//Shuffle
int pos = shuffle?(int)(Math.random() * (random_urls.size()+1)):j;
random_urls.add(pos,url);
}
//Add this list to the list
trackerUrlLists.add(random_urls);
}
}
}catch(Exception e){
Debug.printStackTrace( e );
}
trackerUrlListString = "[";
for (int i=0;i<trackerUrlLists.size();i++){
List group = (List)trackerUrlLists.get(i);
trackerUrlListString += (i==0?"":",") + "[";
for (int j=0;j<group.size();j++){
URL u = (URL)group.get(j);
trackerUrlListString += (j==0?"":",") + u.toString();
}
trackerUrlListString += "]";
}
trackerUrlListString += "]";
// System.out.println( trackerUrlListString );
}
protected TRTrackerResponseImpl
decodeTrackerResponse(
byte[] data )
{
String failure_reason;
if ( data == null ){
failure_reason = "no response";
}else{
try{
//parse the metadata
try{
Map metaData = BDecoder.decode(data); //$NON-NLS-1$
// handle any user warnings in the response
try{
byte[] b_warning_message = (byte[])metaData.get( "warning message" );
if ( b_warning_message != null ){
String warning_message = new String(b_warning_message);
if ( !warning_message.equals( last_warning_message )){
last_warning_message = warning_message;
String expanded_message =
MessageText.getString(
"TrackerClient.announce.warningmessage",
new String[]{
announce_data_provider.getName(),
warning_message });
LGLogger.logUnrepeatableAlert(
LGLogger.AT_WARNING,
expanded_message );
}
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
long time_to_wait;
try {
if( announce_data_provider.getRemaining() == 0 ) { //is a seed
time_to_wait = ((Long) metaData.get("interval")).longValue();
}
else { // slightly shorten the wait so we don't time out
time_to_wait = (6 * ((Long) metaData.get("interval")).intValue()) / 7;
}
// guard against crazy return values
if ( time_to_wait < 0 || time_to_wait > 0xffffffffL ){
time_to_wait = 0xffffffffL;
}
}catch( Exception e ){
byte[] failure_reason_bytes = (byte[]) metaData.get("failure reason");
if ( failure_reason_bytes == null ){
System.out.println("Problems with Tracker, will retry in 1 minute");
return( new TRTrackerResponseImpl( TRTrackerResponse.ST_OFFLINE, getErrorRetryInterval() ));
}else{
// explicit failure from the tracker
failure_reason = new String( failure_reason_bytes, Constants.DEFAULT_ENCODING);
return( new TRTrackerResponseImpl( TRTrackerResponse.ST_REPORTED_ERROR, getErrorRetryInterval(), failure_reason ));
}
}
//System.out.println("Response from Announce: " + new String(data));
Long incomplete_l = (Long)metaData.get("incomplete");
Long complete_l = (Long)metaData.get("complete");
if ( incomplete_l != null || complete_l != null ){
LGLogger.log(componentID, evtFullTrace, LGLogger.INFORMATION,
"ANNOUNCE SCRAPE1: seeds=" +complete_l+ " peers=" +incomplete_l);
}
//build the list of peers
List valid_meta_peers = new ArrayList();
Object meta_peers_peek = metaData.get( "peers" );
// list for non-compact returns
if ( meta_peers_peek instanceof List ){
List meta_peers = (List)meta_peers_peek;
//for every peer
int peers_length = meta_peers.size();
for (int i = 0; i < peers_length; i++) {
Map peer = (Map) meta_peers.get(i);
Object s_peerid = peer.get("peer id");
Object s_ip = peer.get("ip");
Object s_port = peer.get("port");
// Assert that all ip and port are available
if ( s_ip != null && s_port != null ){
//get the peer ip address
String ip = new String((byte[]) s_ip, Constants.DEFAULT_ENCODING);
//get the peer port number
int peer_port = ((Long) s_port).intValue();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -