mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 00:51:37 +01:00
minor bugfixes for singleusermode, added seiso command and basic item implementation
items need to check the inventory of the user themselves also !iteminfo and !use commands should be super easy to make i do wonder if there's a nicer way to create the Item objects
This commit is contained in:
@@ -17,21 +17,26 @@ export class Command {
|
||||
|
||||
import { readdir } from 'node:fs/promises';
|
||||
const commands = new Map<string, Command>;
|
||||
const intents: string[] = [];
|
||||
const commandintents: string[] = [];
|
||||
|
||||
const files = await readdir(import.meta.dir);
|
||||
for (const file of files) {
|
||||
if (!file.endsWith('.ts')) continue;
|
||||
if (file === import.meta.file) continue;
|
||||
const command: Command = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
||||
intents.push(...command.requiredIntents);
|
||||
commandintents.push(...command.requiredIntents);
|
||||
for (const alias of command.aliases) {
|
||||
commands.set(alias, command); // Since it's not a primitive type the map is filled with references to the command, not the actual object
|
||||
};
|
||||
};
|
||||
|
||||
import items from "../items";
|
||||
for (const [name, item] of Array.from(items)) {
|
||||
commands.set(name, item); // As Item is basically just Command but with more parameters, this should work fine
|
||||
};
|
||||
|
||||
export default commands;
|
||||
export { intents };
|
||||
export { commandintents };
|
||||
|
||||
import { singleUserMode, chatterApi, chatterId, streamerId } from "..";
|
||||
|
||||
|
||||
15
bot/commands/seiso.ts
Normal file
15
bot/commands/seiso.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command, sendMessage } from ".";
|
||||
import { timeout } from "../lib/timeout";
|
||||
|
||||
export default new Command('seiso', ['seiso'], ['moderator:manage:banned_users'], async (msg, user) => {
|
||||
const rand = Math.floor(Math.random() * 101);
|
||||
if (rand > 75) await sendMessage(`${rand}% seiso YAAAA`, msg.messageId);
|
||||
else if (rand > 51) await sendMessage(`${rand}% seiso POGGERS`, msg.messageId);
|
||||
else if (rand === 50) await sendMessage(`${rand}% seiso ok`, msg.messageId);
|
||||
else if (rand > 30) await sendMessage(`${rand}% seiso SWEAT`, msg.messageId);
|
||||
else if (rand > 10) await sendMessage(`${rand}% seiso catErm`, msg.messageId);
|
||||
else {
|
||||
await sendMessage(`${rand}% seiso RIPBOZO`);
|
||||
timeout(user, 'TOO YABAI!', 60);
|
||||
};
|
||||
});
|
||||
@@ -1,7 +1,8 @@
|
||||
import { createAuthProvider } from "./auth";
|
||||
import { ApiClient } from "@twurple/api";
|
||||
import { EventSubHttpListener, ReverseProxyAdapter } from "@twurple/eventsub-http";
|
||||
import { intents } from "./commands";
|
||||
import { commandintents } from "./commands";
|
||||
import { itemintents } from "./items";
|
||||
|
||||
const CHATTERBASEINTENTS = ["user:read:chat", "user:write:chat", "user:bot"];
|
||||
const STREAMERBASEINTENTS = ["user:read:chat", "moderation:read", "channel:manage:moderators"];
|
||||
@@ -17,8 +18,8 @@ if (hostName === "") { console.error('Please set a EVENTSUB_HOSTNAME in the .env
|
||||
const port = Number(process.env.EVENTSUB_PORT) ?? 0;
|
||||
if (port === 0) { console.error('Please set a EVENTSUB_PORT in the .env'); process.exit(1); };
|
||||
|
||||
const chatterIntents = singleUserMode ? CHATTERBASEINTENTS.concat(STREAMERBASEINTENTS) : CHATTERBASEINTENTS;
|
||||
const streamerIntents = STREAMERBASEINTENTS.concat(intents);
|
||||
const streamerIntents = STREAMERBASEINTENTS.concat(commandintents, itemintents);
|
||||
const chatterIntents = singleUserMode ? CHATTERBASEINTENTS.concat(streamerIntents) : CHATTERBASEINTENTS;
|
||||
|
||||
export const chatterAuthProvider = await createAuthProvider(chatterId, chatterIntents);
|
||||
export const streamerAuthProvider = singleUserMode ? undefined : await createAuthProvider(streamerId, streamerIntents, true);
|
||||
@@ -38,6 +39,6 @@ export const eventSub = new EventSubHttpListener({
|
||||
|
||||
export const commandPrefix = process.env.COMMAND_PREFIX ?? "!";
|
||||
|
||||
export const unbannableUsers = [chatterId, streamerId]
|
||||
export const unbannableUsers = [chatterId, streamerId];
|
||||
|
||||
await import("./events");
|
||||
|
||||
22
bot/items/grenade.ts
Normal file
22
bot/items/grenade.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { redis } from "bun";
|
||||
import { sendMessage } from "../commands";
|
||||
import { timeout } from "../lib/timeout";
|
||||
import { Item } from ".";
|
||||
import { User } from "../user";
|
||||
|
||||
export default new Item('grenade', 'Grenade', 's',
|
||||
'Give a random chatter a 60s timeout',
|
||||
['grenade'],
|
||||
['moderator:manage:banned_users'],
|
||||
async (msg, user) => {
|
||||
const targets = await redis.keys('vulnchatters:*');
|
||||
if (targets.length === 0) { await sendMessage('No vulnerable chatters to blow up', msg.messageId); return; };
|
||||
const selection = targets[Math.floor(Math.random() * targets.length)]!;
|
||||
const target = await User.initUserId(selection.split(':')[1]!);
|
||||
await Promise.all([
|
||||
timeout(target!, `You got hit by ${user.displayName}'s grenade!`, 60),
|
||||
redis.del(selection),
|
||||
sendMessage(`wybuh ${target?.displayName} got hit by ${user.displayName}'s grenade wybuh`)
|
||||
]);
|
||||
}
|
||||
);
|
||||
47
bot/items/index.ts
Normal file
47
bot/items/index.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { EventSubChannelChatMessageEvent } from "@twurple/eventsub-base";
|
||||
import { User } from "../user";
|
||||
|
||||
export class Item {
|
||||
public readonly name: string;
|
||||
public readonly prettyName: string;
|
||||
public readonly plural: string;
|
||||
public readonly description: string;
|
||||
public readonly aliases: string[];
|
||||
public readonly requiredIntents: string[];
|
||||
public readonly execute: (message: EventSubChannelChatMessageEvent, sender: User) => Promise<void>;
|
||||
/** Creates an item object
|
||||
* @param name - internal name of item
|
||||
* @param prettyName - name of item for presenting to chat
|
||||
* @param plural - plural appendage; example: lootbox(es)
|
||||
* @param description - description of what item does
|
||||
* @param aliases - alternative ways to activate item
|
||||
* @param requiredIntents - required twitch API scopes to use item
|
||||
* @param execution - code that gets executed when item gets used */
|
||||
constructor(name: string, prettyName: string, plural: string, description: string, aliases: string[], requiredIntents: string[], execution: (message: EventSubChannelChatMessageEvent, sender: User) => Promise<void>) {
|
||||
this.name = name;
|
||||
this.prettyName = prettyName;
|
||||
this.plural = plural;
|
||||
this.description = description;
|
||||
this.aliases = aliases;
|
||||
this.requiredIntents = requiredIntents;
|
||||
this.execute = execution;
|
||||
};
|
||||
};
|
||||
|
||||
import { readdir } from 'node:fs/promises';
|
||||
const items = new Map<string, Item>;
|
||||
const itemintents: string[] = [];
|
||||
|
||||
const files = await readdir(import.meta.dir);
|
||||
for (const file of files) {
|
||||
if (!file.endsWith('.ts')) continue;
|
||||
if (file === import.meta.file) continue;
|
||||
const item: Item = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
||||
itemintents.push(...item.requiredIntents);
|
||||
for (const alias of item.aliases) {
|
||||
items.set(alias, item); // Since it's not a primitive type the map is filled with references to the item, not the actual object
|
||||
};
|
||||
};
|
||||
|
||||
export default items;
|
||||
export { itemintents };
|
||||
Reference in New Issue
Block a user