From 61da0fd6e0ce27b5a4250984ea62bccaf1f71845 Mon Sep 17 00:00:00 2001 From: qwerinope Date: Tue, 9 Sep 2025 00:06:10 +0200 Subject: [PATCH] remod hook now persists through restarts --- src/index.ts | 21 +++++++++++++++++---- src/lib/timeout.ts | 4 +++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1193a41..def89d8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,9 @@ import { addAdmin } from "lib/admins"; import logger from "lib/logger"; import { addInvuln } from "lib/invuln"; import { redis } from "bun"; +import { remodMod, timeoutDuration } from "lib/timeout"; +import User from "user"; +import { buildTimeString } from "lib/dateManager"; const CHATTERINTENTS = ["user:read:chat", "user:write:chat", "user:bot"]; const STREAMERINTENTS = ["channel:bot", "user:read:chat", "moderation:read", "channel:manage:moderators", "moderator:manage:banned_users", "bits:read", "channel:moderate"]; @@ -33,20 +36,30 @@ export const streamerUsers = [chatterId, streamerId]; streamerUsers.forEach(async id => await Promise.all([addAdmin(id), addInvuln(id)])); const banned = await streamerApi.moderation.getBannedUsers(streamerId).then(a => a.data); -banned.forEach(async ban => { +for (const ban of banned) { await redis.set(`user:${ban.userId}:timeout`, '1'); const banlength = ban.expiryDate; if (banlength) { redis.expire(`user:${ban.userId}:timeout`, Math.floor((ban.expiryDate.getTime() - Date.now()) / 1000) + 1); logger.info(`Set the timeout of ${ban.userDisplayName} in the Redis/Valkey database.`); }; -}); +}; const mods = await streamerApi.moderation.getModerators(streamerId).then(a => a.data); -mods.forEach(async mod => { +for (const mod of mods) { await redis.set(`user:${mod.userId}:mod`, '1'); logger.info(`Set the mod status of ${mod.userDisplayName} in the Redis/Valkey database.`); -}); +}; + +const bannedmods = await redis.keys('user:*:remod').then(a => Array.from(a).map(b => b.slice(5, -6))); +for (const remod of bannedmods) { + const target = await User.initUserId(remod); + const durationdata = await timeoutDuration(target!); + let duration = 0; + if (durationdata) duration = Math.floor((durationdata * 1000 - Date.now()) / 1000); + remodMod(target!, duration); + logger.info(`Set the remod timer for ${target?.displayName} to ${duration} seconds.`); +}; const streamdata = await streamerApi.streams.getStreamByUserId(streamerId); if (streamdata) await redis.set('streamIsLive', '1'); diff --git a/src/lib/timeout.ts b/src/lib/timeout.ts index c6fb3a8..2a96e76 100644 --- a/src/lib/timeout.ts +++ b/src/lib/timeout.ts @@ -25,6 +25,7 @@ export const timeout = async (user: User, reason: string, duration?: number): Pr if (await redis.exists(`user:${user.id}:mod`)) { if (!duration) duration = 60; // make sure that mods don't get perma-banned + await redis.set(`user:${user.id}:remod`, '1'); remodMod(user, duration); await streamerApi.moderation.removeModerator(streamerId, user.id!); }; @@ -43,7 +44,7 @@ export const timeout = async (user: User, reason: string, duration?: number): Pr }; /** Give the target mod status back after timeout */ -function remodMod(target: User, duration: number) { +export function remodMod(target: User, duration: number) { setTimeout(async () => { const bandata = await timeoutDuration(target); if (bandata) { // If the target is still timed out, try again when new timeout expires @@ -52,6 +53,7 @@ function remodMod(target: User, duration: number) { } else { try { await streamerApi.moderation.addModerator(streamerId, target.id); + await redis.del(`user:${target.id}:remod`); } catch (err) { }; // This triggers when the timeout got shortened. try/catch so no runtime error }; }, duration + 3000); // callback gets called after duration of timeout + 3 seconds