📄 torrentutils.java
字号:
/*
* File : TorrentUtils.java
* Created : 13-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.util;
/**
* @author parg
*
*/
import java.io.*;
import java.net.*;
import java.util.*;
import com.aelitis.azureus.core.*;
import com.aelitis.azureus.plugins.dht.DHTPlugin;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.internat.*;
import org.gudy.azureus2.core3.logging.LogRelation;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.disk.*;
import org.gudy.azureus2.core3.download.*;
import org.gudy.azureus2.plugins.PluginInterface;
public class
TorrentUtils
{
private static final String TORRENT_AZ_PROP_DHT_BACKUP_ENABLE = "dht_backup_enable";
private static final String TORRENT_AZ_PROP_DHT_BACKUP_REQUESTED = "dht_backup_requested";
private static final List created_torrents;
private static final Set created_torrents_set;
private static ThreadLocal tls =
new ThreadLocal()
{
public Object
initialValue()
{
return( new HashMap());
}
};
private static volatile Set ignore_set;
private static boolean bSaveTorrentBackup;
static {
COConfigurationManager.addAndFireParameterListener("Save Torrent Backup",
new ParameterListener() {
public void parameterChanged(String parameterName) {
bSaveTorrentBackup = COConfigurationManager.getBooleanParameter(
parameterName, false);
}
});
created_torrents = COConfigurationManager.getListParameter( "my.created.torrents", new ArrayList());
created_torrents_set = new HashSet();
Iterator it = created_torrents.iterator();
while( it.hasNext()){
created_torrents_set.add( new HashWrapper((byte[])it.next()));
}
}
public static TOTorrent
readFromFile(
File file,
boolean create_delegate )
throws TOTorrentException
{
return( readFromFile( file, create_delegate, false ));
}
/**
* If you set "create_delegate" to true then you must understand that this results
* is piece hashes being discarded and then re-read from the torrent file if needed
* Therefore, if you delete the original torrent file you're going to get errors
* if you access the pieces after this (and they've been discarded)
* @param file
* @param create_delegate
* @param force_initial_discard - use to get rid of pieces immediately
* @return
* @throws TOTorrentException
*/
public static TOTorrent
readFromFile(
File file,
boolean create_delegate,
boolean force_initial_discard )
throws TOTorrentException
{
TOTorrent torrent;
try{
torrent = TOTorrentFactory.deserialiseFromBEncodedFile(file);
// make an immediate backup if requested and one doesn't exist
if (bSaveTorrentBackup) {
File torrent_file_bak = new File(file.getParent(), file.getName() + ".bak");
if ( !torrent_file_bak.exists()){
try{
torrent.serialiseToBEncodedFile(torrent_file_bak);
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
}catch (TOTorrentException e){
Debug.outNoStack( e.getMessage() );
File torrentBackup = new File(file.getParent(), file.getName() + ".bak");
if( torrentBackup.exists()){
torrent = TOTorrentFactory.deserialiseFromBEncodedFile(torrentBackup);
// use the original torrent's file name so that when this gets saved
// it writes back to the original and backups are made as required
// - set below
}else{
throw e;
}
}
torrent.setAdditionalStringProperty("torrent filename", file.toString());
if ( create_delegate ){
torrentDelegate res = new torrentDelegate( torrent, file );
if ( force_initial_discard ){
res.discardPieces( SystemTime.getCurrentTime(), true );
}
return( res );
}else{
return( torrent );
}
}
public static TOTorrent
readFromBEncodedInputStream(
InputStream is )
throws TOTorrentException
{
TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedInputStream( is );
// as we've just imported this torrent we want to clear out any possible attributes that we
// don't want such as "torrent filename"
torrent.removeAdditionalProperties();
return( torrent );
}
public static void
writeToFile(
final TOTorrent torrent )
throws TOTorrentException
{
writeToFile( torrent, false );
}
public static void
writeToFile(
TOTorrent torrent,
boolean force_backup )
throws TOTorrentException
{
try{
torrent.getMonitor().enter();
// we've got to re-obtain the pieces here in case they've been thrown
// away to save memory *before* we rename the torrent file!
torrent.getPieces();
String str = torrent.getAdditionalStringProperty("torrent filename");
if (str == null){
throw (new TOTorrentException("TorrentUtils::writeToFile: no 'torrent filename' attribute defined", TOTorrentException.RT_FILE_NOT_FOUND));
}
File torrent_file = new File(str);
if ( ( force_backup ||COConfigurationManager.getBooleanParameter("Save Torrent Backup", false)) &&
torrent_file.exists()) {
File torrent_file_bak = new File(str + ".bak");
try{
// Will return false if it cannot be deleted (including if the file doesn't exist).
torrent_file_bak.delete();
torrent_file.renameTo(torrent_file_bak);
}catch( SecurityException e){
Debug.printStackTrace( e );
}
}
torrent.serialiseToBEncodedFile(torrent_file);
}finally{
torrent.getMonitor().exit();
}
}
public static void
writeToFile(
TOTorrent torrent,
File file )
throws TOTorrentException
{
writeToFile( torrent, file, false );
}
public static void
writeToFile(
TOTorrent torrent,
File file,
boolean force_backup )
throws TOTorrentException
{
torrent.setAdditionalStringProperty("torrent filename", file.toString());
writeToFile( torrent, force_backup );
}
public static String
getTorrentFileName(
TOTorrent torrent )
throws TOTorrentException
{
String str = torrent.getAdditionalStringProperty("torrent filename");
if ( str == null ){
throw( new TOTorrentException("TorrentUtils::getTorrentFileName: no 'torrent filename' attribute defined", TOTorrentException.RT_FILE_NOT_FOUND));
}
return( str );
}
public static void
copyToFile(
TOTorrent torrent,
File file )
throws TOTorrentException
{
try{
torrent.getMonitor().enter();
// we've got to re-obtain the pieces here in case they've been thrown
// away to save memory *before* we rename the torrent file!
torrent.getPieces();
torrent.serialiseToBEncodedFile(file);
}finally{
torrent.getMonitor().exit();
}
}
public static void
delete(
TOTorrent torrent )
throws TOTorrentException
{
try{
torrent.getMonitor().enter();
String str = torrent.getAdditionalStringProperty("torrent filename");
if ( str == null ){
throw( new TOTorrentException("TorrentUtils::delete: no 'torrent filename' attribute defined", TOTorrentException.RT_FILE_NOT_FOUND));
}
if ( !new File(str).delete()){
throw( new TOTorrentException("TorrentUtils::delete: failed to delete '" + str + "'", TOTorrentException.RT_WRITE_FAILS));
}
new File( str + ".bak" ).delete();
}finally{
torrent.getMonitor().exit();
}
}
public static void
delete(
File torrent_file )
{
if ( !FileUtil.deleteWithRecycle( torrent_file )){
Debug.out( "TorrentUtils::delete: failed to delete '" + torrent_file + "'" );
}
new File( torrent_file.toString() + ".bak" ).delete();
}
public static boolean
move(
File from_torrent,
File to_torrent )
{
if ( !FileUtil.renameFile(from_torrent, to_torrent )){
return( false );
}
if ( new File( from_torrent.toString() + ".bak").exists()){
FileUtil.renameFile(
new File( from_torrent.toString() + ".bak"),
new File( to_torrent.toString() + ".bak"));
}
return( true );
}
public static String
exceptionToText(
TOTorrentException e )
{
String errorDetail;
int reason = e.getReason();
if ( reason == TOTorrentException.RT_FILE_NOT_FOUND ){
errorDetail = MessageText.getString("DownloadManager.error.filenotfound" );
}else if ( reason == TOTorrentException.RT_ZERO_LENGTH ){
errorDetail = MessageText.getString("DownloadManager.error.fileempty");
}else if ( reason == TOTorrentException.RT_TOO_BIG ){
errorDetail = MessageText.getString("DownloadManager.error.filetoobig");
}else if ( reason == TOTorrentException.RT_DECODE_FAILS ){
errorDetail = MessageText.getString("DownloadManager.error.filewithouttorrentinfo" );
}else if ( reason == TOTorrentException.RT_UNSUPPORTED_ENCODING ){
errorDetail = MessageText.getString("DownloadManager.error.unsupportedencoding");
}else if ( reason == TOTorrentException.RT_READ_FAILS ){
errorDetail = MessageText.getString("DownloadManager.error.ioerror");
}else if ( reason == TOTorrentException.RT_HASH_FAILS ){
errorDetail = MessageText.getString("DownloadManager.error.sha1");
}else if ( reason == TOTorrentException.RT_CANCELLED ){
errorDetail = MessageText.getString("DownloadManager.error.operationcancancelled");
}else{
errorDetail = Debug.getNestedExceptionMessage(e);
}
String msg = Debug.getNestedExceptionMessage(e);
if ( errorDetail.indexOf( msg ) == -1){
errorDetail += " (" + msg + ")";
}
return( errorDetail );
}
public static List
announceGroupsToList(
TOTorrent torrent )
{
List groups = new ArrayList();
TOTorrentAnnounceURLGroup group = torrent.getAnnounceURLGroup();
TOTorrentAnnounceURLSet[] sets = group.getAnnounceURLSets();
if ( sets.length == 0 ){
List s = new ArrayList();
s.add( torrent.getAnnounceURL().toString());
groups.add(s);
}else{
for (int i=0;i<sets.length;i++){
List s = new ArrayList();
TOTorrentAnnounceURLSet set = sets[i];
URL[] urls = set.getAnnounceURLs();
for (int j=0;j<urls.length;j++){
s.add( urls[j].toString());
}
if ( s.size() > 0 ){
groups.add(s);
}
}
}
return( groups );
}
public static void
listToAnnounceGroups(
List groups,
TOTorrent torrent )
{
try{
TOTorrentAnnounceURLGroup tg = torrent.getAnnounceURLGroup();
if ( groups.size() == 1 ){
List set = (List)groups.get(0);
if ( set.size() == 1 ){
torrent.setAnnounceURL( new URL((String)set.get(0)));
tg.setAnnounceURLSets( new TOTorrentAnnounceURLSet[0]);
return;
}
}
Vector g = new Vector();
for (int i=0;i<groups.size();i++){
List set = (List)groups.get(i);
URL[] urls = new URL[set.size()];
for (int j=0;j<set.size();j++){
urls[j] = new URL((String)set.get(j));
}
if ( urls.length > 0 ){
g.add( tg.createAnnounceURLSet( urls ));
}
}
TOTorrentAnnounceURLSet[] sets = new TOTorrentAnnounceURLSet[g.size()];
g.copyInto( sets );
tg.setAnnounceURLSets( sets );
if ( sets.length == 0 ){
// hmm, no valid urls at all
torrent.setAnnounceURL( new URL( "http://no.valid.urls.defined/announce"));
}
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
}
}
public static void
announceGroupsInsertFirst(
TOTorrent torrent,
String first_url )
{
try{
announceGroupsInsertFirst( torrent, new URL( first_url ));
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
}
}
public static void
announceGroupsInsertFirst(
TOTorrent torrent,
URL first_url )
{
announceGroupsInsertFirst( torrent, new URL[]{ first_url });
}
public static void
announceGroupsInsertFirst(
TOTorrent torrent,
URL[] first_urls )
{
TOTorrentAnnounceURLGroup group = torrent.getAnnounceURLGroup();
TOTorrentAnnounceURLSet[] sets = group.getAnnounceURLSets();
TOTorrentAnnounceURLSet set1 = group.createAnnounceURLSet( first_urls );
if ( sets.length > 0 ){
TOTorrentAnnounceURLSet[] new_sets = new TOTorrentAnnounceURLSet[sets.length+1];
new_sets[0] = set1;
System.arraycopy( sets, 0, new_sets, 1, sets.length );
group.setAnnounceURLSets( new_sets );
}else{
TOTorrentAnnounceURLSet set2 = group.createAnnounceURLSet(new URL[]{torrent.getAnnounceURL()});
group.setAnnounceURLSets(
new TOTorrentAnnounceURLSet[]{ set1, set2 });
}
}
public static void
announceGroupsInsertLast(
TOTorrent torrent,
URL[] first_urls )
{
TOTorrentAnnounceURLGroup group = torrent.getAnnounceURLGroup();
TOTorrentAnnounceURLSet[] sets = group.getAnnounceURLSets();
TOTorrentAnnounceURLSet set1 = group.createAnnounceURLSet( first_urls );
if ( sets.length > 0 ){
TOTorrentAnnounceURLSet[] new_sets = new TOTorrentAnnounceURLSet[sets.length+1];
new_sets[sets.length] = set1;
System.arraycopy( sets, 0, new_sets, 0, sets.length );
group.setAnnounceURLSets( new_sets );
}else{
TOTorrentAnnounceURLSet set2 = group.createAnnounceURLSet(new URL[]{torrent.getAnnounceURL()});
group.setAnnounceURLSets(
new TOTorrentAnnounceURLSet[]{ set2, set1 });
}
}
public static void
announceGroupsSetFirst(
TOTorrent torrent,
String first_url )
{
List groups = announceGroupsToList( torrent );
boolean found = false;
outer:
for (int i=0;i<groups.size();i++){
List set = (List)groups.get(i);
for (int j=0;j<set.size();j++){
if ( first_url.equals(set.get(j))){
set.remove(j);
set.add(0, first_url);
groups.remove(set);
groups.add(0,set);
found = true;
break outer;
}
}
}
if ( !found ){
System.out.println( "TorrentUtils::announceGroupsSetFirst - failed to find '" + first_url + "'" );
}
listToAnnounceGroups( groups, torrent );
}
public static boolean
announceGroupsContainsURL(
TOTorrent torrent,
String url )
{
List groups = announceGroupsToList( torrent );
for (int i=0;i<groups.size();i++){
List set = (List)groups.get(i);
for (int j=0;j<set.size();j++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -