Skip to content

Instantly share code, notes, and snippets.

@stevenhao
Last active August 30, 2018 08:36
Show Gist options
  • Save stevenhao/56d0deb14c6d4665046cb9710cf8be42 to your computer and use it in GitHub Desktop.
Save stevenhao/56d0deb14c6d4665046cb9710cf8be42 to your computer and use it in GitHub Desktop.
squarecraft.io enable right click
// ==UserScript==
// @name Squarecraft
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author Steven Hao
// @match http://squarecraft.io/
// @grant none
// ==/UserScript==
if (typeof wsurl === 'undefined') {
var wsurl = "ws://squarecraft.io:5000/ffa"
}
function getWebSocket() {
if (!window.websockets) return;
if (!(wsurl in window.websockets)) return;
return window.websockets[wsurl];
}
if (typeof attached === 'undefined') {
var attached, ws, state, secret, registeredWebsocketListener, registeredClickListeners;
}
function attach() {
if (attached) return;
ws = getWebSocket();
if (!ws) return;
attached = true;
ws.addEventListener('message', event => {
const data = JSON.parse(event.data);
if (data.event === 'connected') {
secret = data.secret;
} else if (data.event === 'update') {
state = data.state;
}
});
}
function registerWebsocketListener() {
if (registeredWebsocketListener) return;
if (!window.onWebsocket) return;
registeredWebsocketListener = true;
window.onWebsocket((websocket) => {
attach();
});
}
setInterval(registerWebsocketListener, 500);
function getUnitId({x, y}) {
if (!attached) return;
return state.squares[y][x] && state.squares[y][x].unit && state.squares[y][x].unit.id;
}
function getDirection({x: fx, y: fy}, {x: tx, y: ty}) {
if (fx === tx) {
if (fy < ty) return 'move_down';
return 'move_up';
}
if (fx < tx) return 'move_left';
return 'move_right';
}
function makeMove(from, to, unitId) {
const ws = getWebSocket();
if (!ws) {
return false;
}
const action = getDirection(from, to);
let move = {
action: action,
source: [from.y, from.x],
target: [to.y, to.x],
unitId: unitId
};
const event = 'move';
console.log('makeMove', secret, move, event);
ws.send(JSON.stringify({
secret,
move,
event,
}));
}
function getXY(el) {
const x = parseInt(el.getAttribute('x'));
const y = parseInt(el.getAttribute('y'));
return { x, y };
}
function getEl({ x, y }) {
return document.querySelector(`.square[x="${x}"][y="${y}"]`);
}
function getGrid() {
const res = [];
document.querySelectorAll('.square').forEach(el => {
const walkable = el.style.backgroundColor !== 'white';
const empty = (el.style.backgroundColor === 'black' || el.style.backgroundColor === 'gray' || el.style.backgroundColor === 'rgb(80, 80, 80)') && !el.style.opacity;
const { x, y } = getXY(el);
if (!res[x]) res[x] = [];
res[x][y] = {
walkable,
empty,
};
});
return res;
}
function getEmptyNeighbors({x, y}, grid) {
return [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]]
.filter(([nx, ny]) => grid[nx] && grid[nx][ny] && grid[nx][ny].walkable)
.map(([nx, ny]) => ({ x: nx, y: ny}));
}
function getPath(start, end, grid) {
const trace = [];
const queue = [start];
trace[start.x] = [];
trace[start.x][start.y] = -1;
while (queue.length > 0) {
const cur = queue.shift();
if (cur.x === end.x && cur.y === end.y) break;
const neighbors = getEmptyNeighbors(cur, grid);
console.log('neighbors=', neighbors);
neighbors.forEach(neighbor => {
if (!trace[neighbor.x]) trace[neighbor.x] = [];
if (trace[neighbor.x][neighbor.y]) return;
console.log('trace', neighbor, cur);
trace[neighbor.x][neighbor.y] = cur;
queue.push(neighbor);
});
}
if (trace[end.x][end.y]) {
let cur = end;
const path = [];
while (cur !== -1) {
path.unshift(cur);
cur = trace[cur.x][cur.y];
}
return path;
}
}
function registerClickListeners() {
if (registeredClickListeners) return;
if (!document.querySelector('.square')) return;
registeredClickListeners = true;
document.querySelectorAll('.square').forEach(el => {
// let newElement = el.cloneNode(true);
// el.parentNode.replaceChild(newElement, el);
// el = newElement;
if (el.marked) return;
el.marked = true;
el.addEventListener('contextmenu', (ev) => {
ev.preventDefault();
const ws = getWebSocket();
if (!ws) {
console.log('no websocket');
return;
}
if (!attached) {
console.log('not attached');
return;
}
const to = getXY(el);
const from = getXY(document.querySelector('.highlighted'));
const grid = getGrid();
const path = getPath(from, to, grid);
const unitId = getUnitId(from);
if (!unitId) {
console.log('no unitId');
return;
}
if (!path) {
console.log('no path');
return;
}
console.log('PATH', path);
path.forEach((cur, i) => {
if (i === path.length - 1) return;
const nxt = path[i + 1];
makeMove(cur, nxt, unitId);
});
});
})
}
setInterval(registerClickListeners, 500);
// ==UserScript==
// @name Websocket Connector
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author Steven Hao
// @match *
// @grant none
// ==/UserScript==
(function() {
var oldWebSocket = WebSocket;
window.websockets = {};
var cbks = [];
window.onWebsocket = function(cbk) {
cbks.push(cbk);
}
WebSocket = function(...args) {
var res = new oldWebSocket(...args);
window.websockets[res.url] = res;
cbks.forEach(cbk => {
cbk(res);
});
return res;
}
WebSocket.prototype = oldWebSocket.prototype;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment