From afbf08f21a4784fafdcf7d5020ad3ee40bdee33f Mon Sep 17 00:00:00 2001 From: qwerinope Date: Sat, 6 Dec 2025 04:51:34 +0100 Subject: [PATCH] fix tsc configs, add realsilverbullets for 6666 bits --- README.md | 1 + biome.json | 5 +- package.json | 1 + src/cheers/index.ts | 14 ++++- src/cheers/realsilverbullet.ts | 88 ++++++++++++++++++++++++++++++ src/cheers/superloot.ts | 2 + src/db/dbCheerEvents.ts | 3 +- src/db/dbTimeouts.ts | 3 +- src/db/schema.ts | 5 +- src/items/index.ts | 15 +++-- src/lib/getStats.ts | 7 ++- src/web/alerts/www/src/main.ts | 1 + src/web/chatWidget/www/src/main.ts | 2 + tsconfig.json | 1 + tsconfig.web.json | 7 ++- 15 files changed, 136 insertions(+), 19 deletions(-) create mode 100644 src/cheers/realsilverbullet.ts diff --git a/README.md b/README.md index 1bc5b26..a32114c 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,7 @@ NAME|AMOUNT|USAGE|FUNCTION `superloot`|150|`cheer150`|Get superloot. Details and drop rates can be found [(here)](#lootbox). `execute`|666|`cheer666 [target]`|Times specified or random vulnerable user out for 30 minutes. On failure gives cheerer a silver bullet `tnt`|1000|`cheer1000`|Gives 5-10 random vulnerable chatters 60 second timeouts. On failure gives cheerer a TNT +`realsilverbullet`|6666|`cheer6666 [target]`|Times specified or random vulnerable chatter out for 24 hours. On failure gives the user nothing. Get scammed. ## Point Redeems diff --git a/biome.json b/biome.json index 93ebc87..6d04103 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.3.7/schema.json", + "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -19,7 +19,8 @@ "suspicious": { "noNonNullAssertedOptionalChain": "off", "noExplicitAny": "off", - "noControlCharactersInRegex": "off" + "noControlCharactersInRegex": "off", + "noTsIgnore": "off" }, "style": { "noNonNullAssertion": "off" diff --git a/package.json b/package.json index cd56746..51a6c5d 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "pg": "^8.16.3" }, "scripts": { + "check": "biome check && tsc -b", "start": "NODE_ENV=production bun src/index.ts", "start-dev": "NODE_ENV=development bun src/index.ts", "start-discord": "NODE_ENV=production bun src/discord/index.ts", diff --git a/src/cheers/index.ts b/src/cheers/index.ts index fdaa602..6ce372f 100644 --- a/src/cheers/index.ts +++ b/src/cheers/index.ts @@ -1,8 +1,16 @@ import type { EventSubChannelChatMessageEvent } from "@twurple/eventsub-base"; import type User from "user"; +export type cheers = + | "execute" + | "grenade" + | "tnt" + | "timeout" + | "superloot" + | "realsilverbullet"; + type cheerOptions = { - name: string; + name: cheers; amount: number; isItem: boolean; execute: ( @@ -12,7 +20,7 @@ type cheerOptions = { }; export class Cheer { - public readonly name: string; + public readonly name: cheers; public readonly amount: number; public readonly execute: ( msg: EventSubChannelChatMessageEvent, @@ -20,7 +28,7 @@ export class Cheer { ) => Promise; public readonly isItem: boolean; constructor(options: cheerOptions) { - this.name = options.name.toLowerCase(); + this.name = options.name; this.amount = options.amount; this.execute = options.execute; this.isItem = options.isItem; diff --git a/src/cheers/realsilverbullet.ts b/src/cheers/realsilverbullet.ts new file mode 100644 index 0000000..06163db --- /dev/null +++ b/src/cheers/realsilverbullet.ts @@ -0,0 +1,88 @@ +import { Cheer } from "cheers"; +import { createCheerEventRecord } from "db/dbCheerEvents"; +import { createTimeoutRecord } from "db/dbTimeouts"; +import { getUserRecord } from "db/dbUser"; +import { sendMessage } from "lib/commandUtils"; +import { parseCheerArgs } from "lib/parseCommandArgs"; +import { redis } from "lib/redis"; +import { timeout } from "lib/timeout"; +import User from "user"; +import { playAlert } from "web/alerts/serverFunctions"; + +export default new Cheer({ + name: "realsilverbullet", + amount: 6666, + isItem: false, + async execute(msg, user) { + const args = parseCheerArgs(msg.messageText); + + let target: User | null; + if (!args[0]) { + const vulnsids = await redis.keys("user:*:vulnerable"); + const baseusers = vulnsids.map((a) => User.initUserId(a.slice(5, -11))); + const users: User[] = []; + for (const user of baseusers) { + const a = await user; + if (!a) continue; + users.push(a); + } + if (users.length === 0) { + await sendMessage("No vulnerable chatters, -6666 KEKPOINT"); + return; + } + target = users[Math.floor(Math.random() * users.length)]!; + await playAlert({ + name: "blastinRoulette", + user: user.displayName, + targets: users.map((a) => a.displayName), + finaltarget: target.displayName, + }); + await new Promise((res, _) => setTimeout(res, 4000)); + } else { + target = await User.initUsername(args[0].toLowerCase()); + } + if (!target) { + await sendMessage("dumbass wasted 6666 bits KEKPOINT", msg.messageId); + return; + } + await getUserRecord(target); + + const result = await timeout( + target, + `You got fucking DELETED by ${user.displayName}!`, + 60 * 60 * 24, + ); + if (result.status) + await Promise.all([ + sendMessage( + `KEKPOINT KEKPOINT KEKPOINT ${target.displayName.toUpperCase()} RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO`, + ), + createTimeoutRecord(user, target, "realsilverbullet"), + createCheerEventRecord(user, "realsilverbullet"), + playAlert({ + name: "userExecution", + user: user.displayName, + target: target.displayName, + }), + ]); + else { + switch (result.reason) { + case "banned": + await sendMessage( + `${target.displayName} is already timed out/banned`, + msg.messageId, + ); + break; + case "illegal": + await Promise.all([ + sendMessage(`${user.displayName} Nou Nou Nou`), + timeout(user, "nah", 60 * 60 * 24), + ]); + break; + case "unknown": + await sendMessage("Something went wrong... oops", msg.messageId); + break; + } + } + }, +}); diff --git a/src/cheers/superloot.ts b/src/cheers/superloot.ts index ea37d4b..7783b04 100644 --- a/src/cheers/superloot.ts +++ b/src/cheers/superloot.ts @@ -1,4 +1,5 @@ import { Cheer } from "cheers"; +import { createCheerEventRecord } from "db/dbCheerEvents"; import { createGetLootRecord } from "db/dbGetLoot"; import { getUserRecord, updateUserRecord } from "db/dbUser"; import itemMap, { type inventory, type items } from "items"; @@ -80,6 +81,7 @@ export default new Cheer({ await Promise.all([ updateUserRecord(user, userData), sendMessage(message, msg.messageId), + createCheerEventRecord(user, "superloot"), createGetLootRecord(user, gainedqbucks, itemDiff, "superloot"), user.clearLock(), ]); diff --git a/src/db/dbCheerEvents.ts b/src/db/dbCheerEvents.ts index ef05135..023e383 100644 --- a/src/db/dbCheerEvents.ts +++ b/src/db/dbCheerEvents.ts @@ -1,3 +1,4 @@ +import type { cheers } from "cheers"; import db from "db/connection"; import { cheerEvents } from "db/schema"; import { and, between, eq, type SQL } from "drizzle-orm"; @@ -6,7 +7,7 @@ import type User from "user"; export async function createCheerEventRecord( user: User, - cheer: items, + cheer: items | cheers, ): Promise { await db .insert(cheerEvents) diff --git a/src/db/dbTimeouts.ts b/src/db/dbTimeouts.ts index 9519e44..292385d 100644 --- a/src/db/dbTimeouts.ts +++ b/src/db/dbTimeouts.ts @@ -1,3 +1,4 @@ +import type { cheers } from "cheers"; import db from "db/connection"; import { timeouts } from "db/schema"; import { and, between, eq, type SQL } from "drizzle-orm"; @@ -7,7 +8,7 @@ import type User from "user"; export async function createTimeoutRecord( user: User, target: User, - item: items, + item: items | cheers, ): Promise { await db.insert(timeouts).values({ user: parseInt(user.id, 10), diff --git a/src/db/schema.ts b/src/db/schema.ts index 3621627..29e12f4 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -1,4 +1,5 @@ import type { AccessToken } from "@twurple/auth"; +import type { cheers as cheertypes } from "cheers"; import { relations } from "drizzle-orm"; import { boolean, @@ -42,7 +43,7 @@ export const timeouts = pgTable("timeouts", { target: integer() .notNull() .references(() => users.id), - item: varchar().$type().notNull(), + item: varchar().$type().notNull(), created: timestamp().defaultNow().notNull(), }); @@ -80,7 +81,7 @@ export const cheerEvents = pgTable("cheerEvents", { user: integer() .notNull() .references(() => users.id), - event: varchar().$type().notNull(), + event: varchar().$type().notNull(), created: timestamp().defaultNow().notNull(), }); diff --git a/src/items/index.ts b/src/items/index.ts index 67f8dba..86882d6 100644 --- a/src/items/index.ts +++ b/src/items/index.ts @@ -1,7 +1,9 @@ import { Command, type commandOptions } from "lib/commandUtils"; import type User from "user"; -interface itemOptions extends commandOptions { +export type items = "blaster" | "silverbullet" | "grenade" | "tnt"; + +interface itemOptions extends Omit { name: items; prettyName: string; plural: string; @@ -10,7 +12,7 @@ interface itemOptions extends commandOptions { } export class Item extends Command { - public readonly name: items; + public readonly name: items = "blaster"; public readonly prettyName: string; public readonly plural: string; public readonly description: string; @@ -18,9 +20,11 @@ export class Item extends Command { /** Creates an item object */ constructor(options: itemOptions) { - options.disableable = true; // Items can always be disabled - options.usertype = "chatter"; // Everyone can use items - super(options); + super({ + ...options, + usertype: "chatter", // Everyone can use items + disableable: true, // Items can always be disabled + }); this.name = options.name; this.prettyName = options.prettyName; this.plural = options.plural; @@ -59,7 +63,6 @@ for (const file of files) { export default itemAliasMap; export { emptyInventory, itemarray, specialAliasItems, itemObjectArray }; -export type items = "blaster" | "silverbullet" | "grenade" | "tnt"; export type inventory = { [key in items]?: number; }; diff --git a/src/lib/getStats.ts b/src/lib/getStats.ts index 7760f02..cb0a14d 100644 --- a/src/lib/getStats.ts +++ b/src/lib/getStats.ts @@ -59,8 +59,11 @@ export async function getItemStats(target: User, thismonth: boolean) { } for (const cheer of cheers) { - if (!returnObj[cheer.event]) returnObj[cheer.event] = 0; - returnObj[cheer.event]! += 1; + if (cheer.event in returnObj) { + if (!returnObj[cheer.event as keyof inventory]) + returnObj[cheer.event as keyof inventory] = 0; + returnObj[cheer.event as keyof inventory]! += 1; + } } return returnObj; diff --git a/src/web/alerts/www/src/main.ts b/src/web/alerts/www/src/main.ts index c2bf2d4..408648b 100644 --- a/src/web/alerts/www/src/main.ts +++ b/src/web/alerts/www/src/main.ts @@ -1,6 +1,7 @@ import type { alertEventData } from "web/alerts/types"; import type { serverInstruction } from "web/serverTypes"; import AlertManager from "./AlertManager"; +// @ts-ignore import "@fontsource/jersey-15"; import TTSManager from "./TTSManager"; diff --git a/src/web/chatWidget/www/src/main.ts b/src/web/chatWidget/www/src/main.ts index 791d0a7..681cd57 100644 --- a/src/web/chatWidget/www/src/main.ts +++ b/src/web/chatWidget/www/src/main.ts @@ -1,4 +1,6 @@ +// @ts-ignore import "./style.css"; +// @ts-ignore import "@fontsource/jersey-15"; import type { twitchEventData } from "web/chatWidget/websockettypes"; diff --git a/tsconfig.json b/tsconfig.json index 199568f..8b453e1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "files": [], "compilerOptions": { + "noEmit": true, "baseUrl": "./src", "paths": { "lib/*": ["./lib/*"], diff --git a/tsconfig.web.json b/tsconfig.web.json index 0d438f2..a97cd22 100644 --- a/tsconfig.web.json +++ b/tsconfig.web.json @@ -3,7 +3,10 @@ "compilerOptions": { "target": "ESNext", "module": "ESNext", - "lib": ["DOM", "ES2020"] + "moduleResolution": "bundler", + "lib": ["DOM", "ES2022"], + "skipLibCheck": true }, - "include": ["src/web/chatWidget/www/**/*", "src/web/alerts/www/**/*"] + "include": ["src/web/chatWidget/www/**/*", "src/web/alerts/www/**/*"], + "exclude": ["node_modules"] }