From 2b90d51647700055fe346e44d7a162b26612ff06 Mon Sep 17 00:00:00 2001 From: qwerinope Date: Mon, 31 Mar 2025 09:05:42 +0200 Subject: [PATCH] inventory system now functional, TODO: add mbucks cmds, allow item usage --- src/commands/give.ts | 60 +++++++++++++++++++++++++++ src/commands/index.ts | 4 +- src/commands/inventory.ts | 20 +++++++++ src/commands/timeout.ts | 4 +- src/items/blaster.ts | 9 ++++ src/items/clipboard.ts | 9 ++++ src/items/grenade.ts | 9 ++++ src/items/items.d.ts | 5 +++ src/items/lootbox.ts | 9 ++++ src/items/silverbullet.ts | 9 ++++ src/items/tnt.ts | 9 ++++ src/items/watergun.ts | 9 ++++ src/lib/itemHelpers/blaster.ts | 13 ------ src/lib/userHelper.ts | 75 +++++++++++++++++++++++----------- 14 files changed, 204 insertions(+), 40 deletions(-) create mode 100644 src/commands/give.ts create mode 100644 src/commands/inventory.ts create mode 100644 src/items/blaster.ts create mode 100644 src/items/clipboard.ts create mode 100644 src/items/grenade.ts create mode 100644 src/items/items.d.ts create mode 100644 src/items/lootbox.ts create mode 100644 src/items/silverbullet.ts create mode 100644 src/items/tnt.ts create mode 100644 src/items/watergun.ts delete mode 100644 src/lib/itemHelpers/blaster.ts diff --git a/src/commands/give.ts b/src/commands/give.ts new file mode 100644 index 0000000..b251baf --- /dev/null +++ b/src/commands/give.ts @@ -0,0 +1,60 @@ +import { changeBalance } from "../lib/userHelper"; +import { changeBlasterCount } from "../items/blaster" +import { changeTntCount } from "../items/tnt"; +import { changeSilverbulletCount } from "../items/silverbullet" +import { changeWatergunCount } from "../items/watergun" +import { changeLootboxCount } from "../items/lootbox" +import { changeGrenadeCount } from "../items/grenade" + +import { createBotCommand } from "@twurple/easy-bot"; +import api from "../lib/api"; + +export default createBotCommand('give', async (params, { say, broadcasterId, userId }) => { + if (userId !== broadcasterId) return + + const target = await api.users.getUserByName(params[0]) + if (!target) { await say(`'${params[0]}' does not exist`); return } + + if (Number(params[2]) === 0) {await say(`Specify the amount`)} + + switch (params[1].toLowerCase()) { + case 'mbucks': + const data1 = await changeBalance(target.name, parseInt(params[2])) + if (!data1.result) { await say(`${target.name} only has ${data1.userBalance}. Cannot subtract ${-parseInt(params[2])} mbucks`); return } + await say(`${target.name} now has ${data1.userBalance.balance} mbucks`) + break + case 'blaster': + const data2 = await changeBlasterCount(target.name, parseInt(params[2])) + if (!data2.result) { await say(`${target.name} only has ${data2.count}. Cannot yoink ${-parseInt(params[2])} blaster${data2.count === 1 ? '' : 's'}`); return } + await say(`${target.name} now has ${data2.count} blaster${data2.count === 1 ? '' : 's'}`) + break + case 'tnt': + const data3 = await changeTntCount(target.name, parseInt(params[2])) + if (!data3.result) { await say(`${target.name} only has ${data3.count}. Cannot yoink ${-parseInt(params[2])} tnt`); return } + await say(`${target.name} now has ${data3.count} tnt`) + break + case 'silverbullet': + const data4 = await changeSilverbulletCount(target.name, parseInt(params[2])) + if (!data4.result) { await say(`${target.name} only has ${data4.count}. Cannot yoink ${-parseInt(params[2])} silverbullet${data4.count === 1 ? '' : 's'}`) } + await say(`${target.name} now has ${data4.count} silverbullet${data4.count === 1 ? '' : 's'}`) + break + case 'watergun': + const data5 = await changeWatergunCount(target.name, parseInt(params[2])) + if (!data5.result) { await say(`${target.name} only has ${data5.count}. Cannot yoink ${-parseInt(params[2])} watergun${data5.count === 1 ? '' : 's'}`) } + await say(`${target.name} now has ${data5.count} watergun${data5.count === 1 ? '' : 's'}`) + break + case 'lootbox': + const data6 = await changeLootboxCount(target.name, parseInt(params[2])) + if (!data6.result) { await say(`${target.name} only has ${data6.count}. Cannot yoink ${-parseInt(params[2])} lootbox${data6.count === 1 ? '' : 'es'}`) } + await say(`${target.name} now has ${data6.count} lootbox${data6.count === 1 ? '' : 'es'}`) + break + case 'grenade': + const data7 = await changeGrenadeCount(target.name, parseInt(params[2])) + if (!data7.result) { await say(`${target.name} only has ${data7.count}. Cannot yoink ${-parseInt(params[2])} grenade${data7.count === 1 ? '' : 's'}`) } + await say(`${target.name} now has ${data7.count} grenade${data7.count === 1 ? '' : 's'}`) + break + default: + await say(`Can't find item ${params[1]}`) + break + } +}) diff --git a/src/commands/index.ts b/src/commands/index.ts index dbfd51f..d3f0cdc 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,4 +1,6 @@ import timeout from "./timeout"; import thank from "./thank" +import give from "./give" +import inventory from "./inventory"; -export default [timeout, thank] \ No newline at end of file +export default [timeout, thank, give, inventory] diff --git a/src/commands/inventory.ts b/src/commands/inventory.ts new file mode 100644 index 0000000..bf93c66 --- /dev/null +++ b/src/commands/inventory.ts @@ -0,0 +1,20 @@ +import { createBotCommand } from "@twurple/easy-bot"; +import { getInventory } from "../lib/userHelper"; +import api from "../lib/api"; + +export default createBotCommand('inv', async (params, { userName, say, reply }) => { + if (params.length !== 0 && !await api.users.getUserByName(params[0])) { say(`User ${params[0]} not found`); return } + + const data = params.length === 0 ? { me: true, inv: await getInventory(userName) } : { me: false, inv: await getInventory(params[0]) } + + await say( + `inventory of ${data.me ? userName : params[0]}: + blaster${data.inv.blaster === 1 ? '' : 's'}: ${data.inv.blaster}, + grenade${data.inv.grenade === 1 ? '' : 's'}: ${data.inv.grenade}, + tnt: ${data.inv.tnt}, + watergun${data.inv.watergun === 1 ? '' : 's'}: ${data.inv.watergun}, + silverbullet${data.inv.silverbullet === 1 ? '' : 's'}: ${data.inv.silverbullet}, + clipboard${data.inv.clipboard === 1 ? '' : 's'}: ${data.inv.clipboard}, + lootbox${data.inv.lootbox === 1 ? '' : 'es'}: ${data.inv.lootbox}` + ) +}, { aliases: ['inventory'] }) diff --git a/src/commands/timeout.ts b/src/commands/timeout.ts index 5e1ee4a..03fbe25 100644 --- a/src/commands/timeout.ts +++ b/src/commands/timeout.ts @@ -5,7 +5,7 @@ import api from "../lib/api"; export default createBotCommand('timeout', async (params, { say, broadcasterId, userName }) => { if (params.length === 0) {await say("nice miss bro"); return} const target = await api.users.getUserByName(params[0]) - const status = await timeout(broadcasterId, target!, 60, `You got blasted by '${userName}'`) + const status = await timeout(broadcasterId, target!, 60, `You got blasted by ${userName}`) if (status.status) { await say(`${params[0]} got mandoooGun by ${userName}! mandoooGOTTEM`) const attacker = await api.users.getUserByName(userName) @@ -24,4 +24,4 @@ export default createBotCommand('timeout', async (params, { say, broadcasterId, break } } -}) \ No newline at end of file +}) diff --git a/src/items/blaster.ts b/src/items/blaster.ts new file mode 100644 index 0000000..3ab295e --- /dev/null +++ b/src/items/blaster.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeBlasterCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.blaster + amount < 0) return {result: false, count: inv.blaster} + inv.blaster += amount + await updateInventory(username, inv) + return {result: true, count: inv.blaster} +} diff --git a/src/items/clipboard.ts b/src/items/clipboard.ts new file mode 100644 index 0000000..f7da99f --- /dev/null +++ b/src/items/clipboard.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeClipboardCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.clipboard+ amount < 0) return {result: false, count: inv.clipboard} + inv.clipboard += amount + await updateInventory(username, inv) + return {result: true, count: inv.clipboard} +} diff --git a/src/items/grenade.ts b/src/items/grenade.ts new file mode 100644 index 0000000..d8495f4 --- /dev/null +++ b/src/items/grenade.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeGrenadeCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.grenade+ amount < 0) return {result: false, count: inv.grenade} + inv.grenade += amount + await updateInventory(username, inv) + return {result: true, count: inv.grenade} +} diff --git a/src/items/items.d.ts b/src/items/items.d.ts new file mode 100644 index 0000000..893eadb --- /dev/null +++ b/src/items/items.d.ts @@ -0,0 +1,5 @@ +interface itemChangeResult { + result: boolean, + count: number +} + diff --git a/src/items/lootbox.ts b/src/items/lootbox.ts new file mode 100644 index 0000000..3cac5bf --- /dev/null +++ b/src/items/lootbox.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeLootboxCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.lootbox+ amount < 0) return {result: false, count: inv.lootbox} + inv.lootbox += amount + await updateInventory(username, inv) + return {result: true, count: inv.lootbox} +} diff --git a/src/items/silverbullet.ts b/src/items/silverbullet.ts new file mode 100644 index 0000000..ccb3054 --- /dev/null +++ b/src/items/silverbullet.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeSilverbulletCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.silverbullet+ amount < 0) return {result: false, count: inv.silverbullet} + inv.silverbullet += amount + await updateInventory(username, inv) + return {result: true, count: inv.silverbullet} +} diff --git a/src/items/tnt.ts b/src/items/tnt.ts new file mode 100644 index 0000000..75e8925 --- /dev/null +++ b/src/items/tnt.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeTntCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.tnt+ amount < 0) return {result: false, count: inv.tnt} + inv.tnt += amount + await updateInventory(username, inv) + return {result: true, count: inv.tnt} +} diff --git a/src/items/watergun.ts b/src/items/watergun.ts new file mode 100644 index 0000000..dba1ca9 --- /dev/null +++ b/src/items/watergun.ts @@ -0,0 +1,9 @@ +import { getInventory, updateInventory } from "../lib/userHelper"; + +export async function changeWatergunCount(username: string, amount = -1): Promise { + let inv = await getInventory(username) + if (amount < 0 && inv.watergun+ amount < 0) return {result: false, count: inv.watergun} + inv.watergun += amount + await updateInventory(username, inv) + return {result: true, count: inv.watergun} +} diff --git a/src/lib/itemHelpers/blaster.ts b/src/lib/itemHelpers/blaster.ts deleted file mode 100644 index a3ec0f6..0000000 --- a/src/lib/itemHelpers/blaster.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getInventory, updateInventory } from "../userHelper"; - -export async function giveBlaster(username:string, amount:number) { - let inv = await getInventory(username) - inv.blaster += amount - await updateInventory(username, inv) -} - -export async function loseBlaster(username: string, amount=1) { - let inv = await getInventory(username) - inv.blaster -= amount - await updateInventory(username, inv) -} \ No newline at end of file diff --git a/src/lib/userHelper.ts b/src/lib/userHelper.ts index 4e81125..b5f1e08 100644 --- a/src/lib/userHelper.ts +++ b/src/lib/userHelper.ts @@ -2,20 +2,7 @@ import pb from './pocketbase' import api from './api' import { HelixUser } from '@twurple/api' -interface inventory { - version: number - - blaster: number - grenade: number - silverbullet: number - tnt: number - watergun: number - - clipboard:number - lootbox:number -} - -const EMPTYINV = { +const EMPTYINV: inventory = { version: 1, blaster: 0, @@ -28,41 +15,81 @@ const EMPTYINV = { lootbox: 0 } -export async function getDBID(user:HelixUser) { +export async function getDBID(user: HelixUser) { try { const DBuser = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) return DBuser.id } catch (error) { await createUser(user!) - const DBuser = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) + const DBuser = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) return DBuser.id } } -export async function getInventory(username:string): Promise{ +type balanceGetResult = { + balance: number, + user: HelixUser +} + +export async function getBalance(username: string): Promise { + const user = await existanceValidation(username) + const data = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) + return { balance: data.balance, user } +} + +type balanceChangeResult = { + result: boolean, + userBalance: balanceGetResult +} + +export async function changeBalance(username: string, amount: number): Promise { + let userBalance = await getBalance(username) + if (amount < 0 && userBalance.balance - amount < 0) return {result: false , userBalance} + const dbuser = await pb.collection('users').getFirstListItem(`twitchid="${userBalance.user.id}"`) + let data = dbuser + data.balance += amount + userBalance.balance += amount + await pb.collection('users').update(dbuser.id, data) + return {result: true, userBalance} +} + +interface inventory { + version: number, + + blaster: number, + grenade: number, + silverbullet: number, + tnt: number, + watergun: number, + + clipboard: number, + lootbox: number +} + +export async function getInventory(username: string): Promise { const user = await existanceValidation(username) const data = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) return data.inventory } -export async function updateInventory(username:string, newinv:inventory) { +export async function updateInventory(username: string, newinv: inventory) { const user = await existanceValidation(username) const data = await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) const recordid = data.id - await pb.collection('users').update(recordid, {inventory:newinv}) + await pb.collection('users').update(recordid, { inventory: newinv }) } -async function existanceValidation(username:string) { +async function existanceValidation(username: string): Promise { const user = await api.users.getUserByName(username) try { - await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) + await pb.collection('users').getFirstListItem(`twitchid="${user!.id}"`) } catch (error) { await createUser(user!) } - return user + return user! } -async function createUser(user:HelixUser) { +async function createUser(user: HelixUser) { const data = { twitchid: user?.id, firstname: user?.name, @@ -70,4 +97,4 @@ async function createUser(user:HelixUser) { balance: 0 } await pb.collection('users').create(data) -} \ No newline at end of file +}