From e3fc3465e9e3588a0818bde7120e03b03cfbdec0 Mon Sep 17 00:00:00 2001 From: qwerinope Date: Fri, 11 Apr 2025 12:48:20 +0200 Subject: [PATCH] part 1 of full item/inventory rework --- src/commands/itemAliases.ts | 59 ++++++------- src/commands/iteminfo.ts | 30 +------ src/commands/use.ts | 24 ++---- src/items/blasters.ts | 76 +++++++++++++++++ src/items/clipboard.ts | 28 +++++++ src/items/explosives.ts | 76 +++++++++++++++++ src/items/index.ts | 18 ++++ src/items/lootbox.ts | 32 +++++++ src/lib/items.ts | 163 +----------------------------------- src/lib/lootboxes.ts | 1 - src/lib/timeoutHelper.ts | 3 +- src/lib/userHelper.ts | 30 ++----- 12 files changed, 281 insertions(+), 259 deletions(-) create mode 100644 src/items/blasters.ts create mode 100644 src/items/clipboard.ts create mode 100644 src/items/explosives.ts create mode 100644 src/items/index.ts create mode 100644 src/items/lootbox.ts diff --git a/src/commands/itemAliases.ts b/src/commands/itemAliases.ts index 4bac4b0..b0d8841 100644 --- a/src/commands/itemAliases.ts +++ b/src/commands/itemAliases.ts @@ -1,39 +1,30 @@ -import { createBotCommand } from "@twurple/easy-bot"; +import { BotCommand, createBotCommand } from "@twurple/easy-bot"; -import { useBlaster, useClipboard, useGrenade, useLootbox, useSilverBullet, useTNT } from "../lib/items"; import api from "../lib/api"; +import items from "../items"; -const blaster = createBotCommand('blaster', async (params, { say, broadcasterId, userId }) => { - const user = await api.users.getUserById(userId) - if (params[0] === undefined) return - await useBlaster(broadcasterId, user!, params[0].replace(/[@]/g, ''), say) -}, { aliases: ['blast'] }) +const aliascommands: BotCommand[] = [] -const silverbullet = createBotCommand('execute', async (params, { say, broadcasterId, userId }) => { - const user = await api.users.getUserById(userId) - if (params[0] === undefined) return - await useSilverBullet(broadcasterId, user!, params[0].replace(/[@]/g, ''), say) -}, { aliases: ['silverbullet'] }) +for (const item of items) { + aliascommands.push(createBotCommand(item.name, async (params, { say, broadcasterId, userId }) => { + const user = await api.users.getUserById(userId) + switch (item.name) { + case 'blaster': + case 'silverbullet': + if (params[0] === undefined) return + await item.execute(user!, say, broadcasterId, params[0].replace(/[@]/g, '')) + break + case 'grenade': + case 'tnt': + case 'lootbox': + await item.execute(user!, say) + break + case 'clipboard': + if (params[0] === undefined) return + await item.execute(user!, say, broadcasterId, params.join(' ')) + break + } + }, { aliases: item.aliases })) +} -const grenade = createBotCommand('grenade', async (_params, { say, broadcasterId, userId }) => { - const user = await api.users.getUserById(userId) - await useGrenade(broadcasterId, user!, say) -}) - -const tnt = createBotCommand('tnt', async (_params, { say, broadcasterId, userId }) => { - const user = await api.users.getUserById(userId) - await useTNT(broadcasterId, user!, say) -}) - -const lootbox = createBotCommand('lootbox', async (_params, { say, userId }) => { - const user = await api.users.getUserById(userId) - await useLootbox(user!, say) -}) - -const clipboard = createBotCommand('clipboard', async (params, { say, broadcasterId, userId }) => { - const user = await api.users.getUserById(userId) - if (params[0] === undefined) return - await useClipboard(broadcasterId, user!, params.join(' '), say) -}) - -export default [blaster, silverbullet, grenade, tnt, lootbox, clipboard] +export default aliascommands diff --git a/src/commands/iteminfo.ts b/src/commands/iteminfo.ts index 097df6e..14a0243 100644 --- a/src/commands/iteminfo.ts +++ b/src/commands/iteminfo.ts @@ -1,31 +1,9 @@ import { createBotCommand } from "@twurple/easy-bot"; +import items from "../items" export default createBotCommand('iteminfo', async (params, { say }) => { if (params[0] === undefined) { await say('No item specified!'); return } - let message = '' - switch (params[0].toLowerCase()) { - case 'blaster': - message = "Use: blaster {target}, Function: Times the target user out for 60 seconds. Aliases: !blast, !blaster" - break - case 'silver': - case 'silverbullet': - message = "Use: silverbullet {target}, Function: Times the target user out for 24 hours. Aliases: !execute, !silverbullet" - break - case 'grenade': - message = "Use: grenade, Function: Times a random chatter out for 60 seconds. Aliases: !grenade" - break - case 'tnt': - message = "Use: tnt, Function: Times out 1 to 10 chatters for 60 seconds. Aliases: !tnt" - break - case 'lootbox': - message = "Use: lootbox, Function: Gives the user some qbucks, and possibly some items. Aliases: !lootbox" - break - case 'clipboard': - message = "Use: clipboard {message}, Function: Starts a two minute long poll with the user specified message. Aliases: !clipboard" - break - default: - message = "Item not found" - break - } - await say(message) + const selection = items.find(item => item.aliases.includes(params[0].toLowerCase())) + if (!selection) { await say('Item not found'); return } + await say(selection[1].description) }, { aliases: ['item'] }) diff --git a/src/commands/use.ts b/src/commands/use.ts index a104b35..17c23f3 100644 --- a/src/commands/use.ts +++ b/src/commands/use.ts @@ -1,37 +1,31 @@ import { createBotCommand } from "@twurple/easy-bot"; -import { useBlaster, useClipboard, useGrenade, useLootbox, useSilverBullet, useTNT } from "../lib/items"; import api from "../lib/api"; +import items from "../items"; export default createBotCommand('use', async (params, { say, broadcasterId, userId }) => { const user = await api.users.getUserById(userId) if (params[0] === undefined) return + const selection = items.find(item => item.aliases.includes(params[0].toLowerCase())) - switch (params[0].toLowerCase()) { + if (!selection) { say(`${params[0]} does not exist!`); return } + + switch (selection.name) { case 'blaster': - if (params[1] === undefined) return - await useBlaster(broadcasterId, user!, params[1].replace(/[@]/g, ''), say) - break - case 'silver': case 'silverbullet': if (params[1] === undefined) return - await useSilverBullet(broadcasterId, user!, params[1].replace(/[@]/g, ''), say) + await selection.execute(user!, say, broadcasterId, params[1].replace(/[@]/g, '')) break case 'grenade': - await useGrenade(broadcasterId, user!, say) - break case 'tnt': - await useTNT(broadcasterId, user!, say) + await selection.execute(user!, say, broadcasterId) break case 'lootbox': - case 'loot': - await useLootbox(user!, say) + await selection.execute(user!, say) break case 'clipboard': if (params[1] === undefined) return - await useClipboard(broadcasterId, user!, params.slice(1).join(' '), say) + await selection.execute(user!, say, broadcasterId, params.slice(1).join(' ')) break - default: - await say(`${params[0]} does not exist!`) } }) diff --git a/src/items/blasters.ts b/src/items/blasters.ts new file mode 100644 index 0000000..f8a4ee1 --- /dev/null +++ b/src/items/blasters.ts @@ -0,0 +1,76 @@ +import { HelixUser } from "@twurple/api"; +import api from "../lib/api"; +import { timeout, addTimeoutToDB } from "../lib/timeoutHelper"; +import { addUsedItem, updateInventory } from "../lib/userHelper"; +import { changeItemCount } from "../lib/items"; + +export const blaster = { + name: 'blaster', + prettyname: 'Blaster', + aliases: ['blast', 'blaster'], + plural: 's', + description: "Use: blaster {target}, Function: Times the target user out for 60 seconds. Aliases: !blast, !blaster", + execute: async (user: HelixUser, say: (arg0: string) => Promise, broadcasterId: string, targetname: string) => { + const target = await api.users.getUserByName(targetname) + + const itemResult = await changeItemCount(user, 'blaster') + + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no blasters!'); return } + + const result = await timeout(broadcasterId, target!, 60, `You got blasted by ${user.name}`) + if (result.status) { + await say(`${targetname} got blasted by ${user.name}! ${user.name} has ${itemResult.count} blaster${itemResult.count === 1 ? '' : 's'} remaining`) + await addTimeoutToDB(user, target!, 'blaster') + await addUsedItem(user, 'blaster') + await updateInventory(user, itemResult.inv!) + } else { + switch (result.reason) { + case 'noexist': + await say(`${targetname} doesn't exist!`) + break + case 'banned': + await say(`${targetname} is already dead!`) + break + case 'unknown': + await say(`NO!`) + await timeout(broadcasterId, user, 60, "NO!") + break + } + } + } +} + +export const silverbullet = { + name: 'silverbullet', + prettyname: 'Silver Bullet', + plural: 's', + aliases: ['execute', 'silver', 'silverbullet'], + description: "Use: silverbullet {target}, Function: Times the target user out for 24 hours. Aliases: !execute, !silverbullet", + execute: async (user: HelixUser, say: (arg0: string) => Promise, broadcasterId: string, targetname: string) => { + const target = await api.users.getUserByName(targetname) + + const itemResult = await changeItemCount(user, 'silverbullet') + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no silver bullets!'); return } + + const result = await timeout(broadcasterId, target!, 60 * 60 * 24, `You got hit by a silver bullet fired by ${user.name}`) + if (result.status) { + await say(`${target?.name} got deleted.`) + await addTimeoutToDB(user, target!, 'silverbullet') + await addUsedItem(user, 'silverbullet') + await updateInventory(user, itemResult.inv!) + } else { + switch (result.reason) { + case 'noexist': + await say(`${targetname} doesn't exist!`) + break + case 'banned': + await say(`${targetname} is already dead!`) + break + case 'unknown': + await say(`NO!`) + await timeout(broadcasterId, user, 60, "NO!") + break + } + } + } +} diff --git a/src/items/clipboard.ts b/src/items/clipboard.ts new file mode 100644 index 0000000..5b68420 --- /dev/null +++ b/src/items/clipboard.ts @@ -0,0 +1,28 @@ +import { HelixUser } from "@twurple/api"; +import api, { broadcasterApi } from "../lib/api" +import { changeItemCount } from "../lib/items"; +import { addUsedItem, updateInventory } from "../lib/userHelper"; + +export const clipboard = { + name: 'clipboard', + prettyname: 'Clipboard', + aliases: ['clipboard'], + plural: 's', + description: "Use: clipboard {message}, Function: Starts a two minute long poll with the user specified message. Aliases: !clipboard", + execute: async (user: HelixUser, say: (arg0: string) => Promise, broadcasterId: string, question: string) => { + const tempapi = broadcasterApi ?? api + + const polldata = await tempapi.polls.getPolls(broadcasterId) + const activepolldata = polldata.data.filter(poll => poll.status === "ACTIVE") + if (activepolldata.length > 0) { await say('Can\'t have two polls active at once.'); return } + + const itemResult = await changeItemCount(user, 'clipboard') + await addUsedItem(user, 'clipboard') + await updateInventory(user, itemResult.inv!) + + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no clipboards!'); return } + + await tempapi.polls.createPoll(broadcasterId, { choices: ['Yes', 'No'], duration: 120, title: question }) + await say(`${user.name} used a clipboard! They have ${itemResult.count} clipboard${itemResult.count === 1 ? '' : 's'} remaining`) + } +} diff --git a/src/items/explosives.ts b/src/items/explosives.ts new file mode 100644 index 0000000..fca9b8e --- /dev/null +++ b/src/items/explosives.ts @@ -0,0 +1,76 @@ +import api from "../lib/api"; +import { addTimeoutToDB } from "../lib/timeoutHelper"; +import { addUsedItem, updateInventory } from "../lib/userHelper"; +import { changeItemCount } from "../lib/items"; +import { vulnerableUsers, timeout } from "../lib/timeoutHelper"; +import { HelixUser } from "@twurple/api"; + +function shuffle(arrayold: any[]) { + let array = arrayold + let currentIndex = array.length; + while (currentIndex != 0) { + let randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; + } + return array +} + +export const grenade = { + name: 'grenade', + prettyname: 'Grenade', + aliases: ['grenade'], + plural: 's', + description: "Use: grenade, Function: Times a random chatter out for 60 seconds. Aliases: !grenade", + execute: async (user: HelixUser, say: (arg0: string) => Promise, broadcasterId: string) => { + if (vulnerableUsers.length === 0) { await say('No chatters to blow up!'); return } + const itemResult = await changeItemCount(user, 'grenade') + + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no grenades!'); return } + const target = await api.users.getUserById(vulnerableUsers[Math.floor(Math.random() * vulnerableUsers.length)]) + const result = await timeout(broadcasterId, target!, 60, `You got hit by ${user.name}'s grenade`) + if (result.status) { + await say(`${target?.name} got blown up by ${user.name}'s grenade!`) + await addTimeoutToDB(user, target!, 'grenade') + await addUsedItem(user, 'grenade') + await updateInventory(user, itemResult.inv!) + } else { + // Banned is not an option, and neither is noexist + await say(`something went wrong`) + console.error(result.reason) + } + } +} + +export const tnt = { + name: 'tnt', + prettyname: 'TNT', + aliases: ['tnt'], + plural: 's', + description: "Use: tnt, Function: Times out 1 to 10 chatters for 60 seconds. Aliases: !tnt", + execute: async (user: HelixUser, say: (args0: string) => Promise, broadcasterId: string) => { + if (vulnerableUsers.length === 0) { await say('No chatters to blow up!'); return } + const itemResult = await changeItemCount(user, 'tnt') + + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no TNT!'); return } + const min = vulnerableUsers.length < 3 ? vulnerableUsers.length : 3 //if less than 3 chatters, use that else 3 + const max = vulnerableUsers.length > 10 ? 10 : vulnerableUsers.length //if more than 10 chatters do 10 else 10 + const blastedusers = Math.floor(Math.random() * (max - min + 1)) + min + const soontobedeadusers = shuffle(vulnerableUsers).slice(vulnerableUsers.length - blastedusers) + const targets = await api.users.getUsersByIds(soontobedeadusers) + for (const target of targets) { + const result = await timeout(broadcasterId, target!, 60, `You got hit by ${user.name}'s TNT`) + if (result.status) { + await say(`${target?.name} got blown up by TNT!`) + await addTimeoutToDB(user, target!, 'tnt') + await updateInventory(user, itemResult.inv!) + } else { + await say(`something went wrong`) + console.error(result.reason) + } + } + + await addUsedItem(user, 'tnt') + await say(`${user.name} blew up ${blastedusers} chatters with their TNT! ${user.name} has ${itemResult.count} tnt${itemResult.count === 1 ? '' : 's'} remaining`) + } +} diff --git a/src/items/index.ts b/src/items/index.ts new file mode 100644 index 0000000..169e601 --- /dev/null +++ b/src/items/index.ts @@ -0,0 +1,18 @@ +import { HelixUser } from "@twurple/api" + +import { blaster, silverbullet } from "./blasters" +import { grenade, tnt } from "./explosives" +import { lootbox } from "./lootbox" +import { clipboard } from "./clipboard" + +interface item { + name: string, + prettyname: string, + aliases: string[], + plural: string, + description: string, + execute: (user: HelixUser, say: (args0: string) => Promise, broadcasterId?: string, targetname?: string) => Promise +} +const data = [blaster, silverbullet, grenade, tnt, lootbox, clipboard] as item[] +export const ITEMS = data.map(item => item.name) +export default data diff --git a/src/items/lootbox.ts b/src/items/lootbox.ts new file mode 100644 index 0000000..fb6d820 --- /dev/null +++ b/src/items/lootbox.ts @@ -0,0 +1,32 @@ +import { HelixUser } from "@twurple/api"; +import { changeItemCount } from "../lib/items"; +import { addUsedItem, changeBalance, getInventory, updateInventory } from "../lib/userHelper"; + +function getRandom(): number { + return Math.floor(Math.random() * 100) +} + +export const lootbox = { + name: 'lootbox', + prettyname: 'Lootbox', + aliases: ['lootbox', 'loot'], + plural: 'es', + description: "Use: lootbox, Function: Gives the user some qbucks, and possibly some items. Aliases: !lootbox", + execute: async (user: HelixUser, say: (arg0: string) => Promise) => { + const itemResult = await changeItemCount(user, 'lootbox') + if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no lootboxes!'); return } + // Lootbox logic will for now just be get 25 qbucks, with 50% chance to get a grenade 25% chance to get a blaster and 10% chance to get TNT + let inventory = await getInventory(user) + let newitems: string[] = [] + await changeBalance(user, 25) + newitems.push('25 qbucks') + if (getRandom() <= 50) { newitems.push('1 grenade'); inventory.grenade += 1 } + if (getRandom() <= 25) { newitems.push('1 blaster'); inventory.blaster += 1 } + if (getRandom() <= 10) { newitems.push('1 tnt'); inventory.tnt += 1 } + inventory.lootbox = itemResult.inv!.lootbox + await updateInventory(user, inventory) + await addUsedItem(user, 'lootbox') + + await say(`${user.name} got: ${newitems.join(' and ')}`) + } +} diff --git a/src/lib/items.ts b/src/lib/items.ts index 933a5b6..00bdad9 100644 --- a/src/lib/items.ts +++ b/src/lib/items.ts @@ -1,9 +1,6 @@ import { HelixUser } from "@twurple/api" -import { addUsedItem, changeBalance, getInventory, inventory, updateInventory } from "../lib/userHelper" -import { timeout, addTimeoutToDB, vulnerableUsers } from "./timeoutHelper" -import api, { broadcasterApi } from "./api" - -export const ITEMS = ['blaster', 'silverbullet', 'grenade', 'tnt', 'clipboard', 'lootbox'] +import { getInventory, inventory, updateInventory } from "../lib/userHelper" +import { ITEMS } from "../items" interface itemChangeResult { result: boolean, @@ -12,7 +9,7 @@ interface itemChangeResult { inv?: inventory } -export async function changeItemCount(user: HelixUser, item: string, amount = -1, preconfirmed=false): Promise { +export async function changeItemCount(user: HelixUser, item: string, amount = -1, preconfirmed = false): Promise { if (!ITEMS.includes(item)) return { result: false, reason: 'noexist', count: 0 } let inv = await getInventory(user) @@ -22,160 +19,8 @@ export async function changeItemCount(user: HelixUser, item: string, amount = -1 Object.defineProperty(inv, item, { value: newcount, }) - + if (amount > 0 || preconfirmed === true) await updateInventory(user, inv) return { result: true, reason: '', count: inv[item], inv } } - -export async function useBlaster(broadcasterId: string, attacker: HelixUser, targetname: string, say: (arg0: string) => Promise) { - const target = await api.users.getUserByName(targetname) - - const itemResult = await changeItemCount(attacker, 'blaster') - - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no blasters!'); return } - - const result = await timeout(broadcasterId, target!, 60, `You got blasted by ${attacker.name}`) - if (result.status) { - await say(`${targetname} got blasted by ${attacker.name}! ${attacker.name} has ${itemResult.count} blaster${itemResult.count === 1 ? '' : 's'} remaining`) - await addTimeoutToDB(attacker, target!, 'blaster') - await addUsedItem(attacker, 'blaster') - await updateInventory(attacker, itemResult.inv!) - } else { - switch (result.reason) { - case 'noexist': - await say(`${targetname} doesn't exist!`) - break - case 'banned': - await say(`${targetname} is already dead!`) - break - case 'unknown': - await say(`NO!`) - await timeout(broadcasterId, attacker, 60, "NO!") - break - } - } -} - -export async function useSilverBullet(broadcasterId: string, attacker: HelixUser, targetname: string, say: (arg0: string) => Promise) { - const target = await api.users.getUserByName(targetname) - - const itemResult = await changeItemCount(attacker, 'silverbullet') - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no silver bullets!'); return } - - const result = await timeout(broadcasterId, target!, 60 * 60 * 24, `You got hit by a silver bullet fired by ${attacker.name}`) - if (result.status) { - await say(`${target?.name} got deleted.`) - await addTimeoutToDB(attacker, target!, 'silverbullet') - await addUsedItem(attacker, 'silverbullet') - await updateInventory(attacker, itemResult.inv!) - } else { - switch (result.reason) { - case 'noexist': - await say(`${targetname} doesn't exist!`) - break - case 'banned': - await say(`${targetname} is already dead!`) - break - case 'unknown': - await say(`NO!`) - await timeout(broadcasterId, attacker, 60, "NO!") - break - } - } -} - -export async function useGrenade(broadcasterId: string, attacker: HelixUser, say: (arg0: string) => Promise) { - if (vulnerableUsers.length === 0) { await say('No chatters to blow up!'); return } - const itemResult = await changeItemCount(attacker, 'grenade') - - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no grenades!'); return } - const target = await api.users.getUserById(vulnerableUsers[Math.floor(Math.random() * vulnerableUsers.length)]) - const result = await timeout(broadcasterId, target!, 60, `You got hit by ${attacker.name}'s grenade`) - if (result.status) { - await say(`${target?.name} got blown up by ${attacker.name}'s grenade!`) - await addTimeoutToDB(attacker, target!, 'grenade') - await addUsedItem(attacker, 'grenade') - await updateInventory(attacker, itemResult.inv!) - } else { - // Banned is not an option, and neither is noexist - await say(`something went wrong`) - console.error(result.reason) - } -} - -export async function useTNT(broadcasterId: string, attacker: HelixUser, say: (args0: string) => Promise) { - if (vulnerableUsers.length === 0) { await say('No chatters to blow up!'); return } - const itemResult = await changeItemCount(attacker, 'tnt') - - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no TNT!'); return } - const min = vulnerableUsers.length < 3 ? vulnerableUsers.length : 3 //if less than 3 chatters, use that else 3 - const max = vulnerableUsers.length > 10 ? 10 : vulnerableUsers.length //if more than 10 chatters do 10 else 10 - const blastedusers = Math.floor(Math.random() * (max - min + 1)) + min - const soontobedeadusers = shuffle(vulnerableUsers).slice(vulnerableUsers.length - blastedusers) - const targets = await api.users.getUsersByIds(soontobedeadusers) - for (const target of targets) { - const result = await timeout(broadcasterId, target!, 60, `You got hit by ${attacker.name}'s TNT`) - if (result.status) { - await say(`${target?.name} got blown up by TNT!`) - await addTimeoutToDB(attacker, target!, 'tnt') - await updateInventory(attacker, itemResult.inv!) - } else { - await say(`something went wrong`) - console.error(result.reason) - } - } - - await addUsedItem(attacker, 'tnt') - await say(`${attacker.name} blew up ${blastedusers} chatters with their TNT! ${attacker.name} has ${itemResult.count} tnt${itemResult.count === 1 ? '' : 's'} remaining`) -} - -function getRandom(): number { - return Math.floor(Math.random() * 100) -} - -export async function useLootbox(user: HelixUser, say: (arg0: string) => Promise) { - const itemResult = await changeItemCount(user, 'lootbox') - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no lootboxes!'); return } - // Lootbox logic will for now just be get 25 qbucks, with 50% chance to get a grenade 25% chance to get a blaster and 10% chance to get TNT - let inventory = await getInventory(user) - let newitems: string[] = [] - await changeBalance(user, 25) - newitems.push('25 qbucks') - if (getRandom() <= 50) { newitems.push('1 grenade'); inventory.grenade += 1 } - if (getRandom() <= 25) { newitems.push('1 blaster'); inventory.blaster += 1 } - if (getRandom() <= 10) { newitems.push('1 tnt'); inventory.tnt += 1 } - inventory.lootbox = itemResult.inv!.lootbox - await updateInventory(user, inventory) - await addUsedItem(user, 'lootbox') - - await say(`${user.name} got: ${newitems.join(' and ')}`) -} - -function shuffle(arrayold: any[]) { - let array = arrayold - let currentIndex = array.length; - while (currentIndex != 0) { - let randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; - } - return array -} - -export async function useClipboard(broadcasterId: string, user: HelixUser, question: string, say: (arg0: string) => Promise) { - const tempapi = broadcasterApi ?? api - - const polldata = await tempapi.polls.getPolls(broadcasterId) - const activepolldata = polldata.data.filter(poll => poll.status === "ACTIVE") - if (activepolldata.length > 0) { await say('Can\'t have two polls active at once.'); return } - - const itemResult = await changeItemCount(user, 'clipboard') - await addUsedItem(user, 'clipboard') - await updateInventory(user, itemResult.inv!) - - if (!itemResult.result && itemResult.reason === 'negative') { await say('You have no clipboards!'); return } - - await tempapi.polls.createPoll(broadcasterId, { choices: ['Yes', 'No'], duration: 120, title: question }) - await say(`${user.name} used a clipboard! They have ${itemResult.count} clipboard${itemResult.count === 1 ? '' : 's'} remaining`) -} diff --git a/src/lib/lootboxes.ts b/src/lib/lootboxes.ts index 1cd9a71..2750a07 100644 --- a/src/lib/lootboxes.ts +++ b/src/lib/lootboxes.ts @@ -1,7 +1,6 @@ import { HelixUser } from "@twurple/api" import pb, { User } from "./pocketbase" - export const COOLDOWN = (!process.env.COOLDOWN ? 60 * 60 * 24 : Number(process.env.COOLDOWN)) * 1000 interface lootboxReadyResult { diff --git a/src/lib/timeoutHelper.ts b/src/lib/timeoutHelper.ts index 2daeaa0..8382c8f 100644 --- a/src/lib/timeoutHelper.ts +++ b/src/lib/timeoutHelper.ts @@ -32,7 +32,6 @@ export async function timeout(broadcasterid: string, target: HelixUser, duration export async function addTimeoutToDB(attacker: HelixUser, target: HelixUser, source: shooter) { // This has passed the existance check so there's no need to check if the users exist (twitch) - const timeoutobj = { source, attacker: attacker.id, @@ -47,7 +46,7 @@ function remodMod(broadcasterid: string, target: HelixUser, duration: number, ap setTimeout(async () => { const bandata = await api.moderation.getBannedUsers(broadcasterid, { userId: target.id }) if (bandata.data.length !== 0) { - const timeoutleft = -Date.now() + Date.parse(bandata.data[0].expiryDate?.toString()! + 3000) // date when timeout expires - current date + 3 seconds constant + const timeoutleft = Date.parse(bandata.data[0].expiryDate?.toString()!) - Date.now() + 3000 // date when timeout expires - current date + 3 seconds constant remodMod(broadcasterid, target, timeoutleft, api) // Call the current function with new time (recursion) } else { // If user is still timed out it doesn't try to remod the target try { diff --git a/src/lib/userHelper.ts b/src/lib/userHelper.ts index ba38890..d02dbb2 100644 --- a/src/lib/userHelper.ts +++ b/src/lib/userHelper.ts @@ -1,16 +1,14 @@ import pb, { User } from './pocketbase' import { HelixUser } from '@twurple/api' +import itemData from '../items' -export const EMPTYINV: inventory = { - version: 1, +const EMPTYINV = itemData.reduce((acc, item) => { + acc[item.name] = 0 + return acc +}, {} as Record) - blaster: 0, - grenade: 0, - silverbullet: 0, - tnt: 0, - - clipboard: 0, - lootbox: 0 +export type inventory = { + [K in (keyof typeof EMPTYINV)]: number } type balanceGetResult = { @@ -79,28 +77,16 @@ async function getItemUses(userId: string, monthdata?: string): Promise item.name === 'blaster').length, grenade: items.filter((item) => item.name === 'grenade').length, silverbullet: items.filter((item) => item.name === 'silverbullet').length, tnt: items.filter((item) => item.name === 'tnt').length, + clipboard: items.filter((item) => item.name === 'clipboard').length, lootbox: items.filter((item) => item.name === 'lootbox').length } } -export interface inventory { - version: number, - - blaster: number, - grenade: number, - silverbullet: number, - tnt: number, - - clipboard: number, - lootbox: number -} - export async function getInventory(user: HelixUser): Promise { await DBValidation(user) const data = await pb.collection('users').getFirstListItem(`id="${user.id}"`)