From d6ba5684e0b62c81fff41d80f96019656f564dbd Mon Sep 17 00:00:00 2001 From: Nanobyte Date: Fri, 26 Feb 2021 01:57:45 +0100 Subject: [PATCH 1/4] Limit reward time per segment --- config.json.example | 3 ++- src/config.ts | 1 + src/routes/getTopUsers.ts | 3 ++- src/types/config.model.ts | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config.json.example b/config.json.example index f8548c1..075872a 100644 --- a/config.json.example +++ b/config.json.example @@ -38,5 +38,6 @@ "max": 20, // 20 requests in 15min time window "statusCode": 200 } - } + }, + "maxRewardTimePerSegmentInSeconds": 86400 // maximum time a user get rewarded in the leaderboard for a single segment } diff --git a/src/config.ts b/src/config.ts index 7a172cc..a37fb6c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -45,6 +45,7 @@ addDefaults(config, { }, userCounterURL: null, youtubeAPIKey: null, + maxRewardTimePerSegmentInSeconds: 86400, }); // Add defaults diff --git a/src/routes/getTopUsers.ts b/src/routes/getTopUsers.ts index cf069a1..c7a6141 100644 --- a/src/routes/getTopUsers.ts +++ b/src/routes/getTopUsers.ts @@ -5,6 +5,7 @@ import {Request, Response} from 'express'; const MILLISECONDS_IN_MINUTE = 60000; const getTopUsersWithCache = createMemoryCache(generateTopUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE); +const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boolean = false) { return new Promise((resolve) => { @@ -25,7 +26,7 @@ function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boolean = f } const rows = db.prepare('all', "SELECT COUNT(*) as totalSubmissions, SUM(views) as viewCount," + - "SUM((sponsorTimes.endTime - sponsorTimes.startTime) / 60 * sponsorTimes.views) as minutesSaved, " + + "SUM(((CASE WHEN endTime - startTime > " + maxRewardTimePerSegmentInSeconds + " THEN " + maxRewardTimePerSegmentInSeconds + " ELSE endTime - startTime END) / 60) * views) as minutesSaved," + "SUM(votes) as userVotes, " + additionalFields + "IFNULL(userNames.userName, sponsorTimes.userID) as userName FROM sponsorTimes LEFT JOIN userNames ON sponsorTimes.userID=userNames.userID " + diff --git a/src/types/config.model.ts b/src/types/config.model.ts index 88af3d2..110b210 100644 --- a/src/types/config.model.ts +++ b/src/types/config.model.ts @@ -36,6 +36,7 @@ export interface SBSConfig { minimumPrefix?: string; maximumPrefix?: string; redis?: redis.ClientOpts; + maxRewardTimePerSegmentInSeconds?: number; } export interface WebhookConfig { From ac945254d6169138680196d4173a60d84f8ee75f Mon Sep 17 00:00:00 2001 From: Nanobyte Date: Tue, 2 Mar 2021 01:22:02 +0100 Subject: [PATCH 2/4] Limit reward time for getSavedTimeForUser endpoint --- src/routes/getSavedTimeForUser.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/routes/getSavedTimeForUser.ts b/src/routes/getSavedTimeForUser.ts index fbf28dc..9bcd420 100644 --- a/src/routes/getSavedTimeForUser.ts +++ b/src/routes/getSavedTimeForUser.ts @@ -1,6 +1,9 @@ import {db} from '../databases/databases'; import {Request, Response} from 'express'; import {getHash} from '../utils/getHash'; +import {config} from '../config'; + +const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; export function getSavedTimeForUser(req: Request, res: Response) { let userID = req.query.userID as string; @@ -15,7 +18,7 @@ export function getSavedTimeForUser(req: Request, res: Response) { userID = getHash(userID); try { - let row = db.prepare("get", "SELECT SUM((endTime - startTime) / 60 * views) as minutesSaved FROM sponsorTimes WHERE userID = ? AND votes > -1 AND shadowHidden != 1 ", [userID]); + let row = db.prepare("get", "SELECT SUM(((CASE WHEN endTime - startTime > " + maxRewardTimePerSegmentInSeconds + " THEN " + maxRewardTimePerSegmentInSeconds + " ELSE endTime - startTime END) / 60) * views) as minutesSaved FROM sponsorTimes WHERE userID = ? AND votes > -1 AND shadowHidden != 1 ", [userID]); if (row.minutesSaved != null) { res.send({ From e883f76e54ffe2149864e41d9df9b11bf277e5ff Mon Sep 17 00:00:00 2001 From: Nanobyte Date: Sat, 20 Mar 2021 01:17:50 +0100 Subject: [PATCH 3/4] Fix quote inconsistency --- src/routes/getTopUsers.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/routes/getTopUsers.ts b/src/routes/getTopUsers.ts index 1303682..6f66e7e 100644 --- a/src/routes/getTopUsers.ts +++ b/src/routes/getTopUsers.ts @@ -16,12 +16,12 @@ async function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boole let additionalFields = ''; if (categoryStatsEnabled) { - additionalFields += `SUM(CASE WHEN category = 'sponsor' THEN 1 ELSE 0 END) as "categorySponsor", - SUM(CASE WHEN category = 'intro' THEN 1 ELSE 0 END) as "categorySumIntro", - SUM(CASE WHEN category = 'outro' THEN 1 ELSE 0 END) as "categorySumOutro", - SUM(CASE WHEN category = 'interaction' THEN 1 ELSE 0 END) as "categorySumInteraction", - SUM(CASE WHEN category = 'selfpromo' THEN 1 ELSE 0 END) as "categorySelfpromo", - SUM(CASE WHEN category = 'music_offtopic' THEN 1 ELSE 0 END) as "categoryMusicOfftopic", `; + additionalFields += `SUM(CASE WHEN category = "sponsor" THEN 1 ELSE 0 END) as "categorySponsor", + SUM(CASE WHEN category = "intro" THEN 1 ELSE 0 END) as "categorySumIntro", + SUM(CASE WHEN category = "outro" THEN 1 ELSE 0 END) as "categorySumOutro", + SUM(CASE WHEN category = "interaction" THEN 1 ELSE 0 END) as "categorySumInteraction", + SUM(CASE WHEN category = "selfpromo" THEN 1 ELSE 0 END) as "categorySelfpromo", + SUM(CASE WHEN category = "music_offtopic" THEN 1 ELSE 0 END) as "categoryMusicOfftopic", `; } const rows = await db.prepare('all', `SELECT COUNT(*) as "totalSubmissions", SUM(views) as "viewCount", @@ -32,7 +32,7 @@ async function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boole LEFT JOIN "privateDB"."shadowBannedUsers" ON "sponsorTimes"."userID"="privateDB"."shadowBannedUsers"."userID" WHERE "sponsorTimes"."votes" > -1 AND "sponsorTimes"."shadowHidden" != 1 AND "privateDB"."shadowBannedUsers"."userID" IS NULL GROUP BY IFNULL("userName", "sponsorTimes"."userID") HAVING "userVotes" > 20 - ORDER BY "` + sortBy + `" DESC LIMIT 100`, []); + ORDER BY "${sortBy}" DESC LIMIT 100`, []); for (let i = 0; i < rows.length; i++) { userNames[i] = rows[i].userName; From e70ae12f2af02ede36e7dff001997d4c1e6b898a Mon Sep 17 00:00:00 2001 From: Ajay Ramachandran Date: Sun, 18 Apr 2021 15:46:46 -0400 Subject: [PATCH 4/4] Fix quote issues --- src/routes/getTopUsers.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/routes/getTopUsers.ts b/src/routes/getTopUsers.ts index 6f66e7e..7978620 100644 --- a/src/routes/getTopUsers.ts +++ b/src/routes/getTopUsers.ts @@ -16,12 +16,12 @@ async function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boole let additionalFields = ''; if (categoryStatsEnabled) { - additionalFields += `SUM(CASE WHEN category = "sponsor" THEN 1 ELSE 0 END) as "categorySponsor", - SUM(CASE WHEN category = "intro" THEN 1 ELSE 0 END) as "categorySumIntro", - SUM(CASE WHEN category = "outro" THEN 1 ELSE 0 END) as "categorySumOutro", - SUM(CASE WHEN category = "interaction" THEN 1 ELSE 0 END) as "categorySumInteraction", - SUM(CASE WHEN category = "selfpromo" THEN 1 ELSE 0 END) as "categorySelfpromo", - SUM(CASE WHEN category = "music_offtopic" THEN 1 ELSE 0 END) as "categoryMusicOfftopic", `; + additionalFields += `SUM(CASE WHEN category = 'sponsor' THEN 1 ELSE 0 END) as "categorySponsor", + SUM(CASE WHEN category = 'intro' THEN 1 ELSE 0 END) as "categorySumIntro", + SUM(CASE WHEN category = 'outro' THEN 1 ELSE 0 END) as "categorySumOutro", + SUM(CASE WHEN category = 'interaction' THEN 1 ELSE 0 END) as "categorySumInteraction", + SUM(CASE WHEN category = 'selfpromo' THEN 1 ELSE 0 END) as "categorySelfpromo", + SUM(CASE WHEN category = 'music_offtopic' THEN 1 ELSE 0 END) as "categoryMusicOfftopic", `; } const rows = await db.prepare('all', `SELECT COUNT(*) as "totalSubmissions", SUM(views) as "viewCount",