Browse Source

测试

torsen
TorsenLi 1 year ago
parent
commit
f17dc70c34
  1. 405
      douyin/background.js
  2. 5
      douyin/manifest.json
  3. 2
      douyin/popup.html
  4. 164
      douyin/popup.js

405
douyin/background.js

@ -58,86 +58,83 @@ const windowProxyMap = new Map();
// 修改代理设置函数 // 修改代理设置函数
function setProxyForWindow(proxyConfig, windowId, callback) { function setProxyForWindow(proxyConfig, windowId, callback) {
const maxRetries = 3; console.log(`设置窗口 ${windowId} 的代理:`, {
let retryCount = 0; host: proxyConfig.host,
port: proxyConfig.port,
function trySetProxy() { username: proxyConfig.username
console.log(`窗口 ${windowId} 设置代理尝试 ${retryCount + 1}/${maxRetries}:`, proxyConfig); });
// 存储当前窗口的代理设置 // 存储当前窗口的代理设置
windowProxyMap.set(windowId, proxyConfig); windowProxyMap.set(windowId, proxyConfig);
// 设置新的代理 // 设置认证监听器
const config = { const authHandler = function(details) {
value: { return {
mode: "fixed_servers", authCredentials: {
rules: { username: proxyConfig.username,
singleProxy: { password: proxyConfig.password
scheme: "http", }
host: proxyConfig.host,
port: parseInt(proxyConfig.port)
},
bypassList: [
"localhost",
"127.0.0.1",
"<local>"
]
}
},
scope: "regular"
}; };
};
// 移除之前的监听器(如果存在)
try {
chrome.webRequest.onAuthRequired.removeListener(authHandler);
} catch (e) {}
// 添加新的监听器
chrome.webRequest.onAuthRequired.addListener(
authHandler,
{ urls: ["<all_urls>"] },
["asyncBlocking"]
);
chrome.proxy.settings.set( // 设置代理配置
config, const config = {
function() { value: {
if (chrome.runtime.lastError) { mode: "fixed_servers",
console.error('设置代理失败:', chrome.runtime.lastError); rules: {
handleError(chrome.runtime.lastError); singleProxy: {
return; scheme: "http",
host: proxyConfig.host,
port: parseInt(proxyConfig.port)
} }
}
},
scope: "regular"
};
// 设置代理
chrome.proxy.settings.set(
config,
function() {
if (chrome.runtime.lastError) {
console.error('设置代理失败:', chrome.runtime.lastError);
callback(chrome.runtime.lastError);
return;
}
// 验证代理设置 console.log(`窗口 ${windowId} 代理设置成功`);
chrome.proxy.settings.get(
{ incognito: false }, // 刷新标签页
function(config) { chrome.tabs.query({ windowId: windowId }, function(tabs) {
console.log(`窗口 ${windowId} 当前代理配置:`, config); if (tabs.length === 0) {
if (config.value.mode === "fixed_servers") { callback(null, true);
// 只刷新当前窗口的标签页 return;
chrome.tabs.query({ windowId: windowId }, function(tabs) { }
let refreshedCount = 0;
if (tabs.length === 0) {
callback(null, true);
return;
}
tabs.forEach(function(tab) { let refreshedCount = 0;
chrome.tabs.reload(tab.id, { bypassCache: true }, function() { tabs.forEach(function(tab) {
refreshedCount++; chrome.tabs.reload(tab.id, { bypassCache: true }, function() {
if (refreshedCount === tabs.length) { refreshedCount++;
callback(null, true); if (refreshedCount === tabs.length) {
} callback(null, true);
});
});
});
} else {
handleError(new Error('代理设置验证失败'));
} }
} });
); });
} });
);
}
function handleError(error) {
if (retryCount < maxRetries - 1) {
retryCount++;
setTimeout(trySetProxy, 2000);
} else {
callback(error);
} }
} );
trySetProxy();
} }
// 消息监听器 // 消息监听器
@ -219,7 +216,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
}) })
.catch(error => { .catch(error => {
console.error('登录请求出错:', error); console.error('登录请求出错:', error);
sendResponse({ status: 'error', message: '登录请出错,请检查网络连接或稍后重试。' }); sendResponse({ status: 'error', message: '登录请出错,请检查网络连接或稍后重试。' });
}); });
} }
@ -245,14 +242,14 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.error('设置代理失败:', error); console.error('设置代理失败:', error);
sendResponse({ success: false, error: error.message }); sendResponse({ success: false, error: error.message });
} else { } else {
console.log('代理已设置到新创建无痕窗口'); console.log('代理已设置到新创建无痕窗口');
sendResponse({ success: true }); sendResponse({ success: true });
} }
} }
); );
}, 1000); }, 1000);
} else { } else {
console.error('建窗口失败'); console.error('建窗口失败');
sendResponse({ success: false, error: '创建窗口失败' }); sendResponse({ success: false, error: '创建窗口失败' });
} }
}); });
@ -266,46 +263,84 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const proxyList = request.proxyList; const proxyList = request.proxyList;
console.log('可用代理列表:', proxyList); console.log('可用代理列表:', proxyList);
if (proxyList.length < incognitoWindows.length) { if (proxyList.length === 0) {
sendResponse({ sendResponse({
success: false, success: false,
error: `代理数量不足,需要 ${incognitoWindows.length} 个代理,但只有 ${proxyList.length}` error: '没有可用的代理'
}); });
return; return;
} }
let completedCount = 0; let completedCount = 0;
let errors = []; let errors = [];
let currentIndex = 0;
// 处理下一个窗口
function processNextWindow() {
if (currentIndex >= incognitoWindows.length) {
checkComplete();
return;
}
// 为每个窗口单独设置代理 const window = incognitoWindows[currentIndex];
incognitoWindows.forEach((window, index) => {
const proxy = proxyList[index]; // 检查窗口是否已经有代理设置
const [host, port] = proxy.split(':'); const existingProxy = windowProxyMap.get(window.id);
if (existingProxy) {
console.log(`窗口 ${window.id} 已有代理设置,跳过:`, {
host: existingProxy.host,
port: existingProxy.port,
username: existingProxy.username
});
completedCount++;
currentIndex++;
processNextWindow();
return;
}
if (!host || !port) { // 使用循环方式获取代理配置
errors.push(`代理格式错误: ${proxy}`); const proxyIndex = currentIndex % proxyList.length;
const proxy = proxyList[proxyIndex];
if (!proxy || !proxy.host || !proxy.port) {
errors.push(`代理配置无效: ${JSON.stringify(proxy)}`);
completedCount++; completedCount++;
checkComplete(); currentIndex++;
processNextWindow();
return; return;
} }
// 为每个窗口设置代理时先激活该窗口 console.log(`窗口 ${window.id} 使用第 ${proxyIndex + 1} 个代理 (总共 ${proxyList.length} 个)`);
// 为窗口设置代理
chrome.windows.update(window.id, { focused: true }, () => { chrome.windows.update(window.id, { focused: true }, () => {
setTimeout(() => { setTimeout(() => {
setProxyForWindow( setProxyForWindow(
{ host, port: parseInt(port) }, proxy,
window.id, window.id,
(error, success) => { (error, success) => {
if (error) { if (error) {
console.error(`窗口 ${window.id} 设置代理失败:`, error);
errors.push(`窗口 ${window.id} 设置代理失败: ${error.message}`); errors.push(`窗口 ${window.id} 设置代理失败: ${error.message}`);
} else {
console.log(`窗口 ${window.id} 使用代理:`, {
host: proxy.host,
port: proxy.port,
username: proxy.username,
password: proxy.password
});
} }
completedCount++; completedCount++;
checkComplete(); currentIndex++;
setTimeout(processNextWindow, 1000); // 等待1秒后处理下一个窗口
} }
); );
}, index * 3000); // 每个窗口间隔3秒 }, 1000);
}); });
}); }
// 开始处理第一个窗口
processNextWindow();
function checkComplete() { function checkComplete() {
if (completedCount === incognitoWindows.length) { if (completedCount === incognitoWindows.length) {
@ -317,33 +352,138 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
} else { } else {
sendResponse({ sendResponse({
success: true, success: true,
message: `已为 ${incognitoWindows.length} 个无痕窗口设置独立代理` message: `已为 ${incognitoWindows.length} 个无痕窗口设置代理`
}); });
} }
} }
} }
} else { } else {
sendResponse({ success: false, error: '未找到无痕窗��' }); sendResponse({ success: false, error: '未找到无痕窗' });
} }
}); });
return true; return true;
} }
if (request.action === 'clearProxy') { if (request.action === 'clearProxy') {
chrome.proxy.settings.clear( try {
{ // 清除代理设置
scope: "regular" chrome.proxy.settings.clear(
}, { scope: "regular" },
() => { async function() {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
console.error('清除代理失败:', chrome.runtime.lastError); console.error('清除代理设置失败:', chrome.runtime.lastError);
sendResponse({ success: false, error: chrome.runtime.lastError.message }); sendResponse({ success: false, error: chrome.runtime.lastError.message });
} else { return;
console.log('代理设置已完全清除'); }
sendResponse({ success: true });
console.log('代理设置已清除');
try {
// 获取所有窗口
const windows = await new Promise((resolve) => {
chrome.windows.getAll({
populate: true
}, resolve);
});
// 清除代理映射
windowProxyMap.clear();
console.log('代理映射已清除');
// 清除认证缓存
const removeCache = async () => {
try {
await chrome.browsingData.remove({
"since": 0
}, {
"cache": true,
"cookies": true,
"passwords": true,
"webSQL": true,
"serviceWorkers": true,
"indexedDB": true
});
console.log('认证缓存已清除');
} catch (error) {
console.error('清除认证缓存失败:', error);
}
};
await removeCache();
// 刷新所有无痕窗口的标签页
for (const window of windows) {
if (window.incognito) {
console.log(`刷新无痕窗口 ${window.id} 的标签页`);
for (const tab of window.tabs) {
try {
// 先导航到空白页面
await new Promise((resolve) => {
chrome.tabs.update(tab.id, { url: 'about:blank' }, resolve);
});
await new Promise(resolve => setTimeout(resolve, 500));
// 然后重新加载原始URL
await new Promise((resolve) => {
chrome.tabs.reload(tab.id, { bypassCache: true }, resolve);
});
// 添加短暂延迟,避免同时刷新太多标签页
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(`刷新标签页 ${tab.id} 失败:`, error);
}
}
}
}
sendResponse({
success: true,
message: '已清除所有代理设置、认证缓存并刷新标签页'
});
} catch (error) {
console.error('刷新标签页时出错:', error);
sendResponse({
success: false,
error: '清除代理成功但刷新标签页失败: ' + error.message
});
}
} }
);
} catch (error) {
console.error('清除代理时出错:', error);
sendResponse({ success: false, error: error.message });
}
return true;
}
if (request.action === 'getCurrentProxy') {
try {
const windowId = request.windowId;
const proxyConfig = windowProxyMap.get(windowId);
if (proxyConfig) {
sendResponse({
success: true,
proxy: {
host: proxyConfig.host,
port: proxyConfig.port,
username: proxyConfig.username
// 出于安全考虑,不返回密码
}
});
} else {
sendResponse({
success: true,
proxy: null
});
} }
); } catch (error) {
console.error('获取代理信息失败:', error);
sendResponse({
success: false,
error: error.message
});
}
return true; return true;
} }
@ -356,7 +496,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
}); });
chrome.windows.onCreated.addListener((window) => { chrome.windows.onCreated.addListener((window) => {
console.log('新窗口创:', { console.log('新窗口创:', {
id: window.id, id: window.id,
incognito: window.incognito, incognito: window.incognito,
type: window.type, type: window.type,
@ -375,21 +515,23 @@ chrome.tabs.onCreated.addListener((tab) => {
}); });
}); });
// 修改错误监听器,添加更多需要忽略的误类型 // 修改错误监听器,添加更多需要忽略的误类型
chrome.webRequest.onErrorOccurred.addListener( chrome.webRequest.onErrorOccurred.addListener(
function(details) { function(details) {
// 扩展需要忽略的错误类型列表 // 扩展需要忽略的错误类型列表
const ignoredErrors = [ const ignoredErrors = [
'net::ERR_ABORTED', // 请求中断 'net::ERR_ABORTED', // 请求中断
'net::ERR_NETWORK_CHANGED', // 网络变化 'net::ERR_NETWORK_CHANGED', // 网络变化
'net::ERR_CONNECTION_CLOSED', // 连接关闭 'net::ERR_CONNECTION_CLOSED', // 连接关闭
'net::ERR_CACHE_MISS', // 缓存未命中 'net::ERR_CACHE_MISS', // 缓存未命中
'net::ERR_EMPTY_RESPONSE', // 空响应 'net::ERR_EMPTY_RESPONSE', // 空响应
'net::ERR_FAILED', // 一般性失败 'net::ERR_FAILED', // 一般性失败
'net::ERR_TIMED_OUT' // 超时 'net::ERR_TIMED_OUT', // 超时
'net::ERR_TOO_MANY_RETRIES', // 重试次数过多
'net::ERR_TUNNEL_CONNECTION_FAILED' // 隧道连接失败
]; ];
// 略的资源类型 // 略的资源类型
const ignoredResourceTypes = [ const ignoredResourceTypes = [
'font', // 字体文件 'font', // 字体文件
'image', // 图片 'image', // 图片
@ -455,25 +597,16 @@ chrome.windows.onFocusChanged.addListener((windowId) => {
} }
}); });
// 添加窗口焦点变化监听器 // 修改窗口焦点变化监听器
chrome.windows.onFocusChanged.addListener((windowId) => { chrome.windows.onFocusChanged.addListener((windowId) => {
if (windowId !== chrome.windows.WINDOW_ID_NONE) { if (windowId !== chrome.windows.WINDOW_ID_NONE) {
const proxyConfig = windowProxyMap.get(windowId); const proxyConfig = windowProxyMap.get(windowId);
if (proxyConfig) { if (proxyConfig) {
console.log(`窗口 ${windowId} 获得焦点,恢复其代理设置:`, proxyConfig); console.log(`窗口 ${windowId} 获得焦点,恢复其代理设置:`, proxyConfig);
chrome.proxy.settings.set({ setProxyForWindow(proxyConfig, windowId, (error) => {
value: { if (error) {
mode: "fixed_servers", console.error('恢复代理设置失败:', error);
rules: { }
singleProxy: {
scheme: "http",
host: proxyConfig.host,
port: parseInt(proxyConfig.port)
},
bypassList: ["localhost", "127.0.0.1", "<local>"]
}
},
scope: "regular"
}); });
} }
} }
@ -483,4 +616,18 @@ chrome.windows.onFocusChanged.addListener((windowId) => {
chrome.windows.onRemoved.addListener((windowId) => { chrome.windows.onRemoved.addListener((windowId) => {
console.log(`窗口 ${windowId} 被关闭,移除其代理设置`); console.log(`窗口 ${windowId} 被关闭,移除其代理设置`);
windowProxyMap.delete(windowId); windowProxyMap.delete(windowId);
}); });
// 添加证书错误处理
chrome.webRequest.onErrorOccurred.addListener(
function(details) {
if (details.error && details.error.includes('ERR_CERT')) {
console.log('忽略证书错误:', details.url);
return { cancel: false };
}
},
{
urls: ["<all_urls>"],
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
}
);

5
douyin/manifest.json

@ -10,7 +10,10 @@
"cookies", "cookies",
"scripting", "scripting",
"proxy", "proxy",
"webRequest" "webRequest",
"webRequestAuthProvider",
"browsingData",
"webNavigation"
], ],
"host_permissions": [ "host_permissions": [
"https://douyin.xingtongworld.com/*", "https://douyin.xingtongworld.com/*",

2
douyin/popup.html

@ -96,7 +96,9 @@
<button id="saveProxies">保存代理</button> <button id="saveProxies">保存代理</button>
<button id="updateProxies">更新代理</button> <button id="updateProxies">更新代理</button>
<button id="clearProxy">清除代理</button> <button id="clearProxy">清除代理</button>
<button id="checkCurrentProxy">查看当前代理</button>
<div id="proxyStatus"></div> <div id="proxyStatus"></div>
<div id="currentProxyStatus"></div>
</div> </div>
<!-- 任务管理部分 --> <!-- 任务管理部分 -->

164
douyin/popup.js

@ -30,7 +30,9 @@ document.addEventListener('DOMContentLoaded', function() {
updateProxiesButton: document.getElementById('updateProxies'), updateProxiesButton: document.getElementById('updateProxies'),
proxyStatusElement: document.getElementById('proxyStatus'), proxyStatusElement: document.getElementById('proxyStatus'),
clearProxyButton: document.getElementById('clearProxy'), clearProxyButton: document.getElementById('clearProxy'),
checkIncognito: document.getElementById('checkIncognito') checkIncognito: document.getElementById('checkIncognito'),
checkCurrentProxy: document.getElementById('checkCurrentProxy'),
currentProxyStatus: document.getElementById('currentProxyStatus')
}; };
// 检查登录状态 // 检查登录状态
@ -256,7 +258,7 @@ document.addEventListener('DOMContentLoaded', function() {
populate: true // 取窗中的所有标签页 populate: true // 取窗中的所有标签页
}); });
// 只检当前窗口中的标签页 // 只检��当前窗口中的标签页
const liveRooms = new Map(); // 存储直播间ID和第一次出现的标签页信息 const liveRooms = new Map(); // 存储直播间ID和第一次出现的标签页信息
const duplicates = new Map(); // 存储重复的直播间信息 const duplicates = new Map(); // 存储重复的直播间信息
@ -384,7 +386,8 @@ document.addEventListener('DOMContentLoaded', function() {
const proxyList = elements.proxyListTextarea.value const proxyList = elements.proxyListTextarea.value
.split('\n') .split('\n')
.map(proxy => proxy.trim()) .map(proxy => proxy.trim())
.filter(proxy => proxy.length > 0 && validateProxy(proxy)); .filter(proxy => proxy.length > 0 && validateProxy(proxy))
.map(proxy => parseProxy(proxy)); // 解析代理字符串
if (proxyList.length === 0) { if (proxyList.length === 0) {
throw new Error('没有可用的代理'); throw new Error('没有可用的代理');
@ -482,6 +485,48 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
}); });
} }
// 添加查看当前代理的功能
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;
}
}
});
}
}); });
// 辅助函数:获取直播间人数 // 辅助函数:获取直播间人数
@ -596,52 +641,83 @@ function validateTask(task) {
return isValidIp && isValidPort; return isValidIp && isValidPort;
} }
// 添加代理验证函数 // 修改代理验证函数
function validateProxy(proxy) { function validateProxy(proxy) {
const [host, port] = proxy.split(':'); try {
if (!host || !port) return false; // 移除 http:// 前缀(如果存在)
if (proxy.startsWith('http://')) {
// 验证IP格式 proxy = proxy.substring(7);
const isValidIp = host.split('.').length === 4 && }
host.split('.').every(num => {
const n = parseInt(num); let host, port;
return !isNaN(n) && n >= 0 && n <= 255;
}); if (proxy.includes('@')) {
// 带认证信息的格式
// 验证端口 const [auth, address] = proxy.split('@');
const isValidPort = !isNaN(parseInt(port)) && // 验证认证信息
parseInt(port) > 0 && const [username, password] = auth.split(':');
parseInt(port) <= 65535; 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;
});
return isValidIp && isValidPort; // 验证端口
const isValidPort = !isNaN(parseInt(port)) &&
parseInt(port) > 0 &&
parseInt(port) <= 65535;
return isValidIp && isValidPort;
} catch (error) {
console.error('代理格式验证失败:', error);
return false;
}
} }
// 修改更新代理按钮的处理逻辑中的代理设置部分 // 修改代理解析函数
async function setProxyWithRetry(proxy, maxRetries = 3) { function parseProxy(proxyString) {
for (let i = 0; i < maxRetries; i++) { try {
try { // 处理完整的代理URL格式
const [proxyHost, proxyPort] = proxy.split(':'); if (proxyString.startsWith('http://')) {
// 移除 'http://' 前缀
const response = await chrome.runtime.sendMessage({ proxyString = proxyString.substring(7);
action: 'setWindowProxy', }
proxy: {
host: proxyHost,
port: parseInt(proxyPort)
}
});
if (response.success) { let username = "", password = "", host = "", port = "";
return true;
} if (proxyString.includes('@')) {
// 带认证信息的格式 username:password@host:port
// 如果设置失败,等待后重试 const [auth, address] = proxyString.split('@');
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); [username, password] = auth.split(':');
} catch (error) { [host, port] = address.split(':');
console.error(`代理设置重试 ${i + 1} 失败:`, error); } else {
if (i === maxRetries - 1) { // 简单格式 host:port
throw error; [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`);
} }
return false;
} }

Loading…
Cancel
Save