// ==UserScript==
// @name Camwhores.tv Utilities Mod
// @namespace https://sleazyfork.org/users/1281730-vipprograms
// @version 1.6.0
// @description Info preview, removal of lock from friends' vidoes, restored upload button, and more.
// @author vipprograms
// @match https://www.camwhores.tv/*
// @grant GM_xmlhttpRequest
// @grant GM.getValue
// @grant GM_getValue
// @grant GM.setValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM.registerMenuCommand
// @grant window.close
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAMUExURQAAAP8ANwwA/////7gbQJkAAAABdFJOUwBA5thmAAAAAWJLR0QDEQxM8gAAAAd0SU1FB+gDHhIuCjXV/h8AAAA4SURBVAjXY2ANDQ1gEA0NDWEIYWBgZAhgAAIUghEiC1YHBhpMDRpIhBbXghUMXKtWLWBgWqHVAACjlwz/pN0YPwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyNC0wMy0zMFQxODo0NjowOSswMDowME+iXNIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjQtMDMtMzBUMTg6NDY6MDkrMDA6MDA+/+RuAAAAKHRFWHRkYXRlOnRpbWVzdGFtcAAyMDI0LTAzLTMwVDE4OjQ2OjEwKzAwOjAwMNiA/AAAAABJRU5ErkJggg==
// @require https://code.jquery.com/jquery-3.7.1.slim.min.js
// ==/UserScript==
(function() {
'use strict';
var _GM_registerMenuCommand, options;
const refreshMessagesTimer = 2500;
function isArrayEmpty(arr) {
return arr.length === 0;
}
function retrieveValueFromStorage(key) {
if (typeof GM_setValue === "function") {
return GM_getValue(key, false); // Default value set to false for boolean
}
else if (typeof GM === "object" && typeof GM.getValue === "function" && typeof GM.setValue === "function") {
return GM.getValue(key, false).then(function(value) {
return value;
});
}
else {
console.error("Unsupported userscript manager.");
return undefined;
}
}
function saveValue(key, array) {
GM.setValue(key, array).then(function() {
console.log("Array saved successfully.");
}).catch(function(error) {
console.error("Error saving array:", error);
});
}
if (typeof GM_registerMenuCommand !== 'undefined') {
_GM_registerMenuCommand = GM_registerMenuCommand;
} else if (typeof GM !== 'undefined' && typeof GM.registerMenuCommand !== 'undefined') {
_GM_registerMenuCommand = GM.registerMenuCommand;
} else {
_GM_registerMenuCommand = (s, f) => { debug(s); debug(f); };
}
function toggleChange(options, optionName, defaultValue = false){
var updatedOptions;
var currentState = options[optionName] !== undefined ? options[optionName] : defaultValue;
_GM_registerMenuCommand((currentState ? "Disable " : "Enable ") + optionName, () => {
currentState = !currentState;
updatedOptions[optionName] = currentState;
saveValue("options", updatedOptions);
setTimeout(() => {
location.reload();
}, 500);
});
updatedOptions = retrieveValueFromStorage("options") || {}; // Ensure options exist
if (updatedOptions[optionName] === undefined) {
updatedOptions[optionName] = defaultValue;
saveValue("options", updatedOptions);
}
}
function createForm(array_name, delimitedString){
return new Promise((resolve, reject) => {
var form = document.createElement('form');
form.classList.add('form-container');
var textBox = document.createElement('textarea');
textBox.classList.add('textarea-input');
textBox.setAttribute('autofocus', 'autofocus');
var buttonsLine = document.createElement('div');
buttonsLine.classList.add('buttons-line');
var submitButton = document.createElement('button');
submitButton.type = 'submit';
submitButton.textContent = 'Submit';
submitButton.classList.add('submit-button');
var cancelButton = document.createElement('button');
cancelButton.type = 'button';
cancelButton.textContent = 'Cancel';
cancelButton.classList.add('cancel-button');
cancelButton.addEventListener('click', function() {
document.body.removeChild(form);
reject('Form cancelled');
});
window.addEventListener('click', function(event) {
if (document.body.contains(form) && !form.contains(event.target)) {
document.body.removeChild(form);
reject('Form cancelled');
}
});
textBox.value = delimitedString;
form.appendChild(textBox);
form.appendChild(buttonsLine);
buttonsLine.appendChild(cancelButton);
buttonsLine.appendChild(submitButton);
document.body.appendChild(form);
form.addEventListener('submit', function(event){
event.preventDefault();
var inputValue = textBox.value.split('\n').map(line => line.trim()).filter(line => line !== '');
document.body.removeChild(form);
resolve(inputValue);
});
});
}
function optionsArrayEditor(array_name, optionsKeyLegible){
_GM_registerMenuCommand("Change " + optionsKeyLegible[array_name], () => {
var originalArray = retrieveValueFromStorage(array_name);
var delimitedString = originalArray.join("\n");
createForm(array_name, delimitedString).then(lines => {
saveValue(array_name, lines);
});
});
}
function optionsStringEditor(string_name, optionsKeyLegible) {
_GM_registerMenuCommand("Change " + optionsKeyLegible[string_name], () => {
var originalString = retrieveValueFromStorage(string_name);
createForm(string_name, originalString).then(lines => {
// Convert array 'lines' to a string by joining values with '\n'
let stringifiedLines = lines.join('\n');
saveValue(string_name, stringifiedLines);
});
});
}
const auto_replies_default = ["Next time you send me a request with 0 videos, I'll block you",
"Very nice videos",
"Why? What's wrong?",
"Sorry, I don't like your videos",
"You don't have any videos"];
const highlight_keywords_default = ['joi', 'cei', 'fuck', "cumshot"];
const friend_request_text_default = "Hi! I'm interested in this video:";
var auto_replies = retrieveValueFromStorage("auto_replies");
var highlight_keywords = retrieveValueFromStorage("highlight_keywords");
var friend_request_text = retrieveValueFromStorage("friend_request_text");
if (!auto_replies) {
auto_replies = auto_replies_default;
saveValue("auto_replies", auto_replies_default);
}
if (!highlight_keywords) {
highlight_keywords = highlight_keywords_default;
saveValue("highlight_keywords", highlight_keywords_default);
}
if (!friend_request_text) {
friend_request_text = friend_request_text_default;
saveValue("friend_request_text", friend_request_text_default);
}
var optionsKeyLegible = {
auto_replies: "template replies",
highlight_keywords: "highlight keywords",
friend_request_text: "friend requests text"
}
optionsArrayEditor("auto_replies", optionsKeyLegible)
optionsArrayEditor("highlight_keywords", optionsKeyLegible)
optionsStringEditor("friend_request_text", optionsKeyLegible)
// BOOL OPTIONS
options = retrieveValueFromStorage("options")
toggleChange(options, "alternative thumbnails", true)
var altThumbs = retrieveValueFromStorage("options")["alternative thumbnails"];
toggleChange(options, "message page auto refresh", true)
var refreshMessagePage = retrieveValueFromStorage("options")["auto refresh message page"];
toggleChange(options, "upload button restore", true)
var restoreUploadButton = retrieveValueFromStorage("options")["restore upload button"];
const style = document.createElement('style');
style.textContent = `
a.button{
color:#4e4e4e !important;
}
ul > li.next,
ul > li.prev {
display: list-item !important;
}
.item:hover > a > div.img > .friends-tag,
.item:hover > a > div.img > .videos-tag{
background-color:#1a1a1a !important;
}
.button{
color: rgb(183, 176, 167);
text-align: center;
border: 1px solid transparent;
font-size: 14px;
padding: 5px 10px;
cursor: pointer;
background: linear-gradient(to bottom, #ffffff 0%, #cccccc 100%);
border-radius: 3px;
display: inline-block;
margin: 0 .3rem .3rem 0;
color: dimgrey;
}
.button:hover{
color: #f56c08 !important;
border: 1px solid transparent;
background: #1e1e1e;
}
div.img span.unread-notification{
background: #c45606ab;
backdrop-filter: blur(5px) brightness(1);
top: 0px;
left: 0px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
outline: 3px solid #f56c08;
animation: glow 5s infinite;
}
@keyframes glow {
0% {
outline-color: #f56c08d6;
}
50% {
outline-color: transparent;
}
100% {
outline-color: #f56c08d6;
}
}
.form-container {
box-sizing: border-box;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 100vw;
width: 800px;
padding: 2.5rem;
border-radius: .25rem;
z-index:99999;
background-color: transparent !important;
backdrop-filter: blur(1rem) brightness(.8) contrast(1.2)
}
.form-container * {
box-sizing: inherit;
}
.textarea-input {
width: 100%;
min-height: 10rem;
padding: 1rem;
border-radius: .25rem;
color-scheme: dark !important;
}
.buttons-line {
margin-top: .3rem;
gap:.3rem;
width: 100%;
display: flex;
}
.submit-button:hover, .cancel-button:hover{
filter: brightness(.8) contrast(1.2)
}
.submit-button, .cancel-button{
transform: .3s;
}
.submit-button {
height: 50px;
flex-grow: 1;
cursor: pointer;
border-radius: .25rem;
color-scheme: dark !important;
font-weight:bold;
border:0;
}
.cancel-button {
width:min-content;
height: 50px;
cursor: pointer;
border-radius: .25rem;
color-scheme: dark !important;
background-color: red;
font-weight:bold;
padding-inline:.5rem;
border:0;
}
input.accept-button {
color: #fff;
background-image: linear-gradient(rgb(0, 128, 0) 0%, rgb(0, 255, 0) 100%);
}
input.accept-button:hover {
color: #fff !important;
background-image: linear-gradient(rgb(34, 139, 34) 0%, rgb(50, 205, 50) 100%) !important;
}
input.reject-button {
color: #fff;
background-image: linear-gradient(rgb(255, 0, 0) 0%, rgb(128, 0, 0) 100%);
}
input.reject-button:hover {
color: #fff !important;
background-image: linear-gradient(rgb(220, 20, 60) 0%, rgb(178, 34, 34) 100%) !important;
}
#vid_previews {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
height: 150px;
margin-top: 1rem;
gap:5px;
}
#vid_previews img {
flex-shrink: 1;
height: auto;
}
`;
document.head.appendChild(style);
function makeValidUrlString(inputString) {
var validString = inputString.replace(/[^\w\s\/-]/g, ''); // Remove special characters
validString = validString.replace(/[-_]{2,}/g, '-'); // Turn consecutive underscores or hyphens into single hyphens
validString = validString.replace(/\s+/g, '-'); // Turn spaces into hyphens
validString = validString.replace(/\//g, '-'); // Turn slashes into hyphens
return validString;
}
function friendRequestSetup(video_title, video_url){
var vid_code = video_url.replace("https://www.camwhores.tv/videos/", "");
var parts = vid_code.split("/");
var videoId = parts[0];
var code = parts[1];
localStorage.setItem('last_cum_title', video_title);
localStorage.setItem('last_cum_vid_id', videoId);
}
// add the upload button back
const nav = document.querySelector('.navigation .primary');
if (restoreUploadButton && ![...nav.querySelectorAll('a')].some(link => link.textContent.trim().includes('Upload'))) {
const uploadLink = document.createElement('a');
uploadLink.href = '/upload-video/';
uploadLink.style.backgroundColor = '#215521';
uploadLink.textContent = 'Upload';
nav.appendChild(uploadLink);
}
if (window.location.href == "https://www.camwhores.tv/my/messages/") {
let fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
if(refreshMessagePage){
$(document).ready(function() {
var linkClicked = parseInt(localStorage.getItem("linkClicked")) > fiveMinutesAgo;
console.log("Initial linkClicked value:", linkClicked);
$(window).on("focus", function() {
localStorage.setItem("linkClicked", fiveMinutesAgo);
linkClicked = false;
console.log("Window is focused");
if (interval !== null) {
clearInterval(interval);
}
});
if (linkClicked) {
console.log("Reloading...");
var interval = setInterval(function() {
location.reload();
}, refreshMessagesTimer);
}
$(document).on("click auxclick", "a", function(event) {
var href = $(this).attr("href");
if (event.button === 0 || event.button === 1) {
// alert("You're trying to go to " + href);
localStorage.setItem("linkClicked", Date.now());
linkClicked = true;
console.log("Link clicked. Will refresh");
}
});
$(window).on("blur", function() {
console.log("Window blur event");
if (linkClicked) {
console.log("Reloading...");
var interval = setInterval(function() {
location.reload();
}, refreshMessagesTimer);
}
});
});
}
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.classList.add("friends-tag");
divElement.textContent = "Friends ✅";
divElement.style.position = "absolute";
divElement.style.top = "0";
divElement.style.right = "0";
divElement.style.backgroundColor = "#414141"; //#1a1a1a
divElement.style.borderBottomLeftRadius = "3px";
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.")){
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) {
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;
}
}
if(videoNumber || videoNumber === 0){
divElement = document.createElement('div');
divElement.classList.add("videos-tag");
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";
divElement.style.borderTopLeftRadius = "3px";
}
if (usernameLink) {
firstDivElement = usernameLink.querySelector('div.img');
if (firstDivElement) {
firstDivElement.appendChild(divElement);
}
}
} // end httpGET reponse
});
} 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");
const h2Element = document.querySelector('#list_members_my_conversations div.headline h2');
const initialText = h2Element.textContent.trim();
// console.log("Initial text: " + initialText);
const checkChangeInterval = setInterval(function() {
const h2Element = document.querySelector('#list_members_my_conversations div.headline h2');
const currentText = h2Element.textContent.trim();
// console.log("Current text: " + currentText);
if (currentText !== initialText) {
clearInterval(checkChangeInterval);
processThumbnails();
}
}, 100);
}
});
}
console.log("Calling functions to apply styles and process thumbnails");
setTimeout(function() {
processThumbnails();
var thumbnailsProcessed = processThumbnails();
if (!thumbnailsProcessed) {
console.log("Processing thumbnails failed. Retrying in 1000 milliseconds.");
setTimeout(function() {
processThumbnails(); // Retry processing thumbnails
}, 1000);
}
addButtonEventListener();
}, 1000);
setInterval(function() {
processThumbnails()
console.log("Updating status of users")
}, 3000);
const refreshIcon = document.createElement('span');
refreshIcon.innerHTML = '↻'; // Unicode for refresh icon
refreshIcon.title = 'Refresh Utilities Mod';
refreshIcon.style.cursor = 'pointer';
refreshIcon.style.marginLeft = '10px'; // Adjust margin as needed
refreshIcon.addEventListener('click', function() {
processThumbnails()
console.log('Refreshing...');
});
const h2Element = document.querySelector('#list_members_my_conversations .headline h2');
console.log("adding..?")
h2Element.appendChild(refreshIcon);
}else if(window.location.href.startsWith("https://www.camwhores.tv/my/messages/")) {
const textarea = document.querySelector("#send_message_message");
const divTextarea = document.createElement('div');
function copyContentToTextarea() {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = divTextarea.innerHTML;
const content = [];
tempDiv.childNodes.forEach(node => {
if (node.nodeType === 3) { // Text node
content.push(node.textContent);
} else if (node.nodeType === 1 && node.tagName === 'IMG') { // Image node
content.push(node.alt);
}
});
const finalText = content.join('').trim(); // Join text content and alt attributes with space
textarea.value = finalText; // Set the final text to the textarea
}
textarea.style.display = "none";
divTextarea.innerHTML = textarea.value;
divTextarea.contentEditable = true;
divTextarea.style.minHeight = "5rem";
divTextarea.style.resize = "vertical";
divTextarea.style.overflow = "auto";
divTextarea.style.fontSize = "14px";
divTextarea.classList.add("textarea");
textarea.parentNode.insertBefore(divTextarea, textarea.nextSibling);
document.querySelectorAll('.smileys-bar img').forEach(function(img) {
img.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
var imgClone = img.cloneNode(true);
imgClone.style.cursor = "auto"; // Add cursor style
divTextarea.appendChild(imgClone);
copyContentToTextarea()
return false;
});
});
divTextarea.addEventListener('input', copyContentToTextarea);
var inlineTexts = document.querySelectorAll('span.inline-text, span.original-text');
inlineTexts.forEach(function(span) {
var lineText = span.textContent.trim();
if (lineText.includes('##')) {
var index = lineText.indexOf(':');
var videoText = lineText.substring(0, index).trim();
var videoInfo = lineText.substring(index + 1).trim().replace('##', '');
let parts = videoInfo.split("\n");
let videoCode = parts[0];
let videoID = parts[1];
let url = 'https://www.camwhores.tv/videos/' + videoID + "/" + makeValidUrlString(videoCode) + '/';
console.log(url)
fetch(url)
.then(response => {
if (response.ok) {
span.innerHTML = videoText + ': <a href="' + url + '" class="toggle-button" style="display:inline-block">'+videoCode+'</a>';
} else if (response.status === 404) {
console.log("URL is 404");
} else {
console.error("Error:", response.status);
}
})
.catch(error => console.error("Error:", error));
// span.innerHTML = videoText + ': <a href="' + url + '" class="toggle-button" style="display:inline-block">Open video</a>';
}
});
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 'Enter') {
event.preventDefault();
document.querySelector('#send_message_form input[type="submit"]').click();
}
});
function fetchAndExtract(url) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function(response) {
document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]/img', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue?.remove();
// Parse the response text into a HTML document
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(response.responseText, "text/html");
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;
let imgData = [];
for (let i = 1; i <= 5; i++) {
let xpath = `/html/body/div[2]/div[2]/div/div[2]/div[3]/div[2]/div/div/div[${i}]/a/div[1]/img`;
let img = htmlDoc.evaluate(xpath, htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (img) {
imgData.push({ src: img.getAttribute('data-original'), alt: img.alt });
}
}
// console.log(imgData);
var confirmButton = document.querySelector('input[name="confirm"]');
var rejectButton = document.querySelector('input[name="reject"]');
let confirmClose = null
let denyClose = null
if (confirmButton) {
let buttonsParent = confirmButton.parentElement;
confirmClose = document.createElement('input');
confirmClose.className = 'submit';
confirmClose.value = 'Confirm & Close';
confirmClose.type = 'submit';
confirmClose.style.margin = '2.5px 3px 0 0';
denyClose = document.createElement('input');
denyClose.className = 'submit';
denyClose.value = 'Deny & Close';
denyClose.type = 'submit';
confirmClose.addEventListener('click', function(event) {
event.preventDefault();
confirmButton.click();
window.close();
});
denyClose.addEventListener('click', function(event) {
event.preventDefault();
rejectButton.click();
window.close();
});
buttonsParent.appendChild(document.createElement('br'));
buttonsParent.appendChild(confirmClose);
buttonsParent.appendChild(denyClose);
let vidPreviewsDiv = document.createElement("div");
vidPreviewsDiv.id = "vid_previews";
imgData.forEach(data => {
let img = document.createElement("img");
img.src = data.src;
img.alt = data.alt;
img.title = data.alt;
vidPreviewsDiv.appendChild(img);
});
buttonsParent.appendChild(vidPreviewsDiv);
}
function updateButtonStyle(button, state) {
if (state && button) {
// button.style.backgroundImage = 'linear-gradient(rgb(0, 128, 0) 0%, rgb(0, 255, 0) 100%)';
// button.style.color = '#fff';
button.classList.add("accept-button");
} else if(button) {
// button.style.backgroundImage = 'linear-gradient(rgb(255, 0, 0) 0%, rgb(128, 0, 0) 100%)';
// button.style.color = '#fff';
button.classList.add("reject-button");
}
}
if (titleElement && titleElement.singleNodeValue && contentElement && contentElement.singleNodeValue && joinedDateElement && joinedDateElement.singleNodeValue) {
var titleText = titleElement.singleNodeValue.textContent;
var extractedTitle = titleText.match(/\(([^)]+)\)/);
if (extractedTitle && extractedTitle.length > 1) {
// THERE ARE VIDEOS
// confirmButton.style.backgroundImage = 'linear-gradient(rgb(0, 128, 0) 0%, rgb(0, 255, 0) 100%)';
// confirmButton.style.color = '#fff';
updateButtonStyle(confirmButton, true)
updateButtonStyle(confirmClose, true)
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 {
// THERE ARE NO VIDEOS
console.log('Title, content, or joined date element not found. Probably no videos uploaded yet.');
// rejectButton.style.backgroundImage = 'linear-gradient(rgb(255, 0, 0) 0%, rgb(128, 0, 0) 100%)';
// rejectButton.style.color = '#fff';
updateButtonStyle(rejectButton, false)
updateButtonStyle(denyClose, false)
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>";
}
}
}
});
}
var bottomDiv = document.querySelector("#send_message_form > div > div.bottom");
var responsesDiv = document.createElement("div");
responsesDiv.id = "responses";
responsesDiv.style.marginTop = "1rem";
bottomDiv.insertAdjacentElement('afterend', responsesDiv);
auto_replies.forEach(function(string) {
var button = document.createElement("button");
button.textContent = string;
button.classList.add("button");
button.addEventListener("click", function(event) {
event.preventDefault();
if (textarea.value.trim() !== '') {
textarea.value += "\n";
}
textarea.value += string;
document.querySelector('#send_message_form').submit();
});
button.style.padding = ".25rem .5rem"
responsesDiv.appendChild(button);
});
// var messageLink = document.evaluate('//*[@id="list_messages_my_conversation_messages"]/div[1]/h2/a[2]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
var messageLink = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[1]/a', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (messageLink && messageLink.singleNodeValue) {
var messageUrl = messageLink.singleNodeValue.href;
const parentElement = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const img = document.createElement('img');
img.src = 'https://samherbert.net/svg-loaders/svg-loaders/three-dots.svg';
img.style.height = "32px";
img.style.width = "32px";
parentElement.appendChild(img);
fetchAndExtract(messageUrl); // SENDING ACTUAL REQUEST
} else {
console.log('Message link not found.');
}
// AESTHETIC CHANGE
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');
if (gen_joined_text) gen_joined_text.innerHTML = "<br>" + gen_joined_text.innerHTML;
}, 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);
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 { byFriend: true, usernameID: null }; // 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;
const hasElement2 = doc.querySelector('body > div.container > div.content > div.block-album > div.album-holder > div.images > span.message') !== null;
// basically the "This video is a private video uploaded by" message
const userURL = doc.querySelector('.username a').href;
var vid_code = userURL.replace("https://www.camwhores.tv/members/", "");
var usernameID = vid_code.split("/")[0];
return { byFriend: hasElement1 || hasElement2, usernameID: usernameID };
} catch (error) {
console.error('Error checking video page:', error);
return { byFriend: false, usernameID: null };
}
}
async function applyStyleToPrivateVideos() {
const privateVideos = addPrivateVideos();
for (const video of privateVideos) {
let videoLink = video.getAttribute('href');
let videoTitle = video.querySelector('strong.title').textContent.trim();
let { byFriend: hasElement, usernameID } = await checkVideoPage(videoLink);
// console.log(videoLink + " " + hasElement);
if (!hasElement) {
video.style.outline = 'green solid 2px';
const linePrivate = video.querySelector('div > .line-private');
if (linePrivate) {
linePrivate.style.display = 'none';
}
let 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 += ' ❌';
const addFriend = document.createElement('a');
addFriend.textContent = '➕';
addFriend.title = 'Friend request';
addFriend.href = "https://www.camwhores.tv/members/" + usernameID + "/#friends";
addFriend.style.zIndex = '10';
addFriend.style.position = 'absolute';
addFriend.style.bottom = '20px';
addFriend.style.right = '0';
addFriend.style.fontSize = '1rem';
addFriend.style.padding = '5px 2.5px';
addFriend.style.backgroundColor = 'hsla(0, 0%, 0%, 0.7)';
addFriend.addEventListener('click', function(event) {
alert(videoTitle)
friendRequestSetup(videoTitle, videoLink)
});
let thumbDiv = video.querySelector('.img')
thumbDiv.appendChild(addFriend);
// video.style.outline = "2px solid red"
}
}
await new Promise(resolve => setTimeout(resolve, 25)); // avoid 503
}
}
applyStyleToPrivateVideos();
function findRelevantKeywords() {
const titles = document.querySelectorAll('.title');
titles.forEach(title => {
const originalText = title.innerHTML;
highlight_keywords.forEach(keyword => {
const regex = new RegExp(keyword, 'gi');
if (originalText.match(regex)) {
const highlightedText = originalText.replace(regex, '<span style="color: green;">$&</span>');
title.innerHTML = highlightedText;
}
});
});
}
findRelevantKeywords()
// Define a global array to store blacklisted image sources
const blacklist = [];
function moveToSecondThumbnail() {
$('.thumb.lazy-load').off('mouseover').off('mouseout');
document.querySelectorAll('.thumb.lazy-load').forEach(image => {
const src = image.getAttribute('src');
if (blacklist.includes(src)) {
return;
}
const newSrc = src.replace('1.jpg', '2.jpg');
// console.log("ye")
if (src && src.endsWith('1.jpg')) {
image.setAttribute('src', newSrc);
}
const images = ['3.jpg', '4.jpg', '5.jpg', '1.jpg', '2.jpg'];
let currentIndex = 0;
let intervalId;
const loopImages = () => {
if (src && src.endsWith('jpg')) {
const newSrcName = images[currentIndex];
const newSrc = src.substring(0, src.length - 5) + newSrcName;
console.log(newSrc)
image.setAttribute('src', newSrc);
currentIndex = (currentIndex + 1) % images.length;
}
};
const mouseoverHandler = () => {
clearInterval(intervalId);
intervalId = setInterval(loopImages, 500);
};
const mouseoutHandler = () => {
if (src && src.endsWith('1.jpg') && !(blacklist.includes(src))) {
image.setAttribute('src', newSrc);
}
clearInterval(intervalId);
};
// Create a new image element to check if the original image was loaded successfully
const testImage = new Image();
testImage.src = src;
testImage.onload = function() {
// Image loaded successfully
// console.log('Image loaded successfully:', src);
};
testImage.onerror = function() {
// Image failed to load (404 error)
// console.log('Image failed to load (404 error):', src);
blacklist.push(src);
image.setAttribute('src', src);
// Remove previous mouseover and mouseout event listeners
image.removeEventListener('mouseover', mouseoverHandler);
image.removeEventListener('mouseout', mouseoutHandler);
};
// Add mouseover and mouseout event listeners
image.addEventListener('mouseover', mouseoverHandler);
image.addEventListener('mouseout', mouseoutHandler);
});
// console.log(blacklist);
}
altThumbs && moveToSecondThumbnail();
setInterval(() => {
applyStyleToPrivateVideos();
findRelevantKeywords()
altThumbs && moveToSecondThumbnail();
}, 750); // 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");
const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2');
const initialText = h2Element.textContent.trim();
// console.log("Initial text: " + initialText);
const checkChangeInterval = setInterval(function() {
const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2');
const currentText = h2Element.textContent.trim();
// console.log("Current text: " + currentText);
if (currentText !== initialText) {
clearInterval(checkChangeInterval);
updateH2Element();
}
}, 100);
}
});
}
updateH2Element()
addButtonEventListener()
// console.log(friend_request_text)
if (window.location.href.endsWith("#friends") && !window.location.href.includes("add_to_friends_done")) {
let addButton = document.querySelector('a[href="#friends"][data-action="add_to_friends"]');
let textarea = document.getElementById('add_to_friends_message');
let lastCumTitle = localStorage.getItem('last_cum_title');
let lastVidCode = localStorage.getItem('last_cum_vid_id');
let lastCumUsername = localStorage.getItem('last_cum_username_fr');
let pageTitle = document.title;
let username = pageTitle.replace("'s Page", "");
if (textarea !== null && !addButton.classList.contains('done') && username !== lastCumUsername && lastCumTitle !== null && addButton !== null) {
textarea.value = "";
textarea.value += friend_request_text + " " + lastCumTitle + "\n##" + lastVidCode;
console.log("Textarea text set");
document.querySelector('input[type="submit"].submit[value="Invite"]').click();
localStorage.setItem('last_cum_username_fr', username);
addButton.click();
}
}else if(window.location.href.includes("add_to_friends_done")){
let addButton = document.querySelector('a[href="#friends"][data-action="add_to_friends"]');
if (addButton !== null && !addButton.classList.contains('done')) {
addButton.classList.add('done');
}
}
} // END of member profile
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 {
var infoElement = null;
if(element1 !== null){
infoElement = element1
}else{
infoElement = element2
}
console.log("Not friends!");
let headline = document.querySelector('body > div.container > div.content > div.headline > h1');
if (headline !== null) {
let title = headline.textContent.trim();
// localStorage.setItem('last_cum_title', title);
var currentUrl = window.location.href;
friendRequestSetup(title, currentUrl);
// var vid_code = currentUrl.replace("https://www.camwhores.tv/videos/", "");
// var parts = vid_code.split("/");
// var videoId = parts[0];
// var code = parts[1];
// localStorage.setItem('last_cum_vid_id', videoId);
// console.log("vid_code:"+vid_code)
// console.log("Video ID: " + videoId);
// console.log("code:\n" + code + "\n"+makeValidUrlString(code));
const userProfileUrl = infoElement.querySelector('a').getAttribute('href') + "#friends";
console.log(userProfileUrl)
const toggleButton = document.createElement('a');
toggleButton.classList.add("button");
toggleButton.textContent = "Send request";
toggleButton.href = userProfileUrl
toggleButton.style.display= "inline-block";
toggleButton.style.display= "#4e4e4e";
infoElement.appendChild(document.createElement('br'));
infoElement.appendChild(toggleButton);
} else {
console.log("Element not found");
}
}
})
.catch(error => console.error('Error fetching:', error));
}
}
}
})();