您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automate badge granting on IMVU avatars page with pop-out interface and clean layout
- // ==UserScript==
- // @name IMVU Badge Granting Automation (Improved UI with URL-based Username)
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description Automate badge granting on IMVU avatars page with pop-out interface and clean layout
- // @author heapsofjoy
- // @match https://avatars.imvu.com/*
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- // Extract username from the URL
- const getUsernameFromUrl = () => {
- const url = window.location.href; // Get the current URL
- console.log("Current URL:", url); // Debugging: check if URL is correct
- const match = url.match(/https:\/\/avatars\.imvu\.com\/([A-Za-z0-9_]+)/); // Match the username part in the URL
- if (match) {
- console.log("Username extracted from URL:", match[1]); // Debugging: show username extracted
- return match[1];
- } else {
- console.error("Username extraction failed from URL."); // Error if username isn't found
- return null;
- }
- };
- // Fetch CID for the entered username
- const getCid = (name) => {
- return fetch(`https://api.imvu.com/user?username=${name}`, { credentials: 'include' })
- .then(response => response.json())
- .then(data => {
- return Object.entries(data.denormalized)[0][1].data.legacy_cid;
- })
- .catch(err => {
- console.error("Error fetching CID:", err); // Debugging: if fetch fails
- });
- };
- // Start granting badges
- let cancelGranting = false; // Flag to control the cancellation of the badge granting process
- const startGrantingBadges = async (referrer, outputBox, titleElement) => {
- const cid = await getCid(referrer);
- if (!cid) {
- showProgress(outputBox, 'Error: Unable to get CID for the username.');
- return;
- }
- // Function to grant a badge
- const func = async (i) => {
- if (cancelGranting) return; // Stop if the user has clicked the stop button
- // Grant the badge
- const response = await fetch('https://avatars.imvu.com/api/service/grant_badge.php', {
- credentials: 'include', // Include credentials (cookies/session info)
- headers: {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0',
- 'Accept': '*/*',
- 'Accept-Language': 'en-US,en;q=0.5',
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- 'X-Requested-With': 'XMLHttpRequest',
- },
- referrer: `https://avatars.imvu.com/${referrer}`,
- body: `sauce=${IMVU.sauce}&badgeid=badge-${cid}-${i}`,
- method: 'POST',
- mode: 'cors',
- });
- // If the badge was granted (check for successful response)
- if (response.ok) {
- showProgress(outputBox, `Granted badge #${i}`);
- } else {
- showProgress(outputBox, `Failed to grant badge #${i}. Trying next.`);
- }
- };
- // Recursive function to iterate badge granting
- const recursive = async (i) => {
- if (cancelGranting) return; // Stop if the user has clicked the stop button
- setTimeout(async () => {
- await func(i); // Try granting the badge
- recursive(i + 1); // Move to the next badge
- }, 2500); // Delay between badge granting
- };
- // Update the title to indicate the process is running
- titleElement.innerText = `Granting badges for ${referrer}...`;
- // Start the recursive badge granting process
- recursive(1);
- };
- // Show progress in the output box
- const showProgress = (outputBox, message) => {
- outputBox.textContent += `\n${message}`;
- outputBox.scrollTop = outputBox.scrollHeight; // Scroll to the bottom
- };
- // Create pop-out button to toggle the interface visibility
- const createPopoutButton = () => {
- const button = document.createElement('button');
- button.innerText = '▶'; // Use a play button icon for a more intuitive look
- button.style.position = 'fixed';
- button.style.bottom = '20px';
- button.style.right = '20px';
- button.style.width = '40px';
- button.style.height = '40px';
- button.style.borderRadius = '50%';
- button.style.backgroundColor = '#4CAF50';
- button.style.color = 'white';
- button.style.border = 'none';
- button.style.fontSize = '20px';
- button.style.cursor = 'pointer';
- button.style.boxShadow = '0 4px 8px rgba(0,0,0,0.3)';
- button.style.transition = 'background-color 0.3s, transform 0.3s';
- // Hover effect
- button.addEventListener('mouseover', () => {
- button.style.backgroundColor = '#45a049';
- button.style.transform = 'scale(1.1)';
- });
- button.addEventListener('mouseout', () => {
- button.style.backgroundColor = '#4CAF50';
- button.style.transform = 'scale(1)';
- });
- // Toggle pop-out box visibility
- button.addEventListener('click', () => {
- const popoutBox = document.getElementById('badge-granting-box');
- popoutBox.style.display = (popoutBox.style.display === 'none' || !popoutBox.style.display) ? 'block' : 'none';
- });
- document.body.appendChild(button);
- };
- // Create the interface container
- const createInterfaceBox = () => {
- const box = document.createElement('div');
- box.id = 'badge-granting-box';
- box.style.position = 'fixed';
- box.style.bottom = '20px';
- box.style.right = '20px';
- box.style.width = '320px';
- box.style.height = '400px';
- box.style.backgroundColor = '#fff';
- box.style.border = '1px solid #ccc';
- box.style.borderRadius = '8px';
- box.style.boxShadow = '0 4px 8px rgba(0,0,0,0.3)';
- box.style.padding = '15px';
- box.style.display = 'none'; // Initially hidden
- // Add Title Above Output Box
- const titleElement = document.createElement('h3');
- titleElement.innerText = 'Initializing...';
- titleElement.style.textAlign = 'center';
- titleElement.style.marginBottom = '10px';
- titleElement.style.fontSize = '18px';
- titleElement.style.fontWeight = 'bold';
- box.appendChild(titleElement);
- // Create output box for displaying progress
- const outputBox = document.createElement('div');
- outputBox.style.height = '250px';
- outputBox.style.overflowY = 'auto';
- outputBox.style.backgroundColor = '#f8f8f8';
- outputBox.style.border = '1px solid #ccc';
- outputBox.style.borderRadius = '5px';
- outputBox.style.fontSize = '14px';
- outputBox.style.padding = '10px';
- outputBox.style.whiteSpace = 'pre-wrap'; // Preserve line breaks
- box.appendChild(outputBox);
- // Create run and stop buttons
- const buttonContainer = document.createElement('div');
- buttonContainer.style.display = 'flex';
- buttonContainer.style.justifyContent = 'space-between';
- buttonContainer.style.marginTop = '10px';
- // Run Button
- const runButton = document.createElement('button');
- runButton.innerText = 'Run';
- runButton.style.flex = '1';
- runButton.style.padding = '10px';
- runButton.style.backgroundColor = '#4CAF50';
- runButton.style.color = 'white';
- runButton.style.border = 'none';
- runButton.style.borderRadius = '5px';
- runButton.style.cursor = 'pointer';
- runButton.addEventListener('click', () => {
- const username = getUsernameFromUrl(); // Get username from the URL
- if (username) {
- showProgress(outputBox, 'Starting badge granting...');
- startGrantingBadges(username, outputBox, titleElement);
- } else {
- showProgress(outputBox, 'Error: Could not extract username.');
- }
- });
- // Stop Button
- const stopButton = document.createElement('button');
- stopButton.innerText = 'Stop';
- stopButton.style.flex = '1';
- stopButton.style.padding = '10px';
- stopButton.style.backgroundColor = '#f44336';
- stopButton.style.color = 'white';
- stopButton.style.border = 'none';
- stopButton.style.borderRadius = '5px';
- stopButton.style.cursor = 'pointer';
- stopButton.addEventListener('click', () => {
- cancelGranting = true; // Stop the granting process
- showProgress(outputBox, 'Process stopped.');
- titleElement.innerText = 'Stopped';
- });
- buttonContainer.appendChild(runButton);
- buttonContainer.appendChild(stopButton);
- box.appendChild(buttonContainer);
- document.body.appendChild(box);
- };
- // Initialize everything
- createPopoutButton();
- createInterfaceBox();
- })();