From d84394f2f15f764db495af1267b3956b242fe464 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Sun, 14 Jul 2024 16:31:01 -0400 Subject: [PATCH 1/8] Switch to using IRC for subscription message detection --- plugins/twitch/main/src/subscriptions.ts | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/plugins/twitch/main/src/subscriptions.ts b/plugins/twitch/main/src/subscriptions.ts index 2298b0eb..2bde5848 100644 --- a/plugins/twitch/main/src/subscriptions.ts +++ b/plugins/twitch/main/src/subscriptions.ts @@ -3,7 +3,7 @@ import { EventSubWsListener } from "@twurple/eventsub-ws" import { TwitchAccount } from "./twitch-auth" import { defineState, defineTrigger, usePluginLogger } from "castmate-core" import { Range } from "castmate-schema" -import { TwitchAPIService, onChannelAuth } from "./api-harness" +import { TwitchAPIService, onBotAuth, onChannelAuth } from "./api-harness" import { ViewerCache } from "./viewer-cache" import { TwitchViewer, TwitchViewerGroup } from "castmate-plugin-twitch-shared" import { inTwitchViewerGroup } from "./group" @@ -34,7 +34,7 @@ export function setupSubscriptions() { viewer: { type: TwitchViewer, required: true, default: "27082158" }, totalMonths: { type: Number, required: true, default: 5 }, streakMonths: { type: Number, required: true, default: 3 }, - durationMonths: { type: Number, required: true, default: 1 }, + //durationMonths: { type: Number, required: true, default: 1 }, message: { type: String, required: true, default: "" }, }, }, @@ -124,7 +124,7 @@ export function setupSubscriptions() { updateSubscriberCount() }) - service.eventsub.onChannelSubscriptionMessage(channel.twitchId, async (event) => { + /*service.eventsub.onChannelSubscriptionMessage(channel.twitchId, async (event) => { logger.log( "Sub Message Received: ", event.userDisplayName, @@ -152,7 +152,7 @@ export function setupSubscriptions() { durationMonths: event.durationMonths, message: event.messageText ?? "", }) - }) + })*/ service.eventsub.onChannelSubscriptionGift(channel.twitchId, async (event) => { ViewerCache.getInstance().cacheGiftSubEvent(event) @@ -172,4 +172,31 @@ export function setupSubscriptions() { updateSubscriberCount() }) + + onBotAuth((channel, service) => { + //Don't trust eventsub subscription messages. They're broken serverside and don't always trigger for first time subs. + service.chatClient.onSub(async (channel, user, subInfo, msg) => { + let tier = 1 + if (subInfo.plan == "2000") { + tier = 2 + } else if (subInfo.plan == "3000") { + tier = 3 + } + + ViewerCache.getInstance() + .getResolvedViewer(subInfo.userId) + .then((viewer) => { + lastSubscriber.value = viewer + }) + + subscription({ + tier, + viewer: subInfo.userId, + totalMonths: subInfo.months, + streakMonths: subInfo.streak ?? 1, + //durationMonths: subInfo..durationMonths, + message: subInfo.message ?? "", + }) + }) + }) } From 6f3ec7ac426aad7208b8d68011b7db30d7509d71 Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 15 Jul 2024 09:59:40 -0400 Subject: [PATCH 2/8] Lower simulated gift sub count --- plugins/twitch/main/src/subscriptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/twitch/main/src/subscriptions.ts b/plugins/twitch/main/src/subscriptions.ts index 2bde5848..31d76beb 100644 --- a/plugins/twitch/main/src/subscriptions.ts +++ b/plugins/twitch/main/src/subscriptions.ts @@ -71,7 +71,7 @@ export function setupSubscriptions() { type: Object, properties: { gifter: { type: TwitchViewer, required: true, default: "27082158" }, - subs: { type: Number, required: true, default: 5 }, + subs: { type: Number, required: true, default: 2 }, }, }, async handle(config, context) { From 2624952a0b21a6530b89f2a430e04b79c80d42fd Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 15 Jul 2024 15:32:22 -0400 Subject: [PATCH 3/8] Make sure everyone is on ES2022 --- libs/castmate-overlay-core/tsconfig.json | 4 ++-- libs/castmate-overlay-macros/tsconfig.json | 2 +- libs/castmate-overlay-widget-loader/tsconfig.json | 4 ++-- libs/castmate-ui-core/tsconfig.json | 4 ++-- libs/castmate-vite/tsconfig.json | 2 +- libs/castmate-ws-rpc/tsconfig.json | 2 +- packages/castmate-obs-overlay/tsconfig.json | 4 ++-- packages/castmate/tsconfig.json | 2 +- plugin-template/renderer/tsconfig.json | 4 ++-- plugins/discord/renderer/tsconfig.json | 4 ++-- plugins/elgato/renderer/tsconfig.json | 4 ++-- plugins/govee/renderer/tsconfig.json | 4 ++-- plugins/http/renderer/tsconfig.json | 4 ++-- plugins/input/renderer/tsconfig.json | 4 ++-- plugins/iot/renderer/tsconfig.json | 4 ++-- plugins/lifx/renderer/tsconfig.json | 4 ++-- plugins/minecraft/renderer/tsconfig.json | 4 ++-- plugins/obs/renderer/tsconfig.json | 4 ++-- plugins/os/renderer/tsconfig.json | 4 ++-- plugins/overlays/overlay/tsconfig.json | 4 ++-- plugins/overlays/renderer/tsconfig.json | 4 ++-- plugins/philips-hue/renderer/tsconfig.json | 4 ++-- plugins/random/overlay/tsconfig.json | 4 ++-- plugins/random/renderer/tsconfig.json | 4 ++-- plugins/remote/renderer/tsconfig.json | 4 ++-- plugins/sound/renderer/tsconfig.json | 4 ++-- plugins/spellcast/renderer/tsconfig.json | 4 ++-- plugins/stream-plans/renderer/tsconfig.json | 4 ++-- plugins/time/renderer/tsconfig.json | 4 ++-- plugins/tplink-kasa/renderer/tsconfig.json | 4 ++-- plugins/twinkly/renderer/tsconfig.json | 4 ++-- plugins/twitch/overlay/tsconfig.json | 4 ++-- plugins/twitch/renderer/tsconfig.json | 4 ++-- plugins/variables/renderer/tsconfig.json | 4 ++-- plugins/voicemod/renderer/tsconfig.json | 4 ++-- plugins/wyze/renderer/tsconfig.json | 4 ++-- 36 files changed, 68 insertions(+), 68 deletions(-) diff --git a/libs/castmate-overlay-core/tsconfig.json b/libs/castmate-overlay-core/tsconfig.json index 4d4faa6f..934d023d 100644 --- a/libs/castmate-overlay-core/tsconfig.json +++ b/libs/castmate-overlay-core/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/libs/castmate-overlay-macros/tsconfig.json b/libs/castmate-overlay-macros/tsconfig.json index ae039036..cb4b1fd0 100644 --- a/libs/castmate-overlay-macros/tsconfig.json +++ b/libs/castmate-overlay-macros/tsconfig.json @@ -6,7 +6,7 @@ "preserveConstEnums": true, "outDir": "dist", "sourceMap": true, - "target": "ES6", + "target": "ES2022", "strictNullChecks": true, "esModuleInterop": true }, diff --git a/libs/castmate-overlay-widget-loader/tsconfig.json b/libs/castmate-overlay-widget-loader/tsconfig.json index f32a276b..13a97455 100644 --- a/libs/castmate-overlay-widget-loader/tsconfig.json +++ b/libs/castmate-overlay-widget-loader/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/libs/castmate-ui-core/tsconfig.json b/libs/castmate-ui-core/tsconfig.json index 4d4faa6f..934d023d 100644 --- a/libs/castmate-ui-core/tsconfig.json +++ b/libs/castmate-ui-core/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/libs/castmate-vite/tsconfig.json b/libs/castmate-vite/tsconfig.json index 75b88507..40f00a10 100644 --- a/libs/castmate-vite/tsconfig.json +++ b/libs/castmate-vite/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "ESNext", "moduleResolution": "Node", - "target": "ES6", + "target": "ES2022", "noImplicitAny": true, "removeComments": true, "preserveConstEnums": true, diff --git a/libs/castmate-ws-rpc/tsconfig.json b/libs/castmate-ws-rpc/tsconfig.json index 36c6976e..8ed3b62e 100644 --- a/libs/castmate-ws-rpc/tsconfig.json +++ b/libs/castmate-ws-rpc/tsconfig.json @@ -6,7 +6,7 @@ "preserveConstEnums": true, "outDir": "dist", "sourceMap": true, - "target": "ES6", + "target": "ES2022", "strictNullChecks": true }, "include": ["src/**/*"], diff --git a/packages/castmate-obs-overlay/tsconfig.json b/packages/castmate-obs-overlay/tsconfig.json index 1b25bf17..2d457fea 100644 --- a/packages/castmate-obs-overlay/tsconfig.json +++ b/packages/castmate-obs-overlay/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/packages/castmate/tsconfig.json b/packages/castmate/tsconfig.json index ec465c84..b6f9d37d 100644 --- a/packages/castmate/tsconfig.json +++ b/packages/castmate/tsconfig.json @@ -3,7 +3,7 @@ "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugin-template/renderer/tsconfig.json b/plugin-template/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugin-template/renderer/tsconfig.json +++ b/plugin-template/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/discord/renderer/tsconfig.json b/plugins/discord/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/discord/renderer/tsconfig.json +++ b/plugins/discord/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/elgato/renderer/tsconfig.json b/plugins/elgato/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/elgato/renderer/tsconfig.json +++ b/plugins/elgato/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/govee/renderer/tsconfig.json b/plugins/govee/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/govee/renderer/tsconfig.json +++ b/plugins/govee/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/http/renderer/tsconfig.json b/plugins/http/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/http/renderer/tsconfig.json +++ b/plugins/http/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/input/renderer/tsconfig.json b/plugins/input/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/input/renderer/tsconfig.json +++ b/plugins/input/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/iot/renderer/tsconfig.json b/plugins/iot/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/iot/renderer/tsconfig.json +++ b/plugins/iot/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/lifx/renderer/tsconfig.json b/plugins/lifx/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/lifx/renderer/tsconfig.json +++ b/plugins/lifx/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/minecraft/renderer/tsconfig.json b/plugins/minecraft/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/minecraft/renderer/tsconfig.json +++ b/plugins/minecraft/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/obs/renderer/tsconfig.json b/plugins/obs/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/obs/renderer/tsconfig.json +++ b/plugins/obs/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/os/renderer/tsconfig.json b/plugins/os/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/os/renderer/tsconfig.json +++ b/plugins/os/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/overlays/overlay/tsconfig.json b/plugins/overlays/overlay/tsconfig.json index 9ef94822..acdc3196 100644 --- a/plugins/overlays/overlay/tsconfig.json +++ b/plugins/overlays/overlay/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/overlays/renderer/tsconfig.json b/plugins/overlays/renderer/tsconfig.json index 14019814..e4a5ab51 100644 --- a/plugins/overlays/renderer/tsconfig.json +++ b/plugins/overlays/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/philips-hue/renderer/tsconfig.json b/plugins/philips-hue/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/philips-hue/renderer/tsconfig.json +++ b/plugins/philips-hue/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/random/overlay/tsconfig.json b/plugins/random/overlay/tsconfig.json index 9ef94822..acdc3196 100644 --- a/plugins/random/overlay/tsconfig.json +++ b/plugins/random/overlay/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/random/renderer/tsconfig.json b/plugins/random/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/random/renderer/tsconfig.json +++ b/plugins/random/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/remote/renderer/tsconfig.json b/plugins/remote/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/remote/renderer/tsconfig.json +++ b/plugins/remote/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/sound/renderer/tsconfig.json b/plugins/sound/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/sound/renderer/tsconfig.json +++ b/plugins/sound/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/spellcast/renderer/tsconfig.json b/plugins/spellcast/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/spellcast/renderer/tsconfig.json +++ b/plugins/spellcast/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/stream-plans/renderer/tsconfig.json b/plugins/stream-plans/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/stream-plans/renderer/tsconfig.json +++ b/plugins/stream-plans/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/time/renderer/tsconfig.json b/plugins/time/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/time/renderer/tsconfig.json +++ b/plugins/time/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/tplink-kasa/renderer/tsconfig.json b/plugins/tplink-kasa/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/tplink-kasa/renderer/tsconfig.json +++ b/plugins/tplink-kasa/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/twinkly/renderer/tsconfig.json b/plugins/twinkly/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/twinkly/renderer/tsconfig.json +++ b/plugins/twinkly/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/twitch/overlay/tsconfig.json b/plugins/twitch/overlay/tsconfig.json index 9ef94822..acdc3196 100644 --- a/plugins/twitch/overlay/tsconfig.json +++ b/plugins/twitch/overlay/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/twitch/renderer/tsconfig.json b/plugins/twitch/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/twitch/renderer/tsconfig.json +++ b/plugins/twitch/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/variables/renderer/tsconfig.json b/plugins/variables/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/variables/renderer/tsconfig.json +++ b/plugins/variables/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/voicemod/renderer/tsconfig.json b/plugins/voicemod/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/voicemod/renderer/tsconfig.json +++ b/plugins/voicemod/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ diff --git a/plugins/wyze/renderer/tsconfig.json b/plugins/wyze/renderer/tsconfig.json index 123eb7c9..aac47dd1 100644 --- a/plugins/wyze/renderer/tsconfig.json +++ b/plugins/wyze/renderer/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ES2022", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ From 669646d352dfc3216d222fb7d5e18331ba6478bf Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 15 Jul 2024 15:32:41 -0400 Subject: [PATCH 4/8] Add some perf measurement (for now) Some users are experiencing really long startup times. Measure some functions to try to narrow it down. --- libs/castmate-core/src/index.ts | 2 + libs/castmate-core/src/plugins/plugin.ts | 10 +- libs/castmate-core/src/util/time-utils.ts | 82 ++++++++++++++++ plugins/twitch/main/src/ads.ts | 18 +++- plugins/twitch/main/src/viewer-cache.ts | 109 ++++++++++++---------- 5 files changed, 169 insertions(+), 52 deletions(-) create mode 100644 libs/castmate-core/src/util/time-utils.ts diff --git a/libs/castmate-core/src/index.ts b/libs/castmate-core/src/index.ts index dad6202d..399a17ca 100644 --- a/libs/castmate-core/src/index.ts +++ b/libs/castmate-core/src/index.ts @@ -49,3 +49,5 @@ export * from "./util/generic-login" export * from "./analytics/analytics-manager" export * from "./info/info-manager" + +export * from "./util/time-utils" diff --git a/libs/castmate-core/src/plugins/plugin.ts b/libs/castmate-core/src/plugins/plugin.ts index d2576fb0..6fb7b4d5 100644 --- a/libs/castmate-core/src/plugins/plugin.ts +++ b/libs/castmate-core/src/plugins/plugin.ts @@ -40,6 +40,7 @@ import { import { ResourceBase, ResourceConstructor } from "../resources/resource" import { PluginManager } from "./plugin-manager" import { Logger, globalLogger, usePluginLogger } from "../logging/logging" +import { startPerfTime } from "../util/time-utils" interface PluginSpec { id: string @@ -97,8 +98,15 @@ export function onUnload(unloadFunc: PluginCallback) { } export function definePluginResource(resourceConstructor: ResourceConstructor) { + const logger = usePluginLogger() + onLoad(async () => { - await resourceConstructor.initialize() + const perf = startPerfTime(`Initing ${resourceConstructor.storage.name}`) + try { + await resourceConstructor.initialize() + } finally { + perf.stop(logger) + } }) onUnload(async () => { diff --git a/libs/castmate-core/src/util/time-utils.ts b/libs/castmate-core/src/util/time-utils.ts new file mode 100644 index 00000000..e706367a --- /dev/null +++ b/libs/castmate-core/src/util/time-utils.ts @@ -0,0 +1,82 @@ +import { isPromise } from "util/types" +import { Logger, usePluginLogger } from "../logging/logging" + +export interface PerfTimer { + name: string + startTime: number + stop(logger: Logger): void +} + +export function startPerfTime(name: string): PerfTimer { + return { + name, + startTime: Date.now(), + stop(logger) { + logger.log("Completed ", name, (Date.now() - this.startTime) / 1000, "seconds") + }, + } +} + +export function measurePerf any>( + original: T, + context: ClassMethodDecoratorContext +) { + const logger = usePluginLogger("perf") + + function replacement(this: This, ...args: Parameters): ReturnType { + const perf = startPerfTime(String(context.name)) + + let result: ReturnType + try { + result = original.call(this, ...args) + + if (isPromise(result)) { + //@ts-ignore Type system too stupid again. + return (async () => { + try { + return await result + } finally { + perf.stop(logger) + } + })() + } else { + perf.stop(logger) + return result + } + } catch (err) { + perf.stop(logger) + throw err + } + } + + return replacement +} + +export function measurePerfFunc any>(func: T, name?: string) { + const logger = usePluginLogger("perf") + return (...args: Parameters): ReturnType => { + const perf = startPerfTime(name ?? func.name) + + let result: ReturnType + try { + result = func(...args) + + if (isPromise(result)) { + //@ts-ignore Type system too stupid again. + return (async () => { + try { + return await result + } finally { + perf.stop(logger) + } + })() + } else { + perf.stop(logger) + return result + } + } catch (err) { + perf.stop(logger) + throw err + } + } +} diff --git a/plugins/twitch/main/src/ads.ts b/plugins/twitch/main/src/ads.ts index 4035cebd..4f151291 100644 --- a/plugins/twitch/main/src/ads.ts +++ b/plugins/twitch/main/src/ads.ts @@ -1,10 +1,22 @@ -import { Service, defineAction, defineState, defineTrigger, onProfilesChanged } from "castmate-core" +import { + Service, + defineAction, + defineState, + defineTrigger, + measurePerf, + measurePerfFunc, + onProfilesChanged, + startPerfTime, + usePluginLogger, +} from "castmate-core" import { TwitchAccount } from "./twitch-auth" import { CommercialLength } from "@twurple/api" import { onChannelAuth } from "./api-harness" import { Duration, Timer, getTimeRemaining, isTimerStarted } from "castmate-schema" export function setupAds() { + const logger = usePluginLogger() + defineAction({ id: "runAd", name: "Run Ad", @@ -77,7 +89,7 @@ export function setupAds() { required: true, }) - async function queryAdSchedule() { + const queryAdSchedule = measurePerfFunc(async function () { const schedule = await TwitchAccount.channel.apiClient.channels.getAdSchedule(TwitchAccount.channel.twitchId) nextAdDuration.value = schedule.duration @@ -94,7 +106,7 @@ export function setupAds() { //Adjust the schedule if necessary scheduleAdTriggers(scheduledAdTriggers) - } + }, "queryAdSchedule") interface ScheduledAdTrigger { advance: Duration diff --git a/plugins/twitch/main/src/viewer-cache.ts b/plugins/twitch/main/src/viewer-cache.ts index 44fddf79..d4acfa2d 100644 --- a/plugins/twitch/main/src/viewer-cache.ts +++ b/plugins/twitch/main/src/viewer-cache.ts @@ -4,12 +4,15 @@ import { ReactiveRef, Service, defineRendererCallable, + measurePerf, + measurePerfFunc, onLoad, onUnload, reactiveRef, registerSchemaExpose, registerSchemaTemplate, registerSchemaUnexpose, + startPerfTime, template, usePluginLogger, } from "castmate-core" @@ -110,7 +113,9 @@ export function setupViewerCache() { }) onChannelAuth(async () => { + const perf = startPerfTime("Viewer Cache Init") await ViewerCache.getInstance().resetCache() + perf.stop(logger) }) } @@ -202,22 +207,25 @@ export const ViewerCache = Service( this.chatterQueryTimer = setTimeout(() => this.updateChatterList(), 60000) } + //@measurePerf private async updateChatterList() { - const newChatters = new Map() - - //TODO: Check if the bot account is active and has moderator privledges, that would give us a guilt free 800 queries - - // Each page can be 1000, so theoretically this will break everything if you have close to 800,000 concurrent viewers - // So.. for now we won't worry about it, but if we get some sort of huge event using it... Put some work in here? - const query = TwitchAccount.channel.apiClient.chat.getChattersPaginated(TwitchAccount.channel.twitchId) - for await (const chatter of query) { - const cached = this.getOrCreate(chatter.userId) - this.updateNameCache(cached, chatter.userDisplayName) - cached.lastSeen = Date.now() - newChatters.set(chatter.userId, cached) - } + return await measurePerfFunc(async () => { + const newChatters = new Map() + + //TODO: Check if the bot account is active and has moderator privledges, that would give us a guilt free 800 queries + + // Each page can be 1000, so theoretically this will break everything if you have close to 800,000 concurrent viewers + // So.. for now we won't worry about it, but if we get some sort of huge event using it... Put some work in here? + const query = TwitchAccount.channel.apiClient.chat.getChattersPaginated(TwitchAccount.channel.twitchId) + for await (const chatter of query) { + const cached = this.getOrCreate(chatter.userId) + this.updateNameCache(cached, chatter.userDisplayName) + cached.lastSeen = Date.now() + newChatters.set(chatter.userId, cached) + } - this.chatters = newChatters + this.chatters = newChatters + }, "updateChatterList")() } private get(userId: string) { @@ -502,53 +510,58 @@ export const ViewerCache = Service( } async getResolvedViewers(userIds: string[]): Promise { - const neededSubIds: string[] = [] - const neededColorIds: string[] = [] - const neededUserInfoIds: string[] = [] - const neededFollowerIds: string[] = [] + const perf = startPerfTime("Resolve Viewer") + try { + const neededSubIds: string[] = [] + const neededColorIds: string[] = [] + const neededUserInfoIds: string[] = [] + const neededFollowerIds: string[] = [] - const cachedUsers = userIds.map((id) => this.getOrCreate(id)) + const cachedUsers = userIds.map((id) => this.getOrCreate(id)) - for (const cached of cachedUsers) { - if (cached.subbed == null || (cached.subbed === true && cached.sub == null)) { - neededSubIds.push(cached.id) - } + for (const cached of cachedUsers) { + if (cached.subbed == null || (cached.subbed === true && cached.sub == null)) { + neededSubIds.push(cached.id) + } - if (cached.color == null) { - neededColorIds.push(cached.id) - } + if (cached.color == null) { + neededColorIds.push(cached.id) + } - if (cached.profilePicture == null || cached.description == null) { - neededUserInfoIds.push(cached.id) - } + if (cached.profilePicture == null || cached.description == null) { + neededUserInfoIds.push(cached.id) + } - if (cached.following == null) { - neededFollowerIds.push(cached.id) + if (cached.following == null) { + neededFollowerIds.push(cached.id) + } } - } - const queryPromises: Promise[] = [] + const queryPromises: Promise[] = [] - if (neededColorIds.length > 0) { - queryPromises.push(this.queryColor(...neededColorIds)) - } + if (neededColorIds.length > 0) { + queryPromises.push(this.queryColor(...neededColorIds)) + } - if (neededFollowerIds.length > 0) { - queryPromises.push(this.queryFollowing(...neededFollowerIds)) - } + if (neededFollowerIds.length > 0) { + queryPromises.push(this.queryFollowing(...neededFollowerIds)) + } - if (neededSubIds.length > 0) { - queryPromises.push(this.querySubInfo(...neededSubIds)) - } + if (neededSubIds.length > 0) { + queryPromises.push(this.querySubInfo(...neededSubIds)) + } - if (neededUserInfoIds.length > 0) { - queryPromises.push(this.queryUserInfo(...neededUserInfoIds)) - } + if (neededUserInfoIds.length > 0) { + queryPromises.push(this.queryUserInfo(...neededUserInfoIds)) + } - await Promise.all(queryPromises) + await Promise.all(queryPromises) - //Safe to cast here since we've resolved everything - return cachedUsers as TwitchViewer[] + //Safe to cast here since we've resolved everything + return cachedUsers as TwitchViewer[] + } finally { + perf.stop(logger) + } } async getDisplayDataByName(name: string) { From 507a8aa9c95dc3a8ec330f3b4383c055996534dc Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 15 Jul 2024 19:13:08 -0400 Subject: [PATCH 5/8] Add some error handling to Channel Point Rewards to hopefully not brick everything on an error --- plugins/twitch/main/src/channelpoints.ts | 50 ++++++++++++++---------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/plugins/twitch/main/src/channelpoints.ts b/plugins/twitch/main/src/channelpoints.ts index 4c17e38a..c183f965 100644 --- a/plugins/twitch/main/src/channelpoints.ts +++ b/plugins/twitch/main/src/channelpoints.ts @@ -393,25 +393,29 @@ export class ChannelPointReward extends Resource r.id == reward.config.twitchId) - await reward.initializeFromTwurple(twitchReward) - await reward.initializeReactivity() + try { + await reward.initializeFromTwurple(twitchReward) + await reward.initializeReactivity() + } catch (err) { + logger.error("Error Initializing Reward", reward.config.name, err) + } } } From c6fa8b3d6b71f6a783929b1ce915224ce2370f6f Mon Sep 17 00:00:00 2001 From: LordTocs Date: Mon, 15 Jul 2024 19:14:06 -0400 Subject: [PATCH 6/8] Bump Version --- package.json | 2 +- packages/castmate/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9d987e65..261ef498 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "castmate-monorepo", - "version": "0.5.1", + "version": "0.5.2", "description": "", "private": true, "type": "module", diff --git a/packages/castmate/package.json b/packages/castmate/package.json index c107ef0e..7cea5fb9 100644 --- a/packages/castmate/package.json +++ b/packages/castmate/package.json @@ -1,6 +1,6 @@ { "name": "castmate", - "version": "0.5.1", + "version": "0.5.2", "description": "CastMate", "author": "LordTocs", "scripts": { From 42abc5163e177f7c8b937ec3d41118007ecd981d Mon Sep 17 00:00:00 2001 From: LordTocs Date: Fri, 19 Jul 2024 09:56:14 -0400 Subject: [PATCH 7/8] Mark beta instead --- package.json | 2 +- packages/castmate/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 261ef498..1e398469 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "castmate-monorepo", - "version": "0.5.2", + "version": "0.5.2-beta", "description": "", "private": true, "type": "module", diff --git a/packages/castmate/package.json b/packages/castmate/package.json index 7cea5fb9..fd433164 100644 --- a/packages/castmate/package.json +++ b/packages/castmate/package.json @@ -1,6 +1,6 @@ { "name": "castmate", - "version": "0.5.2", + "version": "0.5.2-beta", "description": "CastMate", "author": "LordTocs", "scripts": { From 1e9cb7fd083785da1b59fd20133913b07dd20e5f Mon Sep 17 00:00:00 2001 From: LordTocs Date: Fri, 19 Jul 2024 11:50:20 -0400 Subject: [PATCH 8/8] Fix up IRC sub events, still log eventsub sub events Should be a workaround for eventsub serverside glitches --- plugins/twitch/main/src/subscriptions.ts | 54 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/plugins/twitch/main/src/subscriptions.ts b/plugins/twitch/main/src/subscriptions.ts index 31d76beb..0725a8ba 100644 --- a/plugins/twitch/main/src/subscriptions.ts +++ b/plugins/twitch/main/src/subscriptions.ts @@ -64,7 +64,7 @@ export function setupSubscriptions() { type: Object, properties: { subs: { type: Range, name: "Subs Gifted", required: true, default: { min: 1 } }, - group: { type: TwitchViewerGroup, name: "Viewer Group", required: true, default: {} }, + group: { type: TwitchViewerGroup, name: "Viewer Group", required: true }, }, }, context: { @@ -124,9 +124,9 @@ export function setupSubscriptions() { updateSubscriberCount() }) - /*service.eventsub.onChannelSubscriptionMessage(channel.twitchId, async (event) => { + service.eventsub.onChannelSubscriptionMessage(channel.twitchId, async (event) => { logger.log( - "Sub Message Received: ", + "EventSub Sub Message Received: ", event.userDisplayName, event.userId, event.tier, @@ -135,7 +135,7 @@ export function setupSubscriptions() { event.streakMonths ) - let tier = 1 + /*let tier = 1 if (event.tier == "2000") { tier = 2 } else if (event.tier == "3000") { @@ -151,8 +151,8 @@ export function setupSubscriptions() { streakMonths: event.streakMonths ?? 1, durationMonths: event.durationMonths, message: event.messageText ?? "", - }) - })*/ + })*/ + }) service.eventsub.onChannelSubscriptionGift(channel.twitchId, async (event) => { ViewerCache.getInstance().cacheGiftSubEvent(event) @@ -183,6 +183,48 @@ export function setupSubscriptions() { tier = 3 } + logger.log( + "IRC Sub Message Received: ", + subInfo.displayName, + subInfo.userId, + subInfo.plan, + subInfo.months, + subInfo.streak + ) + + ViewerCache.getInstance() + .getResolvedViewer(subInfo.userId) + .then((viewer) => { + lastSubscriber.value = viewer + }) + + subscription({ + tier, + viewer: subInfo.userId, + totalMonths: subInfo.months, + streakMonths: subInfo.streak ?? 1, + //durationMonths: subInfo..durationMonths, + message: subInfo.message ?? "", + }) + }) + + service.chatClient.onResub(async (channel, user, subInfo, msg) => { + let tier = 1 + if (subInfo.plan == "2000") { + tier = 2 + } else if (subInfo.plan == "3000") { + tier = 3 + } + + logger.log( + "IRC ReSub Message Received: ", + subInfo.displayName, + subInfo.userId, + subInfo.plan, + subInfo.months, + subInfo.streak + ) + ViewerCache.getInstance() .getResolvedViewer(subInfo.userId) .then((viewer) => {