// ==UserScript==
// @name cb theatermode clean
// @namespace chaturbate_theater_goes_ladroop
// @version 0.91
// @description profile clean up and video settings
// @license MIT
// @match https://*.chaturbate.com/*
// @noframes
// @grant none
// @run-at document-end
// ==/UserScript==
var n=0; // counters
var i=0;
var varea=""; // video area
var container="";// bio area
var add3=""; // top add
var topbar=""; // menu top bar
var buttons=""; // buttons area
var loggedin=false; // login status
var observer = "";
var observerConfig = "";
var observenode="";// node to observe if page is changed
var roomname="";//broadcasters name
// used in multiple functions
var url="";
var br="";
var ofils=[];
var tags=[];
// things i want to remember across functions from the broadcaster
var allow_group_shows=false;
var allow_private_shows=false;
var room_status="public";
var hls_source=""; // if you want to fork , this contains the HTML5 video link (as not logged in)
test();
// test if bio container is created , give up after 10 seconds
function test(){
if(document.getElementsByClassName("bio-container")[0]){n=0;test2()}
else{
n++;
if (n==100){return}
setTimeout(function(){ test() }, 100);
}
}
// check if data is written in the bio conatiner
function test2(){
if(document.getElementsByClassName("bio-container")[0].getElementsByTagName("span").length >= 2){test3()}
else{
n++;
if (n==30){main()}// no bio
setTimeout(function(){ test2() }, 100);
}
}
// wait if bio is ready
function test3(){
var biocont=document.getElementsByClassName("bio-container")[0].innerHTML;
setTimeout(function(){
if (biocont == document.getElementsByClassName("bio-container")[0].innerHTML){
main();
}else{
test3();
}
}, 100);
}
function main(){
//first get some locations
tags=document.getElementsByTagName("div")[0].childNodes;
add3=tags[0].getElementsByTagName("ins")[0].parentNode;
topbar=tags[0].childNodes[5];
container=document.getElementsByClassName("bio-container")[0];
tags = document.getElementsByTagName("span");
for (n=0; n<tags.length; n++){
if (tags[n].innerHTML == "+ FOLLOW"){
buttons=tags[n].parentNode;
break;
}
}
if (document.getElementById("xmovie")){
varea=document.getElementById("xmovie")}
else{
varea=document.getElementsByTagName("video")[0];
}
roomname=document.location.href.split("/")[3];
if (roomname=="theatermode"){
roomname=document.location.href.split("?b=")[1];
}
// do some actions
removeadds();
cleanoptions();
makebutton();
linkfix();
imgfix();
cleanup();
info();
refreshed();
checkban();
}
//-----------------functions in random order
// remove add's
function removeadds(){
tags=document.getElementsByTagName("div")[0].childNodes;
for (n=0; n<tags.length; n++){
if(tags[n].innerHTML.indexOf("HIDE ALL ADS NOW")!=-1){
tags[n].style.display="none";
observenode=tags[n];
}
}
add3.innerHTML="<div style='font-size: 11px;'>Chaturbate theater mode script version "+GM_info.script.version+"(Beta). Made By Ladroop</div>";
add3.id="update";
window.dispatchEvent(new Event('resize'));
}
//check if you can enter the room and if not make a jpg player. first undo all changes in case you refreshed from a room you could not enter
function checkban(){
if (document.getElementById("vidimg")){
document.getElementById("vidimg").parentNode.removeChild(document.getElementById("vidimg"));
document.getElementById("clean").style.display="block";
if (document.getElementById("xmovie")){
document.getElementById("vidre").style.display="block";
}
}
if (container.innerHTML == ""){
var newvid = document.createElement('img');
newvid.src="https://chaturbate.com/static/theatermodeassets/cam_notice_background.jpg";
newvid.style.width="100%";
newvid.style.height="100%";
newvid.id="vidimg";
var vidpar=varea.parentNode;
vidpar.insertBefore(newvid,vidpar.childNodes[0])
varea=document.getElementById("vidimg");
vreset();
document.getElementById("clean").style.display="none";
document.getElementById("vidre").style.display="none";
var errcnt=1;
var wtime=0;
var cimg = new Image();
cimg.onload = function(){
document.getElementById("vidimg").src=cimg.src;
setTimeout(function(){ cimg.src = 'https://cbjpeg-serve.stream.highwebmedia.com/stream?room='+location.search.split("=")[1]+'&f='+ new Date().getTime();errcnt=1 }, 100);
}
cimg.onerror = function(){
errcnt++;
wtime=100*errcnt;
if (wtime>10000){wtime=10000}
setTimeout(function(){ cimg.src = 'https://cbjpeg-serve.stream.highwebmedia.com/stream?room='+location.search.split("=")[1]+'&f='+ new Date().getTime(); }, wtime);
}
cimg.src = 'https://cbjpeg-serve.stream.highwebmedia.com/stream?room='+location.search.split("=")[1]+'&'+ new Date().getTime();
container.style.height="300px";
}
}
// check if page is refreshed and rewritten
function refreshed(){
observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(mutation.attributeName === 'style'){
observer.disconnect();
removeadds();
if (document.getElementById("xmovie")){
varea=document.getElementById("xmovie")}
else{
varea=document.getElementsByTagName("video")[0];
}
// fix wrong location bug , only with flash
if (document.getElementById("xmovie")){
flashstart();
}
vreset();
// here check if bio is ready again
retest2();
}
});
});
observerConfig = {
attributes: true
}
observer.observe(observenode, observerConfig);
}
// recheck if data is written in the bio conatiner - part of refreshed()
function retest2(){
if(document.getElementsByClassName("bio-container")[0].getElementsByTagName("span").length >= 2){retest3()}
else{
n++;
if (n==30){reclean()}// no bio
setTimeout(function(){ retest2() }, 100);
}
}
// wait if bio is ready - part of refreshed()
function retest3(){
var biocont=document.getElementsByClassName("bio-container")[0].innerHTML;
setTimeout(function(){
if (biocont == document.getElementsByClassName("bio-container")[0].innerHTML){
reclean();
}else{
retest3();
}
}, 100);
}
// clean only bio after refesh and restart the observer - part of refreshed()
function reclean(){
linkfix();
imgfix();
cleanup();
info();
checkban();
observer.observe(observenode, observerConfig);
}
// clean the option bar and see if you're logged in
function cleanoptions(){
tags=topbar.getElementsByTagName("a");
for (n=0; n<tags.length; n++){
if (tags[n].href.indexOf('/login') != -1){
if(tags[n].style.display=="none"){
loggedin=true;
}
}
if (tags[n].href.indexOf('/free_') != -1){
tags[n].href="https://"+location.hostname+"/"+roomname;
tags[n].innerHTML="CHAT IN OLD LAYOUT";
tags[n].addEventListener("click", function(){eraseCookie("cb2")});
}
if (!((tags[n].href.indexOf('/login') != -1)||(tags[n].innerHTML.indexOf('CHAT') != -1)||(tags[n].href.indexOf('/b/') != -1)||(tags[n].href.indexOf('/register') != -1)||(tags[n].href.indexOf('/my_') != -1)||(tags[n].href.indexOf('/tags') != -1))){
tags[n].style.display="none";
}
}
}
// make all new buttons and sliders and set the video filter
function makebutton(){
var butstyle="margin-right: 10px;color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; text-shadow: rgb(241, 129, 18) 1px 1px 0px; padding: 4px 10px 3px; position: relative; top: -6px; right: 1px; float: right; border-radius: 4px; cursor: pointer; display: inline;";
var slistyle="text-align: right; width: 310px;margin-right: 10px;color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; text-shadow: rgb(241, 129, 18) 1px 1px 0px; padding: 4px 10px 3px; position: relative; top: -6px; right: 1px; float: right; border-radius: 4px; display: inline;";
var newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="CLEAN PROFILE = ON";
newbutton.id="clean";
newbutton.addEventListener("click", cleancookie);
buttons.appendChild(newbutton);
newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="VIDEO CONTROLS ON/OFF";
newbutton.addEventListener("click", vcontrol);
buttons.appendChild(newbutton);
newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="RESTART VIDEO";
newbutton.addEventListener("click", flashstart);
newbutton.id="vidre";
buttons.appendChild(newbutton);
var newbr=document.createElement('br');
buttons.appendChild(newbr);
newbr=document.createElement('br');
buttons.appendChild(newbr);
newbutton=document.createElement('span');
newbutton.id="controls";
newbutton.style.display="none";
newbutton.style.position="absolute";
newbutton.style.right="300px";
buttons.appendChild(newbutton);
newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="MIRROR VIDEO";
newbutton.addEventListener("click",mirror);
document.getElementById("controls").appendChild(newbutton);
newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="INVERT VIDEO";
newbutton.addEventListener("click",invert);
document.getElementById("controls").appendChild(newbutton);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbutton=document.createElement('span');
newbutton.setAttribute("style", slistyle);
newbutton.innerHTML="BRIGHTNESS : <input type='range' id='myRange' value=50 style='width: 200px;height:11px;cursor: pointer;'>";
document.getElementById("controls").appendChild(newbutton);
document.getElementById("myRange").addEventListener("change",badjust);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbutton=document.createElement('span');
newbutton.setAttribute("style", slistyle);
newbutton.innerHTML="CONTRAST : <input type='range' id='myRange1' value=50 style='width: 200px;height:11px;cursor: pointer;'>";
document.getElementById("controls").appendChild(newbutton);
document.getElementById("myRange1").addEventListener("change",cadjust);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbutton=document.createElement('span');
newbutton.setAttribute("style", slistyle);
newbutton.innerHTML="SATURATION : <input type='range' id='myRange2' value=50 style='width: 200px;height:11px;cursor: pointer;'>";
document.getElementById("controls").appendChild(newbutton);
document.getElementById("myRange2").addEventListener("change",sadjust);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbutton=document.createElement('span');
newbutton.setAttribute("style", slistyle);
newbutton.innerHTML="HUE : <input type='range' id='myRange3' value=360 min=180 max=540 style='width: 200px;height:11px;cursor: pointer;'>";
document.getElementById("controls").appendChild(newbutton);
document.getElementById("myRange3").addEventListener("change",hadjust);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbr=document.createElement('br');
document.getElementById("controls").appendChild(newbr);
newbutton=document.createElement('span');
newbutton.setAttribute("style", butstyle);
newbutton.innerHTML="RESET ALL";
newbutton.addEventListener("click",vreset);
document.getElementById("controls").appendChild(newbutton);
if (!document.getElementById("xmovie")){
document.getElementById("vidre").style.display="none";
}
vreset();
}
// fix the redirection links in profile
function linkfix(){
tags = container.getElementsByTagName('a');
for (i=0; i<tags.length; i++){
if (tags[i].href.indexOf('?url=') != -1){
tags[i].href=decodeURIComponent(tags[i].href).split("?url=")[1];
}
}
}
// hide the lock on paid profile pictures
function imgfix(){
tags = container.getElementsByTagName('img');
for (i=0; i<tags.length; i++){
if (tags[i].src.indexOf('theatermodeassets/locked_rectangle') != -1){
tags[i].style.display="none";
}
}
}
// get basic info
function info(){
url="https://"+location.hostname+"/api/chatvideocontext/"+roomname+"/";
fetch(url).then(
function(response) {
if (response.status !== 200) {
return;
}
response.json().then(function(data) {
allow_group_shows=data.allow_group_shows;
allow_private_shows=data.allow_private_shows;
room_status=data.room_status;
hls_source=data.hls_source;
if (data.low_satisfaction_score==true){
wprof("Satisfaction score:","<font color=#CC0000>LOW !!!</font>");
}
if (data.is_age_verified==false){
wprof("Status:","Exhibitionist");
return;
}
// next can only be done if logged in
if (loggedin){
getpvt();
getgrp();
getspy();
}
});
}
)
}
// get private costs info - part of info()
function getpvt(){
if (allow_private_shows){
url="https://"+location.hostname+"/tipping/private_show_tokens_per_minute/"+roomname+"/";
fetch(url,{ credentials: "same-origin"}).then(
function(response) {
if (response.status !== 200) {
return;
}
response.json().then(function(data) {
wprof("Minimum private:",data.private_show_minimum_minutes+" Minutes");
wprof("Private recording:",data.recordings_allowed ? "Yes":"No");
wprof("Privateshow:",data.price+" Tk/min");
});
}
)
}else{
wprof("Privateshow:","Disabled");
}
}
// get goupshow costs info - part of info()
function getgrp(){
if (allow_group_shows){
url="https://"+location.hostname+"/tipping/group_show_tokens_per_minute/"+roomname+"/";
fetch(url,{ credentials: "same-origin"}).then(
function(response) {
if (response.status !== 200) {
return;
}
response.text().then(function(data) {
wprof("Groupshow:",data+" Tk/min");
});
}
)
}else{
wprof("Groupshow:","Disabled");
}
}
// get spy costs info - part of info()
function getspy(){
if (room_status=="private"){
url="https://"+location.hostname+"/tipping/spy_on_private_show_tokens_per_minute/"+roomname+"/";
fetch(url,{ credentials: "same-origin"}).then(
function(response) {
if (response.status !== 200) {
return;
}
response.text().then(function(data) {
if (data!="0"){
wprof("Spy on private:",data+" Tk/min");
}else{
wprof("Spy on private:","Disabled");
}
});
}
)
}
}
//-------------- later called functions
// brightness adjust
function badjust(){
br=document.getElementById("myRange").value*2;
ofils=varea.style.filter.split(" ");
varea.style.filter="brightness("+br+"%) "+ofils[1]+" "+ofils[2]+" "+ofils[3]+" "+ofils[4];
}
// contrast adjust
function cadjust(){
br=document.getElementById("myRange1").value*2;
ofils=varea.style.filter.split(" ");
varea.style.filter=ofils[0]+" contrast("+br+"%) "+ofils[2]+" "+ofils[3]+" "+ofils[4];
}
// saturation adjust
function sadjust(){
br=document.getElementById("myRange2").value*2;
ofils=varea.style.filter.split(" ");
varea.style.filter=ofils[0]+" "+ofils[1]+" "+ofils[2]+" saturate("+br+"%) "+ofils[4];
}
// hue adjust
function hadjust(){
br=document.getElementById("myRange3").value;
if (br > 359){br=br-360;}
ofils=varea.style.filter.split(" ");
varea.style.filter=ofils[0]+" "+ofils[1]+" "+ofils[2]+" "+ofils[3]+" hue-rotate("+br+"deg)";
}
// invert video
function invert(){
ofils=varea.style.filter.split(" ");
br=" invert(100%) ";
if (ofils[2]=="invert(100%)"){br=" invert(0%) ";}
varea.style.filter=ofils[0]+" "+ofils[1]+br+ofils[3]+" "+ofils[4];
}
// mirror video
function mirror(){
if (varea.style.transform=="none"){
varea.style.transform="matrix(-1, 0, 0, 1, 0, 0)";
}else{
varea.style.transform="none";
}
}
// reset all video adjustments
function vreset(){
varea.style.filter="brightness(100%) contrast(100%) invert(0%) saturate(100%) hue-rotate(0deg)";
varea.style.transform="none";
document.getElementById("myRange").value=50;
document.getElementById("myRange1").value=50;
document.getElementById("myRange2").value=50;
document.getElementById("myRange3").value=360;
}
// video controls on/off
function vcontrol(){
if (document.getElementById("controls").style.display=="block"){
document.getElementById("controls").style.display="none";
}else{
document.getElementById("controls").style.display="block";
}
}
// swap profile cleanup cookie and cleanup
function cleancookie(){
if (readCookie("pclean")){
eraseCookie("pclean");
}else{
createCookie("pclean",1,30);
}
cleanup();
}
// hide or unhide elements in profile according to cookie
function cleanup(){
var taglist=["a","p","i","strong","b","u","ul","ol","li","h1","h2","h3","img","font","br"];
var claction=!readCookie("pclean");
if (claction){
document.getElementById("clean").innerHTML= "CLEAN PROFILE = ON ";
}else{
document.getElementById("clean").innerHTML= "CLEAN PROFILE = OFF";
}
for (i=0; i<taglist.length-1; i++){
if (claction){
blockelm (taglist[i]);
}else{
unblockelm (taglist[i]);
}
}
}
// hide elements in profile - part of cleanup()
function blockelm(tag){
tags = container.getElementsByTagName(tag);
for (n=0; n<tags.length; n++){
if (tags[n].style.position){
if ((tags[n].style.position.indexOf("absolute")!=-1)||(tags[n].style.position.indexOf("fixed")!=-1)){
if (tags[n].getAttribute("rel")){
tags[n].setAttribute("ostyle", "1");
tags[n].style.display="none";
}
}
}
}
}
// unhine elements in profile if they have been hidden - part of cleanup()
function unblockelm(tag){
tags = container.getElementsByTagName(tag);
for (n=0; n<tags.length; n++){
if (tags[n].style.position){
if (tags[n].getAttribute("ostyle")){
tags[n].style.display="block";
}
}
}
}
// write a line in the profile at the top
function wprof(row1,row2){
var newdiv=document.createElement('div');
newdiv.style.fontWeight="normal";
newdiv.style.margin="9px 0px";
var newspan=document.createElement('span');
newspan.style.display="inline-block";
newspan.style.color="rgb(12, 106, 147)";
newspan.style.fontFamily="UbuntuMedium, Helvetica, Arial, sans-serif";
newspan.style.fontSize="14px";
newspan.style.width="150px";
newspan.innerHTML=row1;
newdiv.appendChild(newspan);
newspan=document.createElement('span');
newspan.style.color="rgb(51, 51, 51)";
newspan.style.fontSize="14px";
newspan.style.width="87.5%";
newspan.innerHTML=row2;
newdiv.appendChild(newspan);
var firstrowp=container.getElementsByTagName("span")[0].parentNode;
firstrowp.parentNode.insertBefore(newdiv, firstrowp);
}
// restarts flash video and puts it back as 1st element
function flashstart(){
var vid=varea.cloneNode(true);
var vidpar=varea.parentNode;
vidpar.removeChild(varea);
vidpar.insertBefore(vid,vidpar.childNodes[0])
varea=document.getElementById("xmovie");
}
// cookie functions
function createCookie(name,value,days,domain){
if (domain){
domain=";domain=."+domain;
}else{
domain = "";
}
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}else{
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/"+domain;
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(n=0;n < ca.length;n++) {
var c = ca[n];
while (c.charAt(0)==' '){
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) == 0){
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function eraseCookie(name,domain){
createCookie(name,"",-1,domain);
}