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

📄 trtrackerbtannouncerimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
				
				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 );
		}
	}
  
	protected String
	trackerURLListToString()
	{
		String 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 += "]";
		
		return( trackerUrlListString );
	}
	
  	protected TRTrackerAnnouncerResponseImpl
  	decodeTrackerResponse(
  		URL			url,
  		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 && 
								COConfigurationManager.getBooleanParameter( "Tracker Client Show Warnings" )){

	 						String	warning_message = new String(b_warning_message);
	 						
								// don't report the same message twice per torrent
							
							if ( !warning_message.equals( last_tracker_message )){
								
								last_tracker_message	= warning_message;
							
								boolean	log_it = false;
								
									// only report a given message once per tracker
								
								try{
									class_mon.enter();
								
									String last_warning_message = (String)tracker_report_map.get( url.getHost());
									
									if ( 	last_warning_message == null ||
											!warning_message.equals( last_warning_message )){
		 							
										log_it	= true;
										
										tracker_report_map.put( url.getHost(), warning_message );
									}
								}finally{
									
									class_mon.exit();
								}
								
								if ( log_it ){
		 							Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE,
											LogAlert.AT_WARNING,
											"TrackerClient.announce.warningmessage"), new String[] {
											announce_data_provider.getName(), warning_message });
		 						}
							}
	 					}
	 				}catch( Throwable e ){
	 					
	 					Debug.printStackTrace( e );
	 				}
	 				
					long	time_to_wait;
										
					try {
						time_to_wait = ((Long) metaData.get("interval")).longValue();

						Long raw_min_interval = (Long) metaData.get("min interval");

						if (Logger.isEnabled()) {
							Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION,
									"Received from announce: 'interval' = " + time_to_wait
											+ "; 'min interval' = " + raw_min_interval));
						}

						// guard against crazy return values
						if (time_to_wait < 0 || time_to_wait > 0xffffffffL) {
							time_to_wait = 0xffffffffL;
						}

						if (raw_min_interval != null) {
							min_interval = raw_min_interval.longValue();

							// ignore useless values
							// Note: Many trackers set min_interval and interval the same.
							if (min_interval < 1) {
								if (Logger.isEnabled()) {
									Logger.log(new LogEvent(
											torrent,
											LOGID,
											LogEvent.LT_INFORMATION,
											"Tracker being silly and "
													+ "returning a 'min interval' of less than 1 second ("
													+ min_interval + ")"));
								}
								min_interval = 0;
							} else if (min_interval > time_to_wait) {
								if (Logger.isEnabled()) {
									Logger.log(new LogEvent(
											torrent,
											LOGID,
											LogEvent.LT_INFORMATION,
											"Tracker being silly and "
													+ "returning a 'min interval' ("
													+ min_interval
													+ ") greater than recommended announce 'interval'"
													+ " (" + time_to_wait + ")"));
								}
								min_interval = 0;
							}
						}

						// roll back 10 seconds to make sure we announce before the tracker
						// times us out.  This is done after min_interval in order not to 
						// mess up the "ignore useless values"
						if (time_to_wait > 30)
							time_to_wait -= 10;

					} catch (Exception e) {
				   	
    				     byte[]	failure_reason_bytes = (byte[]) metaData.get("failure reason");
    						
    				     if ( failure_reason_bytes == null ){
    							
    				    	 if (Logger.isEnabled())
    								Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_WARNING,
    										"Problems with Tracker, will retry in "
    												+ getErrorRetryInterval() + "ms"));
    											   			
    				       return( new TRTrackerAnnouncerResponseImpl( url, torrent_hash, TRTrackerAnnouncerResponse.ST_OFFLINE, getErrorRetryInterval(), "Unknown cause" ));
    	
    				     }
    				     	
    			     		// explicit failure from the tracker
    			     	
    			       failure_reason = new String( failure_reason_bytes, Constants.DEFAULT_ENCODING);
                            				
    			       return( new TRTrackerAnnouncerResponseImpl( url, torrent_hash, TRTrackerAnnouncerResponse.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  ){
				   
				  	 if (Logger.isEnabled())
							Logger.log(new LogEvent(torrent, LOGID,
									"ANNOUNCE SCRAPE1: seeds=" + complete_l + " peers="
											+ incomplete_l));
				   }
           
           
			           //TrackerID extension, used by phpbt trackers.
			           //We reply with '&trackerid=1234' when we receive
			           //'10:tracker id4:1234e' on announce reply.
			           //NOTE: we receive as 'tracker id' but reply as 'trackerid'
			           byte[] trackerid = (byte[])metaData.get( "tracker id" );
			           if( trackerid != null ) {
			             tracker_id = new String( trackerid );
			           }
			           
				    byte[]	crypto_flags = (byte[])metaData.get( "crypto_flags" );
           						
						//build the list of peers
					List valid_meta_peers = new ArrayList();
						
				    Object	meta_peers_peek = metaData.get( "peers" );
				    
				    
			    	Long	az_compact_l 	= (Long)metaData.get( "azcompact" );
			    	long	az_compact		= az_compact_l==null?0:az_compact_l.longValue();

					boolean	this_is_az_tracker = az_compact == 2;
					
					if ( az_tracker != this_is_az_tracker || lastUsedUrl != lastAZTrackerCheckedURL ){
							
						lastAZTrackerCheckedURL = lastUsedUrl;
						
						az_tracker	= this_is_az_tracker;
						
						TRTrackerUtils.setAZTracker( url, az_tracker );
					}

			    	if ( az_compact == 2 ){
			    		
	
			    			// latest return to dictionary based data 
			    		
						List meta_peers = (List)meta_peers_peek;

						int peers_length = meta_peers.size();

						if ( peers_length > 1 ){
								// calculate average rtt to use for those with no rtt
		 					 
							long	total_rtt 	= 0;
							int		rtt_count	= 0;
							
							for ( int i = 0; i < peers_length; i++ ){
							 	
								Map peer = (Map) meta_peers.get(i);
								
					    		Long	l_rtt = (Long)peer.get( "r" );
	
					    		if ( l_rtt != null ){
					    			
					    			total_rtt 	+= l_rtt.longValue();
					    			rtt_count++; 
					    		}
							}
							
							final int average_rtt = (int)( rtt_count==0?0:(total_rtt/rtt_count));
							
								// sort into smallest rtt order with biased at front
							
							Collections.sort(
									meta_peers,
									new Comparator()
									{
										public int 
										compare(
											Object	o1, 
											Object	o2 )
										{
											Map	map1 = (Map)o1;
											Map map2 = (Map)o2;
											
								    		Long	l_rtt1 = (Long)map1.get( "r" );
								    		Long	l_rtt2 = (Long)map2.get( "r" );
	
								    		boolean	biased_1 = map1.containsKey( "b" );
								    		boolean	biased_2 = map2.containsKey( "b" );
								    		
								    		if ( biased_1 == biased_2 ){
								    			
								    			int	rtt1 = l_rtt1==null?average_rtt:l_rtt1.intValue();
								    			int	rtt2 = l_rtt2==null?average_rtt:l_rtt2.intValue();
								    			
								    			return( rtt1 - rtt2 );
								    			
								    		}else if ( biased_1 ){
								    			
								    			return( -1 );
								    		}else{
								    			
								    			return( +1 );
								    		}
										}
									});
							
								// interleave non-biased peers with good rtt
							
							int	biased_pos		= peers_length;
							int	non_biased_pos	= peers_length;
							
							for ( int i = 0; i < peers_length; i++ ){
							 	
								Map peer = (Map) meta_peers.get(i);
			
								if ( peer.containsKey( "b" )){
									
									if ( i == 0 ){
										
										biased_pos	= i;
									}
								}else{
									
									non_biased_pos = i;
									
									break;
								}
							}
								
							List	new_peers = new ArrayList(peers_length);
							
							int		non_biased_start = non_biased_pos;
							
							boolean	last_biased	= true;
								
							while( biased_pos < non_biased_start || non_biased_pos < peers_length ){
								
								if ( biased_pos < non_biased_start ){
									
									if ( non_biased_pos < peers_length ){
										
										Map biased 		= (Map) meta_peers.get(biased_pos);
										Map non_biased 	= (Map) meta_peers.get(non_biased_pos);

										boolean	use_biased;
										
										if ( !last_biased ){
											
											use_biased = true;
											
										}else{
											
									    	Long	l_rtt_biased 		= (Long)biased.get( "r" );
								    		Long	l_rtt_non_biased 	= (Long)non_biased.get( "r" );
		
							    			int	biased_rtt 		= l_rtt_biased==null?average_rtt:l_rtt_biased.intValue();
							    			int	non_biased_rtt 	= l_rtt_non_biased==null?average_rtt:l_rtt_non_biased.intValue();
		
							    			use_biased = non_biased_rtt >= biased_rtt;
										}
										
										if ( use_biased ){
											
											new_peers.add( biased );
											
											biased_pos++;
											
										}else{
											
											new_peers.add( non_biased );
											
											non_biased_pos++;
										}
										
										last_biased = use_biased;
									}else{
										
										new_peers.add(  meta_peers.get( biased_pos++ ));
									}
								}else{
									
									new_peers.add( meta_peers.get( non_biased_pos++ ));
								}
							}
							
							meta_peers = new_peers;
						}
						
						for ( int i = 0; i < peers_length; i++ ){
						 	
							Map peer = (Map) meta_peers.get(i);
							   	
							try{
								byte[]		ip_bytes = (byte[])peer.get("i");
	
					    		int	ip1 = 0xff & ip_bytes[0];
					    		int	ip2 = 0xff & ip_bytes[1];
					    		int	ip3 = 0xff & ip_bytes[2];
					    		int	ip4 = 0xff & ip_bytes[3];
	
					    		String	ip 			= ip1 + "." + ip2 + "." + ip3 + "." + ip4;
					    		
					    		byte[]	tcp_bytes	= (byte[])peer.get("t");
					    		
					    		int		tcp_port 	= ((tcp_bytes[0]&0xff) << 8 ) + (tcp_bytes[1]&0xff );
	                
					    		byte[]	peer_peer_id = getAnonymousPeerId( ip, tcp_port );
	
					    		int		udp_port 	= 0;
					    		
					    		byte[]	udp_bytes = (byte[])peer.get("u");
								
					    		if ( udp_bytes != null ){
					    			
					    			if ( udp_bytes.length == 0 ){
					    				
					    				udp_port = tcp_port;
					    				
					    			}else{
					    				
					    				udp_port	= ((udp_bytes[0]&0xff) << 8 ) + (udp_bytes[1]&0xff );
					    			}
					    		}
					    		
					    		int	http_port = 0;
					    		
					    		byte[]	http_bytes = (byte[])peer.get("h");

					    		if ( http_bytes != null ){
					    			
					    			http_port	= ((http_bytes[0]&0xff) << 8 ) + (http_bytes[1]&0xff );
					    		}
					    		
					    		short	protocol = DownloadAnnounceResultPeer.PROTOCOL_NORMAL;
					    		
					    		byte[]	protocol_bytes = (byte[])peer.get("c");
					    		
					    		if ( protocol_bytes != null ){
					    			
					    			protocol = (protocol_bytes[0]&0x01)==0?DownloadAnnounceResultPeer.PROTOCOL_NORMAL:DownloadAnnounceResultPeer.PROTOCOL_CRYPT;
					    		}
					    		
					    		Long	l_azver = (Long)peer.get("v" );
					    		
					    		byte	az_ver = l_azver==null?TRTrackerAnnouncer.AZ_TRACKER_VERSION_1:l_azver.byteValue();
					    								    		
					    		Long	l_up_speed = (Long)peer.get( "s" );
					    		
								TRTrackerAnnouncerResponsePeerImpl new_peer = 
									new TRTrackerAnnouncerResponsePeerImpl( 
										PEPeerSource.PS_BT_TRACKER, 
										peer_peer_id, 
										ip, 
										tcp_port,
										udp_port,
										http_port,
										protocol,
										az_ver,
										l_up_speed==null?0:l_up_speed.shortValue());
										
								if (Logger.isEnabled()){
									
						    		String	extra = "";
						    		
						    		Long	l_rtt = (Long)peer.get( "r" );
						    				
						    		if ( l_rtt != null ){
						    			
						    			extra = ",rtt=" + l_rtt;
						    		}
						    		
						 

⌨️ 快捷键说明

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