mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 08:41:39 +01:00
part 1 of full item/inventory rework
This commit is contained in:
@@ -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 api from "../lib/api";
|
||||||
|
import items from "../items";
|
||||||
|
|
||||||
const blaster = createBotCommand('blaster', async (params, { say, broadcasterId, userId }) => {
|
const aliascommands: BotCommand[] = []
|
||||||
const user = await api.users.getUserById(userId)
|
|
||||||
if (params[0] === undefined) return
|
|
||||||
await useBlaster(broadcasterId, user!, params[0].replace(/[@]/g, ''), say)
|
|
||||||
}, { aliases: ['blast'] })
|
|
||||||
|
|
||||||
const silverbullet = createBotCommand('execute', async (params, { say, broadcasterId, userId }) => {
|
for (const item of items) {
|
||||||
const user = await api.users.getUserById(userId)
|
aliascommands.push(createBotCommand(item.name, async (params, { say, broadcasterId, userId }) => {
|
||||||
if (params[0] === undefined) return
|
const user = await api.users.getUserById(userId)
|
||||||
await useSilverBullet(broadcasterId, user!, params[0].replace(/[@]/g, ''), say)
|
switch (item.name) {
|
||||||
}, { aliases: ['silverbullet'] })
|
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 }) => {
|
export default aliascommands
|
||||||
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]
|
|
||||||
|
|||||||
@@ -1,31 +1,9 @@
|
|||||||
import { createBotCommand } from "@twurple/easy-bot";
|
import { createBotCommand } from "@twurple/easy-bot";
|
||||||
|
import items from "../items"
|
||||||
|
|
||||||
export default createBotCommand('iteminfo', async (params, { say }) => {
|
export default createBotCommand('iteminfo', async (params, { say }) => {
|
||||||
if (params[0] === undefined) { await say('No item specified!'); return }
|
if (params[0] === undefined) { await say('No item specified!'); return }
|
||||||
let message = ''
|
const selection = items.find(item => item.aliases.includes(params[0].toLowerCase()))
|
||||||
switch (params[0].toLowerCase()) {
|
if (!selection) { await say('Item not found'); return }
|
||||||
case 'blaster':
|
await say(selection[1].description)
|
||||||
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)
|
|
||||||
}, { aliases: ['item'] })
|
}, { aliases: ['item'] })
|
||||||
|
|||||||
@@ -1,37 +1,31 @@
|
|||||||
import { createBotCommand } from "@twurple/easy-bot";
|
import { createBotCommand } from "@twurple/easy-bot";
|
||||||
import { useBlaster, useClipboard, useGrenade, useLootbox, useSilverBullet, useTNT } from "../lib/items";
|
|
||||||
import api from "../lib/api";
|
import api from "../lib/api";
|
||||||
|
import items from "../items";
|
||||||
|
|
||||||
export default createBotCommand('use', async (params, { say, broadcasterId, userId }) => {
|
export default createBotCommand('use', async (params, { say, broadcasterId, userId }) => {
|
||||||
const user = await api.users.getUserById(userId)
|
const user = await api.users.getUserById(userId)
|
||||||
|
|
||||||
if (params[0] === undefined) return
|
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':
|
case 'blaster':
|
||||||
if (params[1] === undefined) return
|
|
||||||
await useBlaster(broadcasterId, user!, params[1].replace(/[@]/g, ''), say)
|
|
||||||
break
|
|
||||||
case 'silver':
|
|
||||||
case 'silverbullet':
|
case 'silverbullet':
|
||||||
if (params[1] === undefined) return
|
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
|
break
|
||||||
case 'grenade':
|
case 'grenade':
|
||||||
await useGrenade(broadcasterId, user!, say)
|
|
||||||
break
|
|
||||||
case 'tnt':
|
case 'tnt':
|
||||||
await useTNT(broadcasterId, user!, say)
|
await selection.execute(user!, say, broadcasterId)
|
||||||
break
|
break
|
||||||
case 'lootbox':
|
case 'lootbox':
|
||||||
case 'loot':
|
await selection.execute(user!, say)
|
||||||
await useLootbox(user!, say)
|
|
||||||
break
|
break
|
||||||
case 'clipboard':
|
case 'clipboard':
|
||||||
if (params[1] === undefined) return
|
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
|
break
|
||||||
default:
|
|
||||||
await say(`${params[0]} does not exist!`)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
76
src/items/blasters.ts
Normal file
76
src/items/blasters.ts
Normal file
@@ -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<void>, 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<void>, 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/items/clipboard.ts
Normal file
28
src/items/clipboard.ts
Normal file
@@ -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<void>, 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`)
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/items/explosives.ts
Normal file
76
src/items/explosives.ts
Normal file
@@ -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<void>, 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<void>, 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`)
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/items/index.ts
Normal file
18
src/items/index.ts
Normal file
@@ -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<void>, broadcasterId?: string, targetname?: string) => Promise<void>
|
||||||
|
}
|
||||||
|
const data = [blaster, silverbullet, grenade, tnt, lootbox, clipboard] as item[]
|
||||||
|
export const ITEMS = data.map(item => item.name)
|
||||||
|
export default data
|
||||||
32
src/items/lootbox.ts
Normal file
32
src/items/lootbox.ts
Normal file
@@ -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<void>) => {
|
||||||
|
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 ')}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
163
src/lib/items.ts
163
src/lib/items.ts
@@ -1,9 +1,6 @@
|
|||||||
import { HelixUser } from "@twurple/api"
|
import { HelixUser } from "@twurple/api"
|
||||||
import { addUsedItem, changeBalance, getInventory, inventory, updateInventory } from "../lib/userHelper"
|
import { getInventory, inventory, updateInventory } from "../lib/userHelper"
|
||||||
import { timeout, addTimeoutToDB, vulnerableUsers } from "./timeoutHelper"
|
import { ITEMS } from "../items"
|
||||||
import api, { broadcasterApi } from "./api"
|
|
||||||
|
|
||||||
export const ITEMS = ['blaster', 'silverbullet', 'grenade', 'tnt', 'clipboard', 'lootbox']
|
|
||||||
|
|
||||||
interface itemChangeResult {
|
interface itemChangeResult {
|
||||||
result: boolean,
|
result: boolean,
|
||||||
@@ -12,7 +9,7 @@ interface itemChangeResult {
|
|||||||
inv?: inventory
|
inv?: inventory
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function changeItemCount(user: HelixUser, item: string, amount = -1, preconfirmed=false): Promise<itemChangeResult> {
|
export async function changeItemCount(user: HelixUser, item: string, amount = -1, preconfirmed = false): Promise<itemChangeResult> {
|
||||||
if (!ITEMS.includes(item)) return { result: false, reason: 'noexist', count: 0 }
|
if (!ITEMS.includes(item)) return { result: false, reason: 'noexist', count: 0 }
|
||||||
let inv = await getInventory(user)
|
let inv = await getInventory(user)
|
||||||
|
|
||||||
@@ -22,160 +19,8 @@ export async function changeItemCount(user: HelixUser, item: string, amount = -1
|
|||||||
Object.defineProperty(inv, item, {
|
Object.defineProperty(inv, item, {
|
||||||
value: newcount,
|
value: newcount,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (amount > 0 || preconfirmed === true) await updateInventory(user, inv)
|
if (amount > 0 || preconfirmed === true) await updateInventory(user, inv)
|
||||||
|
|
||||||
return { result: true, reason: '', count: inv[item], inv }
|
return { result: true, reason: '', count: inv[item], inv }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function useBlaster(broadcasterId: string, attacker: HelixUser, targetname: string, say: (arg0: string) => Promise<void>) {
|
|
||||||
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<void>) {
|
|
||||||
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<void>) {
|
|
||||||
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<void>) {
|
|
||||||
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<void>) {
|
|
||||||
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<void>) {
|
|
||||||
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`)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { HelixUser } from "@twurple/api"
|
import { HelixUser } from "@twurple/api"
|
||||||
import pb, { User } from "./pocketbase"
|
import pb, { User } from "./pocketbase"
|
||||||
|
|
||||||
|
|
||||||
export const COOLDOWN = (!process.env.COOLDOWN ? 60 * 60 * 24 : Number(process.env.COOLDOWN)) * 1000
|
export const COOLDOWN = (!process.env.COOLDOWN ? 60 * 60 * 24 : Number(process.env.COOLDOWN)) * 1000
|
||||||
|
|
||||||
interface lootboxReadyResult {
|
interface lootboxReadyResult {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export async function timeout(broadcasterid: string, target: HelixUser, duration
|
|||||||
|
|
||||||
export async function addTimeoutToDB(attacker: HelixUser, target: HelixUser, source: shooter) {
|
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)
|
// This has passed the existance check so there's no need to check if the users exist (twitch)
|
||||||
|
|
||||||
const timeoutobj = {
|
const timeoutobj = {
|
||||||
source,
|
source,
|
||||||
attacker: attacker.id,
|
attacker: attacker.id,
|
||||||
@@ -47,7 +46,7 @@ function remodMod(broadcasterid: string, target: HelixUser, duration: number, ap
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const bandata = await api.moderation.getBannedUsers(broadcasterid, { userId: target.id })
|
const bandata = await api.moderation.getBannedUsers(broadcasterid, { userId: target.id })
|
||||||
if (bandata.data.length !== 0) {
|
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)
|
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
|
} else { // If user is still timed out it doesn't try to remod the target
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
import pb, { User } from './pocketbase'
|
import pb, { User } from './pocketbase'
|
||||||
import { HelixUser } from '@twurple/api'
|
import { HelixUser } from '@twurple/api'
|
||||||
|
import itemData from '../items'
|
||||||
|
|
||||||
export const EMPTYINV: inventory = {
|
const EMPTYINV = itemData.reduce((acc, item) => {
|
||||||
version: 1,
|
acc[item.name] = 0
|
||||||
|
return acc
|
||||||
|
}, {} as Record<string, number>)
|
||||||
|
|
||||||
blaster: 0,
|
export type inventory = {
|
||||||
grenade: 0,
|
[K in (keyof typeof EMPTYINV)]: number
|
||||||
silverbullet: 0,
|
|
||||||
tnt: 0,
|
|
||||||
|
|
||||||
clipboard: 0,
|
|
||||||
lootbox: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type balanceGetResult = {
|
type balanceGetResult = {
|
||||||
@@ -79,28 +77,16 @@ async function getItemUses(userId: string, monthdata?: string): Promise<inventor
|
|||||||
if (monthdata) monthquery = ` && created~"${monthdata}"`
|
if (monthdata) monthquery = ` && created~"${monthdata}"`
|
||||||
const items = await pb.collection('itemuses').getFullList({ filter: `user="${userId}"${monthquery}` })
|
const items = await pb.collection('itemuses').getFullList({ filter: `user="${userId}"${monthquery}` })
|
||||||
return {
|
return {
|
||||||
version: 1,
|
|
||||||
blaster: items.filter((item) => item.name === 'blaster').length,
|
blaster: items.filter((item) => item.name === 'blaster').length,
|
||||||
grenade: items.filter((item) => item.name === 'grenade').length,
|
grenade: items.filter((item) => item.name === 'grenade').length,
|
||||||
silverbullet: items.filter((item) => item.name === 'silverbullet').length,
|
silverbullet: items.filter((item) => item.name === 'silverbullet').length,
|
||||||
tnt: items.filter((item) => item.name === 'tnt').length,
|
tnt: items.filter((item) => item.name === 'tnt').length,
|
||||||
|
|
||||||
clipboard: items.filter((item) => item.name === 'clipboard').length,
|
clipboard: items.filter((item) => item.name === 'clipboard').length,
|
||||||
lootbox: items.filter((item) => item.name === 'lootbox').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<inventory> {
|
export async function getInventory(user: HelixUser): Promise<inventory> {
|
||||||
await DBValidation(user)
|
await DBValidation(user)
|
||||||
const data = await pb.collection('users').getFirstListItem(`id="${user.id}"`)
|
const data = await pb.collection('users').getFirstListItem(`id="${user.id}"`)
|
||||||
|
|||||||
Reference in New Issue
Block a user