项目介绍
Vertex 是一个专为 PT(私有种子网络)玩家设计的追剧刷流一体化综合管理工具。它集成了多种功能,帮助用户高效地管理和追踪剧集,特别适合喜欢使用 PT 的用户群体。项目基于 JavaScript、Vue.js 和 Less 开发,使用 Node.js 作为后端技术栈,并支持 Docker 容器化部署,简化了环境配置和依赖管理。
主要功能
- 追剧管理:帮助用户追踪和管理剧集进度。
- 刷流支持:优化 PT 网络中的刷流任务,提升效率。
- 自动化任务:通过 Webhook 实现任务触发和通知。
- 媒体库集成:支持与 Emby 等媒体库工具集成,方便播放和管理
部署
其实官网已经有完善的部署
apt update -y &&
apt upgrade -y &&
apt install curl -y &&
curl -fsSL https://get.docker.com -o get-docker.sh &&
sh get-docker.sh &&
timedatectl set-timezone Asia/Shanghai &&
mkdir -p /root/vertex &&
chmod 777 /root/vertex &&
docker run -d --name vertex --restart unless-stopped --network host -v /root/vertex:/vertex -e TZ=Asia/Shanghai lswl/vertex:stable
访问 Vertex
访问 vertex 存储路径 /root/vertex/data/ 鼠标双击 password 查看初始密码。
cat /root/vertex/data/password
如果和上面一样,默认 vertex 服务监听的 3000 端口
访问 ip:3000
默认用户 admin,密码是上面获取的
配置
我这里就不在赘述一些 qb 的连接配置,TG 的通知什么的。
Vertex 的基础安装参照:https://wiki.vertex.icu(感谢栗佬)
根据自身盒子io情况,硬盘大小和刷的站点,勾选删种和修改里面的参数,不要直接套用。
黑车1
(maindata, torrent) => {
const categoryList = ["keep"];
let ruleData = [
{ down: 10, up: 2 },
{ down: 5, up: 1 },
];
const { state, category, uploadSpeed, downloadSpeed } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
for (const rule of ruleData) {
if (
state == "downloading" &&
downloadSpeed >= util.calSize(rule.down, "MiB") &&
uploadSpeed <= util.calSize(rule.up, "MiB")
) {
return true;
}
}
return false;
};
黑车1:是通过写死的 key 和 value 然后 for 循环去取里面的数值,简单粗暴,但是在 2.5g 管以及 10g 管的情况下,判断就用不上了,维护成本过高
黑车2
(maindata, torrent) => {
const categoryList = ["keep"];
const { state, category, uploadSpeed, downloadSpeed } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
state == "downloading" &&
downloadSpeed >= util.calSize(10, "MiB") &&
downloadSpeed / uploadSpeed >= 1.8
) {
return true;
}
return false;
};
黑车2:主要思路是,下载速度除上传速度当大于 1.8 这区间的时候进行删种。分成写两个的原因是黑车 1 是针对刚开始发车追车时候判断的,避免一开始下载 10 上传 5 这种被误删。
无效做种
(maindata, torrent) => {
const categoryList = ["keep"];
const stateList = ["uploading", "stalledUP"];
const { state, uploadSpeed, category, completedTime } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
stateList.indexOf(state) !== -1 &&
uploadSpeed <= util.calSize(512, "KiB") &&
moment().unix() - completedTime >= 5400
) {
return true;
}
return false;
};
无效做种是针对做种超过一个半小时的时候,并且上传小于512kb的种子。如果下载或者做种的种子本身过多,可以进行修改。
分享率
(maindata, torrent) => {
const categoryList = [
"keep",
"chdbits",
"ourbits",
"hdhome",
"lemonhd",
"pter",
"audiences",
"hdchina",
"hdsky",
"hddolby",
];
const { uploaded, size, category } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (uploaded / size >= 3) {
return true;
}
return false;
};
分享率就是3倍跳车,具体要改什么站点,就按格式改categoryList里的参数即可,每个人根据站点以及vip情况自行修改。
最长下载时间
(maindata, torrent) => {
const categoryList = ["keep"];
const stateList = ["downloading", "stalledDL"];
const { state, addedTime, category, uploadSpeed } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
stateList.indexOf(state) !== -1 &&
moment().unix() - addedTime >= 57600 &&
uploadSpeed <= util.calSize(5, "MiB")
) {
return true;
}
return false;
};
针对那些16个小时内没有下完的龟速种子,大部分情况下都是发种人盒子崩了什么的。上传速度如果大于5m的,不删除。
慢车
持续 40s
(maindata, torrent) => {
const categoryList = ["keep"];
const stateList = ["downloading", "stalledDL"];
const { state, uploadSpeed, progress, category, leecher } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
(moment().hour() >= 0 && moment().hour() <= 8) ||
maindata.leechingCount <= 10 ||
leecher >= 100
) {
return false;
}
if (
stateList.indexOf(state) !== -1 &&
uploadSpeed <= util.calSize(250, "KiB") &&
progress >= 0.1
) {
return true;
}
return false;
};
1.在0点-8点这个时间段,种子数量小于10个时跳过,下载人数大于100时跳过,保证夜间不误删,能有足够的种子。
2.进度大于10%,上传速度小于250kb持续40的跳车。
长时间未开始
(maindata, torrent) => {
const categoryList = ["keep"];
const { state, category, progress, addedTime } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
moment().hour() >= 0 &&
moment().hour() <= 8 &&
state == "stalledDL" &&
progress <= 0.05 &&
moment().unix() - addedTime >= 18000
) {
return true;
}
if (
state == "stalledDL" &&
progress <= 0.05 &&
moment().unix() - addedTime >= 14400
) {
return true;
}
return false;
};
删除0-8点这个时间段,超过五小时并且进度小于5%的种子。
删除常规时间段,超过四小时并且进度小于5%的种子
下载人数少
(maindata, torrent) => {
const categoryList = ["keep"];
const stateList = ["downloading", "stalledDL"];
const { state, category, leecher, uploadSpeed, addedTime } = torrent;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (
stateList.indexOf(state) !== -1 &&
leecher <= 10 &&
uploadSpeed <= util.calSize(500, "KiB") &&
moment().unix() - addedTime >= 900
) {
return true;
}
return false;
};
删除下载人数小于10,上传速度低于500kb,添加超过20分钟的非潜力种。
空1小时跳车
持续时间10-15s
(maindata, torrent) => {
const categoryList = ["keep"];
const { state, category, progress } = torrent;
const { eta } = torrent.originProp;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (state == "downloading" && category == 'hdsky' && progress >= 0.05 && progress <= 0.2 && (eta / 60) <= 70) {
return true;
}
return false;
};
瓷器非免跳车
qb的分类必须和下方的判断一致。默认使用hdchina
(maindata, torrent) => {
const categoryList = ["keep"];
const { state, category, addedTime } = torrent;
const { num_incomplete } = torrent.originProp;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (state == 'downloading' && category == 'hdchina' && moment().unix() - addedTime >= 180 && num_incomplete <= 12) {
return true;
}
return false;
};
岛非免跳车
qb的分类必须和下方的判断一致。默认使用chdbits
(maindata, torrent) => {
const categoryList = ["keep"];
const { state, category, addedTime } = torrent;
const { num_incomplete } = torrent.originProp;
if (categoryList.indexOf(category) !== -1) {
return false;
}
if (state == 'downloading' && category == 'chdbits' && moment().unix() - addedTime >= 180 && num_incomplete <= 40) {
return true;
}
return false;
};
剩余空间删种
我这里是 10g,你需要根据你的盒子自己改
根据种子的流行程度动态删除种子
超过七天才可能删除符合规则的种子,删种按分享率删除,每在 3 的基础上多 0.1 分享率就多留一天。
(maindata, torrent) => {
const config = {
deleteHours: 7 * 24 *3600, // 超时才删种的时间
ratioThreshold: 3, // 基础分享率一阈值(上传量 / 种子大小)
enableLogging: false, // 是否启用日志记录
};
const moment = require('moment'); // 确保 moment 模块可用
const now = moment().unix();
// 辅助函数:向 /vertex/log22/log.txt 中追加日志信息
function logFailure(message) {
if (!config.enableLogging) return; // 如果未启用日志记录,直接返回
const fs = require('fs');
const path = require('path');
const logFilePath = '/vertex/log22/log.txt';
const logDir = path.dirname(logFilePath);
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
const logMessage = `${new Date().toISOString()} - ${message}\n`;
fs.appendFileSync(logFilePath, logMessage);
}
// 计算下载时间和分享率
const downloadTime = now - torrent.addedTime;
const downloadTime2 = downloadTime - config.deleteHours;
const extraDays = Math.max(0, Math.floor(downloadTime2 / 86400)); // 每天86400秒
// 动态调整分享率上限
const ratioLimit = config.ratioThreshold + extraDays * 0.1;
// 检查种子是否完成下载
if (now - torrent.completedTime < config.deleteHours ) {
return false; // 不删除种子
}
if (torrent.completedTime > 0 && torrent.ratio < ratioLimit && torrent.uploadSpeed < 10* 1024) {
return true; // 删除种子
}
return false; // 不删除种子
};