add pixelplanet image loading stuff

This commit is contained in:
HF 2022-01-16 11:33:44 +01:00
parent 7344945a43
commit a6fd5b7962
10 changed files with 984 additions and 89 deletions

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
scp ./src/*.js pixelplanet:~/ppfun-bridge/src/ scp -r ./src/* pixelplanet:~/ppfun-bridge/src/
scp ./*.js pixelplanet:~/ppfun-bridge/ scp ./*.js pixelplanet:~/ppfun-bridge/
ssh pixelplanet 'pm2 stop ppfun-bridge; cd ~/ppfun-bridge; pm2 start ecosystem.yml' ssh pixelplanet 'pm2 stop ppfun-bridge; cd ~/ppfun-bridge; pm2 start ecosystem.yml'

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
"name": "ppfun-bridge", "name": "ppfun-bridge",
"version": "1.0.0", "version": "1.0.0",
"description": "pixelplanet.fun matrix bridge", "description": "pixelplanet.fun matrix bridge",
"type": "module",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 0" "test": "echo \"Error: no test specified\" && exit 0"
@ -9,7 +10,9 @@
"author": "hf", "author": "hf",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"canvas": "^2.8.0",
"matrix-appservice-bridge": "^3.2.0", "matrix-appservice-bridge": "^3.2.0",
"node-fetch": "^3.1.0",
"ws": "^8.4.0" "ws": "^8.4.0"
}, },
"optionalDependencies": { "optionalDependencies": {

View File

@ -124,4 +124,4 @@ class Palette {
} }
} }
export default Palette; module.exports = Palette;

View File

@ -0,0 +1,36 @@
const Palette = require('./Palette');
const {
TILE_SIZE,
TILE_ZOOM_LEVEL,
} = require('./constants');
let canvases = new Map();
function fetchCanvasData() {
try {
const response = await fetch('https://pixelplanet.fun/api/me');
if (response.status >= 300) {
throw new Error('Can not connect to pixelplanet!');
}
const data = await response.json();
const ids = Object.keys(data.canvases);
for (let i = 0; i < ids.length; i += 1) {
const id = ids[i];
const canvas = data.canvases[id];
canvas.id = id;
canvas.palette = new Palette(canvas.colors);
canvas.maxTiledZoom = Math.log2(canvas.size / TILE_SIZE) / TILE_ZOOM_LEVEL * 2;
canvasMap.set(canvas.ident, canvas);
}
canvases = canvasMap;
console.log('Successfully fetched canvas data from pixelplanet');
} catch (e) {
console.log('Couldn\'t connect to pixelplanet, trying to connect again in 60s');
setTimeout(fetchCanvasData, 60000);
throw(e)
}
}
fetchCanvasData();
module.exports = canvases;

View File

@ -1,5 +1,7 @@
export const WIDTH = 1024; module.exports = {
export const HEIGHT = 768; WIDTH: 1024;
export const MAX_SCALE = 40; // 52 in log2 HEIGHT: 768;
export const TILE_SIZE = 256; MAX_SCALE: 40; // 52 in log2
export const TILE_ZOOM_LEVEL = 4; TILE_SIZE: 256;
TILE_ZOOM_LEVEL: 4;
}

View File

@ -1,73 +1,48 @@
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import renderCanvas from './renderCanvas'; const canvases = require('./canvases');
import Palette from './Palette'; const renderCanvas = require('./renderCanvas');
import {
TILE_SIZE,
TILE_ZOOM_LEVEL,
} from './constants';
const linkRegExp = /(#[a-z]*,-?[0-9]*,-?[0-9]*(,-?[0-9]+)?)/gi; const linkRegExp = /(#[a-z]*,-?[0-9]*,-?[0-9]*(,-?[0-9]+)?)/gi;
const linkRegExpFilter = (val, ind) => ((ind % 3) !== 2); const linkRegExpFilter = (val, ind) => ((ind % 3) !== 2);
let lastCoords = [];
let canvases = null; function compArray(arr1, arr2) {
for (let i = 0; i <= arr1.length; i += 1) {
async function fetchCanvasData() { if (arr1[i] !== arr2[i]) {
try { return false;
const response = await fetch('https://pixelplanet.fun/api/me');
if (response.status >= 300) {
throw new Error('Can not connect to pixelplanet!');
} }
const data = await response.json();
const canvasMap = new Map();
const ids = Object.keys(data.canvases);
for (let i = 0; i < ids.length; i += 1) {
const id = ids[i];
const canvas = data.canvases[id];
canvas.id = id;
canvas.palette = new Palette(canvas.colors);
canvas.maxTiledZoom = Math.log2(canvas.size / TILE_SIZE) / TILE_ZOOM_LEVEL * 2;
canvasMap.set(canvas.ident, canvas);
}
canvases = canvasMap;
console.log('Successfully fetched canvas data from pixelplanet');
} catch (e) {
console.log('Couldn\'t connect to pixelplanet, trying to connect again in 60s');
setTimeout(fetchCanvasData, 60000);
throw(e)
} }
return true;
} }
fetchCanvasData();
export async function parseCanvasLinks(msg) { async function parseCanvasLinks(text) {
const {
text,
} = msg;
if (!text || !canvases) { if (!text || !canvases) {
return; return null;
} }
const msgArray = text.split(linkRegExp).filter(linkRegExpFilter); const msgArray = text.split(linkRegExp).filter(linkRegExpFilter);
if (msgArray.length > 1) { if (msgArray.length <= 1) {
const coordsParts = msgArray[1].substr(1).split(','); return null;
const [ canvasIdent, x, y, z ] = coordsParts;
const canvas = canvases.get(canvasIdent);
if (!canvas) {
return;
}
console.log(`Fetch canvas ${canvas.title} on ${x}/${y} with zoom ${z}`);
const image = await renderCanvas(canvas, x, y, z);
msg.reply({
attachments: [
{
image,
text: `${canvas.title} on ${x}/${y} with zoom ${z}`,
}
],
});
} }
const coordsParts = msgArray[1].substr(1).split(',');
if (compArray(coordsParts, lastCoords)) {
return null;
}
lastCoords = coordsParts;
const [ canvasIdent, x, y, z ] = coordsParts;
const canvas = canvases.get(canvasIdent);
if (!canvas) {
return;
}
console.log(`Fetch canvas ${canvas.title} on ${x}/${y} with zoom ${z}`);
const image = await renderCanvas(canvas, x, y, z);
return image;
} }
exports.parseCanvasLinks = parseCanvasLinks;

View File

@ -1,31 +1,14 @@
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import { const {
createCanvas, createCanvas,
loadImage, loadImage,
createImageData, createImageData,
} from 'canvas'; } = require('canvas');
import { const {
TILE_SIZE, TILE_SIZE,
} from './constants'; } = require('./constants');
export async function getChunk(
canvas,
zoom,
cx,
cy,
) {
const tile = createCanvas(TILE_SIZE, TILE_SIZE);
const canvasId = canvas.id;
if (canvas.maxTiledZoom === zoom) {
await fetchBaseChunk(canvasId, canvas.palette, zoom, cx, cy, tile);
} else {
await fetchTile(canvasId, zoom, cx, cy, tile);
}
return tile;
}
async function fetchBaseChunk( async function fetchBaseChunk(
canvasId, canvasId,
@ -60,3 +43,20 @@ async function fetchTile(canvasId, zoom, cx, cy, tile) {
const ctx = tile.getContext('2d'); const ctx = tile.getContext('2d');
ctx.drawImage(image, 0, 0); ctx.drawImage(image, 0, 0);
} }
module.exports = function (
canvas,
zoom,
cx,
cy,
) {
const tile = createCanvas(TILE_SIZE, TILE_SIZE);
const canvasId = canvas.id;
if (canvas.maxTiledZoom === zoom) {
await fetchBaseChunk(canvasId, canvas.palette, zoom, cx, cy, tile);
} else {
await fetchTile(canvasId, zoom, cx, cy, tile);
}
return tile;
}

View File

@ -1,14 +1,14 @@
import { createCanvas } from 'canvas'; const { createCanvas } = require('canvas');
import { getChunk } from './loadChunk'; const getChunk = require('./loadChunk');
import { const {
WIDTH, WIDTH,
HEIGHT, HEIGHT,
MAX_SCALE, MAX_SCALE,
TILE_SIZE, TILE_SIZE,
TILE_ZOOM_LEVEL, TILE_ZOOM_LEVEL,
} from './constants'; } = require('./constants');
function coordToChunk(z, canvasSize, tiledScale) { function coordToChunk(z, canvasSize, tiledScale) {
return Math.floor((z + canvasSize / 2) / TILE_SIZE * tiledScale); return Math.floor((z + canvasSize / 2) / TILE_SIZE * tiledScale);

View File

@ -3,6 +3,7 @@
const MatrixBridge = require("matrix-appservice-bridge").Bridge; const MatrixBridge = require("matrix-appservice-bridge").Bridge;
const PPfunSocket = require('./ppfunsocket'); const PPfunSocket = require('./ppfunsocket');
//const parseCanvasLinks = require('./pixelplanet')
class PPfunMatrixBridge { class PPfunMatrixBridge {
constructor(opts) { constructor(opts) {
@ -163,7 +164,7 @@ class PPfunMatrixBridge {
} }
/* /*
* creates matrix rooms for the pixelplaent channels if neccessary and * creates matrix rooms for the pixelplanet channels if neccessary and
* opulates the mToProomMap and pToMroomMap. * opulates the mToProomMap and pToMroomMap.
* @param roomList list of rooms and their names like: * @param roomList list of rooms and their names like:
* [[roomId, roomName], [roomId2, roomName2], ...] * [[roomId, roomName], [roomId2, roomName2], ...]