jank fixes

This commit is contained in:
2025-09-11 14:44:26 +02:00
parent 7af09370da
commit 3e373056c9
8 changed files with 38 additions and 11 deletions

View File

@@ -0,0 +1,20 @@
import { Command, sendMessage } from "commands";
import parseCommandArgs from "lib/parseCommandArgs";
import { timeout } from "lib/timeout";
import User from "user";
import { playAlert } from "web/alerts/serverFunctions";
export default new Command('banclanker', ['banclanker', 'banbot'], 'moderator', async msg => {
const args = parseCommandArgs(msg.messageText);
if (!args[0]) { await sendMessage(`Specify a clanker to ban`, msg.messageId); return; };
const target = await User.initUsername(args[0]);
if (!target) { await sendMessage(`Clanker ${args[0]} doesn't exist`, msg.messageId); return; };
await Promise.all([
timeout(target, `get fucked`),
playAlert({
name: 'userExecution',
user: msg.chatterDisplayName,
target: target.displayName
})
]);
});

View File

@@ -17,7 +17,7 @@ export default new Command('getloot', ['getloot', 'dig', 'loot'], 'chatter', asy
if (await user.greedy()) { if (await user.greedy()) {
await Promise.all([ await Promise.all([
sendMessage(`${user.displayName} STOP BEING GREEDY!!! UltraMad UltraMad UltraMad`), sendMessage(`${user.displayName} STOP BEING GREEDY!!! UltraMad UltraMad UltraMad`),
timeout(user, 'STOP BEING GREEDY!!!', 60) timeout(user, `Wait ${buildTimeString(now - COOLDOWN, lastlootbox)}`, 60)
]); ]);
return; return;
} else { } else {

View File

@@ -1,7 +1,7 @@
import { EventSubChannelChatMessageEvent } from "@twurple/eventsub-base"; import { EventSubChannelChatMessageEvent } from "@twurple/eventsub-base";
import User from "user"; import User from "user";
export type userType = 'chatter' | 'admin' | 'streamer'; export type userType = 'chatter' | 'admin' | 'streamer' | 'moderator';
/** The Command class represents a command */ /** The Command class represents a command */
export class Command { export class Command {
@@ -46,5 +46,5 @@ import { chatterApi, chatterId, streamerId } from "main";
/** Helper function to send a message to the stream */ /** Helper function to send a message to the stream */
export const sendMessage = async (message: string, replyParentMessageId?: string) => { export const sendMessage = async (message: string, replyParentMessageId?: string) => {
await chatterApi.chat.sendChatMessageAsApp(chatterId, streamerId, message, { replyParentMessageId }) return await chatterApi.chat.sendChatMessageAsApp(chatterId, streamerId, message, { replyParentMessageId })
}; };

View File

@@ -1,9 +1,11 @@
import { eventSub, streamerId } from "main"; import { eventSub, streamerApi, streamerId } from "main";
import { deleteBannedUserMessagesFromChatWidget } from "web/chatWidget/message"; import { deleteBannedUserMessagesFromChatWidget } from "web/chatWidget/message";
import { redis } from "bun"; import { redis } from "bun";
eventSub.onChannelBan(streamerId, async msg => { eventSub.onChannelBan(streamerId, async msg => {
deleteBannedUserMessagesFromChatWidget(msg); deleteBannedUserMessagesFromChatWidget(msg);
const welcomemessageid = await redis.get(`user:${msg.userId}:welcomemessageid`);
if (welcomemessageid) { await streamerApi.moderation.deleteChatMessages(streamerId, welcomemessageid); await redis.del(`user:${msg.userId}:welcomemessageid`); };
await redis.set(`user:${msg.userId}:timeout`, '1'); await redis.set(`user:${msg.userId}:timeout`, '1');
if (msg.endDate) await redis.expire(`user:${msg.userId}:timeout`, Math.floor((msg.endDate.getTime() - Date.now()) / 1000)); if (msg.endDate) await redis.expire(`user:${msg.userId}:timeout`, Math.floor((msg.endDate.getTime() - Date.now()) / 1000));
}); });

View File

@@ -30,9 +30,11 @@ async function parseChatMessage(msg: EventSubChannelChatMessageEvent) {
if (!await isInvuln(user?.id!)) user?.setVulnerable(); // Make the user vulnerable to explosions if not marked as invuln if (!await isInvuln(user?.id!)) user?.setVulnerable(); // Make the user vulnerable to explosions if not marked as invuln
if (!await redis.exists(`user:${user?.id}:haschatted`) && !msg.sourceMessageId) { if (!await redis.exists(`user:${user?.id}:haschatted`) && !msg.sourceMessageId) {
await sendMessage(`Welcome ${user?.displayName}. Please note: This chat has PvP, if you get timed out that's part of the qwerinope experience. You have 10 minutes of invincibility. A full list of commands and items can be found here: https://github.com/qwerinope/qweribot/#qweribot`); const message = await sendMessage(`Welcome ${user?.displayName}. Please note: This chat has PvP, if you get timed out that's part of the qwerinope experience. You have 10 minutes of invincibility. A full list of commands and items can be found here: https://github.com/qwerinope/qweribot/#qweribot`);
await redis.set(`user:${user?.id}:haschatted`, "1"); await redis.set(`user:${user?.id}:haschatted`, "1");
if (!streamerUsers.includes(msg.chatterId)) await setTemporaryInvuln(user?.id!); // This would set the invuln expiration lmao await redis.set(`user:${user?.id}:welcomemessageid`, message.id);
await redis.expire(`user:${user?.id}:welcomemessageid`, 600);
if (!await isInvuln(msg.chatterId)) await setTemporaryInvuln(user?.id!); // This would set the invuln expiration lmao
}; };
if (!msg.isCheer && !msg.isRedemption) await handleChatMessage(msg, user!) if (!msg.isCheer && !msg.isRedemption) await handleChatMessage(msg, user!)
@@ -57,6 +59,9 @@ async function handleChatMessage(msg: EventSubChannelChatMessageEvent, user: Use
case "streamer": case "streamer":
if (!streamerUsers.includes(msg.chatterId)) return; if (!streamerUsers.includes(msg.chatterId)) return;
break; break;
case "moderator":
if (!await redis.exists(`user:${user.id}:mod`)) return;
break;
}; };
try { await selected.execute(msg, user); } try { await selected.execute(msg, user); }

View File

@@ -10,7 +10,7 @@ import User from "user";
import { buildTimeString } from "lib/dateManager"; import { buildTimeString } from "lib/dateManager";
const CHATTERINTENTS = ["user:read:chat", "user:write:chat", "user:bot"]; 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", "moderator:manage:shoutouts"]; const STREAMERINTENTS = ["channel:bot", "user:read:chat", "moderation:read", "channel:manage:moderators", "moderator:manage:chat_messages", "moderator:manage:banned_users", "bits:read", "channel:moderate", "moderator:manage:shoutouts"];
export const singleUserMode = process.env.CHATTER_IS_STREAMER === 'true'; export const singleUserMode = process.env.CHATTER_IS_STREAMER === 'true';
export const chatterId = process.env.CHATTER_ID ?? ""; export const chatterId = process.env.CHATTER_ID ?? "";
@@ -33,7 +33,7 @@ export const eventSub = new EventSubWsListener({ apiClient: streamerApi });
export const commandPrefix = process.env.COMMAND_PREFIX ?? "!"; export const commandPrefix = process.env.COMMAND_PREFIX ?? "!";
export const streamerUsers = [chatterId, streamerId]; export const streamerUsers = [chatterId, streamerId];
streamerUsers.forEach(async id => await Promise.all([addAdmin(id), addInvuln(id)])); streamerUsers.forEach(async id => await Promise.all([addAdmin(id), addInvuln(id), redis.set(`user:${id}:mod`, '1')]));
const banned = await streamerApi.moderation.getBannedUsers(streamerId).then(a => a.data); const banned = await streamerApi.moderation.getBannedUsers(streamerId).then(a => a.data);
for (const ban of banned) { for (const ban of banned) {

View File

@@ -1,4 +1,4 @@
export function buildTimeString(time1: number, time2: number) { export function buildTimeString(time1: number, time2: number): string {
const diff = Math.abs(time1 - time2); const diff = Math.abs(time1 - time2);
const timeobj = { const timeobj = {
day: Math.floor(diff / (1000 * 60 * 60 * 24)), day: Math.floor(diff / (1000 * 60 * 60 * 24)),
@@ -13,5 +13,5 @@ export function buildTimeString(time1: number, time2: number) {
stringarray.push(`${value} ${unit}${value === 1 ? '' : 's'}`); stringarray.push(`${value} ${unit}${value === 1 ? '' : 's'}`);
}; };
const last = stringarray.pop(); const last = stringarray.pop();
return stringarray.length === 0 ? last : stringarray.join(', ') + " and " + last; return stringarray.length === 0 ? last! : stringarray.join(', ') + " and " + last;
}; };

View File

@@ -13,7 +13,7 @@ type TimeoutResult = SuccessfulTimeout | UnSuccessfulTimeout;
* @param reason - reason for timeout/ban * @param reason - reason for timeout/ban
* @param duration - duration of timeout. don't specifiy for ban */ * @param duration - duration of timeout. don't specifiy for ban */
export const timeout = async (user: User, reason: string, duration?: number): Promise<TimeoutResult> => { export const timeout = async (user: User, reason: string, duration?: number): Promise<TimeoutResult> => {
if (await isInvuln(user.id)) return { status: false, reason: 'illegal' }; // Don't timeout invulnerable chatters if (await isInvuln(user.id) && duration) return { status: false, reason: 'illegal' }; // Don't timeout invulnerable chatters
// Check if user already has a timeout and handle stacking // Check if user already has a timeout and handle stacking
const banStatus = await timeoutDuration(user); const banStatus = await timeoutDuration(user);