check for requirements in redis in lua

fix #34 fix #36
This commit is contained in:
HF 2022-09-30 11:16:04 +02:00
parent 5ea71d01b4
commit bdf653bda2
7 changed files with 54 additions and 41 deletions

View File

@ -44,7 +44,6 @@ class Ranks {
// pixels placed by day
pDailyStats: [],
};
this.prevTopIds = [];
/*
* we go through socketEvents for sharding
*/
@ -71,11 +70,6 @@ class Ranks {
if (!newRanks) {
return;
}
const { prevTopIds } = newRanks;
if (prevTopIds) {
this.prevTopIds = prevTopIds;
delete newRanks.prevTopIds;
}
this.ranks = {
...this.ranks,
...newRanks,
@ -126,9 +120,9 @@ class Ranks {
}
static async dailyUpdateRanking() {
const prevTopData = await getPrevTop();
const prevTopIds = prevTopData.map((d) => d.id);
const prevTop = await populateRanking(prevTopData);
const prevTop = await populateRanking(
await getPrevTop(),
);
const pDailyStats = await getDailyPixelStats();
const histStats = await getTopDailyHistory();
histStats.users = await populateRanking(histStats.users);
@ -139,7 +133,6 @@ class Ranks {
prevTop,
pDailyStats,
histStats,
prevTopIds,
};
if (socketEvents.amIImportant()) {
// only main shard sends to others

View File

@ -10,7 +10,6 @@ import allowPlace from '../data/redis/cooldown';
import socketEvents from '../socket/socketEvents';
import { setPixelByOffset } from './setPixel';
import isIPAllowed from './isAllowed';
import rankings from './Ranks';
import canvases from './canvases';
import { THREE_CANVAS_HEIGHT, THREE_TILE_SIZE, TILE_SIZE } from './constants';
@ -112,27 +111,7 @@ export default async function drawByOffsets(
* 2: mod
*/
const isAdmin = (user.userlvl === 1);
if (canvas.req !== undefined && !isAdmin) {
if (user.id === null) {
// not logged in
throw new Error(6);
}
if (canvas.req > 0) {
const totalPixels = await user.getTotalPixels();
if (totalPixels < canvas.req) {
// not enough pixels placed yet
throw new Error(7);
}
}
if (canvas.req === 'top'
&& !rankings.prevTopIds.includes(user.id)
) {
// not in top ten
throw new Error(12);
}
}
const req = (isAdmin) ? null : canvas.req;
const clrIgnore = canvas.cli || 0;
const factor = (isAdmin || (user.userlvl > 0 && pixels[0][1] < clrIgnore))
? 0.0 : coolDownFactor;
@ -187,6 +166,7 @@ export default async function drawByOffsets(
}
}
let needProxycheck;
[retCode, pxlCnt, wait, coolDown, needProxycheck] = await allowPlace(
ip,
@ -196,6 +176,7 @@ export default async function drawByOffsets(
canvasId,
i, j,
clrIgnore,
req,
bcd, pcd,
canvas.cds,
pxlOffsets,

View File

@ -186,6 +186,7 @@ class User {
return this.regUser.totalPixels;
}
try {
// TODO does not work anymore
const userq = await sequelize.query(
'SELECT totalPixels FROM Users WHERE id = $1',
{

View File

@ -10,7 +10,7 @@ import { REDIS_URL, SHARD_NAME } from '../../core/config';
const scripts = {
placePxl: defineScript({
NUMBER_OF_KEYS: 8,
NUMBER_OF_KEYS: 9,
SCRIPT: fs.readFileSync('./workers/lua/placePixel.lua'),
transformArguments(...args) {
return args.map((a) => ((typeof a === 'string') ? a : a.toString()));

View File

@ -5,7 +5,12 @@
import client from './client';
import { PREFIX as CAPTCHA_PREFIX } from './captcha';
import { PREFIX as ALLOWED_PREFIX } from './isAllowedCache';
import { RANKED_KEY, DAILY_RANKED_KEY, DAILY_CRANKED_KEY } from './ranks';
import {
RANKED_KEY,
DAILY_RANKED_KEY,
DAILY_CRANKED_KEY,
PREV_DAY_TOP_KEY,
} from './ranks';
import { CAPTCHA_TIME } from '../../core/config';
const PREFIX = 'cd';
@ -30,6 +35,7 @@ export default function allowPlace(
canvasId,
i, j,
clrIgnore,
req,
bcd,
pcd,
cds,
@ -51,14 +57,17 @@ export default function allowPlace(
} else {
idCdKey = 'nope';
}
if (!req && req !== 0) {
req = 'nope';
}
const chunkKey = `ch:${canvasId}:${i}:${j}`;
const cc = country || 'xx';
const rankset = (ranked) ? RANKED_KEY : 'nope';
const rankset = RANKED_KEY;
const dailyset = (ranked) ? DAILY_RANKED_KEY : 'nope';
return client.placePxl(
// eslint-disable-next-line max-len
isalKey, captKey, ipCdKey, idCdKey, chunkKey, rankset, dailyset, DAILY_CRANKED_KEY,
clrIgnore, bcd, pcd, cds, id, cc,
isalKey, captKey, ipCdKey, idCdKey, chunkKey, rankset, dailyset, DAILY_CRANKED_KEY, PREV_DAY_TOP_KEY,
clrIgnore, bcd, pcd, cds, id, cc, req,
...pxls,
);
}

View File

@ -11,9 +11,10 @@
-- 'nope' if not logged in
-- chunk: 'ch:canvasId:i:j'
-- rankset: 'rank' sorted set of pixelcount
-- 'nope' if not increasing ranks
-- dailyset: 'rankd' sorted set of daily pixelcount
-- 'nope' if not increasing ranks
-- countryset: sorted set for country stats
-- prevTop: sorted set of yesterdays top 10
-- Args:
-- clrIgnore: integer number of what colors are considered unset
-- bcd: number baseColldown (fixed to cdFactor and 0 if admin)
@ -21,6 +22,8 @@
-- cds: max cooldown of canvas
-- userId: '0' if not logged in
-- cc country code
-- req: requirements of canvas
-- 'nope', unsigned integer or 'top'
-- off1, chonk offset of first pixel
-- off2, chonk offset of second pixel
-- ..., infinie pixels possible
@ -59,6 +62,32 @@ else
return ret
end
end
-- check if requirements for canvas met
if ARGV[7] ~= "nope" then
if ARGV[5] == "0" then
-- not logged in
ret[1] = 6
return ret;
end
if ARGV[7] == "top" then
local pr = redis.call('zrank', KEYS[9], ARGV[5])
if not pr or pr > 9 then
-- not in yesterdays top 10
ret[1] = 12;
return ret;
end
else
local req = tonumber(ARGV[7])
if req > 0 then
local sc = tonumber(redis.call('zscore', KEYS[6], ARGV[5]))
if not sc or sc < req then
-- not enough pxls placed
ret[1] = 7;
return ret
end
end
end
end
-- get cooldown of user
local cd = redis.call('pttl', KEYS[3])
if cd < 0 then
@ -77,7 +106,7 @@ local cli = tonumber(ARGV[1])
local bcd = tonumber(ARGV[2])
local pcd = tonumber(ARGV[3])
local cds = tonumber(ARGV[4])
for c = 7,#ARGV do
for c = 8,#ARGV do
local off = tonumber(ARGV[c]) * 8
-- get color of pixel on canvas
local sclr = redis.call('bitfield', KEYS[5], 'get', 'u8', off)
@ -114,7 +143,7 @@ if pxlcnt > 0 then
end
end
-- increment pixelcount
if KEYS[6] ~= 'nope' then
if KEYS[7] ~= 'nope' then
redis.call('zincrby', KEYS[6], pxlcnt, ARGV[5])
redis.call('zincrby', KEYS[7], pxlcnt, ARGV[5])
if ARGV[6] ~= 'xx' then

View File

@ -7,7 +7,7 @@ import { getDateKeyOfTs } from '../../core/utils';
export const RANKED_KEY = 'rank';
export const DAILY_RANKED_KEY = 'rankd';
export const DAILY_CRANKED_KEY = 'crankd';
const PREV_DAY_TOP_KEY = 'prankd';
export const PREV_DAY_TOP_KEY = 'prankd';
const DAY_STATS_RANKS_KEY = 'ds';
const CDAY_STATS_RANKS_KEY = 'cds';
const ONLINE_CNTR_KEY = 'tonl';