1. 知乎优化
安装地址
删除没用的垃圾内容
// ==UserScript==
// @name 知乎优化
// @namespace http://tampermonkey.net/
// @version 0.4
// @description Sets custom widths and hides specified elements on Zhihu
// @author You
// @match https://www.zhihu.com/*
// @match http://www.zhihu.com/*
// @match https://zhihu.com/*
// @match http://zhihu.com/*
// @grant none
// @license MIT
// @downloadURL https://update.greasyfork.org/scripts/529684/%E7%9F%A5%E4%B9%8E%E4%BC%98%E5%8C%96.user.js
// @updateURL https://update.greasyfork.org/scripts/529684/%E7%9F%A5%E4%B9%8E%E4%BC%98%E5%8C%96.meta.js
// ==/UserScript==
(function() {
'use strict';
// Function to apply width change
function setMainColumnWidth() {
const mainColumn = document.querySelector('.Topstory-mainColumn');
if (mainColumn) {
mainColumn.style.width = '100%';
console.log('Zhihu Main Column width set to 100%');
}
}
// Function to apply width change for Question pages
function setQuestionMainColumnWidth() {
const mainColumn = document.querySelector('.Question-mainColumn');
if (mainColumn) {
mainColumn.style.width = '100%';
console.log('Zhihu Question Main Column width set to 100%');
}
}
// Function to apply custom CSS styles
function applyCustomStyles() {
// Apply styles to .css-11p8nt5 elements
const customElements = document.querySelectorAll('.css-11p8nt5');
if (customElements.length > 0) {
customElements.forEach(element => {
element.style.maxWidth = '0px';
element.style.minWidth = '950px';
console.log('Applied custom styles to .css-11p8nt5');
});
}
const customElements2 = document.querySelectorAll('.css-1kjxdzv');
if (customElements2.length > 0) {
customElements2.forEach(element => {
element.style.maxWidth = '0px';
element.style.minWidth = '950px';
console.log('Applied custom styles to .css-1kjxdzv');
});
}
}
// Function to hide the specified elements
function hideSpecifiedElements() {
// Original element to hide
const elementsToHide1 = document.querySelectorAll('.css-1qyytj7 > div');
if (elementsToHide1.length > 0) {
elementsToHide1.forEach(element => {
element.style.display = 'none';
console.log('Hidden element with class .css-1qyytj7 > div');
});
}
// New elements to hide
// 1. Elements with class .css-29q9fa
const elementsToHide2 = document.querySelectorAll('.css-29q9fa');
if (elementsToHide2.length > 0) {
elementsToHide2.forEach(element => {
element.style.display = 'none';
console.log('Hidden element with class .css-29q9fa');
});
}
// 2. Third AppHeader-Tab
const thirdTab = document.querySelector('li.Tabs-item--noMeta.AppHeader-Tab.Tabs-item:nth-of-type(3)');
if (thirdTab) {
thirdTab.style.display = 'none';
console.log('Hidden third AppHeader Tab');
}
// 3. Fourth AppHeader-Tab
const fourthTab = document.querySelector('li.Tabs-item--noMeta.AppHeader-Tab.Tabs-item:nth-of-type(4)');
if (fourthTab) {
fourthTab.style.display = 'none';
console.log('Hidden fourth AppHeader Tab');
}
// 4. Button with complex class chain
const buttons = document.querySelectorAll('.css-18vqx7l > .fEPKGkUK5jyc4fUuT0QP.Button--plain.FEfUrdfMIKpQDJDqkjte.css-79elbk.Button');
if (buttons.length > 0) {
buttons.forEach(button => {
button.style.display = 'none';
console.log('Hidden specified button');
});
}
}
// Apply immediately for already loaded elements
function applyAllChanges() {
setMainColumnWidth();
setQuestionMainColumnWidth();
hideSpecifiedElements();
applyCustomStyles();
}
// Initial application
applyAllChanges();
// Create a MutationObserver to handle dynamically loaded content
const observer = new MutationObserver(function(mutations) {
applyAllChanges();
});
// Start observing the document body for DOM changes
observer.observe(document.body, { childList: true, subtree: true });
})();
Grok 限制显示脚本
来源自 Grok 限制显示脚本 - 开发调优 - LINUX DO
// ==UserScript==
// @name Grok Rate Limits Viewer
// @namespace https://grok.com/
// @version 1.5
// @description 显示Grok API的速率限制信息
// @author Neuroplexus
// @match https://grok.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// 调试模式设置
const DEBUG_MODE = false; // 设置为true开启调试模式
const DEBUG_VALUES = {
DEFAULT: { remainingQueries: 5, totalQueries: 25, windowSizeSeconds: 3600 },
REASONING: { remainingQueries: 2, totalQueries: 10, windowSizeSeconds: 3600 },
DEEPSEARCH: { remainingQueries: 0, totalQueries: 5, windowSizeSeconds: 3600 }
};
// 添加样式
GM_addStyle(`
#rate-limits-button {
position: relative;
}
#rate-limits-container {
position: fixed;
width: 320px;
background-color: #1a1a1a;
border-radius: 16px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
z-index: 9999;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: #ffffff;
overflow: hidden;
transition: opacity 0.2s ease, transform 0.2s ease;
border: 1px solid #333333;
}
#rate-limits-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
background-color: #222222;
cursor: move;
user-select: none;
border-bottom: 1px solid #333333;
}
#rate-limits-title {
font-weight: 500;
font-size: 14px;
display: flex;
align-items: center;
gap: 10px;
color: #ffffff;
}
#rate-limits-controls {
display: flex;
gap: 12px;
}
.rate-limits-control-button {
background: transparent;
border: none;
color: #cccccc;
cursor: pointer;
padding: 6px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s ease;
}
.rate-limits-control-button:hover {
background-color: #333333;
}
#rate-limits-content {
padding: 24px;
}
.rate-limit-section {
margin-bottom: 24px;
}
.rate-limit-section:last-child {
margin-bottom: 0;
}
.rate-limit-title {
font-weight: 500;
font-size: 13px;
margin-bottom: 12px;
color: #aaaaaa;
}
.rate-limit-info {
display: flex;
justify-content: space-between;
font-size: 13px;
margin-bottom: 8px;
}
.rate-limit-progress-container {
height: 6px;
background-color: #333333;
border-radius: 3px;
overflow: hidden;
margin-top: 10px;
}
.rate-limit-progress-bar {
height: 100%;
background-color: #3a8df4;
border-radius: 3px;
transition: width 0.3s ease;
}
.rate-limit-warning .rate-limit-progress-bar {
background-color: #f0ad4e;
}
.rate-limit-danger .rate-limit-progress-bar {
background-color: #d9534f;
}
.rate-limit-time {
font-size: 11px;
color: #888888;
margin-top: 8px;
text-align: right;
}
/* 徽章容器样式 */
.badge-container {
display: inline-flex;
align-items: center;
overflow: hidden;
transition: width 0.3s ease, margin 0.3s ease;
height: 90%;
vertical-align: middle;
width: 0px; /* 初始宽度为0 */
}
/* 徽章样式 */
.rate-limit-badge {
background-color: white;
color: black;
font-size: 10px;
font-weight: 500;
padding: 0 6px;
border-radius: 10px;
display: flex;
align-items: center;
white-space: nowrap;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
height: 100%;
}
/* 状态指示点 */
.rate-limit-badge::before {
content: '';
display: none;
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 4px;
flex-shrink: 0;
}
.rate-limit-badge.warning::before {
display: block;
background-color: #f0ad4e;
}
.rate-limit-badge.danger::before {
display: block;
background-color: #d9534f;
}
/* 用完次数的按钮样式 */
.rate-limit-depleted {
position: relative;
}
.rate-limit-depleted::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(217, 83, 79, 0.3);
pointer-events: none;
border-radius: inherit;
}
/* 特定元素的徽章容器样式 */
#radix-\\:r14\\: .badge-container {
margin-right: 0px; /* 初始无margin */
}
/* 调试模式指示器 */
.debug-mode-indicator {
position: absolute;
top: 16px;
right: 16px;
background-color: #d9534f;
color: white;
font-size: 10px;
padding: 2px 6px;
border-radius: 10px;
font-weight: bold;
}
`);
// 创建速率限制按钮
function createRateLimitsButton() {
const buttonContainer = document.createElement('a');
buttonContainer.id = 'rate-limits-button';
buttonContainer.className = 'inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium leading-[normal] cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-default [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 text-primary hover:bg-button-ghost-hover h-10 w-10 rounded-full';
buttonContainer.setAttribute('type', 'button');
buttonContainer.setAttribute('data-state', 'closed');
buttonContainer.innerHTML = `
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="20" width="20" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"></path>
<path d="M12 6c-3.309 0-6 2.691-6 6s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 10c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4z"></path>
<path d="M12 8c-2.206 0-4 1.794-4 4s1.794 4 4 4 4-1.794 4-4-1.794-4-4-4zm0 6c-1.084 0-2-.916-2-2s.916-2 2-2 2 .916 2 2-.916 2-2 2z"></path>
</svg>
`;
return buttonContainer;
}
// 创建速率限制窗口
function createRateLimitsContainer() {
const container = document.createElement('div');
container.id = 'rate-limits-container';
container.style.display = GM_getValue('rateLimitsVisible', 'none');
// 从存储中获取位置
const position = GM_getValue('rateLimitsPosition', { x: 20, y: 80 });
container.style.left = `${position.x}px`;
container.style.top = `${position.y}px`;
container.innerHTML = `
<div id="rate-limits-header">
<div id="rate-limits-title">
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"></path>
<path d="M12 6c-3.309 0-6 2.691-6 6s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 10c-2.206 0-4-1.794-4-4s1.794-4 4-4 4 1.794 4 4-1.794 4-4 4z"></path>
<path d="M12 8c-2.206 0-4 1.794-4 4s1.794 4 4 4 4-1.794 4-4-1.794-4-4-4zm0 6c-1.084 0-2-.916-2-2s.916-2 2-2 2 .916 2 2-.916 2-2 2z"></path>
</svg>
速率限制
</div>
<div id="rate-limits-controls">
<button id="rate-limits-refresh" class="rate-limits-control-button" title="刷新">
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
<path d="M10 11H7.101l.001-.009a4.956 4.956 0 0 1 .752-1.787 5.054 5.054 0 0 1 2.2-1.811c.302-.128.617-.226.938-.291a5.078 5.078 0 0 1 2.018 0 4.978 4.978 0 0 1 2.525 1.361l1.416-1.412a7.036 7.036 0 0 0-2.224-1.501 6.921 6.921 0 0 0-1.315-.408 7.079 7.079 0 0 0-2.819 0 6.94 6.94 0 0 0-1.316.409 7.04 7.04 0 0 0-3.08 2.534 6.978 6.978 0 0 0-1.054 2.505c-.028.135-.043.273-.063.41H2l4 4 4-4zm4 2h2.899l-.001.008a4.976 4.976 0 0 1-2.103 3.138 4.943 4.943 0 0 1-1.787.752 5.073 5.073 0 0 1-2.017 0 4.956 4.956 0 0 1-1.787-.752 5.072 5.072 0 0 1-.74-.61L7.05 16.95a7.032 7.032 0 0 0 2.225 1.5c.424.18.867.317 1.315.408a7.07 7.07 0 0 0 2.818 0 7.031 7.031 0 0 0 4.395-2.945 6.974 6.974 0 0 0 1.053-2.503c.027-.135.043-.273.063-.41H22l-4-4-4 4z"></path>
</svg>
</button>
<button id="rate-limits-close" class="rate-limits-control-button" title="关闭">
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" height="16" width="16" xmlns="http://www.w3.org/2000/svg">
<path d="m16.192 6.344-4.243 4.242-4.242-4.242-1.414 1.414L10.535 12l-4.242 4.242 1.414 1.414 4.242-4.242 4.243 4.242 1.414-1.414L13.364 12l4.242-4.242z"></path>
</svg>
</button>
</div>
</div>
<div id="rate-limits-content">
<div class="rate-limit-section" id="default-rate-limit">
<div class="rate-limit-title">默认请求</div>
<div class="rate-limit-info">
<span>剩余请求数</span>
<span id="default-remaining">--/--</span>
</div>
<div class="rate-limit-progress-container">
<div class="rate-limit-progress-bar" style="width: 0%"></div>
</div>
<div class="rate-limit-time" id="default-time">窗口: -- 小时</div>
</div>
<div class="rate-limit-section" id="reasoning-rate-limit">
<div class="rate-limit-title">推理请求</div>
<div class="rate-limit-info">
<span>剩余请求数</span>
<span id="reasoning-remaining">--/--</span>
</div>
<div class="rate-limit-progress-container">
<div class="rate-limit-progress-bar" style="width: 0%"></div>
</div>
<div class="rate-limit-time" id="reasoning-time">窗口: -- 小时</div>
</div>
<div class="rate-limit-section" id="deepsearch-rate-limit">
<div class="rate-limit-title">深度搜索</div>
<div class="rate-limit-info">
<span>剩余请求数</span>
<span id="deepsearch-remaining">--/--</span>
</div>
<div class="rate-limit-progress-container">
<div class="rate-limit-progress-bar" style="width: 0%"></div>
</div>
<div class="rate-limit-time" id="deepsearch-time">窗口: -- 小时</div>
</div>
</div>
`;
// 如果是调试模式,添加指示器
if (DEBUG_MODE) {
const debugIndicator = document.createElement('div');
debugIndicator.className = 'debug-mode-indicator';
debugIndicator.textContent = 'DEBUG';
container.appendChild(debugIndicator);
}
return container;
}
// 创建徽章元素
function createBadge(type, position = 'end') {
// 创建徽章容器
const badgeContainer = document.createElement('div');
badgeContainer.className = 'badge-container';
badgeContainer.id = `${type.toLowerCase()}-badge-container`;
// 创建徽章
const badge = document.createElement('div');
badge.className = 'rate-limit-badge';
badge.id = `${type.toLowerCase()}-badge`;
badge.textContent = '--/--';
badgeContainer.appendChild(badge);
return badgeContainer;
}
// 更新徽章信息
function updateBadge(type, data) {
const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
if (!badgeContainer) return;
const badge = document.getElementById(`${type.toLowerCase()}-badge`);
if (!badge) return;
const parentElement = badgeContainer.parentElement;
if (!parentElement) return;
if (data) {
const { remainingQueries, totalQueries } = data;
const badgeText = `${remainingQueries}/${totalQueries}`;
badge.textContent = badgeText;
// 移除所有状态类
badge.classList.remove('warning', 'danger');
parentElement.classList.remove('rate-limit-depleted');
// 设置状态
if (remainingQueries === 0) {
badge.classList.add('danger');
parentElement.classList.add('rate-limit-depleted');
} else if (remainingQueries <= 3) {
badge.classList.add('warning');
}
} else {
badge.textContent = '--/--';
badge.classList.remove('warning', 'danger');
parentElement.classList.remove('rate-limit-depleted');
}
}
// 隐藏徽章
function hideBadge(type) {
const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
if (badgeContainer) {
badgeContainer.style.width = '0px';
if (badgeContainer.parentElement && badgeContainer.parentElement.id === 'radix-:r14:') {
badgeContainer.style.marginRight = '0px';
} else {
badgeContainer.style.marginLeft = '0px';
}
}
}
// 显示徽章
function showBadge(type) {
const badgeContainer = document.getElementById(`${type.toLowerCase()}-badge-container`);
const badge = document.getElementById(`${type.toLowerCase()}-badge`);
if (badgeContainer && badge) {
// 计算徽章实际宽度
const tempBadge = badge.cloneNode(true);
tempBadge.style.position = 'absolute';
tempBadge.style.visibility = 'hidden';
tempBadge.style.width = 'auto';
document.body.appendChild(tempBadge);
const badgeWidth = tempBadge.offsetWidth;
document.body.removeChild(tempBadge);
// 设置容器宽度
if (badgeContainer.parentElement && badgeContainer.parentElement.id === 'radix-:r14:') {
badgeContainer.style.width = `${badgeWidth}px`;
badgeContainer.style.marginRight = '6px';
} else {
badgeContainer.style.width = `${badgeWidth}px`;
badgeContainer.style.marginLeft = '6px';
}
}
}
// 将秒转换为小时,保留一位小数
function secondsToHours(seconds) {
return (seconds / 3600).toFixed(1);
}
// 更新速率限制信息
function updateRateLimitInfo(type, data) {
const section = document.getElementById(`${type.toLowerCase()}-rate-limit`);
if (!section) return;
const remaining = document.getElementById(`${type.toLowerCase()}-remaining`);
const timeElement = document.getElementById(`${type.toLowerCase()}-time`);
const progressBar = section.querySelector('.rate-limit-progress-bar');
// 如果是调试模式,使用调试值
let displayData = data;
if (DEBUG_MODE && DEBUG_VALUES[type]) {
displayData = DEBUG_VALUES[type];
}
if (displayData) {
const { remainingQueries, totalQueries, windowSizeSeconds } = displayData;
const percentage = (remainingQueries / totalQueries) * 100;
remaining.textContent = `${remainingQueries}/${totalQueries}`;
// 将秒转换为小时显示
timeElement.textContent = `窗口: ${secondsToHours(windowSizeSeconds)} 小时`;
progressBar.style.width = `${percentage}%`;
// 设置颜色状态
section.classList.remove('rate-limit-warning', 'rate-limit-danger');
if (remainingQueries === 0) {
section.classList.add('rate-limit-danger');
} else if (remainingQueries <= 3) {
section.classList.add('rate-limit-warning');
}
// 更新徽章
updateBadge(type, displayData);
} else {
remaining.textContent = '--/--';
timeElement.textContent = '窗口: -- 小时';
progressBar.style.width = '0%';
updateBadge(type, null);
}
}
// 发送速率限制请求
async function fetchRateLimit(type) {
// 如果是调试模式,直接使用调试值并更新UI
if (DEBUG_MODE && DEBUG_VALUES[type]) {
updateRateLimitInfo(type, DEBUG_VALUES[type]);
return DEBUG_VALUES[type];
}
try {
const response = await fetch('/rest/rate-limits', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
requestKind: type,
modelName: 'grok-3'
})
});
if (response.ok) {
const data = await response.json();
updateRateLimitInfo(type, data);
return data;
} else {
console.error(`获取${type}速率限制失败:`, response.status);
updateRateLimitInfo(type, null);
}
} catch (error) {
console.error(`获取${type}速率限制出错:`, error);
updateRateLimitInfo(type, null);
}
return null;
}
// 刷新所有速率限制
async function refreshAllRateLimits() {
if (DEBUG_MODE) {
// 在调试模式下,直接使用调试值更新所有类型
updateRateLimitInfo('DEFAULT', DEBUG_VALUES['DEFAULT']);
updateRateLimitInfo('REASONING', DEBUG_VALUES['REASONING']);
updateRateLimitInfo('DEEPSEARCH', DEBUG_VALUES['DEEPSEARCH']);
// 更新上次刷新时间
lastRefreshTime = Date.now();
scheduleNextRefresh();
return;
}
// 非调试模式下,正常请求API
await Promise.all([
fetchRateLimit('DEFAULT'),
fetchRateLimit('REASONING'),
fetchRateLimit('DEEPSEARCH')
]);
// 更新上次刷新时间
lastRefreshTime = Date.now();
scheduleNextRefresh();
}
// 为指定按钮添加徽章
function addBadgesToButtons() {
// 为DeepSearch按钮添加徽章
const deepSearchButton = document.querySelector('button.overflow-hidden:nth-child(1)');
if (deepSearchButton && !deepSearchButton.querySelector('#deepsearch-badge-container')) {
const badge = createBadge('DEEPSEARCH');
deepSearchButton.appendChild(badge);
// 添加鼠标事件
deepSearchButton.addEventListener('mouseenter', () => showBadge('DEEPSEARCH'));
deepSearchButton.addEventListener('mouseleave', () => hideBadge('DEEPSEARCH'));
// 如果是调试模式,立即更新徽章
if (DEBUG_MODE && DEBUG_VALUES['DEEPSEARCH']) {
updateBadge('DEEPSEARCH', DEBUG_VALUES['DEEPSEARCH']);
}
}
// 为Think按钮添加徽章
const thinkButton = document.querySelector('button.gap-2:nth-child(2)');
if (thinkButton && !thinkButton.querySelector('#reasoning-badge-container')) {
const badge = createBadge('REASONING');
thinkButton.appendChild(badge);
// 添加鼠标事件
thinkButton.addEventListener('mouseenter', () => showBadge('REASONING'));
thinkButton.addEventListener('mouseleave', () => hideBadge('REASONING'));
// 如果是调试模式,立即更新徽章
if (DEBUG_MODE && DEBUG_VALUES['REASONING']) {
updateBadge('REASONING', DEBUG_VALUES['REASONING']);
}
}
// 为grok3按钮添加徽章 - 在最前方插入
const grokButton = document.querySelector('#radix-\\:r14\\:');
if (grokButton && !grokButton.querySelector('#default-badge-container')) {
const badge = createBadge('DEFAULT', 'start');
grokButton.insertBefore(badge, grokButton.firstChild);
// 添加鼠标事件
grokButton.addEventListener('mouseenter', () => showBadge('DEFAULT'));
grokButton.addEventListener('mouseleave', () => hideBadge('DEFAULT'));
// 如果是调试模式,立即更新徽章
if (DEBUG_MODE && DEBUG_VALUES['DEFAULT']) {
updateBadge('DEFAULT', DEBUG_VALUES['DEFAULT']);
}
}
}
// 拦截 fetch 请求
const originalFetch = window.fetch;
window.fetch = async function(input, init) {
const response = await originalFetch(input, init);
// 如果是调试模式,不处理实际API响应
if (DEBUG_MODE) {
return response;
}
// 克隆响应以便我们可以读取它
if (input && input.toString().includes('/rest/rate-limits')) {
const clonedResponse = response.clone();
try {
const data = await clonedResponse.json();
if (init && init.body) {
const body = JSON.parse(init.body);
updateRateLimitInfo(body.requestKind, data);
lastRefreshTime = Date.now();
scheduleNextRefresh();
}
} catch (e) {
console.error('解析速率限制响应失败:', e);
}
}
return response;
};
// 拦截 XMLHttpRequest
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...args) {
this._url = url;
return originalXHROpen.apply(this, [method, url, ...args]);
};
XMLHttpRequest.prototype.send = function(body) {
// 如果是调试模式,不处理实际API响应
if (DEBUG_MODE) {
return originalXHRSend.apply(this, arguments);
}
if (this._url && this._url.toString().includes('/rest/rate-limits')) {
const originalOnLoad = this.onload;
this.onload = function() {
try {
if (this.responseText) {
const data = JSON.parse(this.responseText);
if (body) {
const requestBody = JSON.parse(body);
updateRateLimitInfo(requestBody.requestKind, data);
lastRefreshTime = Date.now();
scheduleNextRefresh();
}
}
} catch (e) {
console.error('解析速率限制响应失败:', e);
}
if (originalOnLoad) {
originalOnLoad.apply(this);
}
};
}
return originalXHRSend.apply(this, arguments);
};
// 设置定时刷新
let refreshTimer = null;
let lastRefreshTime = 0;
const REFRESH_INTERVAL = 10 * 60 * 1000; // 10分钟
function scheduleNextRefresh() {
if (refreshTimer) {
clearTimeout(refreshTimer);
}
const timeUntilNextRefresh = Math.max(0, REFRESH_INTERVAL - (Date.now() - lastRefreshTime));
refreshTimer = setTimeout(refreshAllRateLimits, timeUntilNextRefresh);
}
// 拖拽功能
function enableDrag(element, handle) {
let isDragging = false;
let offsetX, offsetY;
handle.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - element.getBoundingClientRect().left;
offsetY = e.clientY - element.getBoundingClientRect().top;
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
// 确保窗口不会超出屏幕
const maxX = window.innerWidth - element.offsetWidth;
const maxY = window.innerHeight - element.offsetHeight;
element.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
element.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
});
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
// 保存位置
GM_setValue('rateLimitsPosition', {
x: parseInt(element.style.left),
y: parseInt(element.style.top)
});
}
});
}
// 监视DOM变化,为按钮添加徽章
function setupButtonBadgeObserver() {
const observer = new MutationObserver(() => {
addBadgesToButtons();
});
observer.observe(document.body, { childList: true, subtree: true });
}
// 初始化函数
function initialize() {
// 等待目标元素加载
const targetSelector = 'div.absolute:nth-child(3)';
const observer = new MutationObserver((mutations, obs) => {
const targetElement = document.querySelector(targetSelector);
if (targetElement) {
obs.disconnect();
// 创建按钮和容器
const button = createRateLimitsButton();
const container = createRateLimitsContainer();
// 添加到页面的最前面
if (targetElement.firstChild) {
targetElement.insertBefore(button, targetElement.firstChild);
} else {
targetElement.appendChild(button);
}
document.body.appendChild(container);
// 启用拖拽
const handle = document.getElementById('rate-limits-header');
enableDrag(container, handle);
// 绑定事件
button.addEventListener('click', () => {
const isVisible = container.style.display !== 'none';
container.style.display = isVisible ? 'none' : 'block';
GM_setValue('rateLimitsVisible', isVisible ? 'none' : 'block');
});
document.getElementById('rate-limits-refresh').addEventListener('click', refreshAllRateLimits);
document.getElementById('rate-limits-close').addEventListener('click', () => {
container.style.display = 'none';
GM_setValue('rateLimitsVisible', 'none');
});
// 初始加载数据
refreshAllRateLimits();
// 设置按钮徽章观察器
setupButtonBadgeObserver();
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
// 启动脚本
initialize();
})();
3. grok 添加上传文件
来源自 让 Grok 支持上传文件 - 开发调优 / 开发调优, Lv1 - LINUX DO
// ==UserScript==
// @name Grok 添加上传文件按钮
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 给 Grok 加上“上传文件按钮”
// @author [email protected] & claude-3-7-sonnet
// @match https://grok.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Function to find the target div and add the upload button
function addUploadButton() {
// Find the target div - using a selector that matches the structure provided
const targetDiv = document.querySelector('.grow.flex.gap-1\\.5.max-w-full');
if (!targetDiv) {
console.log('Target div not found. Retrying in 1 second...');
setTimeout(addUploadButton, 1000);
return;
}
// Check if button already exists to avoid duplicates
if (document.getElementById('custom-upload-button')) {
return;
}
// Create the button element
const uploadButton = document.createElement('button');
uploadButton.id = 'custom-upload-button';
uploadButton.className = 'gap-2 whitespace-nowrap text-sm font-medium leading-[normal] cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 disabled:cursor-default [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:-mx-0.5 text-primary h-9 rounded-full px-3.5 py-2 border border-toggle-border overflow-hidden flex items-center justify-center bg-transparent hover:bg-toggle-hover';
uploadButton.type = 'button';
uploadButton.tabIndex = '0';
uploadButton.setAttribute('aria-pressed', 'false');
uploadButton.setAttribute('data-state', 'closed');
// Create SVG icon for the button
const svgIcon = `
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="stroke-[2] text-secondary">
<path d="M12 15V3M12 3L7 8M12 3L17 8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M20 17V19C20 20.1046 19.1046 21 18 21H6C4.89543 21 4 20.1046 4 19V17" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`;
// Set button content with icon and text
uploadButton.innerHTML = svgIcon + '<span>上传文件</span>';
// Create hidden file input element
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.style.display = 'none';
fileInput.id = 'hidden-file-input';
document.body.appendChild(fileInput);
// Add click event to the upload button
uploadButton.addEventListener('click', function() {
fileInput.click();
});
// Add change event to the file input
fileInput.addEventListener('change', function(event) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
handleFileUpload(file);
}
});
// Add the button to the target div
targetDiv.appendChild(uploadButton);
console.log('Upload button added successfully');
}
// Function to handle file upload
function handleFileUpload(file) {
console.log('File selected:', file.name);
// You may need to customize this part based on how the website handles uploads
// Option 1: If the website uses clipboard events, simulate a paste event
try {
// Create a ClipboardItem and add it to the clipboard
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
// Create and dispatch a paste event
const pasteEvent = new ClipboardEvent('paste', {
clipboardData: dataTransfer,
bubbles: true
});
document.activeElement.dispatchEvent(pasteEvent);
console.log('Paste event dispatched');
} catch (error) {
console.error('Error simulating paste:', error);
// Option 2: If the website uses XMLHttpRequest or fetch for uploads
// This is a placeholder - you'll need to customize this based on the actual upload endpoint
const formData = new FormData();
formData.append('file', file);
// Example upload code - replace URL with the actual upload endpoint
/*
fetch('/upload-endpoint', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log('Upload successful:', data);
})
.catch(error => {
console.error('Error uploading file:', error);
});
*/
}
}
// Run the function after the page loads
window.addEventListener('load', addUploadButton);
// Also run it after a short delay in case the div is added dynamically
setTimeout(addUploadButton, 2000);
// Optional: Set up a MutationObserver to detect if the target div appears later
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
addUploadButton();
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
4. grok 显示用量
来源自 你们的网页版 grok 3 用超标过吗? - #8,来自 lkw123
// ==UserScript==
// @name Grok Helper
// @namespace https://github.com/BlueSkyXN/GPT-Models-Plus
// @version 0.1.1
// @author BlueSkyXN
// @description Monitor Grok API rate limits (DEFAULT, REASONING, DEEPSEARCH), show summary + detail on hover
// @match https://grok.com/*
// @match https://ubiquitous-lolly-397934.netlify.app/*
// @grant GM_addStyle
// @supportURL https://github.com/BlueSkyXN/GPT-Models-Plus
// @homepageURL https://github.com/BlueSkyXN/GPT-Models-Plus
// @downloadURL https://github.com/BlueSkyXN/GPT-Models-Plus/blob/main/GrokHelper.js
// @updateURL https://github.com/BlueSkyXN/GPT-Models-Plus/blob/main/GrokHelper.js
// ==/UserScript==
(function() {
'use strict';
// 三种模式 -> 中文名称对应表
const MODE_LABELS = {
DEFAULT: '标准',
REASONING: '思考',
DEEPSEARCH: '深度'
};
// 我们需要查询的三种模式
const REQUEST_KINDS = Object.keys(MODE_LABELS);
// 添加自定义样式
GM_addStyle(`
.grok-monitor {
position: fixed;
left: 16px;
top: 72px; /* 位于 logo 下方 */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
z-index: 100;
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 8px 12px;
gap: 8px;
border: 1px solid #ccc; /* 灰色圆角线始终显示 */
border-radius: 8px;
background-color: #fff; /* 背景白色,可按需改 */
color: #1a1a1a;
box-shadow: 0 2px 4px rgba(0,0,0,0.08); /* 轻微投影,可选 */
transition: all 0.2s ease;
opacity: 0.9;
}
/* 悬浮时增加不透明度 */
.grok-monitor:hover {
opacity: 1;
}
/* 小版本:只显示总结行 */
.grok-monitor-summary {
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
font-weight: 500;
font-size: 14px;
}
/* 指示灯 */
.grok-monitor-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
flex-shrink: 0;
transition: background-color 0.2s ease;
}
/* 大版本:详细行,默认隐藏,悬浮时显示 */
.grok-monitor-details {
display: none; /* 默认隐藏 */
flex-direction: column;
gap: 4px;
font-size: 13px;
}
/* 悬浮时让 details 显示 */
.grok-monitor:hover .grok-monitor-details {
display: flex;
}
.grok-monitor-kind-row {
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
}
.grok-monitor-kind-name {
font-weight: 600;
}
/* 更新动画(请求中时可以使用) */
.grok-monitor.updating .grok-monitor-indicator {
animation: pulse 1s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.2);
opacity: 0.7;
}
}
/* 深色模式下可自行调整 */
@media (prefers-color-scheme: dark) {
.grok-monitor {
background-color: #2b2b2b;
color: #fff;
border-color: #666;
}
}
`);
// 工具函数:格式化等待时间
function formatWaitTime(seconds) {
if (seconds <= 0) return '0m';
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
if (hours > 0 && minutes > 0) {
return `${hours}h${minutes}m`;
} else if (hours > 0) {
return `${hours}h`;
} else {
return `${minutes}m`;
}
}
// 创建监控器UI
function createMonitor() {
const monitor = document.createElement('div');
monitor.className = 'grok-monitor';
// ---- 小版本(默认显示) ----
const summaryRow = document.createElement('div');
summaryRow.className = 'grok-monitor-summary';
// 剩余次数总和文本
const sumSpan = document.createElement('span');
sumSpan.textContent = '剩余总数: ...';
// 指示灯
const indicator = document.createElement('div');
indicator.className = 'grok-monitor-indicator';
summaryRow.appendChild(sumSpan);
summaryRow.appendChild(indicator);
// ---- 大版本(悬浮后展开) ----
const details = document.createElement('div');
details.className = 'grok-monitor-details';
// 为每种模式添加一行
REQUEST_KINDS.forEach(kind => {
const row = document.createElement('div');
row.className = 'grok-monitor-kind-row';
// 中文名称
const nameSpan = document.createElement('span');
nameSpan.className = 'grok-monitor-kind-name';
nameSpan.textContent = MODE_LABELS[kind];
// 剩余/等待 文本
const infoSpan = document.createElement('span');
infoSpan.textContent = '...';
row.appendChild(nameSpan);
row.appendChild(infoSpan);
details.appendChild(row);
});
// 组装
monitor.appendChild(summaryRow);
monitor.appendChild(details);
document.body.appendChild(monitor);
return monitor;
}
// 获取当前域名的基础URL
function getBaseUrl() {
return window.location.origin;
}
// 获取每种模式的限额
async function fetchRateLimit(kind) {
try {
// 使用动态的基础URL
const baseUrl = getBaseUrl();
const response = await fetch(`${baseUrl}/rest/rate-limits`, {
method: 'POST',
headers: {
'accept': '*/*',
'content-type': 'application/json'
},
body: JSON.stringify({
requestKind: kind,
modelName: "grok-3"
}),
credentials: 'include'
});
if (response.ok) {
return await response.json();
} else {
throw new Error(`Failed to fetch ${kind} rate limit`);
}
} catch (error) {
console.error('Rate limit check failed:', error);
return null;
}
}
// 一次获取所有模式数据
async function getAllRateLimits() {
const results = {};
for (const kind of REQUEST_KINDS) {
// 可改成 Promise.all 并行请求,这里顺序也行
results[kind] = await fetchRateLimit(kind);
}
return results;
}
// 更新UI
function updateUI(results) {
const monitor = document.querySelector('.grok-monitor');
const sumSpan = monitor.querySelector('.grok-monitor-summary span');
const indicator = monitor.querySelector('.grok-monitor-indicator');
// 给指示灯加 "updating" 动画效果
monitor.classList.add('updating');
// 计算合计剩余次数
let sum = 0;
REQUEST_KINDS.forEach(kind => {
const data = results[kind];
if (data && data.remainingQueries > 0) {
sum += data.remainingQueries;
}
});
// 小版本文本:合计剩余
sumSpan.textContent = `剩余总数: ${sum}`;
// 指示灯颜色
if (sum === 0) {
indicator.style.backgroundColor = '#EF4444'; // 红色
} else if (sum > 0 && sum < 5) {
indicator.style.backgroundColor = '#F59E0B'; // 黄色
} else {
indicator.style.backgroundColor = '#10B981'; // 绿色
}
// 更新大版本详细数据
const detailRows = monitor.querySelectorAll('.grok-monitor-kind-row');
detailRows.forEach(row => {
const label = row.querySelector('.grok-monitor-kind-name').textContent;
const kind = Object.keys(MODE_LABELS).find(k => MODE_LABELS[k] === label);
const data = results[kind];
const infoSpan = row.querySelector('span:nth-child(2)');
if (!data) {
infoSpan.textContent = '获取失败';
return;
}
const { remainingQueries, waitTimeSeconds } = data;
if (remainingQueries > 0) {
infoSpan.textContent = `剩余: ${remainingQueries}`;
} else {
infoSpan.textContent = `等待: ${formatWaitTime(waitTimeSeconds)}`;
}
});
// 1s 后移除更新动画
setTimeout(() => monitor.classList.remove('updating'), 1000);
}
// 定时检查
async function checkRateLimits() {
const results = await getAllRateLimits();
updateUI(results);
}
// 初始化
function init() {
createMonitor();
checkRateLimits(); // 立即检查一次
setInterval(checkRateLimits, 30000); // 每 30s 检查
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
5. fuclaude seesion切换
来自于 我和claude合作的切换sessionKey的油猴脚本,同时参考了几位大佬的帖子,适用于fuclaude! - 资源荟萃 - LINUX DO
个人更改
// ==UserScript==
// @name claudeSessionKeySwitch
// @version 2.4
// @description 使用sessionKey自动登录claude(可拖拽圆形图标,双击显示选项面板)
// @match https://claude.ai/*
// @match https://demo.fuclaude.com/*
// @match https://claude.asia/*
// @grant GM_setValue
// @grant GM_getValue
// @license GNU GPLv3
// @namespace https://greasyfork.org/users/1337296
// ==/UserScript==
(function() {
'use strict';
const tokens = [
{name: 'name', key: 'key'},
];
const createElem = (tag, styles) => {
const elem = document.createElement(tag);
Object.assign(elem.style, styles);
return elem;
};
// Get saved position or use defaults
const savedPosition = {
left: GM_getValue('buttonLeft', 10),
bottom: GM_getValue('buttonBottom', 10)
};
// Create circular toggle button
const toggleButton = createElem('button', {
width: '30px',
height: '30px',
borderRadius: '50%',
backgroundColor: '#faf9f5',
color: '#007bff',
cursor: 'move',
position: 'fixed',
bottom: `${savedPosition.bottom}px`,
left: `${savedPosition.left}px`,
zIndex: '10000',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
boxShadow: '0 2px 5px rgba(0,0,0,0.1)',
transition: 'background-color 0.3s ease',
outline: 'none',
padding: '0',
userSelect: 'none',
touchAction: 'none'
});
toggleButton.innerHTML = '🔑';
const dropdownContainer = createElem('div', {
position: 'fixed',
backgroundColor: '#faf9f5',
padding: '20px',
borderRadius: '12px',
boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
display: 'none',
flexDirection: 'column',
gap: '15px',
width: '500px',
maxHeight: '80vh',
overflowY: 'auto',
zIndex: '9999',
border: '1px solid #e0e0e0',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)'
});
// Add title
const titleContainer = createElem('div', {
marginBottom: '15px',
textAlign: 'center',
borderBottom: '2px solid #eee',
paddingBottom: '10px'
});
titleContainer.innerHTML = '<h2 style="margin:0;color:#333;font-size:18px;">Claude Session Key Switch</h2>';
dropdownContainer.appendChild(titleContainer);
// Create grid container for tokens
const gridContainer = createElem('div', {
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: '10px',
margin: '10px 0'
});
// Get saved switch times
const switchTimes = GM_getValue('switchTimes', {});
tokens.forEach(token => {
const tokenCard = createElem('div', {
padding: '15px',
borderRadius: '8px',
backgroundColor: '#fff',
border: '1px solid #ddd',
cursor: 'pointer',
transition: 'all 0.3s ease'
});
const lastSwitchTime = switchTimes[token.name] || '未使用';
// 计算时间差
let color = '#666'; // 默认颜色
if(lastSwitchTime !== '未使用') {
const fiveHoursInMs = 5 * 60 * 60 * 1000; // 5小时转换为毫秒
const switchTimestamp = new Date(lastSwitchTime).getTime();
const currentTime = new Date().getTime();
// 如果时间差大于5小时显示红色,否则显示绿色
color = currentTime - switchTimestamp > fiveHoursInMs ? 'green' : 'red';
}
tokenCard.innerHTML = `
<div style="font-weight:bold;color:#333;margin-bottom:5px">${token.name}</div>
<div style="font-size:12px;">上次切换: <span style="color:${color}">${lastSwitchTime}</span></div>
`;
tokenCard.addEventListener('mouseover', () => {
tokenCard.style.backgroundColor = '#f0f7ff';
tokenCard.style.borderColor = '#007bff';
});
tokenCard.addEventListener('mouseout', () => {
tokenCard.style.backgroundColor = '#fff';
tokenCard.style.borderColor = '#ddd';
});
tokenCard.addEventListener('click', () => {
// Update switch time
const now = new Date().toLocaleString('zh-CN');
switchTimes[token.name] = now;
GM_setValue('switchTimes', switchTimes);
// Update display
tokenCard.querySelector('div:last-child').textContent = `上次切换: ${now}`;
// Store selection and trigger login
localStorage.setItem('claudeSelectedToken', token.key);
handleTokenSelection(token.key);
});
gridContainer.appendChild(tokenCard);
});
dropdownContainer.appendChild(gridContainer);
// Add info section
const infoSection = createElem('div', {
marginTop: '15px',
padding: '10px',
backgroundColor: '#f8f9fa',
borderRadius: '6px',
fontSize: '12px',
color: '#666'
});
infoSection.innerHTML = '双击按钮展开/收起面板 • 拖拽按钮调整位置';
dropdownContainer.appendChild(infoSection);
let isDragging = false;
let startX, startY;
let buttonLeft = savedPosition.left;
let buttonBottom = savedPosition.bottom;
function onMouseDown(e) {
if (e.target === toggleButton) {
isDragging = true;
const buttonRect = toggleButton.getBoundingClientRect();
startX = e.clientX - buttonRect.left;
startY = e.clientY - buttonRect.top;
toggleButton.style.cursor = 'grabbing';
}
}
function onMouseMove(e) {
if (!isDragging) return;
e.preventDefault();
const newLeft = e.clientX - startX;
const newTop = e.clientY - startY;
// Calculate bottom position from top
const bottom = window.innerHeight - newTop - toggleButton.offsetHeight;
// Ensure button stays within window bounds
const maxLeft = window.innerWidth - toggleButton.offsetWidth;
const maxBottom = window.innerHeight - toggleButton.offsetHeight;
buttonLeft = Math.min(Math.max(newLeft, 0), maxLeft);
buttonBottom = Math.min(Math.max(bottom, 0), maxBottom);
// Update button position
toggleButton.style.left = `${buttonLeft}px`;
toggleButton.style.bottom = `${buttonBottom}px`;
toggleButton.style.top = 'auto';
}
function onMouseUp() {
if (isDragging) {
isDragging = false;
toggleButton.style.cursor = 'move';
// Save position to GM storage
GM_setValue('buttonLeft', buttonLeft);
GM_setValue('buttonBottom', buttonBottom);
}
}
// Double click detection
let lastClickTime = 0;
toggleButton.addEventListener('click', (e) => {
const clickTime = new Date().getTime();
const timeDiff = clickTime - lastClickTime;
if (timeDiff < 300) { // Double click threshold
dropdownContainer.style.display = dropdownContainer.style.display === 'none' ? 'flex' : 'none';
e.stopPropagation();
}
lastClickTime = clickTime;
});
// Add drag events
toggleButton.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
// Close dropdown when clicking outside
document.addEventListener('click', (e) => {
if (!dropdownContainer.contains(e.target) && e.target !== toggleButton) {
dropdownContainer.style.display = 'none';
}
});
function handleTokenSelection(token) {
if (token === '') {
console.log('Empty token selected. No action taken.');
} else {
autoLogin(token);
}
}
function autoLogin(token) {
const currentURL = window.location.href;
let loginUrl;
if (currentURL.startsWith('https://demo.fuclaude.com/')) {
loginUrl = `https://demo.fuclaude.com/login_token?session_key=${token}`;
} else if (currentURL.startsWith('https://claude.asia/')) {
loginUrl = `https://claude.asia/login_token?session_key=${token}`;
} else {
loginUrl = `https://demo.fuclaude.com/login_token?session_key=${token}`;
}
window.location.href = loginUrl;
}
// Initialize the UI
document.body.appendChild(dropdownContainer);
document.body.appendChild(toggleButton);
})();
6. GitHub 中文化插件
开源地址 maboloshi/github-chinese: GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese)
安装地址
7. 网盘有效性检查
网盘助手,自动识别并检查链接状态,自动填写密码并跳转。现已支持 百度网盘
蓝奏云
腾讯微云
阿里云盘
天翼云盘
123网盘
迅雷云盘
夸克网盘
奶牛网盘
文叔叔
115网盘
移动彩云
// @note 支持百度云、蓝奏云、腾讯微云、阿里云盘、天翼云盘、123网盘、夸克网盘、迅雷网盘、奶牛网盘、文叔叔、115网盘
8. 星号密码显示助手
当鼠标停留在密码框时显示星号密码。再也不担心忘记密码和输错密码了。
开源地址
安装地址
大家可以推荐一下自己在用的。