📄 startstoprulesdefaultplugin.java
字号:
/*
* File : StartStopRulesDefaultPlugin.java
* Created : 12-Jan-2004
* By : TuxPaper
*
* 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 com.aelitis.azureus.plugins.startstoprules.defaultplugin;
import java.util.*;
import org.gudy.azureus2.core3.config.COConfigurationListener;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
import com.aelitis.azureus.plugins.startstoprules.defaultplugin.ui.swt.StartStopRulesDefaultPluginSWTUI;
import org.gudy.azureus2.plugins.*;
import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
import org.gudy.azureus2.plugins.download.*;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
import org.gudy.azureus2.plugins.ui.UIInstance;
import org.gudy.azureus2.plugins.ui.UIManager;
import org.gudy.azureus2.plugins.ui.UIManagerListener;
import org.gudy.azureus2.plugins.ui.config.ConfigSection;
import org.gudy.azureus2.plugins.ui.menus.MenuItem;
import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
import org.gudy.azureus2.plugins.ui.tables.*;
/** Handles Starting and Stopping of torrents.
*
* TODO: RANK_TIMED is quite a hack and is spread all over. It needs to be
* redone, probably with a timer on each seeding torrent which triggers
* when time is up and it needs to stop.
*
* BUG: When "AutoStart 0 Peers" is on, and minSpeedForActivelySeeding is
* enabled, the 0 peer torrents will continuously switch from seeding to
* queued, probably due to the connection attempt registering speed.
* This might be fixed by the "wait XX ms before switching active state"
* code.
*
* Other Notes:
* "CD" is often used to refer to "Seed" or "Seeding", because "C" sounds like
* "See"
*/
public class StartStopRulesDefaultPlugin implements Plugin,
COConfigurationListener, AEDiagnosticsEvidenceGenerator
{
// for debugging
private static final String sStates = " WPRDS.XEQ";
/** Do not rank completed torrents */
public static final int RANK_NONE = 0;
/** Rank completed torrents using Seeds:Peer Ratio */
public static final int RANK_SPRATIO = 1;
/** Rank completed torrents using Seed Count method */
public static final int RANK_SEEDCOUNT = 2;
/** Rank completed torrents using a timed rotation of minTimeAlive */
public static final int RANK_TIMED = 3;
/**
* Force at least one check every period of time (in ms).
* Used in ChangeFlagCheckerTask
*/
private static final int FORCE_CHECK_PERIOD = 60000;
/**
* Check for non triggerable changes ever period of time (in ms)
*/
private static final int CHECK_FOR_GROSS_CHANGE_PERIOD = 30000;
/**
* Interval in ms between checks to see if the {@link #somethingChanged}
* flag changed
*/
private static final int PROCESS_CHECK_PERIOD = 500;
/** Wait xx ms before starting completed torrents (so scrapes can come in) */
private static final int MIN_SEEDING_STARTUP_WAIT = 20000;
/** Wait at least xx ms for first scrape, before starting completed torrents */
private static final int MIN_FIRST_SCRAPE_WAIT = 90000;
// Core/Plugin classes
private AEMonitor this_mon = new AEMonitor("StartStopRules");
private PluginInterface pi;
protected PluginConfig plugin_config;
private DownloadManager download_manager;
protected LoggerChannel log;
/** Used only for RANK_TIMED. Recalculate ranks on a timer */
private RecalcSeedingRanksTask recalcSeedingRanksTask;
/** Map to relate downloadData to a Download */
private static Map downloadDataMap = AEMonitor.getSynchronisedMap(new HashMap());
private volatile boolean closingDown;
private volatile boolean somethingChanged;
private Set ranksToRecalc = new HashSet();
/** When rules class started. Used for initial waiting logic */
private long startedOn;
// Config Settings
/** Whether Debug Info is written to the log and tooltip */
protected boolean bDebugLog;
/** Ranking System to use. One of RANK_* constants */
private int iRankType = -1;
private int minSpeedForActiveSeeding;
// count x peers as a full copy, but..
private int numPeersAsFullCopy;
// don't count x peers as a full copy if seeds below
private int iFakeFullCopySeedStart;
private int _maxActive;
private boolean _maxActiveWhenSeedingEnabled;
private int _maxActiveWhenSeeding;
private int maxDownloads;
private int minDownloads;
private boolean bAutoReposition;
private long minTimeAlive;
private boolean bAutoStart0Peers;
private int iMaxUploadSpeed;
private static boolean bAlreadyInitialized = false;
// UI
private TableColumn seedingRankColumn;
// UI
private TableContextMenuItem debugMenuItem = null;
private boolean bSWTUI = false;
TorrentAttribute torrentAttributeContent = null;
public void initialize(PluginInterface _plugin_interface) {
if (bAlreadyInitialized) {
System.err.println("StartStopRulesDefaultPlugin Already initialized!!");
} else {
bAlreadyInitialized = true;
}
AEDiagnostics.addEvidenceGenerator(this);
startedOn = SystemTime.getCurrentTime();
pi = _plugin_interface;
torrentAttributeContent = pi.getTorrentManager().getPluginAttribute(
TorrentAttribute.TA_CONTENT_MAP);
download_manager = pi.getDownloadManager();
pi.getPluginProperties().setProperty("plugin.version", "1.0");
pi.getPluginProperties().setProperty("plugin.name", "Start/Stop Rules");
pi.getPluginconfig().setPluginConfigKeyPrefix("");
// Create a configModel for StartStopRules
// We always need to do this in order to set up configuration defaults
UIManager manager = pi.getUIManager();
// TODO: don't name it Q
final BasicPluginConfigModel configModel = manager.createBasicPluginConfigModel(
ConfigSection.SECTION_ROOT, "Q");
setupConfigModel(configModel);
pi.addListener(new PluginListener() {
public void initializationComplete() {
// CPU Intensive, delay until a little after all plugin initializations
// XXX Would be better if we could delay it until UI is done,
// but there may be no UI..
new DelayedEvent("StartStop:initComp", 12000, new AERunnable() {
public void runSupport() {
download_manager.addListener(new StartStopDMListener());
SimpleTimer.addPeriodicEvent("StartStop:gross",
CHECK_FOR_GROSS_CHANGE_PERIOD, new ChangeCheckerTimerTask());
SimpleTimer.addPeriodicEvent("StartStop:check",
PROCESS_CHECK_PERIOD, new ChangeFlagCheckerTask());
}
});
}
public void closedownInitiated() {
closingDown = true;
// we don't want to go off recalculating stuff when config is saved
// on closedown
COConfigurationManager.removeListener(StartStopRulesDefaultPlugin.this);
}
public void closedownComplete() { /* not implemented */
}
});
log = pi.getLogger().getChannel("StartStopRules");
log.log(LoggerChannel.LT_INFORMATION,
"Default StartStopRules Plugin Initialisation");
COConfigurationManager.addListener(this);
plugin_config = pi.getPluginconfig();
try {
pi.getUIManager().addUIListener(new UIManagerListener() {
public void UIAttached(UIInstance instance) {
TableManager tm = pi.getUIManager().getTableManager();
seedingRankColumn = tm.createColumn(
TableManager.TABLE_MYTORRENTS_COMPLETE, "SeedingRank");
seedingRankColumn.initialize(TableColumn.ALIGN_TRAIL,
TableColumn.POSITION_LAST, 80, TableColumn.INTERVAL_LIVE);
SeedingRankColumnListener columnListener = new SeedingRankColumnListener(
downloadDataMap, plugin_config);
seedingRankColumn.addCellRefreshListener(columnListener);
tm.addColumn(seedingRankColumn);
if (instance instanceof UISWTInstance) {
bSWTUI = true;
// We have our own config model :)
configModel.destroy();
new StartStopRulesDefaultPluginSWTUI(pi);
}
}
public void UIDetached(UIInstance instance) {
}
});
} catch (Throwable e) {
Debug.printStackTrace(e);
}
reloadConfigParams();
}
/**
* @param configModel
*
*/
private void setupConfigModel(BasicPluginConfigModel configModel) {
String PREFIX_RES = "ConfigView.label.seeding.";
configModel.addIntParameter2(
"StartStopManager_iRankType",
"ConfigView.label.seeding.rankType",
com.aelitis.azureus.plugins.startstoprules.defaultplugin.StartStopRulesDefaultPlugin.RANK_SPRATIO);
configModel.addIntParameter2("StartStopManager_iRankTypeSeedFallback",
"ConfigView.label.seeding.rankType.seed.fallback", 0);
configModel.addBooleanParameter2("StartStopManager_bAutoReposition",
"ConfigView.label.seeding.autoReposition", false);
configModel.addIntParameter2("StartStopManager_iMinSeedingTime",
"ConfigView.label.minSeedingTime", 60 * 3);
// ignore rules subsection
// ---------
configModel.addBooleanParameter2("StartStopManager_bIgnore0Peers",
"ConfigView.label.seeding.ignore0Peers", true);
configModel.addIntParameter2("StartStopManager_iIgnoreSeedCount",
"ConfigView.label.ignoreSeeds", 0);
// for "Stop Peers Ratio" ignore rule
configModel.addIntParameter2("StartStopManager_iIgnoreRatioPeersSeedStart",
"ConfigView.label.seeding.fakeFullCopySeedStart", 0);
// for "Stop Ratio" ignore rule
configModel.addIntParameter2("StartStopManager_iIgnoreShareRatioSeedStart",
"ConfigView.label.seeding.fakeFullCopySeedStart", 0);
// Auto Starting
// ---------
configModel.addBooleanParameter2("StartStopManager_bPreferLargerSwarms",
"ConfigView.label.seeding.preferLargerSwarms", true);
configModel.addBooleanParameter2("StartStopManager_bAutoStart0Peers",
"ConfigView.label.seeding.autoStart0Peers", false);
configModel.addIntParameter2("StartStopManager_iMinPeersToBoostNoSeeds",
"ConfigView.label.minPeersToBoostNoSeeds", 1);
// queue section
// ---------
configModel.addIntParameter2("StartStopManager_iMinSpeedForActiveDL",
"ConfigView.label.minSpeedForActiveDL", 512);
configModel.addIntParameter2("StartStopManager_iMinSpeedForActiveSeeding",
"ConfigView.label.minSpeedForActiveSeeding", 512);
configModel.addBooleanParameter2("StartStopManager_bDebugLog",
"ConfigView.label.queue.debuglog", false);
configModel.addBooleanParameter2("StartStopManager_bNewSeedsMoveTop",
"ConfigView.label.queue.newseedsmovetop", true);
configModel.addIntParameter2(
"StartStopManager_iMaxActiveTorrentsWhenSeeding",
"ConfigView.label.queue.maxactivetorrentswhenseeding", 0);
configModel.addBooleanParameter2(
"StartStopManager_bMaxActiveTorrentsWhenSeedingEnabled",
"ConfigView.label.queue.maxactivetorrentswhenseeding", false);
// first Priority subsection
// ---------
configModel.addIntParameter2("StartStopManager_iFirstPriority_Type",
"ConfigView.label.seeding.firstPriority",
DefaultRankCalculator.FIRSTPRIORITY_ANY);
configModel.addIntParameter2("StartStopManager_iFirstPriority_ShareRatio",
"ConfigView.label.seeding.firstPriority.shareRatio", 500);
configModel.addIntParameter2(
"StartStopManager_iFirstPriority_SeedingMinutes",
"ConfigView.label.seeding.firstPriority.seedingMinutes", 0);
configModel.addIntParameter2("StartStopManager_iFirstPriority_DLMinutes",
"ConfigView.label.seeding.firstPriority.DLMinutes", 0);
// for ignore FP rules
configModel.addIntParameter2(
"StartStopManager_iFirstPriority_ignoreSPRatio",
"ConfigView.label.seeding.firstPriority.ignoreSPRatio", 0);
configModel.addBooleanParameter2(
"StartStopManager_bFirstPriority_ignore0Peer",
"ConfigView.label.seeding.firstPriority.ignore0Peer", false);
// seeding subsection
configModel.addIntParameter2("StartStopManager_iAddForSeedingDLCopyCount",
"ConfigView.label.seeding.addForSeedingDLCopyCount", 1);
configModel.addIntParameter2("StartStopManager_iNumPeersAsFullCopy",
PREFIX_RES + "numPeersAsFullCopy", 0);
configModel.addIntParameter2("StartStopManager_iFakeFullCopySeedStart",
PREFIX_RES + "fakeFullCopySeedStart", 1);
configModel.destroy();
}
public static DefaultRankCalculator getRankCalculator(Download dl) {
return (DefaultRankCalculator) downloadDataMap.get(dl);
}
private void recalcAllSeedingRanks(boolean force) {
if (closingDown) {
return;
}
try {
this_mon.enter();
DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) downloadDataMap.values().toArray(
new DefaultRankCalculator[0]);
// Check Group #1: Ones that always should run since they set things
for (int i = 0; i < dlDataArray.length; i++) {
if (force)
dlDataArray[i].getDownloadObject().setSeedingRank(0);
dlDataArray[i].recalcSeedingRank();
}
} finally {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -