Greasy Fork is available in English.
play/record/modify macros ing
// ==UserScript==
// @name pl macros
// @namespace http://tampermonkey.net/
// @version 0.0085
// @author Heptatron
// @description play/record/modify macros ing
// @match *://powerline.io/*
// @license MIT
// @grant none
// ==/UserScript==
(function () {
'use strict';
var intervals = {};
var keys = {};
var lastTime, tos = [];
var reg, regp, regr, ni;
var A='WDSA';
var B=[...'?wasdqpkzifWASDQPKZIF]-\\[.,;/=`()+|'.split(''), 'Escape', 'Tab'];
var sp=0;
var cm=0;
var im=0;
var rr=0;
var rb=0;
var dd=0;
var ll=0;
var cpreg=[0, 0];
var nu='';
document.addEventListener('keydown', (e) => {
if (rb==1 && !(B.includes(e.key))){
reg=regr=e.key.toUpperCase();
intervals[regr] = [];
keys[regr] = '';
document.addEventListener('keydown', log);
rb += 1;
}
else if (!(B.includes(e.key)) && !(rb == 2 && (e.key.toUpperCase() === regr|| e.key === ' '))) {
if (sp>0){
cpreg[sp-1] = e.key.toUpperCase();
sp = (sp+1)%3;
if (sp == 0 && intervals[cpreg[0]]){
intervals[cpreg[1]] = intervals[cpreg[0]];
keys[cpreg[1]] = keys[cpreg[0]].replaceAll(cpreg[0], cpreg[1]);
beep();reg = cpreg[1];
}
}
else if (cm>0){
cpreg[cm-1] = e.key.toUpperCase();
cm = (cm+1)%3;
if (cm == 0 && intervals[cpreg[0]]&& intervals[cpreg[1]]){
intervals[cpreg[0]] = intervals[cpreg[0]].concat(intervals[cpreg[1]]);
keys[cpreg[0]] += keys[cpreg[1]].replaceAll(cpreg[1], cpreg[0]);
beep();reg = cpreg[0];
}
}else if (im>0){
cpreg[im-1] = e.key.toUpperCase();
im = (im+1)%3;
if (im == 0 && intervals[cpreg[0]] && intervals[cpreg[1]] && intervals[cpreg[0]][1] && intervals[cpreg[1]][1]){
var i = [1, 1]
var t1_arr = intervals[cpreg[0]].map((x=>y=>x+=y)(0));
var t2_arr = intervals[cpreg[1]].map((x=>y=>x+=y)(0));
var i_arr = [0];
var k_str = keys[cpreg[0]][0];
while(1){
if (t1_arr.length > i[0]){
if (t2_arr.length > i[1]){
if (t1_arr[i[0]] < t2_arr[i[1]]){
i_arr.push(t1_arr[i[0]]);
k_str += keys[cpreg[0]][i[0]];
i[0] += 1;
} else{
i_arr.push(t2_arr[i[1]]);
k_str += keys[cpreg[1]][i[1]];
i[1] += 1;
}
} else {
i_arr.push(t1_arr[i[0]]);
k_str += keys[cpreg[0]][i[0]];
i[0] += 1;
}
} else if (t2_arr.length > i[1]){
i_arr.push(t2_arr[i[1]]);
k_str += keys[cpreg[1]][i[1]];
i[1] += 1;
} else {
break;
}
}
intervals[cpreg[0]] = [0].concat(i_arr.slice(1).map((x, i)=>x-i_arr[i]));
keys[cpreg[0]] = k_str.replaceAll(cpreg[1], cpreg[0]);
beep();reg = cpreg[0];
}
} else if (rr == 1){
reg = e.key.toUpperCase();
rr++;
} else if (rr > 0){
nu += e.key;
} else if (dd == 1){
reg = e.key.toUpperCase();
dd++;
} else if (dd > 0){
nu += e.key;
} else if (ll == 1){
reg = e.key.toUpperCase();
ll++;
} else if (ll > 0){
nu += e.key;
} else if(e.key !== ' ' && intervals[e.key.toUpperCase()]){
reg=regp = e.key.toUpperCase();
path(intervals[regp], keys[regp]);
console.log(regp, intervals[regp], keys[regp].replace(/ /g, '-'));
}
} else if (e.key === 'q') {
if (rb==0){
lastTime = null;
}else if(rb==2){
tos.map((to)=>{clearTimeout(to);});
beep();reg=regp;
document.removeEventListener('keydown', log);
}
rb = (rb+1)%3;
} else if(e.key === '='){
if (rr>0){
if (intervals[reg]){
nu = parseInt(nu);
intervals[reg] = new Array(nu).fill(intervals[reg]).flat();
keys[reg] = new Array(nu).fill(keys[reg]).join('');
}
nu = '';
rr = 0;
beep();
}else {
rr++;
}
} else if(e.key === '/'){
if (dd>0){
if (intervals[reg]){
ni = intervals[reg].map((x)=>x/parseFloat(nu.replace("'", '.')));
if (ni.reduce((x, y)=>x+y)>.001)intervals[reg]=ni;
}
dd = 0;
nu='';
beep();
} else{
dd++;
}
} else if(e.key == '?'){
if (ll>0){
if (intervals[reg]){
var max = Math.max(...intervals[reg]);
intervals[reg] = intervals[reg].map(x=>Math.round(x/max*parseFloat(nu))*max/parseFloat(nu));
}
ll = 0;
nu='';
beep();
} else{
ll++;
}
} else if(e.key === 'Escape'){
sp=0;
cm=0;
im=0;
rr=0;
rb=0;
dd=0;
ll=0;
tos.map((to)=>{clearTimeout(to);});
document.removeEventListener('keydown', log);
} else if(e.key === '('){
ni = intervals[reg].map((x)=>x/1.07);
if (ni.reduce((x, y)=>x+y)>.001)intervals[reg]=ni
} else if(e.key === ')'){
intervals[reg] = intervals[reg].map((x)=>x*1.07);
} else if(e.key === '['){
keys[reg] = keys[reg].split('').map((x)=>A.includes(x)?A[(A.indexOf(x)+3)%4]:x).join('');
} else if(e.key === ']'){
keys[reg] = keys[reg].split('').map((x)=>A.includes(x)?A[(A.indexOf(x)+1)%4]:x).join('');
} else if(e.key === '-'){
keys[reg] = keys[reg].replaceAll('D', '.').replaceAll('A', 'D').replaceAll('.', 'A');
console.log('horz', reg);
} else if(e.key === '\\'){
keys[reg] = keys[reg].replaceAll('W', '.').replaceAll('S', 'W').replaceAll('.', 'S');
console.log('vert', reg);
} else if(e.key === '|'){
keys[reg] = ' ' + keys[reg].slice(0, keys[reg].length-2).split('').reverse().join('').replaceAll('W', '.').replaceAll('S', 'W').replaceAll('.', 'S') + 'D';
intervals[reg] = [0, ...intervals[reg].slice(1).reverse()];
} else if(e.key === '`'){
keys[reg] = keys[reg].replace(/./g, ' ');
} else if(e.key === '.'){
sp += 1;
} else if(e.key === ','){
cm += 1;
} else if(e.key === ';'){
im += 1;
} else if(e.key === '+'){
save();
} else if(e.key === 'Tab'){
e.preventDefault();
load().catch(console.error);
}
});
function sendKey(key) {
let keyCode;
let code;
if (key === 'Enter') {
keyCode = 13;
code = 'Enter';
} else {
keyCode = key.charCodeAt(0);
code = 'Key' + key.toUpperCase();
}
const down = new KeyboardEvent('keydown', { bubbles: true });
Object.defineProperty(down, 'keyCode', { get: () => keyCode });
Object.defineProperty(down, 'which', { get: () => keyCode });
Object.defineProperty(down, 'key', { get: () => key });
Object.defineProperty(down, 'code', { get: () => code });
document.dispatchEvent(down);
const up = new KeyboardEvent('keyup', { bubbles: true });
Object.defineProperty(up, 'keyCode', { get: () => keyCode });
Object.defineProperty(up, 'which', { get: () => keyCode });
Object.defineProperty(up, 'key', { get: () => key });
Object.defineProperty(up, 'code', { get: () => code });
document.dispatchEvent(up);
}
function path(C, P){
if((typeof C=== 'undefined')) return;
tos.map((to)=>{clearTimeout(to);});
var n = C.length;
var t = 0;
for (var i=0; i<n; i++){
t += C[i%C.length];
tos.push(setTimeout((i)=>{sendKey(P[i%P.length]);(i==n-1)&&beep();}, t, i));
}
}
function log(e){
if(!((regr+A+' ').includes(e.key.toUpperCase())))return;
const now = performance.now();
keys[regr] += e.key.toUpperCase();
intervals[regr].push((lastTime !== null)?+(now - lastTime).toFixed(2):0);
lastTime = now;
}
function save() {
const data = [JSON.stringify({ i: intervals, k: keys })];
const file = new File(data, `macro_${Date.now()}.json`, { type: "application/json" });
const url = URL.createObjectURL(file);
const a = document.createElement("a");
a.href = url;
a.download = file.name;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
async function load() {
const gg = document.createElement("input");
gg.type = "file";
gg.accept = ".json,application/json";
gg.style.display = "none";
document.body.appendChild(gg);
try {
const ff = await new Promise((resolve, reject) => {
gg.addEventListener("change", () => {
const file = gg.files && gg.files[0];
if (file) {
resolve(file);
} else {
reject(new Error("No file selected"));
}
}, { once: true });
gg.click();
});
const text = await ff.text();
const r = JSON.parse(text);
for (const hh of Object.keys(r.i)) {
intervals[hh] = r.i[hh];
keys[hh] = r.k[hh];
}
} finally {
gg.remove();
}
}
function beep() {
var snd = new Audio("data:audio/mpeg;base64,SUQzBAAAAAAAIlRTU0UAAAAOAAADTGF2ZjYxLjcuMTAwAAAAAAAAAAAAAAD/+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJbmZvAAAADwAAAAsAAAVNADo6Ojo6Ojo6Ok5OTk5OTk5OTmJiYmJiYmJiYnZ2dnZ2dnZ2domJiYmJiYmJiZ2dnZ2dnZ2dnbGxsbGxsbGxscTExMTExMTExNjY2NjY2NjY2Ozs7Ozs7Ozs7P///////////wAAAABMYXZjNjEuMTkAAAAAAAAAAAAAAAAkBfIAAAAAAAAFTRaQIpQAAAAAAAAAAAAAAAAAAAAA//sQZAAP8GUAvAABEAANgAegAAAAAegBChQhAAAzgCCChjAAlDjBr3eX8h/XyeIMp1n/KHIY6z+T2foKagxiAMLUvE7/60+IHbS4Pp1VvWbr2GE+iuM5D91qVe49wExqUA8ANjZwsB7/+xJkBoAA3RDNhjRAAA0BGYDCiAACwCVwGREAADYEbQMOIACayBPyiwfhwK/CoIs76X+EQbZgHDviGUflzvymUBmCwQZc0EoB6QB5yWTG08mQyh/RV0vPHBQTAbseWoP9H/Sq1n//khz/+xBkAoAAkwjZBmBAAA2g2sDHgABCnCc2GPAAADwDpkMSAABPeG7FqcpVD3wLavz1Pe//GQrm46cSVgpt3/E1iQmNtbfhJQ1U2o1TKjwNN0w9TNDlYJZYKHSbdVCMAUQ6f9fnETHJwv/7EmQCgACdCtwGSEAADiErAMOAAAKMLVodgYAgNISqA5oQBfIvi5BwBB5O4oxh75C3T7+sriOTCMS7nb/VLHui3jjjz8q0ux+q4KGI8ktc97+ilEkpL+tFE1EFCaBci8bClRzZNWDlhf/7EGQDD/CbCs2B6MBIDkE5oCAsBUI8IxoOGGEgNwEiwYMAADTgOcdghrwHah2Vcptg6mhTd3WAbAqEINk8XYnEAMGBkkRJOlOgxag1ISzY/pDXQ8E6dFWToaCoi//6lTgwP1JEhmpN//sSZAQP8JcDxAOmABAO4FiAYMEAAnwRFA29IAA4geIBowQIIrvyr3fq1p0dRlZ58GUGDWZbLercv29v16zGeUBPQA9LkJSJC1oSzZ//rb0OUZDSLNRQ1i2Q3Qv919OhPfgAyKABpMSC//sQZASP8IoERgOYQAAOAEiAZYIAAhARFg5hIAA6AaIBtIgAFjYT//+zv+VPpcFKjJakevpf//dqag4m+hZKjYkuQBEq0f///V+ox33NvBQEbGchbarZ//qVOHKUxQCQriSgIiSw4Zr/+xJkBw/wXgRHA48wCA8gaIBtJgAB3BMYDiQCYDWBocGkjAAN7BBIDQ2hO3///3fWdEhppcKLAuMHBMysxnQo6NYdGA+UcILpT0//9So3FiQylAgoRxAKBTJ2jGGU4wAEbcRQtyoTvmH/+xBkDY/wagPFA69ICgqgWIBt4gFBkA8SDeGAKDKBoYHMCAUFQwZEUPiyqF4GBcSDvoJEpwgUJUHaOnCk1GjAknxBYIm0WpOGuDE34B3SgeF5Ck+ZFQI6dUpRVewGSJNEVRTNgxYGqP/7EkQXD/BsA0MDkDAIDoBokG3mAQHEDxAM4SAoMwHkAYSEDZF3NBlKqklrNwDAqIBWED1JSEgcNP8WFQUUegmoUrAqCZl3WKiyTEFNRTMuMTAxIChiZXRhIDMpqqqqqqqqqqqqqqqqqv/7EGQeD/B4BLeBKTAIDaC2wBhjIQAAAaQAAAAgAAA0gAAABKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
snd.play();
}
})();