// ==UserScript==
// @name PPPC
// @description Pixel Place Parallel Connections
// @version 1.5.1
// @author 0vC4
// @namespace https://gf.qytechs.cn/users/670183
// @match https://pixelplace.io/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
// @license MIT
// @grant none
// @run-at document-start
// ==/UserScript==
const PPPC = (() => {
if (window.PPPC) return window.PPPC;
const log = console.log;
const PPPC = {
config({timer}) {
this.timer = timer;
},
get settings() {
return JSON.parse(localStorage.settings || '""')
},
set settings(json) {
localStorage.settings = JSON.stringify(json);
},
async show() {
return JSON.stringify([
(await cookieStore.get('authId')).value,
(await cookieStore.get('authToken')).value,
(await cookieStore.get('authKey')).value
]);
},
async add(username, scheme) {
const settings = this.settings;
settings.userlist[username] = scheme;
this.settings = settings;
return true;
},
async remove(username) {
const settings = this.settings;
delete settings.userlist[username];
this.settings = settings;
return true;
},
async save() {
const settings = this.settings;
settings.current = {
authId: (await cookieStore.get('authId')).value,
authToken: (await cookieStore.get('authToken')).value,
authKey: (await cookieStore.get('authKey')).value
};
this.settings = settings;
},
async load(scheme = null) {
const settings = this.settings;
await cookieStore.set('authId', scheme ? scheme[0] : settings.current.authId);
await cookieStore.set('authToken', scheme ? scheme[1] : settings.current.authToken);
await cookieStore.set('authKey', scheme ? scheme[2] : settings.current.authKey);
delete settings.current;
this.settings = settings;
},
async join(username, server) {
const settings = this.settings;
if (!settings.userlist[username]) return null;
const [id, token, key] = settings.userlist[username];
await cookieStore.set('authId', id);
await cookieStore.set('authToken', token);
await cookieStore.set('authKey', key);
await fetch(`https://pixelplace.io/api/get-painting.php?id=${server}&connected=1`);
if (!(await cookieStore.get('authToken'))) {
log(username, "is banned or it has wrong data, please remove this account using PPPC.remove('"+username+"');");
return null;
}
settings.userlist[username] = [
(await cookieStore.get('authId')).value,
(await cookieStore.get('authToken')).value,
(await cookieStore.get('authKey')).value
];
this.settings = settings;
return settings.userlist[username];
},
async connect(username, boardId) {
const result = await this.join(username, boardId);
if (!result) return null;
const [authId, authToken, authKey] = result;
const timer = this.timer;
const user = new WebSocket('wss://pixelplace.io/socket.io/?EIO=3&transport=websocket');
user.onmessage = ({data}) => {
const [code, msg] = data.split(/(?<=^\d+)(?=[^\d])/);
if (code == '40') user.send('42' + JSON.stringify(
["init", { authKey, authToken, authId, boardId }]
));
const message = JSON.parse(msg || '[]');
if (message.pingInterval) user.ping = timer.setInterval(() => user.send('2'), message.pingInterval);
if (!message.length) return arguments;
const [event, json] = message;
if (event == 'throw.error') user.close();
};
user.onclose = () => {
log(username, 'bot disconnected');
timer.clearInterval(user.ping);
};
user.set = (x,y,p) => user.send(`42["p",[${x},${y},${p},1]]`);
return user;
},
async connectAll(serverId) {
const names = Object.keys(this.settings.userlist);
const arr = [];
await this.save();
let n = 0;
for (let i = 0; i < names.length; i++) {
let ws = null;
try {
ws = await this.connect(names[i], serverId);
} catch (e) {
ws = null;
}
if (!ws) {
n++;
continue;
}
arr[i-n] = ws;
ws.addEventListener('close', e => arr.splice(arr.indexOf(ws), 1));
}
await this.load();
await this.save();
log(names.length-n, 'bots connected');
this.bots = arr;
return arr;
},
async disconnect(){
this.bots.filter(Boolean).map(ws => ws.close&&ws.close());
}
};
if (!PPPC.settings) PPPC.settings = {
userlist: {}
};
window.PPPC = PPPC;
return PPPC;
})();
// 0vC4#7152