您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Information preview inside messages, removal of private lock from videos uploaded by friends, and more
当前为
// ==UserScript== // @name Camwhores.tv Utilities Mod // @namespace https://sleazyfork.org/users/1281730-vipprograms // @version 0.12 // @description Information preview inside messages, removal of private lock from videos uploaded by friends, and more // @author vipprograms // @match https://www.camwhores.tv/* // @grant GM_xmlhttpRequest // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAMUExURQAAAP8ANwwA/////7gbQJkAAAABdFJOUwBA5thmAAAAAWJLR0QDEQxM8gAAAAd0SU1FB+gDHhIuCjXV/h8AAAA4SURBVAjXY2ANDQ1gEA0NDWEIYWBgZAhgAAIUghEiC1YHBhpMDRpIhBbXghUMXKtWLWBgWqHVAACjlwz/pN0YPwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyNC0wMy0zMFQxODo0NjowOSswMDowME+iXNIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjQtMDMtMzBUMTg6NDY6MDkrMDA6MDA+/+RuAAAAKHRFWHRkYXRlOnRpbWVzdGFtcAAyMDI0LTAzLTMwVDE4OjQ2OjEwKzAwOjAwMNiA/AAAAABJRU5ErkJggg== // ==/UserScript== (function() { 'use strict'; const style = document.createElement('style'); style.textContent = ` ul > li.next, ul > li.prev { display: list-item !important; } `; document.head.appendChild(style); if (window.location.href == "https://www.camwhores.tv/my/messages/") { // Function to apply styles to unread notifications // Function to apply styles to unread notifications function applyStylesToNotifications() { console.log("Applying styles to notifications"); var unreadNotifications = document.querySelectorAll('.unread-notification'); unreadNotifications.forEach(function(notification) { notification.style.top = "0"; notification.style.left = "0"; }); } // Function to process thumbnails function processThumbnails() { // console.log("Processing thumbnails"); var thumbnails = document.querySelectorAll('strong.title'); if (thumbnails.length === 0) { console.log("Thumbnails not found. Retrying in 1000 milliseconds."); setTimeout(function() { processThumbnails(); // Retry processing thumbnails }, 1000); return false; // Return false if thumbnails not found } thumbnails.forEach(function(thumbnail) { var usernameText = thumbnail.textContent.trim(); if (usernameText) { var usernameLink = document.querySelector('a[title="' + usernameText + '"]'); if (usernameLink) { var href = usernameLink.getAttribute('href'); var userIdMatch = href.match(/\/(\d+)\/$/); if (userIdMatch && userIdMatch.length > 1) { var userId = userIdMatch[1]; var usernameUrl = "https://www.camwhores.tv/members/" + userId + "/"; GM_xmlhttpRequest({ method: "GET", url: usernameUrl, onload: function(response) { var parser = new DOMParser(); var htmlDoc = parser.parseFromString(response.responseText, "text/html"); var infoMessage = htmlDoc.querySelector('.info-message'); var usernameLink = document.querySelector('a[title="' + usernameText + '"]'); // console.log(usernameText + ": " + usernameUrl) // console.log(usernameLink) if (infoMessage && infoMessage.textContent.includes("is in your friends list.")) { if (usernameLink) { var divElement = document.createElement('div'); divElement.textContent = "Friends ✅"; divElement.style.position = "absolute"; divElement.style.top = "0"; divElement.style.right = "0"; divElement.style.backgroundColor = "black"; divElement.style.color = "white"; divElement.style.padding = "3px 5px"; if (usernameLink) { var firstDivElement = usernameLink.querySelector('div.img'); if (firstDivElement) { firstDivElement.appendChild(divElement); } } } } if(infoMessage && infoMessage.textContent.includes("wants to be your friend.")){ var divElement = document.createElement('div'); divElement.textContent = "👀"; divElement.title = "Wants to be your friend!"; divElement.style.position = "absolute"; divElement.style.bottom = "0"; divElement.style.left = "0"; // divElement.style.backgroundColor = "aquamarine"; divElement.style.color = "white"; divElement.style.fontSize = "1rem"; divElement.style.padding = ".5rem .25rem"; if (usernameLink) { var firstDivElement = usernameLink.querySelector('div.img'); if (firstDivElement) { firstDivElement.appendChild(divElement); } } } var titleVideosElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos"]/div[1]/h2', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); var videoNumber = 0; if (titleVideosElement && titleVideosElement.singleNodeValue) { var titleVideosText = titleVideosElement.singleNodeValue.textContent; if (titleVideosText) { var matches = titleVideosText.match(/\(([^)]+)\)/); videoNumber = matches ? matches[1] : 0; } } var divElement = document.createElement('div'); divElement.textContent = videoNumber; divElement.style.position = "absolute"; divElement.style.bottom = "0"; divElement.style.right = "0"; divElement.style.backgroundColor = "CadetBlue"; divElement.style.color = "white"; divElement.style.padding = "3px 5px"; if (usernameLink) { var firstDivElement = usernameLink.querySelector('div.img'); if (firstDivElement) { firstDivElement.appendChild(divElement); } } } }); } else { console.log("User ID not found in href for:", usernameText); } } else { console.log("Username link not found for:", usernameText); } } }); return true; // Return true if thumbnails processed successfully } // Function to add event listener to buttons function addButtonEventListener() { console.log("Adding event listener to buttons"); document.addEventListener('click', function(event) { var target = event.target; if (target && target.matches('a[data-action="ajax"]')) { // console.log("Button clicked"); setTimeout(function() { applyStylesToNotifications(); processThumbnails(); }, 1000); } }); } // Call the functions to apply styles and process thumbnails console.log("Calling functions to apply styles and process thumbnails"); // Delay execution of initialization code by 1 second setTimeout(function() { applyStylesToNotifications(); var thumbnailsProcessed = processThumbnails(); if (!thumbnailsProcessed) { console.log("Processing thumbnails failed. Retrying in 1000 milliseconds."); setTimeout(function() { processThumbnails(); // Retry processing thumbnails }, 1000); } addButtonEventListener(); }, 1000); }else if(window.location.href.startsWith("https://www.camwhores.tv/my/messages/")) { // Function to fetch the URL and extract title, content, and joined date function fetchAndExtract(url) { GM_xmlhttpRequest({ method: "GET", url: url, onload: function(response) { // Parse the response text into a HTML document var parser = new DOMParser(); var htmlDoc = parser.parseFromString(response.responseText, "text/html"); // Get the text of the specified elements var titleElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos"]/div[1]/h2', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); var contentElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos_items"]/div[1]/a/div[3]/div[1]/em', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); var joinedDateElement = htmlDoc.evaluate('/html/body/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[3]/em', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); var joinedDateText = joinedDateElement.singleNodeValue.textContent; // Check if the elements exist if (titleElement && titleElement.singleNodeValue && contentElement && contentElement.singleNodeValue && joinedDateElement && joinedDateElement.singleNodeValue) { var titleText = titleElement.singleNodeValue.textContent; // Extract text inside parentheses from title var extractedTitle = titleText.match(/\(([^)]+)\)/); if (extractedTitle && extractedTitle.length > 1) { var contentText = contentElement.singleNodeValue.textContent; var generatedText = "<div id=gen_joined_text>Joined " + joinedDateText + "<br>" + extractedTitle[1] + " videos, last " + contentText + "</div>"; // Add generated text to the visible page var messageDiv = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (messageDiv && messageDiv.singleNodeValue) { messageDiv.singleNodeValue.innerHTML += generatedText; } } else { console.log('Text inside parentheses in title not found.'); } } else { console.log('Title, content, or joined date element not found. Probably no videos uploaded yet.'); // Add "No videos" to the visible page var messageDiv = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (messageDiv && messageDiv.singleNodeValue) { messageDiv.singleNodeValue.innerHTML += "<div id=gen_joined_text>Joined " + joinedDateText + "<br>" + "<b>No videos</b></div>"; } } } }); } // Get the href attribute of the first message var messageLink = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[1]/a', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); // Check if the element exists if (messageLink && messageLink.singleNodeValue) { // Get the URL from the message link var messageUrl = messageLink.singleNodeValue.href; // Fetch and extract title, content, and joined date from the URL fetchAndExtract(messageUrl); } else { console.log('Message link not found.'); } // Remove class "bottom" from specified element var bottomElement = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]/form/div', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (bottomElement && bottomElement.singleNodeValue) { bottomElement.singleNodeValue.style.marginTop = "1em"; bottomElement.singleNodeValue.style.marginBottom = "1em"; bottomElement.singleNodeValue.classList.remove("bottom"); } else { console.log('Bottom element not found.'); setTimeout(function() { var gen_joined_text = document.getElementById('gen_joined_text'); gen_joined_text.innerHTML = "<br>" + gen_joined_text.innerHTML; // gen_joined_text.style.marginTop = "1em"; // gen_joined_text.classList.add("custom-margin-top"); }, 200); // Adjust the delay time as needed } }else if(window.location.href !== "https://www.camwhores.tv/my/videos/") { // Set to store unique video elements const processedVideos = new Set(); function addPrivateVideos() { const private_videos = []; const videoElements = document.querySelectorAll('.line-premium, .line-private'); videoElements.forEach(video => { const parentDiv = video.parentElement; if ( parentDiv.tagName === 'DIV' && parentDiv.parentElement.tagName === 'A' && !processedVideos.has(parentDiv.parentElement) ) { private_videos.push(parentDiv.parentElement); // Add the video element to the set of processed videos processedVideos.add(parentDiv.parentElement); } }); return private_videos; } async function checkVideoPage(url) { try { const response = await fetch(url); // Check if the response status code indicates an error if (!response.ok) { console.error('Error loading video page:', response.status); return true; // Return true if there's an error loading the page } const html = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const hasElement1 = doc.querySelector('body > div.container > div.content > div.block-video > div.video-holder > div.player > div > div > span') !== null; // body > div.container > div.content > div.block-video > div.video-holder > div.player > div > div > span // basically the "This video is a private video uploaded by" message const hasElement2 = doc.querySelector('body > div.container > div.content > div.block-album > div.album-holder > div.images > span.message') !== null; return hasElement1 || hasElement2; } catch (error) { console.error('Error checking video page:', error); return false; } } async function applyStyleToPrivateVideos() { const privateVideos = addPrivateVideos(); for (const video of privateVideos) { const videoLink = video.getAttribute('href'); // console.log(videoLink); const hasElement = await checkVideoPage(videoLink); // console.log(videoLink + " " + hasElement); if (!hasElement) { video.style.outline = '2px solid green'; const linePrivate = video.querySelector('div > .line-private'); if (linePrivate) { linePrivate.style.display = 'none'; } const imgElement = video.querySelector('div > img'); if (imgElement) { imgElement.style.opacity = '1'; } }else{ // add ❌ const linePrivate = video.querySelector('div > .line-private > span'); if (linePrivate) { linePrivate.textContent += ' ❌'; } } await new Promise(resolve => setTimeout(resolve, 25)); // avoid 503 } } // Call the applyStyleToPrivateVideos function initially applyStyleToPrivateVideos(); // Set interval to repeatedly check for private videos and apply styling setInterval(() => { applyStyleToPrivateVideos(); }, 1000); // Interval in milliseconds (every second) if (window.location.href.startsWith("https://www.camwhores.tv/members/")) { console.log("NOT messages, user PROFILE"); function updateH2Element() { const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2'); if (h2Element) { const text = h2Element.textContent; const startIndex = text.indexOf('('); const endIndex = text.indexOf(')', startIndex); if (startIndex !== -1 && endIndex !== -1 && text.includes("Page")) { const videos_total = parseInt(text.substring(startIndex + 1, endIndex)); const rounded_videos_total = Math.ceil(videos_total / 5); const innerHTML = h2Element.innerHTML.trim(); if (!innerHTML.includes('/')) { h2Element.innerHTML = innerHTML + '/' + rounded_videos_total; } } } } function addButtonEventListener() { console.log("Adding event listener to buttons"); document.addEventListener('click', function(event) { var target = event.target; if (target && target.matches('a[data-action="ajax"]')) { console.log("Button clicked"); setTimeout(function() { updateH2Element() }, 750); } }); } updateH2Element() addButtonEventListener() } if(window.location.href.startsWith("https://www.camwhores.tv/videos/")){ const element1 = document.querySelector('body > div.container > div.content > div.block-video > div.video-holder > div.player > div > div > span'); const element2 = document.querySelector('body > div.container > div.content > div.block-album > div.album-holder > div.images > span.message'); if (element1 !== null || element2 !== null) { const href = document.querySelector('#tab_video_info > div > div.block-user > div > a').href; fetch(href) .then(response => response.text()) .then(html => { const htmlDoc = new DOMParser().parseFromString(html, 'text/html'); const infoMessage = htmlDoc.querySelector('.info-message'); if (infoMessage && infoMessage.textContent.includes("is in your friends list.")) { const friends_string = "You're already friends! Reloading in 4 seconds"; (element1 || element2).textContent = friends_string; setInterval(() => { location.reload(); }, 4000); } else { console.log("Not friends!"); } }) .catch(error => console.error('Error fetching:', error)); } } } })();