From 6ad79250e5870256b1957b29380de5b66d6b6483 Mon Sep 17 00:00:00 2001 From: HF Date: Fri, 1 Jul 2022 23:45:25 +0200 Subject: [PATCH] fix race conditions --- src/core/draw.js | 36 ++++++++++++++++++++++++++++++++++++ src/socket/SocketClient.js | 2 +- src/ui/placePixel.js | 5 +++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/core/draw.js b/src/core/draw.js index 0dc1fde..9009120 100644 --- a/src/core/draw.js +++ b/src/core/draw.js @@ -22,6 +22,28 @@ export function setCoolDownFactor(fac) { coolDownFactor = fac; } +/* + * IPs who are currently requesting pixels + * (have to log in order to avoid race conditions) + */ +const curReqIPs = new Map(); +setInterval(() => { + // clean up old data + const ts = Date.now() - 20 * 1000; + const ips = [...curReqIPs.keys()]; + for (let i = 0; i < ips.length; i += 1) { + const ip = ips[i]; + const limiter = curReqIPs.get(ip); + if (limiter && ts > limiter) { + curReqIPs.delete(ip); + logger.warn( + `Pixel requests from ${ip} got stuck`, + ); + } + } +}, 20 * 1000); + + /** * * By Offset is prefered on server side @@ -47,10 +69,20 @@ export async function drawByOffsets( let retCode = 0; let pxlCnt = 0; let rankedPxlCnt = 0; + const { ip } = user; try { const startTime = Date.now(); + if (curReqIPs.has(ip)) { + // already setting a pixel somewhere + logger.warn( + `Got simultanious requests from ${user.ip}`, + ); + throw new Error(13); + } + curReqIPs.set(ip, startTime); + const canvas = canvases[canvasId]; if (!canvas) { // canvas doesn't exist @@ -182,6 +214,10 @@ export async function drawByOffsets( } } + if (retCode !== 13) { + curReqIPs.delete(ip); + } + if (pxlCnt) { user.setWait(wait, canvasId); if (rankedPxlCnt) { diff --git a/src/socket/SocketClient.js b/src/socket/SocketClient.js index 8911bf4..e3aa530 100644 --- a/src/socket/SocketClient.js +++ b/src/socket/SocketClient.js @@ -99,9 +99,9 @@ class SocketClient extends EventEmitter { if (this.canvasId !== null) { this.ws.send(RegisterCanvas.dehydrate(this.canvasId)); } - this.processMsgQueue(); console.log(`Register ${chunks.length} chunks`); this.ws.send(RegisterMultipleChunks.dehydrate(chunks)); + this.processMsgQueue(); } setCanvas(canvasId) { diff --git a/src/ui/placePixel.js b/src/ui/placePixel.js index 2dfd1fe..9ffcfbf 100644 --- a/src/ui/placePixel.js +++ b/src/ui/placePixel.js @@ -246,6 +246,11 @@ export function receivePixelReturn( errorTitle = t`Not allowed`; msg = t`Just the Top10 of yesterday can place here`; break; + case 13: + errorTitle = t`You are weird`; + // eslint-disable-next-line max-len + msg = t`Server got confused by your pixels. Are you playing on multiple devices?`; + break; default: errorTitle = t`Weird`; msg = t`Couldn't set Pixel`;