You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
723 lines
25 KiB
723 lines
25 KiB
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('DOM 已加载完成');
|
|
|
|
// 获取所有需要的元素
|
|
const elements = {
|
|
usernameInput: document.getElementById('username'),
|
|
passwordInput: document.getElementById('password'),
|
|
liveIdInput: document.getElementById('liveId'),
|
|
openIncognitoButton: document.getElementById('openIncognito'),
|
|
openLiveButton: document.getElementById('openLive'),
|
|
loginButton: document.getElementById('login'),
|
|
userinfoElement: document.getElementById('userinfo'),
|
|
checkOnlineStatusButton: document.getElementById('checkOnlineStatus'),
|
|
liveRoomIdInput: document.getElementById('liveRoomId'),
|
|
openLiveRoomButton: document.getElementById('openLiveRoom'),
|
|
checkViewersButton: document.getElementById('checkViewers'),
|
|
liveRoomCountElement: document.getElementById('liveRoomCount'),
|
|
batchOpenIncognitoBtn: document.getElementById('batchOpenIncognito'),
|
|
incognitoCountInput: document.getElementById('incognitoCount'),
|
|
getCurrentRoomIdButton: document.getElementById('getCurrentRoomId'),
|
|
currentRoomIdElement: document.getElementById('currentRoomId'),
|
|
taskListTextarea: document.getElementById('taskList'),
|
|
saveTasksButton: document.getElementById('saveTasks'),
|
|
executeTasksButton: document.getElementById('executeTasks'),
|
|
taskStatusElement: document.getElementById('taskStatus'),
|
|
checkDuplicateRoomsButton: document.getElementById('checkDuplicateRooms'),
|
|
duplicateRoomsStatusElement: document.getElementById('duplicateRoomsStatus'),
|
|
proxyListTextarea: document.getElementById('proxyList'),
|
|
saveProxiesButton: document.getElementById('saveProxies'),
|
|
updateProxiesButton: document.getElementById('updateProxies'),
|
|
proxyStatusElement: document.getElementById('proxyStatus'),
|
|
clearProxyButton: document.getElementById('clearProxy'),
|
|
checkIncognito: document.getElementById('checkIncognito'),
|
|
checkCurrentProxy: document.getElementById('checkCurrentProxy'),
|
|
currentProxyStatus: document.getElementById('currentProxyStatus')
|
|
};
|
|
|
|
// 检查登录状态
|
|
chrome.storage.local.get(['loginStatus', 'loginInfo'], function(data) {
|
|
if (data.loginStatus && elements.userinfoElement) {
|
|
elements.userinfoElement.textContent = '已登录:' + data.loginInfo.uname;
|
|
}
|
|
});
|
|
|
|
// 批量打开无痕窗口
|
|
if (elements.batchOpenIncognitoBtn && elements.incognitoCountInput) {
|
|
elements.batchOpenIncognitoBtn.addEventListener('click', async () => {
|
|
const count = parseInt(elements.incognitoCountInput.value) || 1;
|
|
const actualCount = Math.min(Math.max(count, 1), 10);
|
|
|
|
for (let i = 0; i < actualCount; i++) {
|
|
await chrome.runtime.sendMessage({
|
|
action: 'openIncognitoDouyin',
|
|
username: elements.usernameInput ? elements.usernameInput.value : '',
|
|
password: elements.passwordInput ? elements.passwordInput.value : ''
|
|
});
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
}
|
|
});
|
|
}
|
|
|
|
// 打开单个无痕窗口
|
|
if (elements.openIncognitoButton) {
|
|
elements.openIncognitoButton.addEventListener('click', function() {
|
|
console.log('打开无痕窗口按钮被点击');
|
|
chrome.runtime.sendMessage({
|
|
action: 'openIncognitoDouyin',
|
|
username: elements.usernameInput ? elements.usernameInput.value : '',
|
|
password: elements.passwordInput ? elements.passwordInput.value : ''
|
|
});
|
|
});
|
|
}
|
|
|
|
// 打开直播间
|
|
if (elements.openLiveButton && elements.liveIdInput) {
|
|
elements.openLiveButton.addEventListener('click', () => {
|
|
console.log('打开直播间按钮被点击');
|
|
const liveId = elements.liveIdInput.value.trim();
|
|
if (liveId) {
|
|
const liveUrl = `https://live.douyin.com/${liveId}`;
|
|
chrome.runtime.sendMessage({ action: 'openLiveIncognito', url: liveUrl });
|
|
} else {
|
|
alert('请输入直播ID');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 打开指定直播间
|
|
if (elements.openLiveRoomButton && elements.liveRoomIdInput) {
|
|
elements.openLiveRoomButton.addEventListener('click', function() {
|
|
console.log('打开指定直播间按钮被点击');
|
|
const liveRoomId = elements.liveRoomIdInput.value.trim();
|
|
if (liveRoomId) {
|
|
const liveRoomUrl = `https://live.douyin.com/${liveRoomId}`;
|
|
chrome.tabs.create({ url: liveRoomUrl });
|
|
} else {
|
|
alert('请输入直播间ID');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 查看观众数量
|
|
if (elements.checkViewersButton) {
|
|
elements.checkViewersButton.addEventListener('click', async function() {
|
|
console.log('查看观众数量按钮被点击');
|
|
try {
|
|
const count = await getLiveRoomCount();
|
|
if (elements.liveRoomCountElement) {
|
|
elements.liveRoomCountElement.textContent = count ? `观众数量: ${count}` : '无法获取观众数量';
|
|
}
|
|
} catch (error) {
|
|
console.error('获取观众数量失败:', error);
|
|
alert('获取观众数量失败');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 登录功能
|
|
if (elements.loginButton && elements.usernameInput && elements.passwordInput) {
|
|
elements.loginButton.addEventListener('click', function() {
|
|
const username = elements.usernameInput.value.trim();
|
|
const password = elements.passwordInput.value.trim();
|
|
|
|
if (!username || !password) {
|
|
alert('请输入账号和密码!');
|
|
return;
|
|
}
|
|
chrome.runtime.sendMessage({ action: 'login', username, password });
|
|
});
|
|
}
|
|
|
|
// 检查在线状态
|
|
if (elements.checkOnlineStatusButton) {
|
|
elements.checkOnlineStatusButton.addEventListener('click', function() {
|
|
injectContentScriptAndSendMessage('checkOnlineStatus');
|
|
});
|
|
}
|
|
|
|
// 获取当前直播间ID
|
|
if (elements.getCurrentRoomIdButton) {
|
|
elements.getCurrentRoomIdButton.addEventListener('click', async function() {
|
|
console.log('获取当前直播间ID按钮被点击');
|
|
try {
|
|
const tabs = await chrome.tabs.query({active: true, currentWindow: true});
|
|
if (!tabs[0]) {
|
|
throw new Error('未找到活动标签页');
|
|
}
|
|
|
|
const response = await chrome.tabs.sendMessage(tabs[0].id, {
|
|
action: 'getCurrentRoomId'
|
|
});
|
|
|
|
if (response && response.roomId) {
|
|
elements.currentRoomIdElement.textContent = `当前直播间ID: ${response.roomId}`;
|
|
// 可选:自动填充到输入框
|
|
if (elements.liveRoomIdInput) {
|
|
elements.liveRoomIdInput.value = response.roomId;
|
|
}
|
|
} else {
|
|
elements.currentRoomIdElement.textContent = '未能获取直播间ID';
|
|
}
|
|
} catch (error) {
|
|
console.error('获取直播间ID失败:', error);
|
|
alert('获取直播间ID失败,请确保您在抖音直播页');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 加载保存的任务
|
|
chrome.storage.local.get(['tasks'], function(data) {
|
|
if (data.tasks && elements.taskListTextarea) {
|
|
elements.taskListTextarea.value = data.tasks.join('\n');
|
|
}
|
|
});
|
|
|
|
// 保存任务按钮
|
|
if (elements.saveTasksButton && elements.taskListTextarea) {
|
|
elements.saveTasksButton.addEventListener('click', function() {
|
|
const tasks = elements.taskListTextarea.value
|
|
.split('\n')
|
|
.map(task => task.trim())
|
|
.filter(task => task.length > 0)
|
|
.map(task => {
|
|
// 验证务格式
|
|
const parts = task.split('-');
|
|
if (parts.length !== 2) {
|
|
throw new Error(`任务格式错误: ${task}\n正确格式: 直播间ID-代理IP:端口`);
|
|
}
|
|
const [roomId, proxy] = parts;
|
|
if (!roomId || !proxy || !proxy.includes(':')) {
|
|
throw new Error(`任务格式错误: ${task}\n正确格式: 直播间ID-代理IP:端口`);
|
|
}
|
|
return task;
|
|
});
|
|
|
|
chrome.storage.local.set({ tasks: tasks }, function() {
|
|
if (elements.taskStatusElement) {
|
|
elements.taskStatusElement.textContent = `已存 ${tasks.length} 个任务`;
|
|
setTimeout(() => {
|
|
elements.taskStatusElement.textContent = '';
|
|
}, 2000);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// 执行任务按钮
|
|
if (elements.executeTasksButton) {
|
|
elements.executeTasksButton.addEventListener('click', async function() {
|
|
try {
|
|
const data = await chrome.storage.local.get(['tasks']);
|
|
const tasks = data.tasks || [];
|
|
|
|
if (tasks.length === 0) {
|
|
alert('没有可执行的任务');
|
|
return;
|
|
}
|
|
|
|
if (elements.taskStatusElement) {
|
|
elements.taskStatusElement.textContent = '开始执行任务...';
|
|
}
|
|
|
|
for (let i = 0; i < tasks.length; i++) {
|
|
const task = tasks[i];
|
|
if (elements.taskStatusElement) {
|
|
elements.taskStatusElement.textContent = `正在执行任务 ${i + 1}/${tasks.length}`;
|
|
}
|
|
|
|
// 这里执行具体任务
|
|
await executeTask(task);
|
|
|
|
// 任务之间添加延迟
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
}
|
|
|
|
if (elements.taskStatusElement) {
|
|
elements.taskStatusElement.textContent = '所有任务执行完成';
|
|
setTimeout(() => {
|
|
elements.taskStatusElement.textContent = '';
|
|
}, 2000);
|
|
}
|
|
} catch (error) {
|
|
console.error('执行任务时出错:', error);
|
|
if (elements.taskStatusElement) {
|
|
elements.taskStatusElement.textContent = '执行任务时出错: ' + error.message;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 修改检查重复直播间功能
|
|
if (elements.checkDuplicateRoomsButton) {
|
|
elements.checkDuplicateRoomsButton.addEventListener('click', async function() {
|
|
console.log('检查重复直播间按钮被点击');
|
|
try {
|
|
// 首先获取当前窗口
|
|
const currentWindow = await chrome.windows.getCurrent({
|
|
populate: true // 取窗中的所有标签页
|
|
});
|
|
|
|
// 只检��当前窗口中的标签页
|
|
const liveRooms = new Map(); // 存储直播间ID和第一次出现的标签页信息
|
|
const duplicates = new Map(); // 存储重复的直播间信息
|
|
|
|
// 遍历当前窗口的所有标签页
|
|
for (const tab of currentWindow.tabs) {
|
|
const match = tab.url.match(/live\.douyin\.com\/([^/?]+)/);
|
|
if (match) {
|
|
const roomId = match[1];
|
|
if (liveRooms.has(roomId)) {
|
|
// 发现重复,记录重复的标签页信息
|
|
if (!duplicates.has(roomId)) {
|
|
// 第一次发现重复,将原始标签页信息也加入到重复列表
|
|
duplicates.set(roomId, {
|
|
original: liveRooms.get(roomId),
|
|
duplicates: []
|
|
});
|
|
}
|
|
duplicates.get(roomId).duplicates.push({
|
|
tabId: tab.id,
|
|
url: tab.url
|
|
});
|
|
} else {
|
|
// 记录第一次出现的标签页信息
|
|
liveRooms.set(roomId, {
|
|
tabId: tab.id,
|
|
url: tab.url
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// 显示结果并处理重复
|
|
if (elements.duplicateRoomsStatusElement) {
|
|
if (duplicates.size > 0) {
|
|
let message = '当前窗口发现并处理重复的直播间:\n';
|
|
|
|
// 处理每个重复的直播间
|
|
for (const [roomId, info] of duplicates) {
|
|
message += `房间ID ${roomId}:\n`;
|
|
message += `- 保留标签页 ${info.original.tabId}\n`;
|
|
|
|
// 关闭重复的标签页
|
|
for (const dupTab of info.duplicates) {
|
|
message += `- 关闭标签页 ${dupTab.tabId}\n`;
|
|
try {
|
|
await chrome.tabs.remove(dupTab.tabId);
|
|
} catch (error) {
|
|
console.error(`关闭标签页 ${dupTab.tabId} 失败:`, error);
|
|
}
|
|
}
|
|
|
|
// 切换到留的标签页
|
|
try {
|
|
await chrome.tabs.update(info.original.tabId, { active: true });
|
|
} catch (error) {
|
|
console.error(`切换到标签页 ${info.original.tabId} 失败:`, error);
|
|
}
|
|
}
|
|
|
|
elements.duplicateRoomsStatusElement.textContent = message;
|
|
} else {
|
|
elements.duplicateRoomsStatusElement.textContent = '当前窗口未发现重复的直播间';
|
|
}
|
|
|
|
// 5秒后清除状态信息
|
|
setTimeout(() => {
|
|
elements.duplicateRoomsStatusElement.textContent = '';
|
|
}, 5000);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('检查重复直播间时出错:', error);
|
|
if (elements.duplicateRoomsStatusElement) {
|
|
elements.duplicateRoomsStatusElement.textContent = '检查失败: ' + error.message;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 加载保存的代理列表
|
|
chrome.storage.local.get(['proxyList'], function(data) {
|
|
if (data.proxyList && elements.proxyListTextarea) {
|
|
elements.proxyListTextarea.value = data.proxyList.join('\n');
|
|
}
|
|
});
|
|
|
|
// 保存代理按钮
|
|
if (elements.saveProxiesButton && elements.proxyListTextarea) {
|
|
elements.saveProxiesButton.addEventListener('click', function() {
|
|
try {
|
|
const proxies = elements.proxyListTextarea.value
|
|
.split('\n')
|
|
.map(proxy => proxy.trim())
|
|
.filter(proxy => proxy.length > 0)
|
|
.map(proxy => {
|
|
// 验证代理格式
|
|
if (!validateProxy(proxy)) {
|
|
throw new Error(`代理格式错误: ${proxy}\n正确格式: IP:端口`);
|
|
}
|
|
return proxy;
|
|
});
|
|
|
|
chrome.storage.local.set({ proxyList: proxies }, function() {
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = `已保存 ${proxies.length} 个代理`;
|
|
setTimeout(() => {
|
|
elements.proxyStatusElement.textContent = '';
|
|
}, 2000);
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('保存代理时出错:', error);
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = error.message;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 修改更新代理按钮的处理逻辑
|
|
if (elements.updateProxiesButton && elements.proxyListTextarea) {
|
|
elements.updateProxiesButton.addEventListener('click', async function() {
|
|
try {
|
|
// 获取代理列表
|
|
const proxyList = elements.proxyListTextarea.value
|
|
.split('\n')
|
|
.map(proxy => proxy.trim())
|
|
.filter(proxy => proxy.length > 0 && validateProxy(proxy))
|
|
.map(proxy => parseProxy(proxy)); // 解析代理字符串
|
|
|
|
if (proxyList.length === 0) {
|
|
throw new Error('没有可用的代理');
|
|
}
|
|
|
|
// 发送消息给background script,包含完整的代理列表
|
|
const response = await chrome.runtime.sendMessage({
|
|
action: 'setWindowProxy',
|
|
proxyList: proxyList
|
|
});
|
|
|
|
if (response.success) {
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = response.message;
|
|
setTimeout(() => {
|
|
elements.proxyStatusElement.textContent = '';
|
|
}, 3000);
|
|
}
|
|
} else {
|
|
throw new Error(response.error || '更新代理失败');
|
|
}
|
|
} catch (error) {
|
|
console.error('更新代理时出错:', error);
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = error.message;
|
|
setTimeout(() => {
|
|
elements.proxyStatusElement.textContent = '';
|
|
}, 3000);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 添加清除代理按钮功能
|
|
if (elements.clearProxyButton) {
|
|
elements.clearProxyButton.addEventListener('click', async function() {
|
|
try {
|
|
// 发送消息给background script清除代理
|
|
await chrome.runtime.sendMessage({
|
|
action: 'clearProxy'
|
|
});
|
|
|
|
// 获取所有无痕窗口
|
|
const windows = await chrome.windows.getAll({
|
|
windowTypes: ['normal'],
|
|
populate: true
|
|
});
|
|
|
|
// 刷新所有无痕窗口的标签页
|
|
for (const window of windows) {
|
|
if (window.incognito) {
|
|
for (const tab of window.tabs) {
|
|
await chrome.tabs.reload(tab.id, { bypassCache: true });
|
|
// 添加短暂延迟,避免同时刷新太多标签页
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = '已清除所有代理设置';
|
|
setTimeout(() => {
|
|
elements.proxyStatusElement.textContent = '';
|
|
}, 3000);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('清除代理时出错:', error);
|
|
if (elements.proxyStatusElement) {
|
|
elements.proxyStatusElement.textContent = '清除代理失败: ' + error.message;
|
|
setTimeout(() => {
|
|
elements.proxyStatusElement.textContent = '';
|
|
}, 3000);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 检查无痕窗口数量
|
|
if (elements.checkIncognito) {
|
|
elements.checkIncognito.addEventListener('click', function() {
|
|
chrome.runtime.sendMessage({ action: 'checkIncognitoWindows' }, function(response) {
|
|
const statusDiv = document.getElementById('incognitoStatus');
|
|
if (response.count === 0) {
|
|
statusDiv.textContent = '当前没有无痕窗口';
|
|
} else {
|
|
statusDiv.textContent = `当前有 ${response.count} 个无痕窗口`;
|
|
|
|
// 可选:显示详细信息
|
|
const details = response.windows.map(w =>
|
|
`窗口ID: ${w.id}, 类型: ${w.type}, 标签数: ${w.tabCount}`
|
|
).join('\n');
|
|
console.log('无痕窗口详情:', details);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// 添加查看当前代理的功能
|
|
if (elements.checkCurrentProxy) {
|
|
elements.checkCurrentProxy.addEventListener('click', async function() {
|
|
try {
|
|
// 获取当前窗口
|
|
const currentWindow = await chrome.windows.getCurrent();
|
|
|
|
// 获取代理信息
|
|
const proxyInfo = await chrome.runtime.sendMessage({
|
|
action: 'getCurrentProxy',
|
|
windowId: currentWindow.id
|
|
});
|
|
|
|
// 显示代理信息
|
|
if (elements.currentProxyStatus) {
|
|
if (proxyInfo.success) {
|
|
if (proxyInfo.proxy) {
|
|
const proxyText = `当前窗口ID: ${currentWindow.id}\n` +
|
|
`代理服务器: ${proxyInfo.proxy.host}:${proxyInfo.proxy.port}\n` +
|
|
`用户名: ${proxyInfo.proxy.username}`;
|
|
elements.currentProxyStatus.textContent = proxyText;
|
|
} else {
|
|
elements.currentProxyStatus.textContent = '当前窗口未设置代理';
|
|
}
|
|
} else {
|
|
elements.currentProxyStatus.textContent = proxyInfo.error || '获取代理信息失败';
|
|
}
|
|
|
|
// 3秒后清除状态信息
|
|
setTimeout(() => {
|
|
elements.currentProxyStatus.textContent = '';
|
|
}, 3000);
|
|
}
|
|
} catch (error) {
|
|
console.error('查看代理信息失败:', error);
|
|
if (elements.currentProxyStatus) {
|
|
elements.currentProxyStatus.textContent = '查看代理信息失败: ' + error.message;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// 辅助函数:获取直播间人数
|
|
async function getLiveRoomCount() {
|
|
try {
|
|
const tabs = await chrome.tabs.query({active: true, currentWindow: true});
|
|
if (!tabs[0]) return null;
|
|
const response = await chrome.tabs.sendMessage(tabs[0].id, {action: "getLiveRoomCount"});
|
|
return response.count;
|
|
} catch (error) {
|
|
console.error("获取直播间人数失败:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// 辅助函数:注入内容脚本并发送消息
|
|
function injectContentScriptAndSendMessage(action) {
|
|
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
|
if (!tabs[0]) {
|
|
alert('无法获取当前标签页');
|
|
return;
|
|
}
|
|
|
|
chrome.scripting.executeScript({
|
|
target: {tabId: tabs[0].id},
|
|
files: ['content.js']
|
|
}, function() {
|
|
if (chrome.runtime.lastError) {
|
|
console.error('注入脚本失败:', chrome.runtime.lastError);
|
|
return;
|
|
}
|
|
|
|
chrome.tabs.sendMessage(tabs[0].id, {action: action}, function(response) {
|
|
if (chrome.runtime.lastError) {
|
|
console.error('发送消息失败:', chrome.runtime.lastError);
|
|
return;
|
|
}
|
|
console.log('收到响应:', response);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// 监听登录结果
|
|
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
|
if (request.action === 'loginResult') {
|
|
const userinfoElement = document.getElementById('userinfo');
|
|
if (request.status === 'success' && userinfoElement) {
|
|
userinfoElement.textContent = '已登录:' + request.uname;
|
|
} else {
|
|
alert('登录失败:' + (request.message || '未知错误'));
|
|
}
|
|
}
|
|
});
|
|
|
|
// 修改执行任务的函数
|
|
async function executeTask(task) {
|
|
try {
|
|
// 解析任务字符串
|
|
const [roomId, proxyString] = task.split('-');
|
|
const [proxyHost, proxyPort] = proxyString.split(':');
|
|
|
|
// 验证数据
|
|
if (!roomId || !proxyHost || !proxyPort) {
|
|
throw new Error(`任务格式错误: ${task}`);
|
|
}
|
|
|
|
// 构建直播间URL
|
|
const liveUrl = `https://live.douyin.com/${roomId}`;
|
|
|
|
// 发送消息给background script,包含代理信息
|
|
await chrome.runtime.sendMessage({
|
|
action: 'openLiveWithProxy',
|
|
url: liveUrl,
|
|
proxy: {
|
|
host: proxyHost,
|
|
port: proxyPort
|
|
}
|
|
});
|
|
|
|
console.log(`已执行任务: 打开直播间 ${roomId}, 使用代理 ${proxyHost}:${proxyPort}`);
|
|
|
|
} catch (error) {
|
|
console.error(`执行任务 "${task}" 时出错:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// 添加任务格式验证函数
|
|
function validateTask(task) {
|
|
const parts = task.split('-');
|
|
if (parts.length !== 2) return false;
|
|
|
|
const [roomId, proxy] = parts;
|
|
if (!roomId || !proxy) return false;
|
|
|
|
const [host, port] = proxy.split(':');
|
|
if (!host || !port) return false;
|
|
|
|
// 简单的IP格式验证
|
|
const isValidIp = host.split('.').length === 4 &&
|
|
host.split('.').every(num => {
|
|
const n = parseInt(num);
|
|
return !isNaN(n) && n >= 0 && n <= 255;
|
|
});
|
|
|
|
// 简单的端口验证
|
|
const isValidPort = !isNaN(parseInt(port)) &&
|
|
parseInt(port) > 0 &&
|
|
parseInt(port) <= 65535;
|
|
|
|
return isValidIp && isValidPort;
|
|
}
|
|
|
|
// 修改代理验证函数
|
|
function validateProxy(proxy) {
|
|
try {
|
|
// 移除 http:// 前缀(如果存在)
|
|
if (proxy.startsWith('http://')) {
|
|
proxy = proxy.substring(7);
|
|
}
|
|
|
|
let host, port;
|
|
|
|
if (proxy.includes('@')) {
|
|
// 带认证信息的格式
|
|
const [auth, address] = proxy.split('@');
|
|
// 验证认证信息
|
|
const [username, password] = auth.split(':');
|
|
if (!username || !password) return false;
|
|
|
|
[host, port] = address.split(':');
|
|
} else {
|
|
// 简单格式
|
|
[host, port] = proxy.split(':');
|
|
}
|
|
|
|
if (!host || !port) return false;
|
|
|
|
// 验证IP格式
|
|
const isValidIp = host.split('.').length === 4 &&
|
|
host.split('.').every(num => {
|
|
const n = parseInt(num);
|
|
return !isNaN(n) && n >= 0 && n <= 255;
|
|
});
|
|
|
|
// 验证端口
|
|
const isValidPort = !isNaN(parseInt(port)) &&
|
|
parseInt(port) > 0 &&
|
|
parseInt(port) <= 65535;
|
|
|
|
return isValidIp && isValidPort;
|
|
} catch (error) {
|
|
console.error('代理格式验证失败:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 修改代理解析函数
|
|
function parseProxy(proxyString) {
|
|
try {
|
|
// 处理完整的代理URL格式
|
|
if (proxyString.startsWith('http://')) {
|
|
// 移除 'http://' 前缀
|
|
proxyString = proxyString.substring(7);
|
|
}
|
|
|
|
let username = "", password = "", host = "", port = "";
|
|
|
|
if (proxyString.includes('@')) {
|
|
// 带认证信息的格式 username:password@host:port
|
|
const [auth, address] = proxyString.split('@');
|
|
[username, password] = auth.split(':');
|
|
[host, port] = address.split(':');
|
|
} else {
|
|
// 简单格式 host:port
|
|
[host, port] = proxyString.split(':');
|
|
}
|
|
|
|
if (!host || !port) {
|
|
throw new Error(`代理格式错误: ${proxyString}`);
|
|
}
|
|
|
|
return {
|
|
username,
|
|
password,
|
|
host,
|
|
port: parseInt(port)
|
|
};
|
|
} catch (error) {
|
|
console.error('解析代理字符串失败:', error);
|
|
throw new Error(`代理格式错误: ${proxyString}\n正确格式: http://username:password@host:port`);
|
|
}
|
|
}
|
|
|