Keyboard Display Script

shows keyboard inputs on screen

Versão de: 07/08/2019. Veja: a última versão.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Keyboard Display Script
// @namespace    http://tampermonkey.net/
// @version      0.25.2
// @description  shows keyboard inputs on screen 
// @author       Oki and meppydc
// @match        https://*.jstris.jezevec10.com/*
// @grant        none
// ==/UserScript==

/**************************
   Keyboard Display Script
**************************/
(function() {
    window.addEventListener('load', function() {

        //Only display the keyboard if either in a Game or Replay
        if (typeof Game != "undefined" || typeof Replayer != "undefined") {

            //labels are     0     1     2          3
            var labels = ['180','SD', 'HD',      'CCW',
                          // 4     5     6     7    8     9
                          'HL', 'CW', 'jez', '<', 'v', '>']
            //          left right  sd hd ccw cw hold 180 reset new
            //order is: [6,    8,   1,  2, 3,  5,  4,  0] (.22)
            //order is: [7,    9,   8,  2, 5,  6,  1,  4] (.23)
            //order is: [7,    9,   8,  2, 5,  6,  1,  4] (.24)
            //order is: [7,    9,   8,  2, 5,  6,  1,  4,   0    3] (.24.1)
            //order is: [7,    9,   8,  3, 5,  6,  2,  4,   0    1] (.24.2)
            //0.25 added crap ton of variables, maybe use dictionary instead?
            //0.25.1 enum
            let kbdisplay = {left:7,right:9,sd:1,hd:2,ccw:3,cw:5,hold:5,180:0,reset:6,new:8}


            //var highlight = [[6,2],[8,2],[6,0],[8,0],[3,2],[5,2],[0,2],[2,2],[1,2],,[4,2]][this['actions'][this['ptr']]["a"]] //reference




            if (typeof getParams != "function") {
                var getParams = a => {
                    var params = a.slice(a.indexOf("(") + 1);
                    params = params.substr(0, params.indexOf(")")).split(",");
                    return params
                }
            }
            if (typeof trim != "function") {
                var trim = a => {
                    a = a.slice(0, -1);
                    a = a.substr(a.indexOf("{") + 1);
                    return a
                }
            }

            //Create the "keyboard holder". It's a div positioned where the keyboard will be, but it doesnt contain anything yet.
            var kbhold = document.createElement("div");
            kbhold.id = "keyboardHolder";
            kbhold.style.position = "absolute"
            //Im trying to position it relative to the main canvas (this doesnt really work well...)
            kbhold.style.left = (myCanvas.getBoundingClientRect().left - 300) + "px";
            kbhold.style.top = (myCanvas.getBoundingClientRect().top + 100) + "px";

            //Helper method for keyboards in replays
            if (typeof Replayer != "undefined" && typeof Game == "undefined") {
                Replayer["pressKey"] = function(num, type) {
                    console.log(num)
                    //type: 0=release 1=down 2=press
                    //Highlights the corresponding key
                    //gets array of all "kbkey" classes and takes cell "num" and hightlights it
                    document.getElementsByClassName("kbkey")[num].style.backgroundColor = type ? "lightgoldenrodyellow" : ""
                    if (type == 2) {
                        //from replay data you dont really know how long a key has been pressed. im using 100ms as a default
                        setTimeout(x => {
                            document.getElementsByClassName("kbkey")[num].style.backgroundColor = ""
                        }, 100)
                    }

                }
                //positions the keyboard holder differently for replays (thanks to meppydc)
                kbhold.style.left = (myCanvas.getBoundingClientRect().right + 200) + "px";
                kbhold.style.top = (myCanvas.getBoundingClientRect().top + 200) + "px";
            }

            document.body.appendChild(kbhold);


            //(important)
            //this is what is pasted into the keyboard holder and makes up the entire visual keyboard.
            //(i decompressed and tidied it up a bit)
            //basically it's a table consisting of 2 rows and 6 columns
            //maybe read up on css tables if you wanna add new cells


            f = `

<style>
#kbo {text-align:center;position: absolute;font-size:15px;}
#kbo .tg {border-collapse:collapse;border-spacing:0;color:red;}
#kbo .tg td{padding:10px 5px;border-style:solid;border-width:2px;}
#kbo .tg th{padding:10px 5px;border-style:solid;border-width:2px;}
#kbo .tg .tg-wp8o{border-color:#000000;border:inherit;}
#kbo .tg .tg-tc3e{border-color:#34ff34;}
#kbo .tg .tg-jy2k{border-color:#f8a102;}
#kbo .tg .tg-p39m{border-color:#f8ff00;
}</style>

<div id=\"kbo\"><div id=\"kps\"></div>
<table class=\"tg\">
	<tr>
		<td class=\"tg-tc3e kbkey\">${labels[0]}</td>
		<td class=\"tg-tc3e kbkey\">${labels[1]}</td>
		<td class=\"tg-tc3e kbkey\">${labels[2]}</td>
		<td class=\"tg-wp8o\"></td>
		<td class=\"tg-jy2k kbkey\">${labels[3]}</td>
		<td class=\"tg-wp8o\"></td>
	</tr>
	<tr>
		<td class=\"tg-p39m kbkey\">${labels[4]}</td>
		<td class=\"tg-p39m kbkey\">${labels[5]}</td>
		<td class=\"tg-p39m kbkey\">${labels[6]}</td>
		<td class=\"tg-jy2k kbkey\">${labels[7]}</td>
		<td class=\"tg-jy2k kbkey\">${labels[8]}</td>
		<td class=\"tg-jy2k kbkey\">${labels[9]}</td>
	</tr>
</table>
</div>
`
            keyboardHolder.innerHTML = f

            //keyboard if in game (not replays)********************************************************************************************************************************
            if (typeof Game != "undefined") {

                document['addEventListener']('keydown', press);
                document['addEventListener']('keyup', press);

                function press(e) {
                    if (~Game['set2ings'].indexOf(e.keyCode)) {
                        //console.log(Game['set2ings'])//displays the keycodes of your controls
                        // left right sd hd ccw cw hold 180
                        //(important)
                        //listens to pressed keys and highlights the corresponsing div.
                        //the magic array converts between the actions and the div that is highlighted.
                        //If you change the order of the boxes, you might also have to adjust the numbers in this array
                        //           left right sd hd ccw cw hold 180 reset new
                        //order is: [6,    8,   1,  2, 3,  5,  4,  0] (.22 order)
                        //order is: [7,    9,   8,  2, 5,  6,  1,  4] (.23 order)
                        //order is: [7,    9,   8,  2, 5,  6,  1,  4] (.24 order)
                        //order is: [7,    9,   8,  2, 5,  6,  1,  4,   0    3] (.24.1 order)
                        //order is: [7,    9,   8,  3, 5,  6,  2,  4,   0    1] (.24.2 order)
                        var corresponding = [kbdisplay.left, kbdisplay.right, kbdisplay.sd, kbdisplay.hd, kbdisplay.ccw, kbdisplay.cw, kbdisplay.hold, kbdisplay['180'], kbdisplay.reset, kbdisplay.new][Game['set2ings'].indexOf(e.keyCode)]
                        document.getElementsByClassName("kbkey")[corresponding].style.backgroundColor = ["lightgoldenrodyellow", ""][+(e.type == "keyup")]
                    }
                }

                //This saves the settings array (which maps all actions in jstris to their keycodes) to a global variable for me to use (called Game['se2ings'])
                //resets every time a new game is started
                var set2ings = Game['prototype']['readyGo'].toString()
                set2ings = "Game['set2ings']=this.Settings.controls;" + trim(set2ings)
                Game['prototype']['readyGo'] = new Function(set2ings);

                //calculates kps from kpp and pps and writes it into the kps element
                var updateTextBarFunc = Game['prototype']['updateTextBar'].toString()
                updateTextBarFunc = trim(updateTextBarFunc) + ";kps.innerHTML='KPS: '+(this.getKPP()*this.placedBlocks/this.clock).toFixed(2)"
                Game['prototype']['updateTextBar'] = new Function(updateTextBarFunc);
            } else {

                //else: we're in a replay********************************************************************************************************************************

                var website = "jstris.jezevec10.com"
                var url = window.location.href
                var parts = url.split("/")

                if (parts[3] == "replay" && parts[2].endsWith(website)) {

                    //making a web request for the sole purpose of getting the DAS that was used for the replay
                    //(can be done more elegantly)
                    fetch("https://" + parts[2] + "/replay/data?id=" + (parts.length == 6 ? (parts[5] + "&live=1") : (parts[4])))
                        .then(function(response) {
                            return response.json();
                        })
                        .then(function(jsonResponse) {
                            var das = jsonResponse.c.das
                            var playT = Replayer['prototype']['playUntilTime'].toString()
                            var playTparams = getParams(playT);


                            //going though the list of actions done in the replay, and translating that into the timings for highlighting the divs
                            //i dont rememer how exactly i did this but it's not pretty
                            var insert1 = `
			kps.innerHTML="KPS: "+(this.getKPP()*this.placedBlocks/(this.clock/1000)).toFixed(2)
			this["delayedActions"] = []
			for (var i = 0; i < this["actions"].length; i++) {
				var action = JSON.parse(JSON.stringify(this["actions"][i]));
				if(action.a == 2 || action.a == 3){
					action.t = (action.t-` + das + `)>0 ? (action.t-` + das + `) : 0
				}
				this["delayedActions"].push(action)
			}

			this["delayedActions"].sort(function(a, b) {
    			return a.t - b.t;
			});

			var oldVals = [this["timer"],this["ptr"]]

			while (` + playTparams[0] + ` >= this['delayedActions'][this['ptr']]['t']) {
			    if (this['ptr']) {
			        this['timer'] += (this['delayedActions'][this['ptr']]['t'] - this['delayedActions'][this['ptr'] - 1]['t']) / 1000
			    };
			    if(this['delayedActions'][this['ptr']]["a"] == 2){
			    	Replayer["pressKey"](${kbdisplay.left},1)
			    }
				if(this['delayedActions'][this['ptr']]["a"] == 3){
			    	Replayer["pressKey"](${kbdisplay.right},1)
			    }

			    this['ptr']++;
			    if (this['delayedActions']['length'] === this['ptr']) {
			        this['reachedEnd'] = true;
			        break
			    }
			};

			this["timer"] = oldVals[0]
			this["ptr"] = oldVals[1]`


                            //this maps a specific action (this['actions'][this['ptr']]["a"]) to what to do with the divs
                            //the list of what action code equals what action is in that one harddrop forum post
                            //for example, if you DAS_LEFT then left will be held down.
                            //You might also adjust the numbers here (the first number in the pairs. remap them the same as in the magic array)
                            var insert2 = `
			var highlight = [[${kbdisplay.left},2],[${kbdisplay.right},2],[${kbdisplay.left},0],[${kbdisplay.right},0],[${kbdisplay.ccw},2],[${kbdisplay.cw},2],[${kbdisplay['180']},2],[${kbdisplay.hd},2],[${kbdisplay.sd},2],,[${kbdisplay.hold},2]][this['actions'][this['ptr']]["a"]]
			if(highlight){
				Replayer["pressKey"](...highlight)
			};
			`

                            playT = playT.replace(";", insert1 + ";")
                            playT = playT.replace("1000};", "1000};" + insert2)
                            Replayer['prototype']['playUntilTime'] = new Function(...playTparams, trim(playT));

                        //i hate myself - Oki
                        //I heard jez whips Oki - meppydc
                        //I hate myself as well once it stopped working when I did basically nothing - meppydc
                        //typing var names sucks - meppydc
                        });
                }
            }
        }
    });
})();