cb theatermode clean

profile clean up and video settings

As of 2018-06-06. See the latest version.

// ==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 : &nbsp;&nbsp;&nbsp;&nbsp;<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 : &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;";
		}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);
	}