📄 globalmanagerimpl.java
字号:
public boolean
redirectTrackerUrl(
HashWrapper hash,
URL old_url,
URL new_url )
{
DownloadManager dm = getDownloadManager(hash);
if ( dm == null || dm.getTorrent() == null ){
return( false );
}
return( TorrentUtils.replaceAnnounceURL( dm.getTorrent(), old_url, new_url ));
}
});
trackerScraper.addListener(
new TRTrackerScraperListener() {
public void scrapeReceived(TRTrackerScraperResponse response) {
HashWrapper hash = response.getHash();
DownloadManager manager = (DownloadManager)manager_map.get( hash );
if ( manager != null ) {
manager.setTrackerScrapeResponse( response );
}
}
});
try{
host_support = new GlobalManagerHostSupport( this );
}catch( Throwable e ){
Logger.log(new LogEvent(LOGID, "Hosting unavailable", e));
}
checker = new Checker();
checker.start();
if ( stats_writer != null ){
stats_writer.initialisationComplete();
}
torrent_folder_watcher = new TorrentFolderWatcher( this );
TRTrackerUtils.addListener(
new TRTrackerUtilsListener()
{
public void
announceDetailsChanged()
{
Logger.log(new LogEvent(LOGID,
"Announce details have changed, updating trackers"));
trackerAnnounceAll();
}
});
}
public void loadExistingTorrentsNow(final GlobalMangerProgressListener listener,
boolean async)
{
if (loadTorrentsDelay == null) {
return;
}
loadTorrentsDelay = null;
//System.out.println(SystemTime.getCurrentTime() + ": load via " + Debug.getCompressedStackTrace());
if (async) {
AEThread thread = new AEThread("load torrents", true) {
public void runSupport() {
loadDownloads(listener);
}
};
thread.setPriority(3);
thread.start();
} else {
loadDownloads(listener);
}
}
public DownloadManager
addDownloadManager(
String fileName,
String savePath)
{
// TODO: add optionalHash?
return addDownloadManager(fileName, null, savePath, DownloadManager.STATE_WAITING, true);
}
public DownloadManager
addDownloadManager(
String fileName,
byte[] optionalHash,
String savePath,
int initialState,
boolean persistent )
{
return addDownloadManager(fileName, optionalHash, savePath, initialState,
persistent, false, null);
}
/**
* @return true, if the download was added
*
* @author Rene Leonhardt
*/
public DownloadManager
addDownloadManager(
String torrent_file_name,
byte[] optionalHash,
String savePath,
int initialState,
boolean persistent,
boolean for_seeding,
DownloadManagerInitialisationAdapter _adapter )
{
boolean needsFixup = false;
DownloadManager manager;
// wait for "load existing" to complete
loadingSem.reserve(60 * 1000);
DownloadManagerInitialisationAdapter adapter = getDMAdapter(_adapter);
/* to recover the initial state for non-persistent downloads the simplest way is to do it here
*/
List file_priorities = null;
if (!persistent) {
Map save_download_state = (Map) saved_download_manager_state.get(new HashWrapper(
optionalHash));
if (save_download_state != null) {
if (save_download_state.containsKey("state")) {
int saved_state = ((Long) save_download_state.get("state")).intValue();
if (saved_state == DownloadManager.STATE_STOPPED) {
initialState = saved_state;
}
}
file_priorities = (List) save_download_state.get("file_priorities");
// non persistent downloads come in at random times
// If it has a position, it's probably invalid because the
// list has been fixed up to remove gaps. Set a flag to
// do another fixup after adding
Long lPosition = (Long) save_download_state.get("position");
if (lPosition != null) {
if (lPosition.longValue() != -1) {
needsFixup = true;
}
}
}
}
File torrentDir = null;
File fDest = null;
try {
File f = new File(torrent_file_name);
if (!f.exists()) {
throw (new IOException("Torrent file '" + torrent_file_name
+ "' doesn't exist"));
}
if (!f.isFile()) {
throw (new IOException("Torrent '" + torrent_file_name
+ "' is not a file"));
}
fDest = TorrentUtils.copyTorrentFileToSaveDir(f, persistent);
String fName = fDest.getCanonicalPath();
// now do the creation!
DownloadManager new_manager = DownloadManagerFactory.create(this,
optionalHash, fName, savePath, initialState, persistent, for_seeding,
file_priorities, adapter);
manager = addDownloadManager(new_manager, true, true);
// if a different manager is returned then an existing manager for
// this torrent exists and the new one isn't needed (yuck)
if (manager == null || manager != new_manager) {
fDest.delete();
File backupFile = new File(fName + ".bak");
if (backupFile.exists())
backupFile.delete();
}
} catch (IOException e) {
System.out.println("DownloadManager::addDownloadManager: fails - td = "
+ torrentDir + ", fd = " + fDest);
Debug.printStackTrace(e);
manager = DownloadManagerFactory.create(this, optionalHash,
torrent_file_name, savePath, initialState, persistent, for_seeding,
file_priorities, adapter);
manager = addDownloadManager(manager, true, true);
} catch (Exception e) {
// get here on duplicate files, no need to treat as error
manager = DownloadManagerFactory.create(this, optionalHash,
torrent_file_name, savePath, initialState, persistent, for_seeding,
file_priorities, adapter);
manager = addDownloadManager(manager, true, true);
}
if (needsFixup && manager != null) {
if (manager.getPosition() <= downloadManagerCount(manager.isDownloadComplete(false))) {
fixUpDownloadManagerPositions();
}
}
return manager;
}
protected DownloadManager
addDownloadManager(
DownloadManager download_manager,
boolean save,
boolean notifyListeners)
{
if (!isStopping) {
// make sure we have existing ones loaded so that existing check works
loadExistingTorrentsNow(null, false);
try{
managers_mon.enter();
int existing_index = managers_cow.indexOf( download_manager );
if (existing_index != -1) {
DownloadManager existing = (DownloadManager)managers_cow.get(existing_index);
download_manager.destroy( true );
return( existing );
}
DownloadManagerStats dm_stats = download_manager.getStats();
HashWrapper hashwrapper = null;
try {
hashwrapper = download_manager.getTorrent().getHashWrapper();
} catch (Exception e1) { }
Map save_download_state = (Map)saved_download_manager_state.get(hashwrapper);
long saved_data_bytes_downloaded = 0;
long saved_data_bytes_uploaded = 0;
long saved_discarded = 0;
long saved_hashfails = 0;
long saved_SecondsDownloading = 0;
long saved_SecondsOnlySeeding = 0;
if ( save_download_state != null ){
// once the state's been used we remove it
saved_download_manager_state.remove( hashwrapper );
int maxDL = save_download_state.get("maxdl")==null?0:((Long) save_download_state.get("maxdl")).intValue();
int maxUL = save_download_state.get("maxul")==null?0:((Long) save_download_state.get("maxul")).intValue();
Long lDownloaded = (Long) save_download_state.get("downloaded");
Long lUploaded = (Long) save_download_state.get("uploaded");
Long lCompleted = (Long) save_download_state.get("completed");
Long lDiscarded = (Long) save_download_state.get("discarded");
Long lHashFailsCount = (Long) save_download_state.get("hashfails"); // old method, number of fails
Long lHashFailsBytes = (Long) save_download_state.get("hashfailbytes"); // new method, bytes failed
Long nbUploads = (Long)save_download_state.get("uploads"); // migrated to downloadstate in 2403
if ( nbUploads != null ){
// migrate anything other than the default value of 4
int maxUploads = nbUploads.intValue();
if ( maxUploads != 4 ){
// hmm, can't currently remove maxuploads as it stops people regressing to earlier
// version. So currently we store maxuploads still and only overwrite the dm state
// value if the stored value is non-default and the state one is
if ( download_manager.getMaxUploads() == 4 ){
download_manager.setMaxUploads( maxUploads );
}
}
}
dm_stats.setDownloadRateLimitBytesPerSecond( maxDL );
dm_stats.setUploadRateLimitBytesPerSecond( maxUL );
if (lCompleted != null) {
dm_stats.setDownloadCompleted(lCompleted.intValue());
}
if (lDiscarded != null) {
saved_discarded = lDiscarded.longValue();
}
if ( lHashFailsBytes != null ){
saved_hashfails = lHashFailsBytes.longValue();
}else if ( lHashFailsCount != null) {
TOTorrent torrent = download_manager.getTorrent();
if ( torrent != null ){
saved_hashfails = lHashFailsCount.longValue() * torrent.getPieceLength();
}
}
Long lPosition = (Long) save_download_state.get("position");
// 2.2.0.1 - category moved to downloadstate - this here for
// migration purposes
String sCategory = null;
if (save_download_state.containsKey("category")){
try{
sCategory = new String((byte[]) save_download_state.get("category"), Constants.DEFAULT_ENCODING);
}catch( UnsupportedEncodingException e ){
Debug.printStackTrace(e);
}
}
if (sCategory != null) {
Category cat = CategoryManager.getCategory(sCategory);
if (cat != null) download_manager.getDownloadState().setCategory(cat);
}
download_manager.requestAssumedCompleteMode();
if (lDownloaded != null && lUploaded != null) {
boolean bCompleted = download_manager.isDownloadComplete(false);
long lUploadedValue = lUploaded.longValue();
long lDownloadedValue = lDownloaded.longValue();
if ( bCompleted && (lDownloadedValue == 0)){
//Gudy : I say if the torrent is complete, let's simply set downloaded
//to size in order to see a meaningfull share-ratio
//Gudy : Bypass this horrible hack, and I don't care of first priority seeding...
/*
if (lDownloadedValue != 0 && ((lUploadedValue * 1000) / lDownloadedValue < minQueueingShareRatio) )
lUploadedValue = ( download_manager.getSize()+999) * minQueueingShareRatio / 1000;
*/
// Parg: quite a few users have complained that they want "open-for-seeding" torrents to
// have an infinite share ratio for seeding rules (i.e. so they're not first priority)
int dl_copies = COConfigurationManager.getIntParameter("StartStopManager_iAddForSeedingDLCopyCount");
lDownloadedValue = download_manager.getSize() * dl_copies;
download_manager.getDownloadState().setFlag( DownloadManagerState.FLAG_ONLY_EVER_SEEDED, true );
}
saved_data_bytes_downloaded = lDownloadedValue;
saved_data_bytes_uploaded = lUploadedValue;
}
if (lPosition != null)
download_manager.setPosition(lPosition.intValue());
// no longer needed code
// else if (dm_stats.getDownloadCompleted(false) < 1000)
// dm.setPosition(bCompleted ? numCompleted : numDownloading);
Long lSecondsDLing = (Long)save_download_state.get("secondsDownloading");
if (lSecondsDLing != null) {
saved_SecondsDownloading = lSecondsDLing.longValue();
}
Long lSecondsOnlySeeding = (Long)save_download_state.get("secondsOnlySeeding");
if (lSecondsOnlySeeding != null) {
saved_SecondsOnlySeeding = lSecondsOnlySeeding.longValue();
}
Long already_allocated = (Long)save_download_state.get( "allocated" );
if( already_allocated != null && already_allocated.intValue() == 1 ) {
download_manager.setDataAlreadyAllocated( true );
}
Long creation_time = (Long)save_download_state.get( "creationTime" );
if ( creation_time != null ){
long ct = creation_time.longValue();
if ( ct < SystemTime.getCurrentTime()){
download_manager.setCreationTime( ct );
}
}
}else{
// no stats, bodge the uploaded for seeds
if ( dm_stats.getDownloadCompleted(false) == 1000 ){
int dl_copies = COConfigurationManager.getIntParameter("StartStopManager_iAddForSeedingDLCopyCount");
saved_data_bytes_downloaded = download_manager.getSize()*dl_copies;
}
}
dm_stats.restoreSessionTotals(
saved_data_bytes_downloaded,
saved_data_bytes_uploaded,
saved_discarded,
saved_hashfails,
saved_SecondsDownloading,
saved_SecondsOnlySeeding );
boolean isCompleted = download_manager.isDownloadComplete(false);
if (download_manager.getPosition() == -1) {
int endPosition = 0;
for (int i = 0; i < managers_cow.size(); i++) {
DownloadManager dm = (DownloadManager) managers_cow.get(i);
boolean dmIsCompleted = dm.isDownloadComplete(false);
if (dmIsCompleted == isCompleted)
endPosition++;
}
download_manager.setPosition(endPosition + 1);
}
// Even though when the DownloadManager was created, onlySeeding was
// most likely set to true for completed torrents (via the Initializer +
// readTorrent), there's a chance that the torrent file didn't have the
// resume data. If it didn't, but we marked it as complete in our
// downloads config file, we should set to onlySeeding
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -