您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
shows keyboard inputs on screen
// ==UserScript== // @name Jstris Keyboard Display Script // @namespace http://tampermonkey.net/ // @version 0.0.0 // @description shows keyboard inputs on screen // @author mat1jaczyyy (based on Oki and meppydc's works) // @match https://*.jstris.jezevec10.com/* // @grant none // @license MIT // ==/UserScript== /* eslint-disable no-undef */ (function() { window.addEventListener('load', function() { const isGame = typeof Game != "undefined"; const isReplayer = typeof Replayer != "undefined"; if (!isGame && !isReplayer) return; const pos = {x: -300, y: 100}; const keyConfig = [ [ 'new', null, {k: 'reset', l: 'F4'}, ], [ null ], [ '180', 'ccw', 'cw', null, null, 'hd', ], [ null, null, {k: 'hold', l: 'HLD'}, null, {k: 'left', l: 'L'}, 'sd', {k: 'right', l: 'R'} ] ]; var kbhold = document.createElement("div"); kbhold.id = "keyboardHolder"; kbhold.style.position = "absolute" kbhold.style.left = (myCanvas.getBoundingClientRect().left + pos.x) + "px"; kbhold.style.top = (myCanvas.getBoundingClientRect().top + pos.y) + "px"; document.body.appendChild(kbhold); let keyTable = ` <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 .kbnone{border-color:#000000;border:inherit;} #kbo .tg .kbkey{border-color:#34ff34;background-color:black;} </style> <div id="kbo"> <div id="kps"></div> <table class="tg"> `; for (const row of keyConfig) { keyTable += `<tr>`; for (const key of row) { let isKey = key != null; let label = ""; let cssClass = "kbnone"; if (isKey) { label = typeof key == 'string'? key.toUpperCase() : key.l; cssClass = "kbkey kbd-" + (typeof key == 'string'? key.toLowerCase() : key.k); } keyTable += `<td class="${cssClass}">${label}</td>`; } keyTable += `</tr>`; } keyTable += ` </table> </div> `; keyboardHolder.innerHTML = keyTable; let inject = function(o, f, c) { let text = o.prototype[f].toString(); let params = text.slice(text.indexOf("(") + 1, text.indexOf(")")) .trim().split(",") .map(i => i.trim()) .filter(i => i); let body = text.slice(text.indexOf("{") + 1, -1); o.prototype[f] = new Function(...params, c(params, body)); }; let setKey = function(key, type) { for (const td of document.getElementsByClassName(`kbd-${key}`)) { td.style.backgroundColor = ["", "lightgoldenrodyellow"][type]; } } if (isGame) { inject(Game, 'readyGo', (p, i) => "Game['set2ings'] = this.Settings.controls;" + i); inject(Game, 'updateTextBar', (p, i) => i + "; kps.innerHTML = 'KPS: ' + (this.getKPP() * this.placedBlocks / this.clock).toFixed(2);"); let press = function (e) { if (typeof Game.set2ings == 'undefined') return; let i = Game.set2ings.indexOf(e.keyCode); if (i == -1) return; let key = ['left', 'right', 'sd', 'hd', 'ccw', 'cw', 'hold', '180', 'reset', 'new'][i]; setKey(key, +(e.type == "keydown")) } document.addEventListener('keydown', press); document.addEventListener('keyup', press); } else if (isReplayer) { var url = window.location.href.split("/") if (!url[2].endsWith("jstris.jezevec10.com")) return; if (url[3] != "replay") return; fetch(`https://${url[2]}/replay/data?id=${url.length == 6? (url[5] + "&live=1") : url[4]}&type=0`) .then(res => res.json()) .then(json => { let das = json.c.das; Replayer.setKey = setKey; inject(Replayer, 'playUntilTime', (p, i) => { let before = `; kps.innerHTML = 'KPS: ' + (this.getKPP() * this.placedBlocks / this.clock * 1000).toFixed(2); if (this.ptr == 0) Replayer.lastPtr = -1; this.kbdActions = []; for (let i = 0; i < this.actions.length; i++) { let o = {a: this.actions[i].a, t: this.actions[i].t}; if (o.a == 2 || o.a == 3) { o.a -= 2; for (let j = i - 1; j >= 0; j--) { if (this.kbdActions[j].a < 2) { this.kbdActions[j].a += 2; break; } } } this.kbdActions.push(o); } let pressKey = function(key, type) { Replayer.setKey(key, Math.min(type, 1)); if (type == 2) { setTimeout(x => Replayer.setKey(key, 0), ${das} * 3 / 5) } }; `; let after = `; if (this.ptr != Replayer.lastPtr && this.ptr - 1 < this.kbdActions.length) { var highlight = [ ["left", 2], ["right", 2], ["left", 1], ["right", 1], ["ccw", 2], ["cw", 2], ["180", 2], ["hd", 2], ["sd", 2], null, ["hold", 2] ][this.kbdActions[this.ptr - 1].a]; if (highlight) { pressKey(...highlight) } } Replayer.lastPtr = this.ptr; `; return before + i + after; }); }); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址