📄 startstoprulesdefaultplugin.java
字号:
this_mon.exit();
}
}
/** A simple timer task to recalculate all seeding ranks.
*/
private class RecalcSeedingRanksTask implements TimerEventPerformer
{
boolean bCancel = false;
public void perform(TimerEvent event) {
if (bCancel) {
event.cancel();
return;
}
// System.out.println("RecalcAllSeedingRanks");
recalcAllSeedingRanks(false);
}
/**
*
*/
public void cancel() {
bCancel = true;
}
}
/** This class check if the somethingChanged flag and call process() when
* its set. This allows pooling of changes, thus cutting down on the number
* of sucessive process() calls.
*/
private class ChangeFlagCheckerTask implements TimerEventPerformer
{
long last_process_time = 0;
public void perform(TimerEvent event) {
if (closingDown)
return;
long now = SystemTime.getCurrentTime();
if (now < last_process_time
|| now - last_process_time >= FORCE_CHECK_PERIOD) {
somethingChanged = true;
}
if (somethingChanged) {
try {
last_process_time = now;
process();
} catch (Exception e) {
Debug.printStackTrace(e);
}
}
}
}
/** Listen to Download changes and recalc SR if needed
*/
private class StartStopDownloadListener implements DownloadListener
{
public void stateChanged(Download download, int old_state, int new_state) {
DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
if (dlData != null) {
// force a SR recalc, so that it gets position properly next process()
requestProcessCycle(dlData);
if (bDebugLog)
log.log(dlData.dl.getTorrent(), LoggerChannel.LT_INFORMATION,
"somethingChanged: stateChange from " + sStates.charAt(old_state)
+ " (" + old_state + ") to " + sStates.charAt(new_state)
+ " (" + new_state + ")");
}
}
public void positionChanged(Download download, int oldPosition,
int newPosition) {
DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
if (dlData != null) {
requestProcessCycle(dlData);
if (bDebugLog)
log.log(dlData.dl.getTorrent(), LoggerChannel.LT_INFORMATION,
"somethingChanged: positionChanged from " + oldPosition + " to "
+ newPosition);
}
}
}
/** Update SeedingRank when a new scrape result comes in.
*/
private class StartStopDMTrackerListener implements DownloadTrackerListener
{
public void scrapeResult(DownloadScrapeResult result) {
Download dl = result.getDownload();
// Skip if error (which happens when listener is first added and the
// torrent isn't scraped yet)
if (result.getResponseType() == DownloadScrapeResult.RT_ERROR) {
if (bDebugLog)
log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
"Ignored somethingChanged: new scrapeResult (RT_ERROR)");
return;
}
DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(dl);
if (dlData != null) {
requestProcessCycle(dlData);
if (bDebugLog)
log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
"somethingChanged: new scrapeResult S:" + result.getSeedCount()
+ ";P:" + result.getNonSeedCount());
}
}
public void announceResult(DownloadAnnounceResult result) {
// Announces are useless to us. Even if the announce contains seed/peer
// count, they are not stored in the DownloadAnnounceResult. Instead,
// they are passed off to the DownloadScrapeResult, and a scrapeResult
// is triggered
}
}
private class StartStopDownloadActivationListener implements
DownloadActivationListener
{
public boolean activationRequested(DownloadActivationEvent event) {
//System.out.println("StartStop: activation request: count = "
// + event.getActivationCount());
Download download = event.getDownload();
DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
// ok to be null
requestProcessCycle(dlData);
if (download.isComplete()) {
// quick and dirty check: keep connection if scrape peer count is 0
// there's a (good?) chance we'll start in the next process cycle
DownloadScrapeResult sr = event.getDownload().getLastScrapeResult();
int numPeers = sr.getNonSeedCount();
if (numPeers <= 0) {
return true;
}
}
return false;
}
}
/* Create/Remove downloadData object when download gets added/removed.
* RecalcSeedingRank & process if necessary.
*/
private class StartStopDMListener implements DownloadManagerListener
{
private DownloadTrackerListener download_tracker_listener;
private DownloadListener download_listener;
private DownloadActivationListener download_activation_listener;
public StartStopDMListener() {
download_tracker_listener = new StartStopDMTrackerListener();
download_listener = new StartStopDownloadListener();
download_activation_listener = new StartStopDownloadActivationListener();
}
public void downloadAdded(Download download) {
DefaultRankCalculator dlData = null;
if (downloadDataMap.containsKey(download)) {
dlData = (DefaultRankCalculator) downloadDataMap.get(download);
} else {
dlData = new DefaultRankCalculator(StartStopRulesDefaultPlugin.this,
download);
downloadDataMap.put(download, dlData);
download.addListener(download_listener);
download.addTrackerListener(download_tracker_listener, false);
download.addActivationListener(download_activation_listener);
}
if (dlData != null) {
requestProcessCycle(dlData);
if (bDebugLog)
log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
"somethingChanged: downloadAdded, state: "
+ sStates.charAt(download.getState()));
}
}
public void downloadRemoved(Download download) {
download.removeListener(download_listener);
download.removeTrackerListener(download_tracker_listener);
download.removeActivationListener(download_activation_listener);
if (downloadDataMap.containsKey(download)) {
downloadDataMap.remove(download);
}
requestProcessCycle(null);
if (bDebugLog)
log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
"somethingChanged: downloadRemoved");
}
}
private long changeCheckCount = 0;
private long changeCheckTotalMS = 0;
private long changeCheckMaxMS = 0;
private class ChangeCheckerTimerTask implements TimerEventPerformer
{
long lLastRunTime = 0;
public void perform(TimerEvent event) {
long now = 0;
// make sure process isn't running and stop it from running while we do stuff
try {
this_mon.enter();
now = SystemTime.getCurrentTime();
//System.out.println(SystemTime.getCurrentTime() - lLastRunTime);
if (now > lLastRunTime && now - lLastRunTime < 1000) {
return;
}
lLastRunTime = now;
DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) downloadDataMap.values().toArray(
new DefaultRankCalculator[0]);
int iNumDLing = 0;
int iNumCDing = 0;
for (int i = 0; i < dlDataArray.length; i++) {
if (dlDataArray[i].changeChecker()) {
requestProcessCycle(dlDataArray[i]);
}
// Check DLs for change in activeness (speed threshold)
// (The call sets somethingChanged it was changed)
if (dlDataArray[i].getActivelyDownloading())
iNumDLing++;
// Check Seeders for change in activeness (speed threshold)
// (The call sets somethingChanged it was changed)
if (dlDataArray[i].getActivelySeeding()) {
iNumCDing++;
}
}
int iMaxSeeders = calcMaxSeeders(iNumDLing);
if (iNumCDing > iMaxSeeders) {
requestProcessCycle(null);
if (bDebugLog)
log.log(LoggerChannel.LT_INFORMATION,
"somethingChanged: More Seeding than limit");
}
} finally {
if (now > 0) {
changeCheckCount++;
long timeTaken = (SystemTime.getCurrentTime() - now);
changeCheckTotalMS += timeTaken;
if (timeTaken > changeCheckMaxMS) {
changeCheckMaxMS = timeTaken;
}
}
this_mon.exit();
}
}
}
// ConfigurationListener
public void configurationSaved() {
reloadConfigParams();
}
private void reloadConfigParams() {
try {
this_mon.enter();
int iNewRankType = plugin_config.getIntParameter("StartStopManager_iRankType");
minSpeedForActiveSeeding = plugin_config.getIntParameter("StartStopManager_iMinSpeedForActiveSeeding");
_maxActive = plugin_config.getIntParameter("max active torrents");
_maxActiveWhenSeedingEnabled = plugin_config.getBooleanParameter("StartStopManager_bMaxActiveTorrentsWhenSeedingEnabled");
_maxActiveWhenSeeding = plugin_config.getIntParameter("StartStopManager_iMaxActiveTorrentsWhenSeeding");
minDownloads = plugin_config.getIntParameter("min downloads");
maxDownloads = plugin_config.getIntParameter("max downloads");
numPeersAsFullCopy = plugin_config.getIntParameter("StartStopManager_iNumPeersAsFullCopy");
iFakeFullCopySeedStart = plugin_config.getIntParameter("StartStopManager_iFakeFullCopySeedStart");
bAutoReposition = plugin_config.getBooleanParameter("StartStopManager_bAutoReposition");
minTimeAlive = plugin_config.getIntParameter("StartStopManager_iMinSeedingTime") * 1000;
bDebugLog = plugin_config.getBooleanParameter("StartStopManager_bDebugLog");
bAutoStart0Peers = plugin_config.getBooleanParameter("StartStopManager_bAutoStart0Peers");
iMaxUploadSpeed = plugin_config.getIntParameter("Max Upload Speed KBs", 0);
boolean move_top = plugin_config.getBooleanParameter("StartStopManager_bNewSeedsMoveTop");
plugin_config.setBooleanParameter(
PluginConfig.CORE_PARAM_BOOLEAN_NEW_SEEDS_START_AT_TOP, move_top);
if (iNewRankType != iRankType) {
iRankType = iNewRankType;
// shorten recalc for timed rank type, since the calculation is fast and we want to stop on the second
if (iRankType == RANK_TIMED) {
if (recalcSeedingRanksTask == null) {
recalcSeedingRanksTask = new RecalcSeedingRanksTask();
SimpleTimer.addPeriodicEvent("StartStop:recalcSR", 1000,
recalcSeedingRanksTask);
}
} else if (recalcSeedingRanksTask != null) {
recalcSeedingRanksTask.cancel();
recalcSeedingRanksTask = null;
}
}
/*
// limit _maxActive and maxDownloads based on TheColonel's specs
// maxActive = max_upload_speed / (slots_per_torrent * min_speed_per_peer)
if (_maxActive > 0) {
int iSlotsPerTorrent = plugin_config.getIntParameter("Max Uploads");
// TODO: Track upload speed, storing the max upload speed over a minute
// and use that for "unlimited" setting, or huge settings (like 200)
if (iSlotsPerTorrent > 0) {
int iMinSpeedPerPeer = 3; // for now. TODO: config value
int _maxActiveLimit = iMaxUploadSpeed / (iSlotsPerTorrent * iMinSpeedPerPeer);
if (_maxActive > _maxActiveLimit) {
_maxActive = _maxActiveLimit;
plugin_config.setIntParameter(PluginConfig.CORE_PARAM_INT_MAX_ACTIVE, _maxActive);
}
}
if (maxDownloads > _maxActive) {
maxDownloads = _maxActive;
plugin_config.setIntParameter(PluginConfig.CORE_PARAM_INT_MAX_DOWNLOADS, maxDownloads);
}
}
*/
// force a recalc on all downloads by setting SR to 0, scheduling
// a recalc on next process, and requsting a process cycle
Collection allDownloads = downloadDataMap.values();
DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) allDownloads.toArray(new DefaultRankCalculator[0]);
for (int i = 0; i < dlDataArray.length; i++) {
dlDataArray[i].getDownloadObject().setSeedingRank(0);
}
ranksToRecalc.addAll(allDownloads);
requestProcessCycle(null);
if (bDebugLog) {
log.log(LoggerChannel.LT_INFORMATION, "somethingChanged: config reload");
try {
if (debugMenuItem == null) {
final String DEBUG_MENU_ID = "StartStopRules.menu.viewDebug";
MenuItemListener menuListener = new MenuItemListener() {
public void selected(MenuItem menu, Object target) {
if (!(target instanceof TableRow))
return;
TableRow tr = (TableRow) target;
Object ds = tr.getDataSource();
if (!(ds instanceof Download))
return;
DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(ds);
if (dlData != null) {
if (bSWTUI)
StartStopRulesDefaultPluginSWTUI.openDebugWindow(dlData);
else
pi.getUIManager().showTextMessage(
null,
null,
"FP:\n" + dlData.sExplainFP + "\n" + "SR:"
+ dlData.sExplainSR + "\n" + "TRACE:\n"
+ dlData.sTrace);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -