diff --git a/promotion/can-you-do-zuckerberg.png b/promotion/can-you-do-zuckerberg.png new file mode 100644 index 0000000..14a5556 Binary files /dev/null and b/promotion/can-you-do-zuckerberg.png differ diff --git a/src/canvases.json b/src/canvases.json index 13754b9..df2a1a0 100644 --- a/src/canvases.json +++ b/src/canvases.json @@ -36,8 +36,8 @@ [ 207, 110, 228 ], [ 130, 0, 128 ] ], - "alpha": 0, "size": 65536, + "cli": 2, "bcd": 4000, "pcd" : 7000, "cds": 60000, @@ -82,8 +82,8 @@ [ 122, 148, 156 ], [ 174, 215, 185 ] ], - "alpha": 0, "size" : 1024, + "cli": 2, "bcd": 15000, "pcd": 15000, "cds": 900000, @@ -95,7 +95,6 @@ "ident":"v", "title": "3D Canvas", "colors": [ - [ 202, 227, 255 ], [ 255, 255, 255 ], [ 255, 255, 255 ], [ 228, 228, 228 ], @@ -128,9 +127,9 @@ [ 207, 110, 228 ], [ 130, 0, 128 ] ], - "alpha": 0, "size": 1024, "v": true, + "cli": 1, "bcd": 2000, "pcd" : 2000, "cds": 60000, diff --git a/src/components/Palette.jsx b/src/components/Palette.jsx index 2142537..4558044 100644 --- a/src/components/Palette.jsx +++ b/src/components/Palette.jsx @@ -12,16 +12,33 @@ import type { State } from '../reducers'; const Palette = ({ - colors, selectedColor, paletteOpen, compactPalette, select, + colors, selectedColor, paletteOpen, compactPalette, select, clrIgnore, }) => ( -
+
30 || compactPalette) + ? 'compalette' + : 'widpalette' + }`} + id="colors" + style={{ + display: (paletteOpen) ? 'flex' : 'none', + height: ((colors.length - clrIgnore) > 30 || compactPalette) + ? Math.ceil((colors.length - clrIgnore) / 5 * 28) + : undefined, + }} + > {colors.slice(2).map((color, index) => ( select(index + 2)} + onClick={() => select(index + clrIgnore)} /> ))}
@@ -29,9 +46,13 @@ const Palette = ({ function mapStateToProps(state: State) { const { selectedColor, paletteOpen, compactPalette } = state.gui; - const { palette } = state.canvas; + const { palette, clrIgnore } = state.canvas; return { - colors: palette.colors, selectedColor, paletteOpen, compactPalette, + colors: palette.colors, + selectedColor, + paletteOpen, + compactPalette, + clrIgnore, }; } diff --git a/src/core/Image.js b/src/core/Image.js index 9d75184..cdc18e1 100644 --- a/src/core/Image.js +++ b/src/core/Image.js @@ -36,7 +36,7 @@ export async function imageABGR2Canvas( `Loading image with dim ${width}/${height} to ${x}/${y}/${canvasId}`, ); const canvas = canvases[canvasId]; - const palette = new Palette(canvas.colors, canvas.alpha); + const palette = new Palette(canvas.colors); const canvasMinXY = -(canvas.size / 2); const imageData = new Uint32Array(data.buffer); @@ -112,7 +112,7 @@ export async function imagemask2Canvas( `Loading mask with size ${width} / ${height} to ${x} / ${y} to the canvas`, ); const canvas = canvases[canvasId]; - const palette = new Palette(canvas.colors, canvas.alpha); + const palette = new Palette(canvas.colors); const canvasMinXY = -(canvas.size / 2); const imageData = new Uint8Array(data.buffer); diff --git a/src/core/Palette.js b/src/core/Palette.js index 701fb82..868681f 100644 --- a/src/core/Palette.js +++ b/src/core/Palette.js @@ -13,10 +13,8 @@ class Palette { colors: Array; abgr: Uint32Array; fl: Array; - alpha: number = 0; - constructor(colors: Array, alpha: number = 0) { - this.alpha = alpha; + constructor(colors: Array) { this.length = colors.length; this.rgb = new Uint8Array(this.length * 3); this.colors = new Array(this.length); diff --git a/src/core/Tile.js b/src/core/Tile.js index 9f82813..7e00228 100644 --- a/src/core/Tile.js +++ b/src/core/Tile.js @@ -31,11 +31,10 @@ function deleteSubtilefromTile( for (let row = 0; row < TILE_SIZE; row += 1) { let channelOffset = (offset + row * TILE_SIZE * subtilesInTile) * 3; const max = channelOffset + TILE_SIZE * 3; - const alphaIndex = palette.alpha * 3; while (channelOffset < max) { - buffer[channelOffset++] = palette.rgb[alphaIndex]; - buffer[channelOffset++] = palette.rgb[alphaIndex + 1]; - buffer[channelOffset++] = palette.rgb[alphaIndex + 2]; + buffer[channelOffset++] = palette.rgb[0]; + buffer[channelOffset++] = palette.rgb[1]; + buffer[channelOffset++] = palette.rgb[2]; } } } @@ -244,11 +243,10 @@ export async function createEmptyTile( ); let i = 0; const max = TILE_SIZE * TILE_SIZE * 3; - const alphaIndex = palette.alpha * 3; while (i < max) { - tileRGBBuffer[i++] = palette.rgb[alphaIndex]; - tileRGBBuffer[i++] = palette.rgb[alphaIndex + 1]; - tileRGBBuffer[i++] = palette.rgb[alphaIndex + 2]; + tileRGBBuffer[i++] = palette.rgb[0]; + tileRGBBuffer[i++] = palette.rgb[1]; + tileRGBBuffer[i++] = palette.rgb[2]; } const filename = `${canvasTileFolder}/emptytile.png`; await sharp(Buffer.from(tileRGBBuffer.buffer), { diff --git a/src/core/constants.js b/src/core/constants.js index df9b409..6876390 100644 --- a/src/core/constants.js +++ b/src/core/constants.js @@ -50,7 +50,6 @@ export const DEFAULT_CANVASES = { [207, 110, 228], [130, 0, 128], ], - alpha: 0, size: 65536, bcd: 4000, pcd: 7000, diff --git a/src/core/draw.js b/src/core/draw.js index b8267d7..e34179c 100644 --- a/src/core/draw.js +++ b/src/core/draw.js @@ -99,7 +99,7 @@ async function draw( success: false, }; } - if (color < 2) { + if (color < canvas.cli) { return { error: 'Invalid color selected', success: false, @@ -115,6 +115,13 @@ async function draw( } } + if (color < 0 || color >= canvas.colors.length) { + return { + error: 'Invalid color selected', + success: false, + }; + } + if (canvas.req !== -1) { if (user.id === null) { return { @@ -138,7 +145,7 @@ async function draw( const setColor = await RedisCanvas.getPixel(canvasId, x, y, z); - let coolDown = !(setColor & 0x1E) ? canvas.bcd : canvas.pcd; + let coolDown = (setColor & 0x3F) < canvas.cli ? canvas.bcd : canvas.pcd; if (user.isAdmin()) { coolDown = 0.0; } @@ -156,7 +163,7 @@ async function draw( }; } - if (setColor & 0x20) { + if (setColor & 0x80) { logger.info(`${user.ip} tried to set on protected pixel (${x}, ${y})`); return { errorTitle: 'Pixel Protection', diff --git a/src/core/tilesBackup.js b/src/core/tilesBackup.js index fd7b536..e441ff4 100644 --- a/src/core/tilesBackup.js +++ b/src/core/tilesBackup.js @@ -92,7 +92,7 @@ export async function incrementialBackupRedis( fs.mkdirSync(canvasTileBackupDir); } - const palette = new Palette(canvas.colors, canvas.alpha); + const palette = new Palette(canvas.colors); const chunksXY = (canvas.size / TILE_SIZE); console.log('Creating Incremential Backup...'); const startTime = Date.now(); @@ -182,7 +182,7 @@ export async function createPngBackup( } const canvas = canvases[id]; - const palette = new Palette(canvas.colors, canvas.alpha); + const palette = new Palette(canvas.colors); const chunksXY = (canvas.size / TILE_SIZE); console.log('Create PNG tiles from backup...'); const startTime = Date.now(); diff --git a/src/core/tileserver.js b/src/core/tileserver.js index 61f3761..c974227 100644 --- a/src/core/tileserver.js +++ b/src/core/tileserver.js @@ -44,7 +44,7 @@ class CanvasUpdater { this.id = id; this.canvas = canvases[id]; this.canvasTileFolder = `${TILE_FOLDER}/${id}`; - this.palette = new Palette(this.canvas.colors, this.canvas.alpha); + this.palette = new Palette(this.canvas.colors); this.firstZoomtileWidth = this.canvas.size / TILE_SIZE / TILE_ZOOM_LEVEL; this.maxTiledZoom = getMaxTiledZoom(this.canvas.size); this.startReloadingLoops(); diff --git a/src/data/models/RedisCanvas.js b/src/data/models/RedisCanvas.js index 4caf821..6460da1 100644 --- a/src/data/models/RedisCanvas.js +++ b/src/data/models/RedisCanvas.js @@ -97,9 +97,9 @@ class RedisCanvas { y: number, z: number = null, ): Promise { - // 1st and 2nd bit -> not used yet - // 3rd bit -> protected or not - // rest (5 bits) -> index of color + // 1st bit -> protected or not + // 2nd bit -> unused + // rest (6 bits) -> index of color const canvasSize = canvases[canvasId].size; const [i, j] = getChunkOfPixel(canvasSize, x, y, z); const offset = getOffsetOfPixel(canvasSize, x, y, z); @@ -121,9 +121,8 @@ class RedisCanvas { y: number, z: number = null, ): Promise { - const canvasAlpha = canvases[canvasId].alpha; const clr = RedisCanvas.getPixelIfExists(canvasId, x, y, z); - return (clr == null) ? canvasAlpha : clr; + return (clr == null) ? 0 : clr; } } diff --git a/src/reducers/canvas.js b/src/reducers/canvas.js index 3b7d7bc..11b3c4d 100644 --- a/src/reducers/canvas.js +++ b/src/reducers/canvas.js @@ -26,6 +26,7 @@ export type CanvasState = { canvasMaxTiledZoom: number, canvasStartDate: string, palette: Palette, + clrIgnore: number, view: Cell, scale: number, viewscale: number, @@ -61,6 +62,7 @@ function getViewFromURL(canvases: Object) { const canvasId = getIdFromObject(canvases, almost[0]); let colors; + let clrIgnore; let canvasSize; let canvasStartDate; let is3D; @@ -68,12 +70,14 @@ function getViewFromURL(canvases: Object) { // if canvas informations are not available yet // aka /api/me didn't load yet colors = canvases[DEFAULT_CANVAS_ID].colors; + clrIgnore = 2; canvasSize = 1024; is3D = false; canvasStartDate = null; } else { const canvas = canvases[canvasId]; colors = canvas.colors; + clrIgnore = canvas.cli; canvasSize = canvas.size; is3D = !!canvas.v; canvasStartDate = canvas.sd; @@ -100,20 +104,23 @@ function getViewFromURL(canvases: Object) { canvasStartDate, canvasMaxTiledZoom: getMaxTiledZoom(canvasSize), palette: new Palette(colors, 0), + clrIgnore, view: [x, y], viewscale: urlscale, scale: urlscale, canvases, }; } catch (error) { + const canvas = canvases[DEFAULT_CANVAS_ID]; return { canvasId: DEFAULT_CANVAS_ID, - canvasIdent: canvases[DEFAULT_CANVAS_ID].ident, - canvasSize: canvases[DEFAULT_CANVAS_ID].size, - is3D: !!canvases[DEFAULT_CANVAS_ID].v, + canvasIdent: canvas.ident, + canvasSize: canvas.size, + is3D: !!canvas.v, canvasStartDate: null, - canvasMaxTiledZoom: getMaxTiledZoom(canvases[DEFAULT_CANVAS_ID].size), - palette: new Palette(canvases[DEFAULT_CANVAS_ID].colors, 0), + canvasMaxTiledZoom: getMaxTiledZoom(canvas.size), + palette: new Palette(canvas.colors, 0), + clrIgnore: canvas.cli, view: getGivenCoords(), viewscale: DEFAULT_SCALE, scale: DEFAULT_SCALE, @@ -263,6 +270,7 @@ export default function canvasReducer( sd: canvasStartDate, ident: canvasIdent, v: is3D, + cli: clrIgnore, colors, } = canvas; const canvasMaxTiledZoom = getMaxTiledZoom(canvasSize); @@ -277,6 +285,7 @@ export default function canvasReducer( canvasStartDate, canvasMaxTiledZoom, palette, + clrIgnore, view, viewscale: DEFAULT_SCALE, scale: DEFAULT_SCALE, @@ -297,6 +306,7 @@ export default function canvasReducer( size: canvasSize, sd: canvasStartDate, v: is3D, + cli: clrIgnore, colors, } = canvases[canvasId]; const canvasMaxTiledZoom = getMaxTiledZoom(canvasSize); @@ -311,6 +321,7 @@ export default function canvasReducer( canvasStartDate, canvasMaxTiledZoom, palette, + clrIgnore, canvases, }; } diff --git a/src/routes/api/pixel.js b/src/routes/api/pixel.js index 30d6fc4..05ac9b2 100644 --- a/src/routes/api/pixel.js +++ b/src/routes/api/pixel.js @@ -40,8 +40,6 @@ async function validate(req: Request, res: Response, next) { error = 'y is not a valid number'; } else if (Number.isNaN(clr)) { error = 'No color selected'; - } else if (clr < 0 || clr > 31) { - error = 'Invalid color selected'; } else if (z !== null && Number.isNaN(z)) { error = 'z is not a valid number'; } diff --git a/utils/redisUnprotect.js b/utils/redisUnprotect.js index a377ef8..ad9a31f 100644 --- a/utils/redisUnprotect.js +++ b/utils/redisUnprotect.js @@ -1,5 +1,5 @@ /* @flow */ -//this script just copies chunks from one redis to another with a different key as needed +//this script removes protection from all pixels on main canas import redis from 'redis'; import bluebird from 'bluebird'; @@ -10,8 +10,10 @@ bluebird.promisifyAll(redis.Multi.prototype); //ATTENTION Make suer to set the rdis URLs right!!! -const url = "redis://localhost:6379"; -const redis = redis.createClient(url, { return_buffers: true }); +const urlo = "redis://localhost:6379"; +const url = "redis://localhost:6380"; +const rediso = redis.createClient(urlo, { return_buffers: true }); +const redisc = redis.createClient(url, { return_buffers: true }); const CANVAS_SIZE = 256 * 256; const TILE_SIZE = 256; @@ -21,26 +23,25 @@ async function moveProtection() { for (let x = 0; x < CHUNKS_XY; x++) { for (let y = 0; y < CHUNKS_XY; y++) { const key = `ch:0:${x}:${y}`; - const chunk = await redis.getAsync(key); + const chunk = await redisc.getAsync(key); if (chunk) { const buffer = new Uint8Array(chunk); let changed = false; for (let u = 0; u < buffer.length; ++u) { const bit = buffer[u]; - if (bit & 0x20) { - // move protected bit from 0x20 to 0x80 - buffer[u] = (bit & 0x1F) | 0x80; + if (bit & 0x80) { + buffer[u] = bit & 0x1F; changed = true; } } if (changed) { - const setNXArgs = [key, Buffer.from(buffer.buffer).toString('binary')] - await redis.sendCommandAsync('SETNX', setNXArgs); + await rediso.setAsync(key, Buffer.from(buffer.buffer)); console.log("Changed Chunk ", key); } } } } + console.log("done"); } moveProtection();