mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-18 22:41:38 +01:00
add basic redeem handling, nerf silver bullets to 30 minutes
This commit is contained in:
@@ -161,7 +161,7 @@ COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
|
|||||||
NAME|COMMAND|FUNCTION|ALIASES|COST
|
NAME|COMMAND|FUNCTION|ALIASES|COST
|
||||||
-|-|-|-|-
|
-|-|-|-|-
|
||||||
Blaster|`blaster {target}`|Times targeted user out for 60 seconds|`blaster` `blast`|100
|
Blaster|`blaster {target}`|Times targeted user out for 60 seconds|`blaster` `blast`|100
|
||||||
Silver Bullet|`silverbullet {target}`|Times targeted user out for 24 hours|`silverbullet` `execute` `{blastin}`|6666
|
Silver Bullet|`silverbullet {target}`|Times targeted user out for 30 minutes|`silverbullet` `execute` `{blastin}`|666
|
||||||
Grenade|`grenade`|Times a random vulnerable chatter out for 60 seconds|`grenade`|99
|
Grenade|`grenade`|Times a random vulnerable chatter out for 60 seconds|`grenade`|99
|
||||||
TNT|`tnt`|Give 5-10 random chatters 60 second timeouts|`tnt`|1000
|
TNT|`tnt`|Give 5-10 random chatters 60 second timeouts|`tnt`|1000
|
||||||
|
|
||||||
@@ -171,5 +171,5 @@ NAME|AMOUNT|USAGE|FUNCTION
|
|||||||
-|-|-|-
|
-|-|-|-
|
||||||
`grenade`|99|`cheer99`|Times a random vulnerable chatter out for 60 seconds. Of failure gives cheerer a grenade
|
`grenade`|99|`cheer99`|Times a random vulnerable chatter out for 60 seconds. Of failure gives cheerer a grenade
|
||||||
`timeout`|100|`cheer100 {target}`|Times specified user out for 1 minute. On failure gives cheerer a blaster
|
`timeout`|100|`cheer100 {target}`|Times specified user out for 1 minute. On failure gives cheerer a blaster
|
||||||
|
`execute`|666|`cheer666 {target}`|Times specified 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
|
`tnt`|1000|`cheer1000`|Gives 5-10 random vulnerable chatters 60 second timeouts. On failure gives cheerer a TNT
|
||||||
`execute`|6666|`cheer6666 {target}`|Times specified user out for 24 hours. On failure gives cheerer a silver bullet
|
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import { playAlert } from "web/alerts/serverFunctions";
|
|||||||
|
|
||||||
const ITEMNAME = 'silverbullet';
|
const ITEMNAME = 'silverbullet';
|
||||||
|
|
||||||
export default new Cheer('execute', 6666, async (msg, user) => {
|
export default new Cheer('execute', 666, async (msg, user) => {
|
||||||
const args = parseCheerArgs(msg.messageText);
|
const args = parseCheerArgs(msg.messageText);
|
||||||
if (!args[0]) { await handleNoTarget(msg, user, ITEMNAME, false); return; };
|
if (!args[0]) { await handleNoTarget(msg, user, ITEMNAME, false); return; };
|
||||||
const target = await User.initUsername(args[0].toLowerCase());
|
const target = await User.initUsername(args[0].toLowerCase());
|
||||||
if (!target) { await handleNoTarget(msg, user, ITEMNAME, false); return; };
|
if (!target) { await handleNoTarget(msg, user, ITEMNAME, false); return; };
|
||||||
await getUserRecord(target);
|
await getUserRecord(target);
|
||||||
|
|
||||||
const result = await timeout(target, `You got executed by ${user.displayName}!`, 60 * 60 * 24);
|
const result = await timeout(target, `You got executed by ${user.displayName}!`, 60 * 30);
|
||||||
if (result.status) await Promise.all([
|
if (result.status) await Promise.all([
|
||||||
sendMessage(`${target.displayName} RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO`),
|
sendMessage(`${target.displayName} RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO`),
|
||||||
createTimeoutRecord(user, target, ITEMNAME),
|
createTimeoutRecord(user, target, ITEMNAME),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export async function connectionCheck() {
|
|||||||
pgstatus = true;
|
pgstatus = true;
|
||||||
} catch { };
|
} catch { };
|
||||||
const tempclient = new RedisClient(undefined, {
|
const tempclient = new RedisClient(undefined, {
|
||||||
connectionTimeout: 100,
|
connectionTimeout: 200,
|
||||||
maxRetries: 1,
|
maxRetries: 1,
|
||||||
});
|
});
|
||||||
let redisstatus = false;
|
let redisstatus = false;
|
||||||
|
|||||||
18
src/events/channelPoints.ts
Normal file
18
src/events/channelPoints.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { sendMessage } from "commands";
|
||||||
|
import logger from "lib/logger";
|
||||||
|
import { eventSub, streamerId } from "main";
|
||||||
|
import { activeRedeems } from "pointRedeems";
|
||||||
|
import User from "user";
|
||||||
|
|
||||||
|
eventSub.onChannelRedemptionAdd(streamerId, async msg => {
|
||||||
|
const selection = activeRedeems.get(msg.rewardId);
|
||||||
|
if (!selection) { logger.warn(`Can't find the ${msg.rewardTitle} redeem`); return; };
|
||||||
|
const user = await User.initUsername(msg.userName);
|
||||||
|
try {
|
||||||
|
await selection.execute(msg, user!);
|
||||||
|
await msg.updateStatus('FULFILLED');
|
||||||
|
} catch (err) {
|
||||||
|
await sendMessage(`[ERROR]: Something went wrong with ${user?.displayName}'s redeem!`);
|
||||||
|
logger.err(err as string);
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -12,7 +12,7 @@ import { connectionCheck } from "connectionCheck";
|
|||||||
await connectionCheck();
|
await connectionCheck();
|
||||||
|
|
||||||
const CHATTERINTENTS = ["user:read:chat", "user:write:chat", "user:bot", "user:manage:whispers"];
|
const CHATTERINTENTS = ["user:read:chat", "user:write:chat", "user:bot", "user:manage:whispers"];
|
||||||
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", "channel:read:subscriptions"];
|
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", "channel:read:subscriptions", "channel:manage:redemptions"];
|
||||||
|
|
||||||
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 ?? "";
|
||||||
@@ -72,4 +72,6 @@ if (streamdata) await redis.set('streamIsLive', '1');
|
|||||||
|
|
||||||
await import("./events");
|
await import("./events");
|
||||||
|
|
||||||
|
await import("./pointRedeems");
|
||||||
|
|
||||||
await import("./web");
|
await import("./web");
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ export default new Item({
|
|||||||
name: ITEMNAME,
|
name: ITEMNAME,
|
||||||
prettyName: 'Silver bullet',
|
prettyName: 'Silver bullet',
|
||||||
plural: 's',
|
plural: 's',
|
||||||
description: 'Times a specific person out for 24 hours',
|
description: 'Times a specific person out for 30 minutes',
|
||||||
aliases: ['execute', 'silverbullet'],
|
aliases: ['execute', 'silverbullet'],
|
||||||
specialaliases: ['blastin'],
|
specialaliases: ['blastin'],
|
||||||
price: 6666,
|
price: 666,
|
||||||
execution: async (msg, user, specialargs) => {
|
execution: async (msg, user, specialargs) => {
|
||||||
const messagequery = parseCommandArgs(msg.messageText, specialargs?.activation);
|
const messagequery = parseCommandArgs(msg.messageText, specialargs?.activation);
|
||||||
if (!messagequery[0]) { await sendMessage('Please specify a target'); return; };
|
if (!messagequery[0]) { await sendMessage('Please specify a target'); return; };
|
||||||
@@ -31,7 +31,7 @@ export default new Item({
|
|||||||
const userObj = await getUserRecord(user);
|
const userObj = await getUserRecord(user);
|
||||||
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any silver bullets!`, msg.messageId); await user.clearLock(); return; };
|
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any silver bullets!`, msg.messageId); await user.clearLock(); return; };
|
||||||
|
|
||||||
const result = await timeout(target, `You got blasted by ${user.displayName}!`, 60 * 60 * 24);
|
const result = await timeout(target, `You got blasted by ${user.displayName}!`, 60 * 30);
|
||||||
if (result.status) await Promise.all([
|
if (result.status) await Promise.all([
|
||||||
sendMessage(`${target.displayName} RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO`),
|
sendMessage(`${target.displayName} RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO RIPBOZO`),
|
||||||
changeItemCount(user, userObj, ITEMNAME),
|
changeItemCount(user, userObj, ITEMNAME),
|
||||||
|
|||||||
77
src/pointRedeems/index.ts
Normal file
77
src/pointRedeems/index.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { EventSubChannelRedemptionAddEvent } from "@twurple/eventsub-base";
|
||||||
|
import User from "user";
|
||||||
|
|
||||||
|
export type pointRedeemOptions = {
|
||||||
|
name: string;
|
||||||
|
title: string;
|
||||||
|
prompt?: string;
|
||||||
|
cost: number;
|
||||||
|
color?: string;
|
||||||
|
execution: (message: EventSubChannelRedemptionAddEvent, sender: User) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The Command class represents a command */
|
||||||
|
export default class PointRedeem {
|
||||||
|
public readonly name: string;
|
||||||
|
public readonly title: string;
|
||||||
|
public readonly prompt?: string;
|
||||||
|
public readonly cost: number;
|
||||||
|
public readonly color?: string;
|
||||||
|
public readonly execute: (message: EventSubChannelRedemptionAddEvent, sender: User) => Promise<void>;
|
||||||
|
constructor(options: pointRedeemOptions) {
|
||||||
|
this.name = options.name
|
||||||
|
this.title = options.title;
|
||||||
|
this.prompt = options.prompt;
|
||||||
|
this.cost = options.cost;
|
||||||
|
this.color = options.color;
|
||||||
|
this.execute = options.execution;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
import { readdir } from 'node:fs/promises';
|
||||||
|
|
||||||
|
const pointRedeems = new Map<number, PointRedeem>;
|
||||||
|
|
||||||
|
/** A map of all (including inactive) redeems mapped to names */
|
||||||
|
const namedRedeems = new Map<string, PointRedeem>;
|
||||||
|
|
||||||
|
const files = await readdir(import.meta.dir);
|
||||||
|
for (const file of files) {
|
||||||
|
if (!file.endsWith('.ts')) continue;
|
||||||
|
if (file === import.meta.file) continue;
|
||||||
|
const redeem: PointRedeem = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
||||||
|
pointRedeems.set(redeem.cost, redeem);
|
||||||
|
namedRedeems.set(redeem.name, redeem);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { namedRedeems };
|
||||||
|
|
||||||
|
const activeRedeems = new Map<string, PointRedeem>;
|
||||||
|
|
||||||
|
import { streamerApi, streamerId } from "main";
|
||||||
|
import logger from "lib/logger";
|
||||||
|
|
||||||
|
const currentRedeems = new Map<string, string>;
|
||||||
|
await streamerApi.channelPoints.getCustomRewards(streamerId).then(a => a.map(b => currentRedeems.set(b.title, b.id)));
|
||||||
|
for (const [_, redeem] of Array.from(pointRedeems)) {
|
||||||
|
const selection = currentRedeems.get(redeem.title);
|
||||||
|
if (selection) {
|
||||||
|
currentRedeems.delete(redeem.title);
|
||||||
|
activeRedeems.set(selection, redeem);
|
||||||
|
} else {
|
||||||
|
const creation = await streamerApi.channelPoints.createCustomReward(streamerId, {
|
||||||
|
title: redeem.title,
|
||||||
|
prompt: redeem.prompt,
|
||||||
|
cost: redeem.cost,
|
||||||
|
backgroundColor: redeem.color
|
||||||
|
});
|
||||||
|
logger.ok(`Created custom point redeem ${redeem.title}`);
|
||||||
|
activeRedeems.set(creation.id, redeem);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.from(currentRedeems).map(async ([title, redeem]) => { await streamerApi.channelPoints.deleteCustomReward(streamerId, redeem); logger.ok(`Deleted custom point redeem ${title}`); });
|
||||||
|
|
||||||
|
logger.ok("Successfully synced all custom point redeems");
|
||||||
|
|
||||||
|
export { activeRedeems };
|
||||||
16
src/pointRedeems/qbucksredeem.ts
Normal file
16
src/pointRedeems/qbucksredeem.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { sendMessage } from "commands";
|
||||||
|
import { getUserRecord } from "db/dbUser";
|
||||||
|
import { changeBalance } from "lib/changeBalance";
|
||||||
|
import PointRedeem from "pointRedeems";
|
||||||
|
|
||||||
|
export default new PointRedeem({
|
||||||
|
name: "qbucksredeem",
|
||||||
|
title: "FREE MONEY",
|
||||||
|
prompt: "GET 100 QBUCKS!",
|
||||||
|
color: '#00FF00',
|
||||||
|
cost: 1000,
|
||||||
|
execution: async (_msg, user) => {
|
||||||
|
await changeBalance(user, await getUserRecord(user), 100);
|
||||||
|
await sendMessage(`${user.displayName} got 100 qbucks for their point redeem`);
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -3,18 +3,41 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./src",
|
"baseUrl": "./src",
|
||||||
"paths": {
|
"paths": {
|
||||||
"lib/*": ["./lib/*"],
|
"lib/*": [
|
||||||
"main": ["./index.ts"],
|
"./lib/*"
|
||||||
"user": ["./user.ts"],
|
],
|
||||||
"commands": ["./commands/index.ts"],
|
"main": [
|
||||||
"items": ["./items/index.ts"],
|
"./index.ts"
|
||||||
"cheers": ["./cheers/index.ts"],
|
],
|
||||||
"events": ["./events/index.ts"],
|
"user": [
|
||||||
"web/*": ["./web/*"]
|
"./user.ts"
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
"./commands/index.ts"
|
||||||
|
],
|
||||||
|
"items": [
|
||||||
|
"./items/index.ts"
|
||||||
|
],
|
||||||
|
"cheers": [
|
||||||
|
"./cheers/index.ts"
|
||||||
|
],
|
||||||
|
"events": [
|
||||||
|
"./events/index.ts"
|
||||||
|
],
|
||||||
|
"web/*": [
|
||||||
|
"./web/*"
|
||||||
|
],
|
||||||
|
"pointRedeems": [
|
||||||
|
"./pointRedeems/index.ts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "./tsconfig.bot.json" },
|
{
|
||||||
{ "path": "./tsconfig.web.json" }
|
"path": "./tsconfig.bot.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.web.json"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user