您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button to copy SteamCMD workshop download commands
- // ==UserScript==
- // @name Steam Workshop Copy SteamCMD Button
- // @namespace http://steamcommunity.com/
- // @version 1.0
- // @description Adds a button to copy SteamCMD workshop download commands
- // @author TheFantasticLoki
- // @match https://steamcommunity.com/sharedfiles/filedetails/*
- // @grant GM_setClipboard
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- // Function to extract item ID from URL
- function getWorkshopItemIdFromUrl() {
- const urlParams = new URLSearchParams(window.location.search);
- return urlParams.get('id');
- }
- // Function to find game ID
- function getGameId() {
- // Look for game ID in breadcrumbs
- const breadcrumbs = document.querySelectorAll('.breadcrumbs a');
- for (const crumb of breadcrumbs) {
- const href = crumb.getAttribute('href');
- if (href && href.includes('/app/')) {
- const match = href.match(/\/app\/(\d+)/);
- if (match && match[1]) {
- return match[1];
- }
- }
- }
- // Alternative method: look for game app link
- const appLinks = document.querySelectorAll('a[href*="/app/"]');
- for (const link of appLinks) {
- const match = link.href.match(/\/app\/(\d+)/);
- if (match && match[1]) {
- return match[1];
- }
- }
- return null;
- }
- function createCopyButton(gameId, workshopItemId) {
- // Create styles for our custom elements
- const styleEl = document.createElement('style');
- styleEl.textContent = `
- .steam_cmd_copy_btn {
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- width: 33px;
- height: 33px;
- background: #3d6c8d;
- border-radius: 4px;
- margin: 0 5px;
- transition: background 0.2s;
- position: relative;
- }
- .steam_cmd_copy_btn:hover {
- background: #67c1f5;
- }
- .steam_cmd_copy_btn svg {
- width: 25px;
- height: 25px;
- vertical-align: middle;
- fill: white;
- }
- .steam_cmd_copy_tooltip {
- display: none;
- position: fixed;
- background-color: #171a21;
- color: #fff;
- text-align: center;
- border-radius: 3px;
- padding: 8px 12px;
- z-index: 9999;
- border: 1px solid #4d4d4d;
- white-space: nowrap;
- font-size: 12px;
- box-shadow: 0 0 5px rgba(0,0,0,0.3);
- pointer-events: none;
- }
- .steam_cmd_command {
- font-family: monospace;
- background: #32353c;
- padding: 4px 6px;
- border-radius: 2px;
- margin-top: 5px;
- display: block;
- }
- `;
- document.head.appendChild(styleEl);
- // Create the button element
- const copyButton = document.createElement('div');
- copyButton.className = 'steam_cmd_copy_btn';
- // Create SVG icon for clipboard
- copyButton.innerHTML = `
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
- <path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/>
- </svg>
- `;
- // Create tooltip as a separate element attached to body
- const tooltip = document.createElement('div');
- tooltip.className = 'steam_cmd_copy_tooltip';
- tooltip.innerHTML = `Copy SteamCMD<span class="steam_cmd_command">workshop_download_item ${gameId} ${workshopItemId}</span>`;
- document.body.appendChild(tooltip);
- // Handle tooltip positioning
- copyButton.addEventListener('mouseenter', function(e) {
- const rect = copyButton.getBoundingClientRect();
- tooltip.style.display = 'block';
- // Position tooltip above the button
- tooltip.style.left = rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2) + 'px';
- tooltip.style.top = rect.top - tooltip.offsetHeight - 10 + 'px';
- // If tooltip would go off the top, show it below instead
- if (rect.top - tooltip.offsetHeight < 0) {
- tooltip.style.top = rect.bottom + 10 + 'px';
- }
- });
- copyButton.addEventListener('mouseleave', function() {
- tooltip.style.display = 'none';
- });
- // Add click event to copy the command
- copyButton.addEventListener('click', function(e) {
- e.preventDefault();
- e.stopPropagation();
- const command = `workshop_download_item ${gameId} ${workshopItemId}`;
- GM_setClipboard(command);
- // Visual feedback
- tooltip.innerHTML = 'Copied!';
- setTimeout(function() {
- tooltip.innerHTML = `Copy SteamCMD<span class="steam_cmd_command">workshop_download_item ${gameId} ${workshopItemId}</span>`;
- }, 2000);
- });
- // Clean up tooltip when button is removed
- const cleanupTooltip = new MutationObserver(function(mutations) {
- if (!document.body.contains(copyButton)) {
- tooltip.remove();
- cleanupTooltip.disconnect();
- }
- });
- cleanupTooltip.observe(document.body, { childList: true, subtree: true });
- return copyButton;
- }
- // Main function to run when page is loaded
- function addCopyButtons() {
- // Check if we've already run
- if (document.querySelector('.steam_cmd_copy_btn')) {
- return; // Skip if buttons already exist
- }
- const gameId = getGameId();
- if (!gameId) {
- console.log('Could not find game ID');
- return;
- }
- // First check for single item page
- const singleSubscribeButton = document.getElementById('SubscribeItemBtn');
- if (singleSubscribeButton) {
- const workshopItemId = getWorkshopItemIdFromUrl();
- if (workshopItemId) {
- // Find the parent div of the subscribe button
- const subscribeButtonContainer = singleSubscribeButton.closest('div');
- if (subscribeButtonContainer && subscribeButtonContainer.parentNode) {
- // Create a new container div for our button
- const copyButtonContainer = document.createElement('div');
- copyButtonContainer.style.display = 'inline-block';
- copyButtonContainer.style.marginLeft = '5px';
- // Add the copy button to its container
- const copyButton = createCopyButton(gameId, workshopItemId);
- copyButtonContainer.appendChild(copyButton);
- // Insert after the subscribe button's container
- subscribeButtonContainer.parentNode.insertBefore(
- copyButtonContainer,
- subscribeButtonContainer.nextSibling
- );
- }
- }
- return;
- }
- // Collection page handling - targeting the exact structure seen in collections
- const subscriptionControls = document.querySelectorAll('.subscriptionControls');
- subscriptionControls.forEach(controlsDiv => {
- // Check if we already added a button here
- if (controlsDiv.querySelector('.steam_cmd_copy_btn')) {
- return;
- }
- // Find the subscribe button inside this controls div
- const subscribeButton = controlsDiv.querySelector('[id^="SubscribeItemBtn"]');
- if (subscribeButton) {
- // Extract workshop ID from button ID (format: SubscribeItemBtn###)
- const match = subscribeButton.id.match(/SubscribeItemBtn(\d+)/);
- if (match && match[1]) {
- const workshopItemId = match[1];
- // Create copy button
- const copyButton = createCopyButton(gameId, workshopItemId);
- // Directly append to the controls div instead of creating a new container
- controlsDiv.appendChild(copyButton);
- }
- }
- });
- }
- // Use mutation observer to run when content changes (for dynamic loading)
- function initObserver() {
- const observer = new MutationObserver((mutations) => {
- for (const mutation of mutations) {
- if (mutation.addedNodes.length) {
- addCopyButtons();
- }
- }
- });
- observer.observe(document.body, { childList: true, subtree: true });
- }
- // Check if the page is already loaded
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
- addCopyButtons();
- initObserver();
- } else {
- // Wait for page to load
- window.addEventListener('DOMContentLoaded', () => {
- addCopyButtons();
- initObserver();
- });
- }
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址